1 package annotator.find; 2 3 import java.util.List; 4 5 import type.ArrayType; 6 import type.BoundedType; 7 import type.DeclaredType; 8 import type.Type; 9 10 /** 11 * Superclass for {@link Insertion} classes for which insertion may 12 * result in code generation other than just annotations. 13 * {@code TypedInsertion}s keep track of insertions on inner types. If 14 * there is no type given in the source, one may be generated (along 15 * with other code necessary in the context) to serve as an insertion 16 * site. 17 * <p> 18 * We don't know until the end of the whole insertion process whether 19 * the type already exists or not. To remedy this, we store a reference 20 * to each insertion on an inner type of a receiver in two places: the 21 * global list of all insertions and the {@code TypedInsertion} that is 22 * the parent of the inner type insertion. If the type is not already 23 * present, the inner type insertions are inserted into the new type and 24 * labeled as "inserted" (with {@link Insertion#setInserted(boolean)}) 25 * so they are not inserted as the rest of the insertions list is 26 * processed. 27 * 28 * @author dbro 29 */ 30 public abstract class TypedInsertion extends Insertion { 31 /** 32 * The type for insertion. 33 */ 34 protected Type type; 35 36 /** 37 * If true only the annotations from {@link type} will be inserted. 38 */ 39 protected boolean annotationsOnly; 40 41 /** 42 * The inner types to go on this insertion. See {@link ReceiverInsertion} 43 * for more details. 44 */ 45 protected List<Insertion> innerTypeInsertions; 46 TypedInsertion(Type type, Criteria criteria, List<Insertion> innerTypeInsertions)47 public TypedInsertion(Type type, Criteria criteria, 48 List<Insertion> innerTypeInsertions) { 49 this(type, criteria, false, innerTypeInsertions); 50 } 51 TypedInsertion(Type type, Criteria criteria, boolean b, List<Insertion> innerTypeInsertions)52 public TypedInsertion(Type type, Criteria criteria, boolean b, 53 List<Insertion> innerTypeInsertions) { 54 super(criteria, b); 55 this.type = type; 56 this.innerTypeInsertions = innerTypeInsertions; 57 annotationsOnly = false; 58 } 59 60 /** 61 * If {@code true} only the annotations on {@code type} will be inserted. 62 * This is useful when the "new" has already been inserted. 63 */ setAnnotationsOnly(boolean annotationsOnly)64 public void setAnnotationsOnly(boolean annotationsOnly) { 65 this.annotationsOnly = annotationsOnly; 66 } 67 68 /** 69 * Sets the type. 70 */ setType(Type type)71 public void setType(Type type) { 72 this.type = type; 73 } 74 75 /** 76 * Gets the type. It is assumed that the returned value will be 77 * modified to update the type to be inserted. 78 */ getType()79 public Type getType() { 80 return type; 81 } 82 83 /** 84 * Gets the inner type insertions associated with this insertion. 85 * @return a copy of the inner types 86 */ getInnerTypeInsertions()87 public List<Insertion> getInnerTypeInsertions() { 88 return innerTypeInsertions; 89 } 90 getBaseType()91 public DeclaredType getBaseType() { 92 return getBaseType(type); 93 } 94 getBaseType(Type type)95 public static DeclaredType getBaseType(Type type) { 96 switch (type.getKind()) { 97 case DECLARED: 98 return (DeclaredType) type; 99 case BOUNDED: 100 return getBaseType(((BoundedType) type).getName()); 101 case ARRAY: 102 return getBaseType(((ArrayType) type).getComponentType()); 103 default: // should never be reached 104 return null; 105 } 106 } 107 } 108