下面列出了org.objectweb.asm.Opcodes# ACC_ENUM 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
isInterface = Modifier.isInterface(access);
isEnum = (access & Opcodes.ACC_ENUM) !=0;
this.classname = name;
this.superclassname = superName;
for(String iface : interfaces){
/*if(iface.equals("java/io/Serializable")){
isSerializable = true;
}
else*/ if(iface.equals("java/io/Externalizable")){//iface requies the existance of the read and write object methods, no no further check is needed
isExternalizable = true;
break;
}
}
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
// Get the class name, access flags, and interfaces information (step 1, 2 and 3) for SVUID
// computation.
computeSvuid = (access & Opcodes.ACC_ENUM) == 0;
if (computeSvuid) {
this.name = name;
this.access = access;
this.interfaces = interfaces.clone();
this.svuidFields = new ArrayList<>();
this.svuidConstructors = new ArrayList<>();
this.svuidMethods = new ArrayList<>();
}
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
// Get the class name, access flags, and interfaces information (step 1, 2 and 3) for SVUID
// computation.
computeSVUID = (access & Opcodes.ACC_ENUM) == 0;
if (computeSVUID) {
this.name = name;
this.access = access;
this.interfaces = new String[interfaces.length];
this.svuidFields = new ArrayList<Item>();
this.svuidConstructors = new ArrayList<Item>();
this.svuidMethods = new ArrayList<Item>();
System.arraycopy(interfaces, 0, this.interfaces, 0, interfaces.length);
}
super.visit(version, access, name, signature, superName, interfaces);
}
/**
* Gets the field access flags (see JVMS8 4.5) for the given variable element, augmented by the
* special ASM pseudo-access flag for @Deprecated fields.
*/
public int getAccessFlags(VariableElement variableElement) {
int result = getCommonAccessFlags(variableElement);
if (variableElement.getKind() == ElementKind.ENUM_CONSTANT) {
result = result | Opcodes.ACC_ENUM;
}
return result;
}
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
isEnumCls = (access & Opcodes.ACC_ENUM) != 0 && superName.equals("java/lang/Enum");
if(fromName.equals(name)){//TODO: remove this check
super.visit(version, ACC_PUBLIC + ACC_SUPER + ACC_STATIC, globName, null, "com/concurnas/bootstrap/runtime/cps/CObject", null);
}
this.superClass = superName;
this.ifaces = interfaces;
return;
}
public static String getAccessString(int access) {
List<String> tokens = new ArrayList<>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0)
tokens.add("private");
if ((access & Opcodes.ACC_PROTECTED) != 0)
tokens.add("protected");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_SYNTHETIC) != 0)
tokens.add("synthetic");
// if ((access & Opcodes.ACC_SUPER) != 0)
// tokens.add("super"); implied by invokespecial insn
if ((access & Opcodes.ACC_ABSTRACT) != 0)
tokens.add("abstract");
if ((access & Opcodes.ACC_INTERFACE) != 0)
tokens.add("interface");
if ((access & Opcodes.ACC_ENUM) != 0)
tokens.add("enum");
if ((access & Opcodes.ACC_ANNOTATION) != 0)
tokens.add("annotation");
if (!tokens.contains("interface") && !tokens.contains("enum") && !tokens.contains("annotation"))
tokens.add("class");
if (tokens.size() == 0)
return "[Error parsing]";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
sb.append(" ");
sb.append(tokens.get(i));
}
return sb.toString();
}
public static String getAccessString(int access) {
List<String> tokens = new ArrayList<String>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0)
tokens.add("private");
if ((access & Opcodes.ACC_PROTECTED) != 0)
tokens.add("protected");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_SYNTHETIC) != 0)
tokens.add("synthetic");
// if ((access & Opcodes.ACC_SUPER) != 0)
// tokens.add("super"); implied by invokespecial insn
if ((access & Opcodes.ACC_ABSTRACT) != 0)
tokens.add("abstract");
if ((access & Opcodes.ACC_INTERFACE) != 0)
tokens.add("interface");
if ((access & Opcodes.ACC_ENUM) != 0)
tokens.add("enum");
if ((access & Opcodes.ACC_ANNOTATION) != 0)
tokens.add("annotation");
if (!tokens.contains("interface") && !tokens.contains("enum")
&& !tokens.contains("annotation"))
tokens.add("class");
if (tokens.size() == 0)
return "[Error parsing]";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
sb.append(" ");
sb.append(tokens.get(i));
}
return sb.toString();
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
cls.setBaseClass(superName);
cls.setBaseInterfaces(interfaces);
if((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT) {
cls.setIsAbstract(true);
}
if((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) {
cls.setIsInterface(true);
}
if((access & Opcodes.ACC_ANNOTATION) == Opcodes.ACC_ANNOTATION) {
cls.setIsAnnotation(true);
}
if((access & Opcodes.ACC_SYNTHETIC) == Opcodes.ACC_SYNTHETIC) {
cls.setIsSynthetic(true);
}
if((access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL) {
cls.setFinalClass(true);
}
if ("com/codename1/testing/UnitTest".equals(superName) || "com/codename1/testing/AbstractTest".equals(superName)) {
cls.setIsUnitTest(true);
}
if ((access & Opcodes.ACC_ENUM) == Opcodes.ACC_ENUM) {
cls.setIsEnum(true);
}
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public ElementType getType() {
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
return ElementType.ANNOTATION;
}
if ((access & Opcodes.ACC_INTERFACE) != 0) {
return ElementType.INTERFACE;
}
if ((access & Opcodes.ACC_ENUM) != 0) {
return ElementType.ENUM;
}
return ElementType.CLASS;
}
private static void makeEnumsFinal(Set<String> all, ClassNode n) {
n.innerClasses.forEach(
x -> {
if (all.contains(x.name) && (x.access & Opcodes.ACC_ENUM) == Opcodes.ACC_ENUM) {
x.access &= ~Opcodes.ACC_ABSTRACT;
x.access |= Opcodes.ACC_FINAL;
}
});
if ((n.access & Opcodes.ACC_ENUM) == Opcodes.ACC_ENUM) {
n.access &= ~Opcodes.ACC_ABSTRACT;
n.access |= Opcodes.ACC_FINAL;
}
}
public boolean isEnum() {
return ( super.access & Opcodes.ACC_ENUM ) != 0;
}
/**
* Appends a string representation of the given access flags to {@link #stringBuilder}.
*
* @param accessFlags some access flags.
*/
private void appendAccess(final int accessFlags) {
if ((accessFlags & Opcodes.ACC_PUBLIC) != 0) {
stringBuilder.append("public ");
}
if ((accessFlags & Opcodes.ACC_PRIVATE) != 0) {
stringBuilder.append("private ");
}
if ((accessFlags & Opcodes.ACC_PROTECTED) != 0) {
stringBuilder.append("protected ");
}
if ((accessFlags & Opcodes.ACC_FINAL) != 0) {
stringBuilder.append("final ");
}
if ((accessFlags & Opcodes.ACC_STATIC) != 0) {
stringBuilder.append("static ");
}
if ((accessFlags & Opcodes.ACC_SYNCHRONIZED) != 0) {
stringBuilder.append("synchronized ");
}
if ((accessFlags & Opcodes.ACC_VOLATILE) != 0) {
stringBuilder.append("volatile ");
}
if ((accessFlags & Opcodes.ACC_TRANSIENT) != 0) {
stringBuilder.append("transient ");
}
if ((accessFlags & Opcodes.ACC_ABSTRACT) != 0) {
stringBuilder.append("abstract ");
}
if ((accessFlags & Opcodes.ACC_STRICT) != 0) {
stringBuilder.append("strictfp ");
}
if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0) {
stringBuilder.append("synthetic ");
}
if ((accessFlags & Opcodes.ACC_MANDATED) != 0) {
stringBuilder.append("mandated ");
}
if ((accessFlags & Opcodes.ACC_ENUM) != 0) {
stringBuilder.append("enum ");
}
}
/**
* Gets the class access flags (see JVMS8 4.1) for the given type element, augmented by the
* special ASM pseudo-access flag for @Deprecated types.
*/
public int getAccessFlags(TypeElement typeElement) {
ElementKind kind;
try {
kind = typeElement.getKind();
} catch (CannotInferException e) {
Preconditions.checkState(typeElement.getNestingKind().isNested());
// We cannot know the access flags of an inferred type element. However, the only
// flag that matters in the InnerClasses table is ACC_STATIC. When reading the
// InnerClasses table, the compiler may create ClassSymbols for types it hasn't
// seen before, and the absence of ACC_STATIC will cause it to mark those
// ClassSymbols as inner classes, and it will not correct that when later loading
// the class from its definitive class file. However, it is safe to mark
// everything with ACC_STATIC, because the compiler *will* properly update
// non-static classes when loading their definitive class files.
// (http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/file/9986bf97a48d/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java#l2272)
return Opcodes.ACC_STATIC;
}
int result = getCommonAccessFlags(typeElement);
switch (kind) {
case ANNOTATION_TYPE:
// No ACC_SUPER here per JVMS 4.1
result = result | Opcodes.ACC_ANNOTATION;
result = result | Opcodes.ACC_INTERFACE;
result = result | Opcodes.ACC_ABSTRACT;
break;
case ENUM:
result = result | Opcodes.ACC_SUPER; // JVMS 4.1
result = result | Opcodes.ACC_ENUM;
if (isAbstractEnum(typeElement)) {
result = result & ~Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT;
}
break;
case INTERFACE:
// No ACC_SUPER here per JVMS 4.1
result = result | Opcodes.ACC_ABSTRACT;
result = result | Opcodes.ACC_INTERFACE;
break;
// $CASES-OMITTED$
default:
result = result | Opcodes.ACC_SUPER; // JVMS 4.1
break;
}
return result;
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
if ((access & Opcodes.ACC_MODULE) != 0) {
// Modules are printed in visitModule.
return;
}
this.access = access;
int majorVersion = version & 0xFFFF;
int minorVersion = version >>> 16;
stringBuilder.setLength(0);
stringBuilder
.append("// class version ")
.append(majorVersion)
.append('.')
.append(minorVersion)
.append(" (")
.append(version)
.append(")\n");
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
stringBuilder.append(DEPRECATED);
}
appendRawAccess(access);
appendDescriptor(CLASS_SIGNATURE, signature);
if (signature != null) {
appendJavaDeclaration(name, signature);
}
appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
stringBuilder.append("@interface ");
} else if ((access & Opcodes.ACC_INTERFACE) != 0) {
stringBuilder.append("interface ");
} else if ((access & Opcodes.ACC_ENUM) == 0) {
stringBuilder.append("class ");
}
appendDescriptor(INTERNAL_NAME, name);
if (superName != null && !"java/lang/Object".equals(superName)) {
stringBuilder.append(" extends ");
appendDescriptor(INTERNAL_NAME, superName);
}
if (interfaces != null && interfaces.length > 0) {
stringBuilder.append(" implements ");
for (int i = 0; i < interfaces.length; ++i) {
appendDescriptor(INTERNAL_NAME, interfaces[i]);
if (i != interfaces.length - 1) {
stringBuilder.append(' ');
}
}
}
stringBuilder.append(" {\n\n");
text.add(stringBuilder.toString());
}
public ArrayList<VarAtScopeLevel> getAllVariablesAtScopeLevel(boolean justFinals, boolean removeNestingIndicactorHelperVars, boolean ignoreIsOverride, boolean justNonNullable)
{
ArrayList<VarAtScopeLevel> ret = new ArrayList<VarAtScopeLevel>();
for(String varname : this.vars.keySet())
{
TypeAndLocation tal = this.vars.get(varname);
if(!justFinals || tal.getLocation().isFinal()){
if(null != tal){
Location loc = tal.getLocation();
if(!removeNestingIndicactorHelperVars || !varname.contains("$n") || loc.localClassImportedField){
int extraModifiers = 0;
boolean assignedOnCreationAndFinal = false;
boolean assignedOnCreation = false;
if(loc instanceof LocationStaticField){
LocationStaticField asstataic = (LocationStaticField)loc;
if(asstataic.enumValue){
extraModifiers += Opcodes.ACC_ENUM + Opcodes.ACC_STATIC;
}
}
else if(loc instanceof LocationClassField) {
if(ignoreIsOverride && ((LocationClassField)loc).isOverride) {
continue;
}
assignedOnCreation = ((LocationClassField)loc).assignedOnCreation;
assignedOnCreationAndFinal = assignedOnCreation && loc.isFinal();
}
if(loc.isTransient()){
extraModifiers += Opcodes.ACC_TRANSIENT;
}
//TODO: add annotation to variable if shared
{
Matcher m = nestedName.matcher(varname);//JPT: a bit hacky, better to find out where $n1$n2 is coming from
if(m.find() && m.find()){//if there are >=2 nested $n then we ignore this
continue;
}
}
if(justNonNullable) {
Type tt = tal.getType();
if(assignedOnCreation) {
continue;
}
if(tt instanceof PrimativeType && !tt.hasArrayLevels()) {
continue;
}
if(tt.getNullStatus() == NullStatus.NULLABLE) {
continue;
}
if(TypeCheckUtils.hasRefLevels(tt)) {
continue;
}
}
ret.add(new VarAtScopeLevel(varname, tal.getType(), loc.isFinal(), loc.getAccessModifier(), extraModifiers, loc.annotations, assignedOnCreationAndFinal, assignedOnCreation, loc.isInjected, loc.isShared()));
}
}
}
}
return ret;
}
public boolean isEnum()
{
return (this.access & Opcodes.ACC_ENUM) != 0;
}
public void setEnum()
{
accessFlags |= Opcodes.ACC_ENUM;
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
if ((access & Opcodes.ACC_MODULE) != 0) {
// Modules are printed in visitModule.
return;
}
this.access = access;
int majorVersion = version & 0xFFFF;
int minorVersion = version >>> 16;
stringBuilder.setLength(0);
stringBuilder
.append("// class version ")
.append(majorVersion)
.append('.')
.append(minorVersion)
.append(" (")
.append(version)
.append(")\n");
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
stringBuilder.append(DEPRECATED);
}
appendRawAccess(access);
appendDescriptor(CLASS_SIGNATURE, signature);
if (signature != null) {
appendJavaDeclaration(name, signature);
}
appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
stringBuilder.append("@interface ");
} else if ((access & Opcodes.ACC_INTERFACE) != 0) {
stringBuilder.append("interface ");
} else if ((access & Opcodes.ACC_ENUM) == 0) {
stringBuilder.append("class ");
}
appendDescriptor(INTERNAL_NAME, name);
if (superName != null && !"java/lang/Object".equals(superName)) {
stringBuilder.append(" extends ");
appendDescriptor(INTERNAL_NAME, superName);
}
if (interfaces != null && interfaces.length > 0) {
stringBuilder.append(" implements ");
for (int i = 0; i < interfaces.length; ++i) {
appendDescriptor(INTERNAL_NAME, interfaces[i]);
if (i != interfaces.length - 1) {
stringBuilder.append(' ');
}
}
}
stringBuilder.append(" {\n\n");
text.add(stringBuilder.toString());
}
/**
* Appends a string representation of the given access flags to {@link #stringBuilder}.
*
* @param accessFlags some access flags.
*/
private void appendAccess(final int accessFlags) {
if ((accessFlags & Opcodes.ACC_PUBLIC) != 0) {
stringBuilder.append("public ");
}
if ((accessFlags & Opcodes.ACC_PRIVATE) != 0) {
stringBuilder.append("private ");
}
if ((accessFlags & Opcodes.ACC_PROTECTED) != 0) {
stringBuilder.append("protected ");
}
if ((accessFlags & Opcodes.ACC_FINAL) != 0) {
stringBuilder.append("final ");
}
if ((accessFlags & Opcodes.ACC_STATIC) != 0) {
stringBuilder.append("static ");
}
if ((accessFlags & Opcodes.ACC_SYNCHRONIZED) != 0) {
stringBuilder.append("synchronized ");
}
if ((accessFlags & Opcodes.ACC_VOLATILE) != 0) {
stringBuilder.append("volatile ");
}
if ((accessFlags & Opcodes.ACC_TRANSIENT) != 0) {
stringBuilder.append("transient ");
}
if ((accessFlags & Opcodes.ACC_ABSTRACT) != 0) {
stringBuilder.append("abstract ");
}
if ((accessFlags & Opcodes.ACC_STRICT) != 0) {
stringBuilder.append("strictfp ");
}
if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0) {
stringBuilder.append("synthetic ");
}
if ((accessFlags & Opcodes.ACC_MANDATED) != 0) {
stringBuilder.append("mandated ");
}
if ((accessFlags & Opcodes.ACC_ENUM) != 0) {
stringBuilder.append("enum ");
}
}
/**
* Utility method to get the access modifiers of a Host
* @param modVal The bitset representation of the Host's modifiers
* @param host The Host (SootClass, SootField or SootMethod) the modifiers are to be retrieved from
* @return A bitset representation of the Host's modifiers in ASM's internal representation
*/
protected static int getModifiers(int modVal, Host host) {
int modifier = 0;
// Retrieve visibility-modifier
if (Modifier.isPublic(modVal)) {
modifier |= Opcodes.ACC_PUBLIC;
} else if (Modifier.isPrivate(modVal)) {
modifier |= Opcodes.ACC_PRIVATE;
} else if (Modifier.isProtected(modVal)) {
modifier |= Opcodes.ACC_PROTECTED;
}
// Retrieve static-modifier
if (Modifier.isStatic(modVal)
&& ((host instanceof SootField) || (host instanceof SootMethod))) {
modifier |= Opcodes.ACC_STATIC;
}
// Retrieve final-modifier
if (Modifier.isFinal(modVal)) {
modifier |= Opcodes.ACC_FINAL;
}
// Retrieve synchronized-modifier
if (Modifier.isSynchronized(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_SYNCHRONIZED;
}
// Retrieve volatile/bridge-modifier
if (Modifier.isVolatile(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_VOLATILE;
}
// Retrieve transient/varargs-modifier
if (Modifier.isTransient(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_TRANSIENT;
}
// Retrieve native-modifier
if (Modifier.isNative(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_NATIVE;
}
// Retrieve interface-modifier
if (Modifier.isInterface(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_INTERFACE;
} else if (host instanceof SootClass) {
/*
* For all classes except for interfaces the super-flag should be
* set. See JVM 8-Specification section 4.1, page 72.
*/
modifier |= Opcodes.ACC_SUPER;
}
// Retrieve abstract-modifier
if (Modifier.isAbstract(modVal) && !(host instanceof SootField)) {
modifier |= Opcodes.ACC_ABSTRACT;
}
// Retrieve strictFP-modifier
if (Modifier.isStrictFP(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_STRICT;
}
/*
* Retrieve synthetic-modifier. Class not present in source-code but
* generated by e.g. compiler TODO Do we need both checks?
*/
if (Modifier.isSynthetic(modVal) || host.hasTag("SyntheticTag")) {
modifier |= Opcodes.ACC_SYNTHETIC;
}
// Retrieve annotation-modifier
if (Modifier.isAnnotation(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_ANNOTATION;
}
// Retrieve enum-modifier
if (Modifier.isEnum(modVal) && !(host instanceof SootMethod)) {
modifier |= Opcodes.ACC_ENUM;
}
return modifier;
}