• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.internal.bytecode;
2 
3 import com.google.common.collect.ImmutableSet;
4 import java.lang.annotation.Annotation;
5 import java.util.ArrayList;
6 import java.util.List;
7 import org.objectweb.asm.Opcodes;
8 import org.objectweb.asm.Type;
9 import org.objectweb.asm.tree.AnnotationNode;
10 import org.objectweb.asm.tree.ClassNode;
11 import org.objectweb.asm.tree.FieldNode;
12 import org.objectweb.asm.tree.MethodNode;
13 
14 public class MutableClass {
15   public final ClassNode classNode;
16   final InstrumentationConfiguration config;
17   final ClassNodeProvider classNodeProvider;
18   final boolean containsStubs;
19 
20   final String internalClassName;
21   private final String className;
22   final Type classType;
23   final ImmutableSet<String> foundMethods;
24 
MutableClass(ClassNode classNode, InstrumentationConfiguration config, ClassNodeProvider classNodeProvider)25   MutableClass(ClassNode classNode, InstrumentationConfiguration config,
26       ClassNodeProvider classNodeProvider) {
27     this.classNode = classNode;
28     this.config = config;
29     this.classNodeProvider = classNodeProvider;
30     this.internalClassName = classNode.name;
31     this.className = classNode.name.replace('/', '.');
32     this.classType = Type.getObjectType(internalClassName);
33     this.containsStubs = config.containsStubs(className);
34 
35     List<String> foundMethods = new ArrayList<>(classNode.methods.size());
36     for (MethodNode methodNode : getMethods()) {
37       foundMethods.add(methodNode.name + methodNode.desc);
38     }
39     this.foundMethods = ImmutableSet.copyOf(foundMethods);
40   }
41 
isInterface()42   public boolean isInterface() {
43     return (classNode.access & Opcodes.ACC_INTERFACE) != 0;
44   }
45 
isAnnotation()46   public boolean isAnnotation() {
47     return (classNode.access & Opcodes.ACC_ANNOTATION) != 0;
48   }
49 
hasAnnotation(Class<? extends Annotation> annotationClass)50   public boolean hasAnnotation(Class<? extends Annotation> annotationClass) {
51     String internalName = "L" + annotationClass.getName().replace('.', '/') + ";";
52     if (classNode.visibleAnnotations == null) {
53       return false;
54     }
55 
56     for (Object visibleAnnotation : classNode.visibleAnnotations) {
57       AnnotationNode annotationNode = (AnnotationNode) visibleAnnotation;
58       if (annotationNode.desc.equals(internalName)) {
59         return true;
60       }
61     }
62     return false;
63   }
64 
getName()65   public String getName() {
66     return className;
67   }
68 
getMethods()69   public Iterable<? extends MethodNode> getMethods() {
70     return new ArrayList<>(classNode.methods);
71   }
72 
addMethod(MethodNode methodNode)73   public void addMethod(MethodNode methodNode) {
74     classNode.methods.add(methodNode);
75   }
76 
getFields()77   public List<FieldNode> getFields() {
78     return classNode.fields;
79   }
80 
addField(int index, FieldNode fieldNode)81   public void addField(int index, FieldNode fieldNode) {
82     classNode.fields.add(index, fieldNode);
83   }
84 
addInterface(String internalName)85   public void addInterface(String internalName) {
86     classNode.interfaces.add(internalName);
87   }
88 }
89