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