Commit f850efb2 authored by Remi Forax's avatar Remi Forax

Simplify the handling of OpenJDK specific module attributes

parent 3b01f9f8
......@@ -30,6 +30,8 @@
package org.objectweb.asm.commons;
import java.util.List;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
......@@ -91,20 +93,12 @@ public class ClassRemapper extends ClassVisitor {
@Override
public void visitAttribute(Attribute attr) {
if (attr instanceof ModuleTargetAttribute) {
ModuleTargetAttribute renamedAttribute = new ModuleTargetAttribute();
((ModuleTargetAttribute)attr).accept(createModuleAttributeRemapper(renamedAttribute));
attr = renamedAttribute;
}
else if (attr instanceof ModuleHashesAttribute) {
ModuleHashesAttribute renamedAttribute = new ModuleHashesAttribute();
((ModuleHashesAttribute)attr).accept(createModuleAttributeRemapper(renamedAttribute));
attr = renamedAttribute;
}
else if (attr instanceof ModuleResolutionAttribute) {
ModuleResolutionAttribute renamedAttribute = new ModuleResolutionAttribute();
((ModuleResolutionAttribute)attr).accept(createModuleAttributeRemapper(renamedAttribute));
attr = renamedAttribute;
if (attr instanceof ModuleHashesAttribute) {
ModuleHashesAttribute hashesAttr = new ModuleHashesAttribute();
List<String> modules = hashesAttr.modules;
for(int i = 0; i < modules.size(); i++) {
modules.set(i, remapper.mapModuleName(modules.get(i)));
}
}
super.visitAttribute(attr);
}
......@@ -160,8 +154,4 @@ public class ClassRemapper extends ClassVisitor {
protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
return new ModuleRemapper(mv, remapper);
}
protected ModuleAttributeRemapper createModuleAttributeRemapper(ModuleAttributeVisitor mv) {
return new ModuleAttributeRemapper(mv, remapper);
}
}
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.commons;
import org.objectweb.asm.Opcodes;
/**
* A {@link ModuleAttributeVisitor} adapter for name remapping.
*
* @author Remi Forax
*/
public class ModuleAttributeRemapper extends ModuleAttributeVisitor {
private final Remapper remapper;
public ModuleAttributeRemapper(final ModuleAttributeVisitor mv,
final Remapper remapper) {
this(Opcodes.ASM6, mv, remapper);
}
protected ModuleAttributeRemapper(final int api, final ModuleAttributeVisitor mv,
final Remapper remapper) {
super(api, mv);
this.remapper = remapper;
}
@Override
public void visitModuleHash(String module, byte[] hash) {
super.visitModuleHash(remapper.mapModuleName(module), hash);
}
}
\ No newline at end of file
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.commons;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Opcodes;
/**
* A visitor for the OpenJDK specific attributes {@link ModuleTargetAttribute},
* {@link ModuleHashesAttribute} and {@link ModuleResolutionAttribute}.
*
* This visitor inherits from {@link Attribute} but should not be used as
* an Attribute, it allows subclasses to be Attributes and to inherits from
* this visitor.
*
* @author Remi Forax
*/
public class ModuleAttributeVisitor extends Attribute {
/**
* Resolution state of a module meaning that the module is not available
* from the class-path by default.
*/
public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
/**
* Resolution state of a module meaning the module is marked as deprecated.
*/
public static final int RESOLUTION_WARN_DEPRECATED = 2;
/**
* Resolution state of a module meaning the module is marked as deprecated
* and will be removed in a future release.
*/
public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
/**
* Resolution state of a module meaning the module is not yet standardized,
* so in incubating mode.
*/
public static final int RESOLUTION_WARN_INCUBATING = 8;
/**
* The ASM API version implemented by this visitor. The value of this field
* must be {@link Opcodes#ASM6}.
*/
protected final int api;
/**
* The module visitor to which this visitor must delegate method calls. May
* be null.
*/
protected ModuleAttributeVisitor mv;
ModuleAttributeVisitor(final int api, final String type) {
super(type);
if (api != Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
}
/**
* Constructs a new {@link ModuleAttributeVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
*/
public ModuleAttributeVisitor(final int api) {
this(api, (String)null);
}
/**
* Constructs a new {@link ModuleAttributeVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
* @param mv
* the attribute visitor to which this visitor must delegate method
* calls. May be null.
*/
public ModuleAttributeVisitor(final int api, final ModuleAttributeVisitor mv) {
this(api, (String)null);
this.mv = mv;
}
/**
* Visit the platform name.
* @param platform the platform name.
*/
public void visitPlatform(final String platform) {
if (mv != null) {
mv.visitPlatform(platform);
}
}
/**
* Visit the name of the algorithm used for hashing.
* @param algorithm the name of the algorithm used for hashing.
*/
public void visitHashAlgorithm(final String algorithm) {
if (mv != null) {
mv.visitHashAlgorithm(algorithm);
}
}
/**
* Visit the hash of a module.
* @param module the module name.
* @param hash the hash.
*
* @see #visitHashAlgorithm(String)
*/
public void visitModuleHash(final String module, final byte[] hash) {
if (mv != null) {
mv.visitModuleHash(module, hash);
}
}
/**
* The resolution state of a module.
* @param resolution the resolution state of the module among
* {@linkplain #RESOLUTION_WARN_DEPRECATED},
* {@linkplain #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}
* and {@linkplain #RESOLUTION_WARN_INCUBATING}.
*/
public void visitResolution(final int resolution) {
if (mv != null) {
mv.visitResolution(resolution);
}
}
}
......@@ -38,32 +38,14 @@ import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
/**
* ModuleHashes attribute.
* This attribute is specific to the OpenJDK and may change in the future.
*
* Unlike a classical ASM attribute, this attribute can interact
* with {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* in two different ways.
* The usual way, by creating an empty attribute using {@link #ModuleHashesAttribute()}
* that will be sent as argument of the method accept of the ClassReader and
* during the parsing the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will be called.
* The visitor way, by creating an empty attribute using
* {@link #ModuleHashesAttribute(int, ModuleAttributeVisitor)} that will called
* the methods of the {@link ModuleAttributeVisitor} when the attribute is found.
* In that case the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will not be called.
*
* Moreover, like the Tree API, this attribute is itself a visitor and has a method
* {@link #accept(ModuleAttributeVisitor)} that allow to extract the values of this
* attribute using a visitor.
*
* @author Remi Forax
*/
public final class ModuleHashesAttribute extends ModuleAttributeVisitor {
public final class ModuleHashesAttribute extends Attribute {
public String algorithm;
public List<String> modules;
public List<byte[]> hashes;
......@@ -77,7 +59,7 @@ public final class ModuleHashesAttribute extends ModuleAttributeVisitor {
*/
public ModuleHashesAttribute(final String algorithm,
final List<String> modules, final List<byte[]> hashes) {
super(Opcodes.ASM6, "ModuleHashes");
super("ModuleHashes");
this.algorithm = algorithm;
this.modules = modules;
this.hashes = hashes;
......@@ -92,64 +74,17 @@ public final class ModuleHashesAttribute extends ModuleAttributeVisitor {
this(null, null, null);
}
/**
* Create an empty attribute that when used with
* {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* will called the visitor taken as parameter if an attribute of the same kind
* is found
*
* @param api the ASM api to use, only {@link Opcodes#ASM6} is valid.
* @param mv a module attribute visitor
*/
public ModuleHashesAttribute(final int api, final ModuleAttributeVisitor mv) {
super(api, "ModuleHashes");
this.mv = mv;
}
/**
* Makes the given visitor visit this attribute.
*
* @param mv a module attribute visitor.
*/
public void accept(final ModuleAttributeVisitor mv) {
mv.visitHashAlgorithm(algorithm);
List<String> modules = this.modules;
if (modules != null) {
List<byte[]> hashes = this.hashes;
int count = modules.size();
for(int i = 0; i < count; i++) {
mv.visitModuleHash(modules.get(i), hashes.get(i));
}
}
}
@Override
public void visitHashAlgorithm(String hashAlgorithm) {
this.algorithm = hashAlgorithm;
}
@Override
public void visitModuleHash(String module, byte[] hash) {
if (modules == null) {
modules = new ArrayList<String>();
hashes = new ArrayList<byte[]>();
}
modules.add(module);
hashes.add(hash);
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
ModuleHashesAttribute attr = null;
ModuleAttributeVisitor mv = (this.mv == null)? attr = new ModuleHashesAttribute(): this.mv;
String hashAlgorithm = cr.readUTF8(off, buf);
mv.visitHashAlgorithm(hashAlgorithm);
int count = cr.readUnsignedShort(off + 2);
ArrayList<String> modules = new ArrayList<String>(count);
ArrayList<byte[]> hashes = new ArrayList<byte[]>(count);
off += 4;
for (int i = 0; i< count; i++) {
for (int i = 0; i < count; i++) {
String module = cr.readModule(off, buf);
int hashLength = cr.readUnsignedShort(off + 2);
off += 4;
......@@ -160,9 +95,10 @@ public final class ModuleHashesAttribute extends ModuleAttributeVisitor {
}
off += hashLength;
mv.visitModuleHash(module, hash);
modules.add(module);
hashes.add(hash);
}
return attr;
return new ModuleHashesAttribute(hashAlgorithm, modules, hashes);
}
@Override
......
......@@ -35,32 +35,37 @@ import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
/**
* ModuleResolution_attribute.
* This attribute is specific to the OpenJDK and may change in the future.
*
* Unlike a classical ASM attribute, this attribute can interact
* with {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* in two different ways.
* The usual way, by creating an empty attribute using {@link #ModuleResolutionAttribute()}
* that will be sent as argument of the method accept of the ClassReader and
* during the parsing the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will be called.
* The visitor way, by creating an empty attribute using
* {@link #ModuleResolutionAttribute(int, ModuleAttributeVisitor)} that will called
* the methods of the {@link ModuleAttributeVisitor} when the attribute is found.
* In that case the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will not be called.
*
* Moreover, like the Tree API, this attribute is itself a visitor and has a method
* {@link #accept(ModuleAttributeVisitor)} that allow to extract the values of this
* attribute using a visitor.
*
* @author Remi Forax
*/
public final class ModuleResolutionAttribute extends ModuleAttributeVisitor {
public final class ModuleResolutionAttribute extends Attribute {
/**
* Resolution state of a module meaning that the module is not available
* from the class-path by default.
*/
public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
/**
* Resolution state of a module meaning the module is marked as deprecated.
*/
public static final int RESOLUTION_WARN_DEPRECATED = 2;
/**
* Resolution state of a module meaning the module is marked as deprecated
* and will be removed in a future release.
*/
public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
/**
* Resolution state of a module meaning the module is not yet standardized,
* so in incubating mode.
*/
public static final int RESOLUTION_WARN_INCUBATING = 8;
public int resolution;
/**
......@@ -71,7 +76,7 @@ public final class ModuleResolutionAttribute extends ModuleAttributeVisitor {
* {@link #RESOLUTION_WARN_INCUBATING}.
*/
public ModuleResolutionAttribute(final int resolution) {
super(Opcodes.ASM6, "ModuleResolution");
super("ModuleResolution");
this.resolution = resolution;
}
......@@ -84,45 +89,10 @@ public final class ModuleResolutionAttribute extends ModuleAttributeVisitor {
this(0);
}
/**
* Create an empty attribute that when used with
* {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* will called the visitor taken as parameter if an attribute of the same kind
* is found
*
* @param api the ASM api to use, only {@link Opcodes#ASM6} is valid.
* @param mv a module attribute visitor
*/
public ModuleResolutionAttribute(final int api, final ModuleAttributeVisitor mv) {
super(api, "ModuleResolution");
this.mv = mv;
}
/**
* Makes the given visitor visit this attribute.
*
* @param mv a module attribute visitor.
*/
public void accept(final ModuleAttributeVisitor mv) {
int resolution = this.resolution;
if (resolution != 0) {
mv.visitResolution(resolution);
}
}
@Override
public void visitResolution(int resolution) {
this.resolution = resolution;
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
int resolution = cr.readUnsignedShort(off);
if (mv != null) {
mv.visitResolution(resolution);
return null;
}
return new ModuleResolutionAttribute(resolution);
}
......
......@@ -35,32 +35,14 @@ import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
/**
* ModuleTarget attribute.
* This attribute is specific to the OpenJDK and may change in the future.
*
* Unlike a classical ASM attribute, this attribute can interact
* with {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* in two different ways.
* The usual way, by creating an empty attribute using {@link #ModuleTargetAttribute()}
* that will be sent as argument of the method accept of the ClassReader and
* during the parsing the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will be called.
* The visitor way, by creating an empty attribute using
* {@link #ModuleTargetAttribute(int, ModuleAttributeVisitor)} that will called
* the methods of the {@link ModuleAttributeVisitor} when the attribute is found.
* In that case the method {@link org.objectweb.asm.ClassVisitor#visitAttribute(Attribute)}
* will not be called.
*
* Moreover, like the Tree API, this attribute is itself a visitor and has a method
* {@link #accept(ModuleAttributeVisitor)} that allow to extract the values of this
* attribute using a visitor.
*
* @author Remi Forax
*/
public final class ModuleTargetAttribute extends ModuleAttributeVisitor {
public final class ModuleTargetAttribute extends Attribute {
public String platform;
/**
......@@ -68,7 +50,7 @@ public final class ModuleTargetAttribute extends ModuleAttributeVisitor {
* @param platform the platform name on which the module can run.
*/
public ModuleTargetAttribute(final String platform) {
super(Opcodes.ASM6, "ModuleTarget");
super("ModuleTarget");
this.platform = platform;
}
......@@ -81,45 +63,10 @@ public final class ModuleTargetAttribute extends ModuleAttributeVisitor {
this(null);
}
/**
* Create an empty attribute that when used with
* {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}
* will called the visitor taken as parameter if an attribute of the same kind
* is found
*
* @param api the ASM api to use, only {@link Opcodes#ASM6} is valid.
* @param mv a module attribute visitor
*/
public ModuleTargetAttribute(final int api, final ModuleAttributeVisitor mv) {
super(api, "ModuleTarget");
this.mv = mv;
}
/**
* Makes the given visitor visit this attribute.
*
* @param mv a module attribute visitor.
*/
public void accept(final ModuleAttributeVisitor mv) {
String platform = this.platform;
if (platform != null) {
mv.visitPlatform(platform);
}
}
@Override
public void visitPlatform(String platform) {
this.platform = platform;
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
String platform = cr.readUTF8(off, buf);
if (mv != null) {
mv.visitPlatform(platform);
return null;
}
String platform = cr.readUTF8(off, buf);
return new ModuleTargetAttribute(platform);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment