下面列出了org.objectweb.asm.Opcodes# ACC_FINAL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Checks that the given access flags do not contain invalid flags. This
* method also checks that mutually incompatible flags are not set
* simultaneously.
*
* @param access
* the access flags to be checked
* @param possibleAccess
* the valid access flags.
*/
static void checkAccess(final int access, final int possibleAccess) {
if ((access & ~possibleAccess) != 0) {
throw new IllegalArgumentException("Invalid access flags: " + access);
}
int pub = (access & Opcodes.ACC_PUBLIC) == 0 ? 0 : 1;
int pri = (access & Opcodes.ACC_PRIVATE) == 0 ? 0 : 1;
int pro = (access & Opcodes.ACC_PROTECTED) == 0 ? 0 : 1;
if (pub + pri + pro > 1) {
throw new IllegalArgumentException("public private and protected are mutually exclusive: " + access);
}
int fin = (access & Opcodes.ACC_FINAL) == 0 ? 0 : 1;
int abs = (access & Opcodes.ACC_ABSTRACT) == 0 ? 0 : 1;
if (fin + abs > 1) {
throw new IllegalArgumentException("final and abstract are mutually exclusive: " + access);
}
}
public void visitEnd() {
if(bNeedBIDField) {
// Add a static field containing the bundle id to the processed class.
// This files is used by the wrapper methods to find the bundle owning
// the class.
// The field has the magic/long name defined by FIELD_BID
// hopefully no-one else uses this
super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
FIELD_BID,
"J",
null,
new Long(bid));
}
super.visitEnd();
if(Activator.debugEnabled()) {
cp.dumpInfo();
}
}
@Override
public boolean writeFieldDefinition(
ClassWriter cw, boolean isFinal, boolean annotateTransitiveFields) {
int accessLevel = Opcodes.ACC_STATIC;
if (visibility != Visibility.PRIVATE) {
accessLevel |= Opcodes.ACC_PUBLIC;
}
if (isFinal) {
accessLevel |= Opcodes.ACC_FINAL;
}
FieldVisitor fv = cw.visitField(accessLevel, fieldName, DESC, null, isFinal ? value : null);
if (annotateTransitiveFields
&& dependencyInfo.dependencyType() == DependencyInfo.DependencyType.TRANSITIVE) {
AnnotationVisitor av =
fv.visitAnnotation(
RClassGenerator.PROVENANCE_ANNOTATION_CLASS_DESCRIPTOR, /*visible=*/ true);
av.visit(RClassGenerator.PROVENANCE_ANNOTATION_LABEL_KEY, dependencyInfo.label());
av.visitEnd();
}
fv.visitEnd();
return !isFinal;
}
public Builder setFinal(boolean isFinal) {
if (isFinal) {
extraAccess |= Opcodes.ACC_FINAL;
} else {
extraAccess &= ~Opcodes.ACC_FINAL;
}
return this;
}
private 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_SYNTHETIC) != 0)
tokens.add("synthetic");
if ((access & Opcodes.ACC_STATIC) != 0)
tokens.add("static");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_TRANSIENT) != 0)
tokens.add("transient");
if ((access & Opcodes.ACC_VOLATILE) != 0)
tokens.add("volatile");
if (tokens.size() == 0)
return "";
// 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();
}
private void addCoverageProbeField() {
super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC
| Opcodes.ACC_SYNTHETIC, CodeCoverageStore.PROBE_FIELD_NAME, "[Z", null,
null);
super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC
| Opcodes.ACC_SYNTHETIC, CodeCoverageStore.PROBE_LENGTH_FIELD_NAME, "I",
null, this.probeCount + 1);
//If there is no <clinit>, then generate one that sets the probe field directly
if (!foundClinit) {
MethodVisitor clinitMv = this.cv
.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
clinitMv.visitCode();
pushConstant(clinitMv, this.classId);
pushConstant(clinitMv, this.probeCount);
clinitMv
.visitMethodInsn(Opcodes.INVOKESTATIC, CodeCoverageStore.CLASS_NAME,
"getOrRegisterClassProbes", "(II)[Z", false);
clinitMv.visitFieldInsn(Opcodes.PUTSTATIC, className,
CodeCoverageStore.PROBE_FIELD_NAME, "[Z");
clinitMv.visitInsn(Opcodes.RETURN);
clinitMv.visitMaxs(0, 0);
clinitMv.visitEnd();
}
}
/**
* Adds a final static serialVersionUID field to the class, with the given value.
*
* @param svuid the serialVersionUID field value.
*/
protected void addSVUID(final long svuid) {
FieldVisitor fieldVisitor =
super.visitField(
Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
if (fieldVisitor != null) {
fieldVisitor.visitEnd();
}
}
/**
* Adds a final static serialVersionUID field to the class, with the given value.
*
* @param svuid the serialVersionUID field value.
*/
// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
protected void addSVUID(final long svuid) {
FieldVisitor fieldVisitor =
super.visitField(
Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
if (fieldVisitor != null) {
fieldVisitor.visitEnd();
}
}
@Override
public FieldVisitor visitField(
final int access,
final String name,
final String desc,
final String signature,
final Object value) {
// Get the class field information for step 4 of the algorithm. Also determine if the class
// already has a SVUID.
if (computeSVUID) {
if ("serialVersionUID".equals(name)) {
// Since the class already has SVUID, we won't be computing it.
computeSVUID = false;
hasSVUID = true;
}
// Collect the non private fields. Only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED,
// ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when computing
// serialVersionUID values.
if ((access & Opcodes.ACC_PRIVATE) == 0
|| (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
int mods =
access
& (Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED
| Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL
| Opcodes.ACC_VOLATILE
| Opcodes.ACC_TRANSIENT);
svuidFields.add(new Item(name, mods, desc));
}
}
return super.visitField(access, name, desc, signature, value);
}
/**
* Adds a final static serialVersionUID field to the class, with the given value.
*
* @param svuid the serialVersionUID field value.
*/
// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
protected void addSVUID(final long svuid) {
FieldVisitor fieldVisitor =
super.visitField(
Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
if (fieldVisitor != null) {
fieldVisitor.visitEnd();
}
}
/**
* Adds a new class.
*
* @param constantPool
* the constant pool instance to use
* @return the class code instance which represents the new class
*/
ClassCode newClass(ConstantPool constantPool) {
int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL;
String className = mainClass.className + '~' + classes.size();
ClassCode classCode = newClass(constantPool, access, className);
classes.add(classCode);
return classCode;
}
/**
* Adds a final static serialVersionUID field to the class, with the given value.
*
* @param svuid the serialVersionUID field value.
*/
// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
protected void addSVUID(final long svuid) {
FieldVisitor fieldVisitor =
super.visitField(
Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
if (fieldVisitor != null) {
fieldVisitor.visitEnd();
}
}
protected static String getAccessString(int access) {
// public, protected, private, abstract, static,
// final, synchronized, native & strictfp are permitted
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_STATIC) != 0)
tokens.add("static");
if ((access & Opcodes.ACC_ABSTRACT) != 0)
tokens.add("abstract");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_SYNCHRONIZED) != 0)
tokens.add("synchronized");
if ((access & Opcodes.ACC_NATIVE) != 0)
tokens.add("native");
if ((access & Opcodes.ACC_STRICT) != 0)
tokens.add("strictfp");
if ((access & Opcodes.ACC_BRIDGE) != 0)
tokens.add("bridge");
if ((access & Opcodes.ACC_VARARGS) != 0)
tokens.add("varargs");
if (tokens.size() == 0)
return "";
// 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 MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
boolean isStatic = (access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC;
boolean isFinal = (access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL;
return new MethodVisitorBuilder(repository, classInfo, name, desc,
signature, exceptions, isStatic, isFinal, JavaVisibility
.valueFromJavaBytecode(access));
}
/**
* Handles the bulk of the processing, mostly delegating to other methods.
*
* @param nodes the ast nodes
* @param source the source unit for the nodes
*/
public void visit(ASTNode[] nodes, SourceUnit source) {
if (!(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class");
}
AnnotationNode node = (AnnotationNode) nodes[0];
AnnotatedNode parent = (AnnotatedNode) nodes[1];
if (VetoableASTTransformation.hasVetoableAnnotation(parent)) {
// VetoableASTTransformation will handle both @Bindable and @Vetoable
return;
}
ClassNode declaringClass = parent.getDeclaringClass();
if (parent instanceof FieldNode) {
if ((((FieldNode) parent).getModifiers() & Opcodes.ACC_FINAL) != 0) {
source.getErrorCollector().addErrorAndContinue("@groovy.beans.Bindable cannot annotate a final property.", node, source);
}
if (VetoableASTTransformation.hasVetoableAnnotation(parent.getDeclaringClass())) {
// VetoableASTTransformation will handle both @Bindable and @Vetoable
return;
}
addListenerToProperty(source, node, declaringClass, (FieldNode) parent);
} else if (parent instanceof ClassNode) {
addListenerToClass(source, (ClassNode) parent);
}
}
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
this.name = name;
append("// Class: ").append(name).newLine();
append("// Access = ");
for (int mods = access; mods != 0;) {
int mod = Integer.lowestOneBit(mods);
switch (mod) {
case Opcodes.ACC_PUBLIC: {
append(" public");
break;
}
case Opcodes.ACC_PRIVATE: {
append(" private");
break;
}
case Opcodes.ACC_PROTECTED: {
append(" protected");
break;
}
case Opcodes.ACC_STATIC: {
append(" static");
break;
}
case Opcodes.ACC_FINAL: {
append(" final");
break;
}
case Opcodes.ACC_INTERFACE: {
append(" interface");
break;
}
case Opcodes.ACC_ABSTRACT: {
append(" abstract");
break;
}
case Opcodes.ACC_SYNTHETIC: {
append(" synthetic");
break;
}
case Opcodes.ACC_ANNOTATION: {
append(" annotation");
break;
}
case Opcodes.ACC_ENUM: {
append(" enum");
break;
}
}
mods ^= mod;
}
newLine();
if (superName != null) append("// Extends: ").append(superName).newLine();
if (interfaces != null && interfaces.length > 0) {
append("// Implements:").newLine();
for (String iName : interfaces) {
append("// ").append(iName).newLine();
}
}
newLine();
append("// DO NOT MODIFY. This is not actually a source file; it is a textual representation of generated code.");
newLine();
append("// Use only for debugging purposes.");
newLine().newLine();
}
/**
* {@inheritDoc}
*/
public int getModifiers() {
return Opcodes.ACC_SYNTHETIC | getBaseModifiers() | (getDeclaringType().isInterface()
? Opcodes.ACC_PUBLIC
: Opcodes.ACC_FINAL);
}
/**
* Appends a string representation of the given access modifiers to
* {@link #buf buf}.
*
* @param access
* some access modifiers.
*/
private void appendAccess(final int access) {
if ((access & Opcodes.ACC_PUBLIC) != 0) {
buf.append("public ");
}
if ((access & Opcodes.ACC_PRIVATE) != 0) {
buf.append("private ");
}
if ((access & Opcodes.ACC_PROTECTED) != 0) {
buf.append("protected ");
}
if ((access & Opcodes.ACC_FINAL) != 0) {
buf.append("final ");
}
if ((access & Opcodes.ACC_STATIC) != 0) {
buf.append("static ");
}
if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
buf.append("synchronized ");
}
if ((access & Opcodes.ACC_VOLATILE) != 0) {
buf.append("volatile ");
}
if ((access & Opcodes.ACC_TRANSIENT) != 0) {
buf.append("transient ");
}
if ((access & Opcodes.ACC_ABSTRACT) != 0) {
buf.append("abstract ");
}
if ((access & Opcodes.ACC_STRICT) != 0) {
buf.append("strictfp ");
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
buf.append("synthetic ");
}
if ((access & Opcodes.ACC_MANDATED) != 0) {
buf.append("mandated ");
}
if ((access & Opcodes.ACC_ENUM) != 0) {
buf.append("enum ");
}
}
@SuppressWarnings("unused")
private static String getAccessModifiers(int access){
LinkedList<String> modifiers = new LinkedList<String>();
if((Opcodes.ACC_ABSTRACT & access) == Opcodes.ACC_ABSTRACT){
modifiers.add("abstract");
}
if((Opcodes.ACC_ANNOTATION & access) == Opcodes.ACC_ANNOTATION){
modifiers.add("annotation");
}
if((Opcodes.ACC_BRIDGE & access) == Opcodes.ACC_BRIDGE){
modifiers.add("bridge");
}
if((Opcodes.ACC_DEPRECATED & access) == Opcodes.ACC_DEPRECATED){
modifiers.add("deprecated");
}
if((Opcodes.ACC_ENUM & access) == Opcodes.ACC_ENUM){
modifiers.add("enum");
}
if((Opcodes.ACC_FINAL & access) == Opcodes.ACC_FINAL){
modifiers.add("final");
}
if((Opcodes.ACC_INTERFACE & access) == Opcodes.ACC_INTERFACE){
modifiers.add("interface");
}
if((Opcodes.ACC_MANDATED & access) == Opcodes.ACC_MANDATED){
modifiers.add("mandated");
}
if((Opcodes.ACC_NATIVE & access) == Opcodes.ACC_NATIVE){
modifiers.add("native");
}
if((Opcodes.ACC_PRIVATE & access) == Opcodes.ACC_PRIVATE){
modifiers.add("private");
}
if((Opcodes.ACC_PROTECTED & access) == Opcodes.ACC_PROTECTED){
modifiers.add("protected");
}
if((Opcodes.ACC_PUBLIC & access) == Opcodes.ACC_PUBLIC){
modifiers.add("public");
}
if((Opcodes.ACC_STATIC & access) == Opcodes.ACC_STATIC){
modifiers.add("static");
}
if((Opcodes.ACC_STRICT & access) == Opcodes.ACC_STRICT){
modifiers.add("strict");
}
if((Opcodes.ACC_SUPER & access) == Opcodes.ACC_SUPER){
modifiers.add("super");
}
if((Opcodes.ACC_SYNCHRONIZED & access) == Opcodes.ACC_SYNCHRONIZED){
modifiers.add("synchronized");
}
if((Opcodes.ACC_SYNTHETIC & access) == Opcodes.ACC_SYNTHETIC){
modifiers.add("synthetic");
}
if((Opcodes.ACC_TRANSIENT & access) == Opcodes.ACC_TRANSIENT){
modifiers.add("transient");
}
if((Opcodes.ACC_VARARGS & access) == Opcodes.ACC_VARARGS){
modifiers.add("varargs");
}
if((Opcodes.ACC_VOLATILE & access) == Opcodes.ACC_VOLATILE){
modifiers.add("volatile");
}
return modifiers.toString();
}
private static boolean isConstant(int access) {
return (access & Opcodes.ACC_FINAL) != 0 && (access & Opcodes.ACC_STATIC) != 0;
}