Home | History | Annotate | Download | only in el
      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 
     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