public ValueAnnotatedTypeFactory(BaseTypeChecker checker) { super(checker); BOTTOMVAL = AnnotationUtils.fromClass(elements, BottomVal.class); UNKNOWNVAL = AnnotationUtils.fromClass(elements, UnknownVal.class); coveredClassStrings = new HashSet<String>(19); coveredClassStrings.add("int"); coveredClassStrings.add("java.lang.Integer"); coveredClassStrings.add("double"); coveredClassStrings.add("java.lang.Double"); coveredClassStrings.add("byte"); coveredClassStrings.add("java.lang.Byte"); coveredClassStrings.add("java.lang.String"); coveredClassStrings.add("char"); coveredClassStrings.add("java.lang.Character"); coveredClassStrings.add("float"); coveredClassStrings.add("java.lang.Float"); coveredClassStrings.add("boolean"); coveredClassStrings.add("java.lang.Boolean"); coveredClassStrings.add("long"); coveredClassStrings.add("java.lang.Long"); coveredClassStrings.add("short"); coveredClassStrings.add("java.lang.Short"); coveredClassStrings.add("byte[]"); if (this.getClass().equals(ValueAnnotatedTypeFactory.class)) { this.postInit(); } }
/** Is the annotation {@code anno} an initialization qualifier? */ protected boolean isInitializationAnnotation(AnnotationMirror anno) { assert anno != null; return AnnotationUtils.areSameIgnoringValues(anno, UNCLASSIFIED) || AnnotationUtils.areSameIgnoringValues(anno, FREE) || AnnotationUtils.areSameIgnoringValues(anno, COMMITTED) || AnnotationUtils.areSameIgnoringValues(anno, FBCBOTTOM); }
public KeyForTransfer(KeyForAnalysis analysis, KeyForSubchecker checker) { super(analysis); this.analysis = analysis; this.checker = checker; UNKNOWNKEYFOR = AnnotationUtils.fromClass(analysis.getTypeFactory().getElementUtils(), UnknownKeyFor.class); KEYFOR = AnnotationUtils.fromClass(analysis.getTypeFactory().getElementUtils(), KeyFor.class); }
/** * Determines the least upper bound of a1 and a2. If a1 and a2 are both the same type of Value * annotation, then the LUB is the result of taking all values from both a1 and a2 and removing * duplicates. If a1 and a2 are not the same type of Value annotation they may still be * mergeable because some values can be implicitly cast as others. If a1 and a2 are both in * {DoubleVal, IntVal} then they will be converted upwards: IntVal → DoubleVal to arrive at * a common annotation type. * * @return the least upper bound of a1 and a2 */ @Override public AnnotationMirror leastUpperBound(AnnotationMirror a1, AnnotationMirror a2) { if (!AnnotationUtils.areSameIgnoringValues(getTopAnnotation(a1), getTopAnnotation(a2))) { return null; } else if (isSubtype(a1, a2)) { return a2; } else if (isSubtype(a2, a1)) { return a1; } // If both are the same type, determine the type and merge: else if (AnnotationUtils.areSameIgnoringValues(a1, a2)) { List<Object> a1Values = AnnotationUtils.getElementValueArray(a1, "value", Object.class, true); List<Object> a2Values = AnnotationUtils.getElementValueArray(a2, "value", Object.class, true); HashSet<Object> newValues = new HashSet<Object>(a1Values.size() + a2Values.size()); newValues.addAll(a1Values); newValues.addAll(a2Values); return createAnnotation(a1.getAnnotationType().toString(), newValues); } // Annotations are in this hierarchy, but they are not the same else { // If either is UNKNOWNVAL, ARRAYLEN, STRINGVAL, or BOOLEAN then // the LUB is // UnknownVal if (!(AnnotationUtils.areSameByClass(a1, IntVal.class) || AnnotationUtils.areSameByClass(a1, DoubleVal.class) || AnnotationUtils.areSameByClass(a2, IntVal.class) || AnnotationUtils.areSameByClass(a2, DoubleVal.class))) { return UNKNOWNVAL; } else { // At this point one of them must be a DoubleVal and one an // IntVal AnnotationMirror doubleAnno; AnnotationMirror intAnno; if (AnnotationUtils.areSameByClass(a2, DoubleVal.class)) { doubleAnno = a2; intAnno = a1; } else { doubleAnno = a1; intAnno = a2; } List<Long> intVals = getIntValues(intAnno); List<Double> doubleVals = getDoubleValues(doubleAnno); for (Long n : intVals) { doubleVals.add(n.doubleValue()); } return createDoubleValAnnotation(doubleVals); } } }
/** * Returns a set of pairs {@code (expr, annotation)} of preconditions according to the given * {@link RequiresQualifier}. */ private Set<Pair<String, String>> getPrecondition(AnnotationMirror requiresAnnotation) { if (requiresAnnotation == null) { return Collections.emptySet(); } Set<Pair<String, String>> result = new HashSet<>(); List<String> expressions = AnnotationUtils.getElementValueArray(requiresAnnotation, "expression", String.class, false); String annotation = AnnotationUtils.getElementValueClassName(requiresAnnotation, "qualifier", false).toString(); for (String expr : expressions) { result.add(Pair.of(expr, annotation)); } return result; }
@Override public Void visitNewClass(NewClassTree node, Void p) { AnnotatedDeclaredType type = atypeFactory.getAnnotatedType(node); ExpressionTree identifier = node.getIdentifier(); if (identifier instanceof AnnotatedTypeTree) { AnnotatedTypeTree t = (AnnotatedTypeTree) identifier; for (AnnotationMirror a : atypeFactory.getAnnotatedType(t).getAnnotations()) { // is this an annotation of the nullness checker? boolean nullnessCheckerAnno = containsSameIgnoringValues(atypeFactory.getNullnessAnnotations(), a); if (nullnessCheckerAnno && !AnnotationUtils.areSame(NONNULL, a)) { // The type is not non-null => warning checker.report(Result.warning("new.class.type.invalid", type.getAnnotations()), node); // Note that other consistency checks are made by isValid. } } if (t.toString().contains("@PolyNull")) { // TODO: this is a hack, but PolyNull gets substituted // afterwards checker.report(Result.warning("new.class.type.invalid", type.getAnnotations()), node); } } // TODO: It might be nicer to introduce a framework-level // isValidNewClassType or some such. return super.visitNewClass(node, p); }
/** @return the String value of a KeyFor, this will throw an exception */ private Set<String> getKeys(final AnnotationMirror keyFor) { if (keyFor.getElementValues().size() == 0) { return new LinkedHashSet<>(); } return new LinkedHashSet<>( AnnotationUtils.getElementValueArray(keyFor, "value", String.class, true)); }
@Override public Void visitWildcard(AnnotatedWildcardType type, Tree tree) { if (visitedNodes.containsKey(type)) { return visitedNodes.get(type); } // Keep in sync with visitTypeVariable Set<AnnotationMirror> onVar = type.getAnnotations(); if (!onVar.isEmpty()) { // System.out.printf("BaseTypeVisitor.TypeValidator.visitWildcard(type: %s, tree: %s)", // type, tree); // TODO: the following check should not be necessary, once we are // able to // recurse on type parameters in AnnotatedTypes.isValidType (see // todo there). { // Check whether multiple qualifiers from the same hierarchy // appear. Set<AnnotationMirror> seenTops = AnnotationUtils.createAnnotationSet(); for (AnnotationMirror aOnVar : onVar) { AnnotationMirror top = atypeFactory.getQualifierHierarchy().getTopAnnotation(aOnVar); if (seenTops.contains(top)) { this.reportError(type, tree); } seenTops.add(top); } } /* TODO: see note with visitTypeVariable if (type.getExtendsBoundField() != null) { AnnotatedTypeMirror upper = type.getExtendsBoundField(); for (AnnotationMirror aOnVar : onVar) { if (upper.isAnnotatedInHierarchy(aOnVar) && !atypeFactory.getQualifierHierarchy().isSubtype(aOnVar, upper.getAnnotationInHierarchy(aOnVar))) { this.reportError(type, tree); } } upper.replaceAnnotations(onVar); } */ if (type.getSuperBoundField() != null) { AnnotatedTypeMirror lower = type.getSuperBoundField(); for (AnnotationMirror aOnVar : onVar) { if (lower.isAnnotatedInHierarchy(aOnVar) && !atypeFactory .getQualifierHierarchy() .isSubtype(lower.getAnnotationInHierarchy(aOnVar), aOnVar)) { this.reportError(type, tree); } } lower.replaceAnnotations(onVar); } } return super.visitWildcard(type, tree); }
public InitializationAnnotatedTypeFactory(BaseTypeChecker checker, boolean useFbc) { super(checker, true); this.useFbc = useFbc; Set<Class<? extends Annotation>> tempInitAnnos = new LinkedHashSet<>(); if (useFbc) { COMMITTED = AnnotationUtils.fromClass(elements, Initialized.class); FREE = AnnotationUtils.fromClass(elements, UnderInitialization.class); NOT_ONLY_COMMITTED = AnnotationUtils.fromClass(elements, NotOnlyInitialized.class); FBCBOTTOM = AnnotationUtils.fromClass(elements, FBCBottom.class); UNCLASSIFIED = AnnotationUtils.fromClass(elements, UnknownInitialization.class); tempInitAnnos.add(UnderInitialization.class); tempInitAnnos.add(Initialized.class); tempInitAnnos.add(UnknownInitialization.class); tempInitAnnos.add(FBCBottom.class); } else { COMMITTED = AnnotationUtils.fromClass(elements, NonRaw.class); FBCBOTTOM = COMMITTED; // @NonRaw is also bottom UNCLASSIFIED = AnnotationUtils.fromClass(elements, Raw.class); FREE = null; // unused NOT_ONLY_COMMITTED = null; // unused tempInitAnnos.add(Raw.class); tempInitAnnos.add(NonRaw.class); } initAnnos = Collections.unmodifiableSet(tempInitAnnos); }
private boolean containsSameIgnoringValues( Set<Class<? extends Annotation>> quals, AnnotationMirror anno) { for (Class<? extends Annotation> q : quals) { if (AnnotationUtils.areSameByClass(anno, q)) { return true; } } return false; }
/** * Determine the type of a field access (implicit or explicit) based on the receiver type and the * declared annotations for the field. * * @param type Type of the field access expression * @param declaredFieldAnnotations Annotations on the element. * @param receiverType Inferred annotations of the receiver */ private void computeFieldAccessType( AnnotatedTypeMirror type, Collection<? extends AnnotationMirror> declaredFieldAnnotations, AnnotatedTypeMirror receiverType, AnnotatedTypeMirror fieldAnnotations, Element element) { // not necessary for primitive fields if (TypesUtils.isPrimitive(type.getUnderlyingType())) { return; } // not necessary if there is an explicit UnknownInitialization // annotation on the field if (AnnotationUtils.containsSameIgnoringValues( fieldAnnotations.getAnnotations(), UNCLASSIFIED)) { return; } if (isUnclassified(receiverType) || isFree(receiverType)) { TypeMirror fieldDeclarationType = element.getEnclosingElement().asType(); boolean isInitializedForFrame = isInitializedForFrame(receiverType, fieldDeclarationType); if (isInitializedForFrame) { // The receiver is initialized for this frame. // Change the type of the field to @UnknownInitialization or @Raw so that // anything can be assigned to this field. type.replaceAnnotation(UNCLASSIFIED); } else if (computingAnnotatedTypeMirrorOfLHS) { // The receiver is not initialized for this frame, but the type of a lhs is being computed. // Change the type of the field to @UnknownInitialization or @Raw so that // anything can be assigned to this field. type.replaceAnnotation(UNCLASSIFIED); } else { // The receiver is not initialized for this frame and the type being computed is not a LHS. // Replace all annotations with the top annotation for that hierarchy. type.clearAnnotations(); type.addAnnotations(qualHierarchy.getTopAnnotations()); } if (!AnnotationUtils.containsSame(declaredFieldAnnotations, NOT_ONLY_COMMITTED) || !useFbc) { // add root annotation for all other hierarchies, and // Committed for the commitment hierarchy type.replaceAnnotation(COMMITTED); } } }
/** @inheritDoc */ @Override public Slot getSlot(final AnnotationMirror annotationMirror) { final int id; if (InferenceQualifierHierarchy.isVarAnnot(annotationMirror)) { if (annotationMirror.getElementValues().isEmpty()) { return null; // TODO: should we instead throw an exception? } else { final AnnotationValue annoValue = annotationMirror.getElementValues().values().iterator().next(); id = Integer.valueOf(annoValue.toString()); } return getVariable(id); } else { if (constantStore != null) { return constantStore.get(AnnotationUtils.annotationName(annotationMirror)); } else { for (Class<? extends Annotation> realAnno : realQualifiers) { if (AnnotationUtils.areSameByClass(annotationMirror, realAnno)) { return new ConstantSlot(annotationMirror, nextId()); } } } } if (InferenceMain.isHackMode()) { return new ConstantSlot( InferenceMain.getInstance() .getRealTypeFactory() .getQualifierHierarchy() .getTopAnnotations() .iterator() .next(), nextId()); } ErrorReporter.errorAbort( annotationMirror + " is a type of AnnotationMirror not handled by getVariableSlot."); return null; // Dead }
/** * Returns a set of triples {@code (expr, (result, annotation))} of conditional postconditions * according to the given {@link EnsuresQualifierIf}. */ private Set<Pair<String, Pair<Boolean, String>>> getConditionalPostcondition( AnnotationMirror ensuresAnnotationIf) { if (ensuresAnnotationIf == null) { return Collections.emptySet(); } Set<Pair<String, Pair<Boolean, String>>> result = new HashSet<>(); List<String> expressions = AnnotationUtils.getElementValueArray( ensuresAnnotationIf, "expression", String.class, false); String annotation = AnnotationUtils.getElementValueClassName(ensuresAnnotationIf, "qualifier", false) .toString(); boolean annoResult = AnnotationUtils.getElementValue(ensuresAnnotationIf, "result", Boolean.class, false); for (String expr : expressions) { result.add(Pair.of(expr, Pair.of(annoResult, annotation))); } return result; }
/** * If any constant-value annotation has > MAX_VALUES number of values provided, treats the * value as UnknownVal. Works together with ValueVisitor.visitAnnotation, which issues a warning * to the user in this case. */ private void replaceWithUnknownValIfTooManyValues(AnnotatedTypeMirror atm) { AnnotationMirror anno = atm.getAnnotationInHierarchy(UNKNOWNVAL); if (anno != null && anno.getElementValues().size() > 0) { List<Object> values = AnnotationUtils.getElementValueArray(anno, "value", Object.class, false); if (values != null && values.size() > MAX_VALUES) { atm.replaceAnnotation(UNKNOWNVAL); } } }
private void getSubSupertypeFor2() { int num = 1; for (AnnotationMirror i : allTypes) { Set<AnnotationMirror> subtypeSet = new HashSet<AnnotationMirror>(); Set<AnnotationMirror> supertypeSet = new HashSet<AnnotationMirror>(); if (AnnotationUtils.areSame(i, this.top)) { subtypeSet.add(this.top); subtypeSet.add(this.bottom); supertypeSet.add(this.top); } else if (AnnotationUtils.areSame(i, this.bottom)) { subtypeSet.add(this.bottom); supertypeSet.add(this.bottom); supertypeSet.add(this.top); } this.subType.put(i, subtypeSet); this.superType.put(i, supertypeSet); this.modifierInt.put(i, num); this.IntModifier.put(num, i); num++; } }
public static List<Character> getCharValues(AnnotationMirror intAnno) { if (intAnno != null) { List<Long> intValues = AnnotationUtils.getElementValueArray(intAnno, "value", Long.class, true); List<Character> charValues = new ArrayList<Character>(); for (Long i : intValues) { charValues.add((char) i.intValue()); } return charValues; } return new ArrayList<>(); }
/** * Returns a set of triples {@code (expr, (result, annotation))} of conditional postconditions on * the method {@code methodElement}. */ public Set<Pair<String, Pair<Boolean, String>>> getConditionalPostconditions( ExecutableElement methodElement) { Set<Pair<String, Pair<Boolean, String>>> result = new HashSet<>(); // Check for a single contract. AnnotationMirror ensuresAnnotationIf = factory.getDeclAnnotation(methodElement, EnsuresQualifierIf.class); result.addAll(getConditionalPostcondition(ensuresAnnotationIf)); // Check for multiple contracts. AnnotationMirror ensuresAnnotationsIf = factory.getDeclAnnotation(methodElement, EnsuresQualifiersIf.class); if (ensuresAnnotationsIf != null) { List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray( ensuresAnnotationsIf, "value", AnnotationMirror.class, false); for (AnnotationMirror a : annotations) { result.addAll(getConditionalPostcondition(a)); } } // Check type-system specific annotations. Class<ConditionalPostconditionAnnotation> metaAnnotation = ConditionalPostconditionAnnotation.class; List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(methodElement, metaAnnotation); for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) { AnnotationMirror anno = r.first; AnnotationMirror metaAnno = r.second; List<String> expressions = AnnotationUtils.getElementValueArray(anno, "expression", String.class, false); String annotationString = AnnotationUtils.getElementValueClassName(metaAnno, "qualifier", false).toString(); boolean annoResult = AnnotationUtils.getElementValue(anno, "result", Boolean.class, false); for (String expr : expressions) { result.add(Pair.of(expr, Pair.of(annoResult, annotationString))); } } return result; }
/** * Returns a set of pairs {@code (expr, annotation)} of preconditions on the element {@code * element}. */ public Set<Pair<String, String>> getPreconditions(Element element) { Set<Pair<String, String>> result = new HashSet<>(); // Check for a single contract. AnnotationMirror requiresAnnotation = factory.getDeclAnnotation(element, RequiresQualifier.class); result.addAll(getPrecondition(requiresAnnotation)); // Check for multiple contracts. AnnotationMirror requiresAnnotations = factory.getDeclAnnotation(element, RequiresQualifiers.class); if (requiresAnnotations != null) { List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray( requiresAnnotations, "value", AnnotationMirror.class, false); for (AnnotationMirror a : annotations) { result.addAll(getPrecondition(a)); } } // Check type-system specific annotations. Class<PreconditionAnnotation> metaAnnotation = PreconditionAnnotation.class; List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(element, metaAnnotation); for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) { AnnotationMirror anno = r.first; AnnotationMirror metaAnno = r.second; List<String> expressions = AnnotationUtils.getElementValueArray(anno, "value", String.class, false); String annotationString = AnnotationUtils.getElementValueClassName(metaAnno, "qualifier", false).toString(); for (String expr : expressions) { result.add(Pair.of(expr, annotationString)); } } return result; }
/** * Subtype testing for initialization annotations. Will return false if either qualifier is not * an initialization annotation. Subclasses should override isSubtype and call this method for * initialization qualifiers. */ public boolean isSubtypeInitialization(AnnotationMirror rhs, AnnotationMirror lhs) { if (!isInitializationAnnotation(rhs) || !isInitializationAnnotation(lhs)) { return false; } // 't' is always a subtype of 't' if (AnnotationUtils.areSame(rhs, lhs)) { return true; } // @Initialized is only a supertype of @FBCBottom. if (isCommitted(lhs)) { return isFbcBottom(rhs); } // @FBCBottom is a supertype of nothing. if (isFbcBottom(lhs)) { return false; } // @FBCBottom is a subtype of everything. if (isFbcBottom(rhs)) { return true; } boolean unc1 = isUnclassified(rhs); boolean unc2 = isUnclassified(lhs); boolean free1 = isFree(rhs); boolean free2 = isFree(lhs); // @Initialized is only a subtype of @UnknownInitialization. if (isCommitted(rhs)) { return unc2; } // @UnknownInitialization is not a subtype of @UnderInitialization. if (unc1 && free2) { return false; } // Now, either both annotations are @UnderInitialization, both annotations are // @UnknownInitialization or anno1 is @UnderInitialization and anno2 is // @UnknownInitialization. assert (free1 && free2) || (unc1 && unc2) || (free1 && unc2); // Thus, we only need to look at the type frame. TypeMirror frame1 = getTypeFrameFromAnnotation(rhs); TypeMirror frame2 = getTypeFrameFromAnnotation(lhs); return types.isSubtype(frame1, frame2); }
@Override public String formatAnnotationString( Collection<? extends AnnotationMirror> annos, boolean printInvisible) { // create an empty annotation set Set<AnnotationMirror> trimmedAnnoSet = AnnotationUtils.createAnnotationSet(); // loop through all the annotation mirrors to see if they use Prefix.one, remove Prefix.one if // it does for (AnnotationMirror anno : annos) { if (UnitsRelationsTools.getPrefix(anno) == Prefix.one) { anno = UnitsRelationsTools.removePrefix(elements, anno); } // add to set trimmedAnnoSet.add(anno); } return super.formatAnnotationString( Collections.unmodifiableSet(trimmedAnnoSet), printInvisible); }
public static List<Boolean> getBooleanValues(AnnotationMirror boolAnno) { if (boolAnno != null) { List<Boolean> boolValues = AnnotationUtils.getElementValueArray(boolAnno, "value", Boolean.class, true); Set<Boolean> boolSet = new TreeSet<>(boolValues); if (boolSet.size() > 1) { // boolSet={true,false}; return new ArrayList<>(); } if (boolSet.size() == 0) { // boolSet={}; return new ArrayList<>(); } if (boolSet.size() == 1) { // boolSet={true} or boolSet={false} return new ArrayList<>(boolSet); } } return new ArrayList<>(); }
/** * Recursive method to handle array initializations. Recursively descends the initializer to * find each dimension's size and create the appropriate annotation for it. * * @param dimensions a list of ExpressionTrees where each ExpressionTree is a specifier of the * size of that dimension (should be an IntVal). * @param type the AnnotatedTypeMirror of the array */ private void handleDimensions( List<? extends ExpressionTree> dimensions, AnnotatedArrayType type) { if (dimensions.size() > 1) { handleDimensions( dimensions.subList(1, dimensions.size()), (AnnotatedArrayType) type.getComponentType()); } AnnotationMirror dimType = getAnnotatedType(dimensions.get(0)).getAnnotationInHierarchy(UNKNOWNVAL); if (!AnnotationUtils.areSameIgnoringValues(dimType, UNKNOWNVAL)) { List<Long> longLengths = getIntValues(dimType); HashSet<Integer> lengths = new HashSet<Integer>(longLengths.size()); for (Long l : longLengths) { lengths.add(l.intValue()); } AnnotationMirror newQual = createArrayLenAnnotation(new ArrayList<>(lengths)); type.replaceAnnotation(newQual); } }
/** Returns whether the field {@code f} is unused, given the annotations on the receiver. */ private boolean isUnused( VariableTree field, Collection<? extends AnnotationMirror> receiverAnnos) { if (receiverAnnos.isEmpty()) { return false; } AnnotationMirror unused = getDeclAnnotation(TreeUtils.elementFromDeclaration(field), Unused.class); if (unused == null) { return false; } Name when = AnnotationUtils.getElementValueClassName(unused, "when", false); for (AnnotationMirror anno : receiverAnnos) { Name annoName = ((TypeElement) anno.getAnnotationType().asElement()).getQualifiedName(); if (annoName.contentEquals(when)) { return true; } } return false; }
public static List<Integer> getArrayLength(AnnotationMirror arrayAnno) { return AnnotationUtils.getElementValueArray(arrayAnno, "value", Integer.class, true); }
public static List<Double> getDoubleValues(AnnotationMirror doubleAnno) { return AnnotationUtils.getElementValueArray(doubleAnno, "value", Double.class, true); }
public static List<Long> getIntValues(AnnotationMirror intAnno) { return AnnotationUtils.getElementValueArray(intAnno, "value", Long.class, true); }
/** * Is {@code anno} the {@link Initialized} annotation? If {@code useFbc} is false, then {@link * NonRaw} is used in the comparison. */ public boolean isCommitted(AnnotationMirror anno) { return AnnotationUtils.areSame(anno, COMMITTED); }
/** * Computes subtyping as per the subtyping in the qualifier hierarchy structure unless both * annotations are Value. In this case, rhs is a subtype of lhs iff lhs contains at least every * element of rhs * * @return true if rhs is a subtype of lhs, false otherwise */ @Override public boolean isSubtype(AnnotationMirror rhs, AnnotationMirror lhs) { if (AnnotationUtils.areSameByClass(lhs, UnknownVal.class) || AnnotationUtils.areSameByClass(rhs, BottomVal.class)) { return true; } else if (AnnotationUtils.areSameByClass(rhs, UnknownVal.class) || AnnotationUtils.areSameByClass(lhs, BottomVal.class)) { return false; } else if (AnnotationUtils.areSameIgnoringValues(lhs, rhs)) { // Same type, so might be subtype List<Object> lhsValues = AnnotationUtils.getElementValueArray(lhs, "value", Object.class, true); List<Object> rhsValues = AnnotationUtils.getElementValueArray(rhs, "value", Object.class, true); return lhsValues.containsAll(rhsValues); } else if (AnnotationUtils.areSameByClass(lhs, DoubleVal.class) && AnnotationUtils.areSameByClass(rhs, IntVal.class)) { List<Long> rhsValues; rhsValues = AnnotationUtils.getElementValueArray(rhs, "value", Long.class, true); List<Double> lhsValues = AnnotationUtils.getElementValueArray(lhs, "value", Double.class, true); boolean same = false; for (Long rhsLong : rhsValues) { for (Double lhsDbl : lhsValues) { if (lhsDbl.doubleValue() == rhsLong.doubleValue()) { same = true; break; } } if (!same) { return false; } } return same; } return false; }
// JLTODO: document! // It's not nice that so many fields are public and non-final. public class LatticeGenerator { public ProcessingEnvironment processingEnv; public QualifierHierarchy qualHierarchy; public Map<AnnotationMirror, Collection<AnnotationMirror>> subType = AnnotationUtils.createAnnotationMap(); public Map<AnnotationMirror, Collection<AnnotationMirror>> superType = AnnotationUtils.createAnnotationMap(); public Map<AnnotationMirror, Collection<AnnotationMirror>> notComparableType = AnnotationUtils.createAnnotationMap(); public Map<AnnotationMirror, Integer> modifierInt = AnnotationUtils.createAnnotationMap(); public Map<Integer, AnnotationMirror> IntModifier = new HashMap<Integer, AnnotationMirror>(); public Set<? extends AnnotationMirror> allTypes; public AnnotationMirror top; public AnnotationMirror bottom; public int numModifiers; public LatticeGenerator(QualifierHierarchy qualHierarchy) { this.qualHierarchy = qualHierarchy; this.allTypes = qualHierarchy.getTypeQualifiers(); this.top = qualHierarchy.getTopAnnotations().iterator().next(); this.bottom = qualHierarchy.getBottomAnnotations().iterator().next(); this.numModifiers = qualHierarchy.getTypeQualifiers().size(); getSubSupertype(); getNotComparable(); // for (AnnotationMirror i : subType.keySet()){ // System.out.println("Key: " + i.toString() + " Value: "+ // subType.get(i).toString()); // } // System.out.println(allTypes.toString()); } public LatticeGenerator( AnnotationMirror dataflowAnnotation, ProcessingEnvironment processingEnv) { this.processingEnv = processingEnv; this.top = dataflowAnnotation; this.bottom = DataflowUtils.createDataflowAnnotation( new HashSet<String>(Arrays.asList("")), processingEnv); this.numModifiers = 2; addAlltypesFor2(); getSubSupertypeFor2(); // TODO: } private void addAlltypesFor2() { Set<AnnotationMirror> all2Types = new HashSet<AnnotationMirror>(); all2Types.add(this.top); all2Types.add(this.bottom); this.allTypes = all2Types; } private void getSubSupertypeFor2() { int num = 1; for (AnnotationMirror i : allTypes) { Set<AnnotationMirror> subtypeSet = new HashSet<AnnotationMirror>(); Set<AnnotationMirror> supertypeSet = new HashSet<AnnotationMirror>(); if (AnnotationUtils.areSame(i, this.top)) { subtypeSet.add(this.top); subtypeSet.add(this.bottom); supertypeSet.add(this.top); } else if (AnnotationUtils.areSame(i, this.bottom)) { subtypeSet.add(this.bottom); supertypeSet.add(this.bottom); supertypeSet.add(this.top); } this.subType.put(i, subtypeSet); this.superType.put(i, supertypeSet); this.modifierInt.put(i, num); this.IntModifier.put(num, i); num++; } } private void getSubSupertype() { int num = 1; for (AnnotationMirror i : allTypes) { Set<AnnotationMirror> subtypeFori = new HashSet<AnnotationMirror>(); Set<AnnotationMirror> supertypeFori = new HashSet<AnnotationMirror>(); for (AnnotationMirror j : allTypes) { if (qualHierarchy.isSubtype(j, i)) { subtypeFori.add(j); } if (qualHierarchy.isSubtype(i, j)) { supertypeFori.add(j); } } subType.put(i, subtypeFori); superType.put(i, supertypeFori); modifierInt.put(i, num); IntModifier.put(num, i); num++; } // for (Integer j: IntModifier.keySet()){ // System.out.println("final key "+j+ " " + "final value: " + // IntModifier.get(j).toString()); // } } private void getNotComparable() { for (AnnotationMirror i : allTypes) { Set<AnnotationMirror> notComparableFori = new HashSet<AnnotationMirror>(); for (AnnotationMirror j : allTypes) { if (!subType.get(i).contains(j) && !subType.get(j).contains(i)) { notComparableFori.add(j); } } if (!notComparableFori.isEmpty()) { notComparableType.put(i, notComparableFori); } } } }
public I18nTreeAnnotator(AnnotatedTypeFactory atypeFactory) { super(atypeFactory); LOCALIZED = AnnotationUtils.fromClass(elements, Localized.class); }