• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package annotations.el;
2 
3 import java.util.LinkedHashMap;
4 
5 import annotations.Annotation;
6 import annotations.util.coll.VivifyingMap;
7 
8 /*>>>
9 import org.checkerframework.checker.nullness.qual.*;
10 */
11 
12 /** An annotated class */
13 public final class AClass extends ADeclaration {
14     /** The class's annotated type parameter bounds */
15     public final VivifyingMap<BoundLocation, ATypeElement> bounds =
16             ATypeElement.<BoundLocation>newVivifyingLHMap_ATE();
17 
18     public final VivifyingMap<TypeIndexLocation, ATypeElement> extendsImplements =
19         ATypeElement.<TypeIndexLocation>newVivifyingLHMap_ATE();
20 
createMethodMap()21     private static VivifyingMap<String, AMethod> createMethodMap() {
22         return new VivifyingMap<String, AMethod>(
23                 new LinkedHashMap<String, AMethod>()) {
24             @Override
25             public  AMethod createValueFor(String k) {
26                 return new AMethod(k);
27             }
28 
29             @Override
30             public boolean subPrune(AMethod v) {
31                 return v.prune();
32             }
33         };
34     }
35 
36     private static VivifyingMap<Integer, ABlock> createInitBlockMap() {
37         return new VivifyingMap<Integer, ABlock>(
38                 new LinkedHashMap<Integer, ABlock>()) {
39             @Override
40             public  ABlock createValueFor(Integer k) {
41                 return new ABlock(k);
42             }
43 
44             @Override
45             public boolean subPrune(ABlock v) {
46                 return v.prune();
47             }
48         };
49     }
50 
51     private static VivifyingMap<String, AExpression> createFieldInitMap() {
52         return new VivifyingMap<String, AExpression>(
53                 new LinkedHashMap<String, AExpression>()) {
54             @Override
55             public  AExpression createValueFor(String k) {
56                 return new AExpression(k);
57             }
58 
59             @Override
60             public boolean subPrune(AExpression v) {
61                 return v.prune();
62             }
63         };
64     }
65 
66 
67     /**
68      * The class's annotated methods; a method's key consists of its name
69      * followed by its erased signature in JVML format.
70      * For example, <code>foo()V</code> or
71      * <code>bar(B[I[[Ljava/lang/String;)I</code>.  The annotation scene library
72      * does not validate the keys, nor does it check that annotated subelements
73      * of the {@link AMethod}s exist in the signature.
74      */
75     public final VivifyingMap<String, AMethod> methods =
76         createMethodMap();
77 
78     public final VivifyingMap<Integer, ABlock> staticInits =
79         createInitBlockMap();
80 
81     public final VivifyingMap<Integer, ABlock> instanceInits =
82         createInitBlockMap();
83 
84     /** The class's annotated fields; map key is field name */
85     public final VivifyingMap<String, AField> fields =
86         AField.<String>newVivifyingLHMap_AF();
87 
88     public final VivifyingMap<String, AExpression> fieldInits =
89         createFieldInitMap();
90 
91     private final String className;
92 
93     // debug fields to keep track of all classes created
94     // private static List<AClass> debugAllClasses = new ArrayList<AClass>();
95     // private final List<AClass> allClasses;
96 
97     AClass(String className) {
98       super("class: " + className);
99       this.className = className;
100       // debugAllClasses.add(this);
101       // allClasses = debugAllClasses;
102     }
103 
104     AClass(AClass clazz) {
105       super(clazz);
106       className = clazz.className;
107       copyMapContents(clazz.bounds, bounds);
108       copyMapContents(clazz.extendsImplements, extendsImplements);
109       copyMapContents(clazz.fieldInits, fieldInits);
110       copyMapContents(clazz.fields, fields);
111       copyMapContents(clazz.instanceInits, instanceInits);
112       copyMapContents(clazz.methods, methods);
113       copyMapContents(clazz.staticInits, staticInits);
114     }
115 
116     @Override
117     public AClass clone() {
118       return new AClass(this);
119     }
120 
121     /**
122      * {@inheritDoc}
123      */
124     @Override
125     public boolean equals(Object o) {
126         return o instanceof AClass
127             && ((AClass) o).equalsClass(this);
128     }
129 
130     final boolean equalsClass(AClass o) {
131         return super.equals(o)
132             && className.equals(o.className)
133             && bounds.equals(o.bounds)
134             && methods.equals(o.methods)
135             && fields.equals(o.fields)
136             && extendsImplements.equals(o.extendsImplements);
137     }
138 
139     /**
140      * {@inheritDoc}
141      */
142     @Override
143     public int hashCode() {
144         return super.hashCode() + bounds.hashCode()
145             + methods.hashCode() + fields.hashCode()
146             + staticInits.hashCode() + instanceInits.hashCode()
147             + extendsImplements.hashCode();
148     }
149 
150     /**
151      * {@inheritDoc}
152      */
153     @Override
154     public boolean prune() {
155         return super.prune() & bounds.prune()
156             & methods.prune() & fields.prune()
157             & staticInits.prune() & instanceInits.prune()
158             & extendsImplements.prune();
159     }
160 
161     @Override
162     public String toString() {
163         return "AClass: " + className;
164     }
165 
166     public String unparse() {
167         return unparse("");
168     }
169 
170     public String unparse(String linePrefix) {
171         StringBuilder sb = new StringBuilder();
172         sb.append(linePrefix);
173         sb.append(toString());
174         sb.append("\n");
175         sb.append(linePrefix);
176         sb.append("Annotations:\n");
177         for (Annotation a : tlAnnotationsHere) {
178             sb.append(linePrefix);
179             sb.append("  " + a + "\n");
180         }
181         sb.append(linePrefix);
182         sb.append("Bounds:\n");
183         plume.UtilMDE.mapToString(sb, bounds, linePrefix + "  ");
184         sb.append(linePrefix);
185         sb.append("Extends/implements:\n");
186         plume.UtilMDE.mapToString(sb, extendsImplements, linePrefix + "  ");
187         sb.append(linePrefix);
188         sb.append("Fields:\n");
189         plume.UtilMDE.mapToString(sb, fields, linePrefix + "  ");
190         sb.append(linePrefix);
191         sb.append("Field Initializers:\n");
192         plume.UtilMDE.mapToString(sb, fieldInits, linePrefix + "  ");
193         sb.append(linePrefix);
194         sb.append("Static Initializers:\n");
195         plume.UtilMDE.mapToString(sb, staticInits, linePrefix + "  ");
196         sb.append(linePrefix);
197         sb.append("Instance Initializers:\n");
198         plume.UtilMDE.mapToString(sb, instanceInits, linePrefix + "  ");
199         sb.append(linePrefix);
200         sb.append("AST Typecasts:\n");
201         plume.UtilMDE.mapToString(sb, insertTypecasts, linePrefix + "  ");
202         sb.append(linePrefix);
203         sb.append("AST Annotations:\n");
204         plume.UtilMDE.mapToString(sb, insertAnnotations, linePrefix + "  ");
205         sb.append(linePrefix);
206         sb.append("Methods:\n");
207         plume.UtilMDE.mapToString(sb, methods, linePrefix + "  ");
208         return sb.toString();
209     }
210 
211     @Override
212     public <R, T> R accept(ElementVisitor<R, T> v, T t) {
213         return v.visitClass(this, t);
214     }
215 }
216