@Override public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { List<? extends ExpressionTree> dimensions = tree.getDimensions(); List<? extends ExpressionTree> initializers = tree.getInitializers(); // Dimensions provided if (!dimensions.isEmpty()) { handleDimensions(dimensions, (AnnotatedArrayType) type); } else { // Initializer used handleInitalizers(initializers, (AnnotatedArrayType) type); AnnotationMirror newQual; Class<?> clazz = ValueCheckerUtils.getClassFromType(type.getUnderlyingType()); String stringVal = null; if (clazz.equals(byte[].class)) { stringVal = getByteArrayStringVal(initializers); } else if (clazz.equals(char[].class)) { stringVal = getCharArrayStringVal(initializers); } if (stringVal != null) { newQual = createStringAnnotation(Collections.singletonList(stringVal)); type.replaceAnnotation(newQual); } } return null; }
protected void reportValidityResult( final /*@CompilerMessageKey*/ String errorType, final AnnotatedTypeMirror type, final Tree p) { checker.report(Result.failure(errorType, type.getAnnotations(), type.toString()), p); isValid = false; }
private AnnotatedTypeMirror getPostFixAnno(UnaryTree tree, AnnotatedTypeMirror anno) { if (anno.hasAnnotation(DoubleVal.class)) { return postFixDouble(anno, tree.getKind() == Tree.Kind.POSTFIX_INCREMENT); } else if (anno.hasAnnotation(IntVal.class)) { return postFixInt(anno, tree.getKind() == Tree.Kind.POSTFIX_INCREMENT); } return anno; }
@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); }
@Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (!type.isAnnotatedInHierarchy(LOCALIZED)) { if (tree.getKind() == Tree.Kind.STRING_LITERAL && tree.getValue().equals("")) { type.addAnnotation(LOCALIZED); } } return super.visitLiteral(tree, type); }
/** * 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); } } }
@Override public Void visitTypeCast(TypeCastTree tree, AnnotatedTypeMirror type) { if (isUnderlyingTypeAValue(type)) { AnnotatedTypeMirror castedAnnotation = getAnnotatedType(tree.getExpression()); List<?> values = getValues(castedAnnotation, type.getUnderlyingType()); type.replaceAnnotation(resultAnnotationHandler(type.getUnderlyingType(), values, tree)); } else if (type.getKind() == TypeKind.ARRAY) { if (tree.getExpression().getKind() == Kind.NULL_LITERAL) { type.replaceAnnotation(BOTTOMVAL); } } return null; }
@Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (!type.isAnnotatedInHierarchy(theAnnot) && tree.getKind() == Tree.Kind.STRING_LITERAL && strContains(lookupKeys, tree.getValue().toString())) { type.addAnnotation(theAnnot); } // A possible extension is to record all the keys that have been used and // in the end output a list of keys that were not used in the program, // possibly pointing to the opposite problem, keys that were supposed to // be used somewhere, but have not been, maybe because of copy-and-paste errors. return super.visitLiteral(tree, type); }
@Override public Void visitMethodInvocation(MethodInvocationTree node, Void p) { if (isInvocationOfEquals(node)) { AnnotatedTypeMirror recv = atypeFactory.getReceiverType(node); AnnotatedTypeMirror comp = atypeFactory.getAnnotatedType(node.getArguments().get(0)); if (this.checker.getLintOption("dotequals", true) && recv.hasEffectiveAnnotation(INTERNED) && comp.hasEffectiveAnnotation(INTERNED)) checker.report(Result.warning("unnecessary.equals"), node); } return super.visitMethodInvocation(node, p); }
public void handle(MethodInvocationTree tree, AnnotatedExecutableType method) { if (TreeUtils.isMethodInvocation(tree, systemGetProperty, env)) { List<? extends ExpressionTree> args = tree.getArguments(); assert args.size() == 1; ExpressionTree arg = args.get(0); if (arg.getKind() == Tree.Kind.STRING_LITERAL) { String literal = (String) ((LiteralTree) arg).getValue(); if (systemProperties.contains(literal)) { AnnotatedTypeMirror type = method.getReturnType(); type.replaceAnnotation(factory.NONNULL); } } } }
private AnnotatedTypeMirror postFixDouble(AnnotatedTypeMirror anno, boolean increment) { List<Double> values = getDoubleValues(anno.getAnnotation(DoubleVal.class)); List<? extends Number> castedValues = NumberUtils.castNumbers(anno.getUnderlyingType(), values); List<Double> results = new ArrayList<>(); for (Number value : castedValues) { NumberMath<?> number = NumberMath.getNumberMath(value); if (increment) { results.add(number.minus(1).doubleValue()); } else { results.add(number.plus(1).doubleValue()); } } anno.replaceAnnotation(createDoubleValAnnotation(results)); return anno; }
@Override public Void visitNewArray(NewArrayTree node, Void p) { AnnotatedArrayType type = atypeFactory.getAnnotatedType(node); AnnotatedTypeMirror componentType = type.getComponentType(); if (componentType.hasEffectiveAnnotation(NONNULL) && !isNewArrayAllZeroDims(node) && !isNewArrayInToArray(node) && !TypesUtils.isPrimitive(componentType.getUnderlyingType()) && checker.getLintOption("forbidnonnullarraycomponents", false)) { checker.report( Result.failure("new.array.type.invalid", componentType.getAnnotations(), type.toString()), node); } return super.visitNewArray(node, p); }
@Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (tree.getKind() != Tree.Kind.NULL_LITERAL) { type.addAnnotation(COMMITTED); } return super.visitLiteral(tree, type); }
/** @inheritDoc */ @Override public VariableSlot getVariableSlot(final AnnotatedTypeMirror atm) { AnnotationMirror annot = atm.getAnnotationInHierarchy(this.varAnnot); if (annot == null) { annot = atm.getAnnotationInHierarchy(this.unqualified); if (annot == null) { if (InferenceMain.isHackMode()) { return null; } ErrorReporter.errorAbort("Missing VarAnnot annotation: " + atm); } } return (VariableSlot) getSlot(annot); }
@Override public Void visitBinary(BinaryTree node, Void p) { // No checking unless the operator is "==" or "!=". if (!(node.getKind() == Tree.Kind.EQUAL_TO || node.getKind() == Tree.Kind.NOT_EQUAL_TO)) return super.visitBinary(node, p); ExpressionTree leftOp = node.getLeftOperand(); ExpressionTree rightOp = node.getRightOperand(); // Check passes if either arg is null. if (leftOp.getKind() == Tree.Kind.NULL_LITERAL || rightOp.getKind() == Tree.Kind.NULL_LITERAL) return super.visitBinary(node, p); AnnotatedTypeMirror left = atypeFactory.getAnnotatedType(leftOp); AnnotatedTypeMirror right = atypeFactory.getAnnotatedType(rightOp); // If either argument is a primitive, check passes due to auto-unboxing if (left.getKind().isPrimitive() || right.getKind().isPrimitive()) return super.visitBinary(node, p); if (!(shouldCheckFor(leftOp) && shouldCheckFor(rightOp))) return super.visitBinary(node, p); // Syntactic checks for legal uses of == if (suppressInsideComparison(node)) return super.visitBinary(node, p); if (suppressEarlyEquals(node)) return super.visitBinary(node, p); if (suppressEarlyCompareTo(node)) return super.visitBinary(node, p); if (suppressClassAnnotation(left, right)) { return super.visitBinary(node, p); } Element leftElt = null; Element rightElt = null; if (left instanceof org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) { leftElt = ((DeclaredType) left.getUnderlyingType()).asElement(); } if (right instanceof org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) { rightElt = ((DeclaredType) right.getUnderlyingType()).asElement(); } // if neither @Interned or @UsesObjectEquals, report error if (!(left.hasEffectiveAnnotation(INTERNED) || (leftElt != null && leftElt.getAnnotation(UsesObjectEquals.class) != null))) checker.report(Result.failure("not.interned", left), leftOp); if (!(right.hasEffectiveAnnotation(INTERNED) || (rightElt != null && rightElt.getAnnotation(UsesObjectEquals.class) != null))) checker.report(Result.failure("not.interned", right), rightOp); return super.visitBinary(node, p); }
private List<?> getValues(AnnotatedTypeMirror type, TypeMirror castTo) { AnnotationMirror anno = type.getAnnotationInHierarchy(UNKNOWNVAL); if (anno == null) { // if type is an AnnotatedTypeVariable (or other type without a primary annotation) // then anno will be null. It would be safe to use the annotation on the upper bound; // however, unless the upper bound was explicitly annotated, it will be unknown. // AnnotatedTypes.findEffectiveAnnotationInHierarchy(, toSearch, top) return new ArrayList<>(); } return ValueCheckerUtils.getValuesCastedToType(anno, castTo); }
@Override public Void visitArray(AnnotatedArrayType type, Tree tree) { // TODO: is there already or add a helper method // to determine the non-array component type AnnotatedTypeMirror comp = type; do { comp = ((AnnotatedArrayType) comp).getComponentType(); } while (comp.getKind() == TypeKind.ARRAY); if (comp != null && comp.getKind() == TypeKind.DECLARED && checker.shouldSkipUses(((AnnotatedDeclaredType) comp).getUnderlyingType().asElement())) { return super.visitArray(type, tree); } if (!visitor.isValidUse(type, tree)) { reportError(type, tree); } return super.visitArray(type, tree); }
/** Returns true if the type's declaration has an @Interned annotation. */ private boolean classIsAnnotated(AnnotatedTypeMirror type) { TypeMirror tm = type.getUnderlyingType(); if (tm == null) { // Maybe a type variable or wildcard had no upper bound return false; } tm = ((com.sun.tools.javac.code.Type) tm).unannotatedType(); if (tm.getKind() == TypeKind.TYPEVAR) { tm = ((TypeVariable) tm).getUpperBound(); } if (tm.getKind() == TypeKind.WILDCARD) { tm = ((WildcardType) tm).getExtendsBound(); } if (tm == null || tm.getKind() == TypeKind.ARRAY) { // Bound of a wildcard might be null return false; } tm = ((com.sun.tools.javac.code.Type) tm).unannotatedType(); if (tm.getKind() != TypeKind.DECLARED) { System.out.printf("InterningVisitor.classIsAnnotated: tm = %s (%s)%n", tm, tm.getClass()); } Element classElt = ((DeclaredType) tm).asElement(); if (classElt == null) { System.out.printf( "InterningVisitor.classIsAnnotated: classElt = null for tm = %s (%s)%n", tm, tm.getClass()); } if (classElt != null) { AnnotatedTypeMirror classType = atypeFactory.fromElement(classElt); assert classType != null; for (AnnotationMirror anno : classType.getAnnotations()) { if (INTERNED.equals(anno)) { return true; } } } return false; }
/** * Reports an error if a comparison of a @NonNull expression with the null literal is performed. */ protected void checkForRedundantTests(BinaryTree node) { final ExpressionTree leftOp = node.getLeftOperand(); final ExpressionTree rightOp = node.getRightOperand(); // respect command-line option if (!checker.getLintOption( AbstractNullnessChecker.LINT_REDUNDANTNULLCOMPARISON, AbstractNullnessChecker.LINT_DEFAULT_REDUNDANTNULLCOMPARISON)) { return; } // equality tests if ((node.getKind() == Tree.Kind.EQUAL_TO || node.getKind() == Tree.Kind.NOT_EQUAL_TO)) { AnnotatedTypeMirror left = atypeFactory.getAnnotatedType(leftOp); AnnotatedTypeMirror right = atypeFactory.getAnnotatedType(rightOp); if (leftOp.getKind() == Tree.Kind.NULL_LITERAL && right.hasEffectiveAnnotation(NONNULL)) checker.report(Result.warning(KNOWN_NONNULL, rightOp.toString()), node); else if (rightOp.getKind() == Tree.Kind.NULL_LITERAL && left.hasEffectiveAnnotation(NONNULL)) checker.report(Result.warning(KNOWN_NONNULL, leftOp.toString()), node); } }
@Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (isUnderlyingTypeAValue(type)) { switch (tree.getKind()) { case BOOLEAN_LITERAL: AnnotationMirror boolAnno = createBooleanAnnotation(Collections.singletonList((Boolean) tree.getValue())); type.replaceAnnotation(boolAnno); return null; case CHAR_LITERAL: AnnotationMirror charAnno = createCharAnnotation(Collections.singletonList((Character) tree.getValue())); type.replaceAnnotation(charAnno); return null; case DOUBLE_LITERAL: AnnotationMirror doubleAnno = createNumberAnnotationMirror( Collections.<Number>singletonList((Double) tree.getValue())); type.replaceAnnotation(doubleAnno); return null; case FLOAT_LITERAL: AnnotationMirror floatAnno = createNumberAnnotationMirror( Collections.<Number>singletonList((Float) tree.getValue())); type.replaceAnnotation(floatAnno); return null; case INT_LITERAL: AnnotationMirror intAnno = createNumberAnnotationMirror( Collections.<Number>singletonList((Integer) tree.getValue())); type.replaceAnnotation(intAnno); return null; case LONG_LITERAL: AnnotationMirror longAnno = createNumberAnnotationMirror( Collections.<Number>singletonList((Long) tree.getValue())); type.replaceAnnotation(longAnno); return null; case STRING_LITERAL: AnnotationMirror stringAnno = createStringAnnotation(Collections.singletonList((String) tree.getValue())); type.replaceAnnotation(stringAnno); return null; default: return null; } } return null; }
@Override public Void visitNewClass(NewClassTree node, AnnotatedTypeMirror p) { super.visitNewClass(node, p); if (useFbc) { boolean allCommitted = true; Type type = ((JCTree) node).type; for (ExpressionTree a : node.getArguments()) { final AnnotatedTypeMirror t = getAnnotatedType(a); allCommitted &= (isCommitted(t) || isFbcBottom(t)); } if (!allCommitted) { p.replaceAnnotation(createFreeAnnotation(type)); } } return null; }
@Override public Void visitMemberSelect(MemberSelectTree tree, AnnotatedTypeMirror type) { if (TreeUtils.isFieldAccess(tree) && isUnderlyingTypeAValue(type)) { VariableElement elem = (VariableElement) InternalUtils.symbol(tree); Object value = elem.getConstantValue(); if (value != null) { // compile time constant type.replaceAnnotation( resultAnnotationHandler( type.getUnderlyingType(), Collections.singletonList(value), tree)); return null; } if (ElementUtils.isStatic(elem) && ElementUtils.isFinal(elem)) { Element e = InternalUtils.symbol(tree.getExpression()); if (e != null) { String classname = ElementUtils.getQualifiedClassName(e).toString(); String fieldName = tree.getIdentifier().toString(); value = evalutator.evaluateStaticFieldAccess(classname, fieldName, tree); if (value != null) type.replaceAnnotation( resultAnnotationHandler( type.getUnderlyingType(), Collections.singletonList(value), tree)); return null; } } if (tree.getIdentifier().toString().equals("length")) { AnnotatedTypeMirror receiverType = getAnnotatedType(tree.getExpression()); if (receiverType.getKind() == TypeKind.ARRAY) { AnnotationMirror arrayAnno = receiverType.getAnnotation(ArrayLen.class); if (arrayAnno != null) { // array.length, where array : @ArrayLen(x) List<Integer> lengths = ValueAnnotatedTypeFactory.getArrayLength(arrayAnno); type.replaceAnnotation(createNumberAnnotationMirror(new ArrayList<Number>(lengths))); return null; } } } } return null; }
/** * 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); } } }
@Override public Void visitMethodInvocation(MethodInvocationTree tree, AnnotatedTypeMirror type) { if (isUnderlyingTypeAValue(type) && methodIsStaticallyExecutable(TreeUtils.elementFromUse(tree))) { // Get argument values List<? extends ExpressionTree> arguments = tree.getArguments(); ArrayList<List<?>> argValues; if (arguments.size() > 0) { argValues = new ArrayList<List<?>>(); for (ExpressionTree argument : arguments) { AnnotatedTypeMirror argType = getAnnotatedType(argument); List<?> values = getValues(argType, argType.getUnderlyingType()); if (values.isEmpty()) { // values aren't known, so don't try to evaluate the // method return null; } argValues.add(values); } } else { argValues = null; } // Get receiver values AnnotatedTypeMirror receiver = getReceiverType(tree); List<?> receiverValues; if (receiver != null && !ElementUtils.isStatic(TreeUtils.elementFromUse(tree))) { receiverValues = getValues(receiver, receiver.getUnderlyingType()); if (receiverValues.isEmpty()) { // values aren't known, so don't try to evaluate the // method return null; } } else { receiverValues = null; } // Evaluate method List<?> returnValues = evalutator.evaluteMethodCall(argValues, receiverValues, tree); AnnotationMirror returnType = resultAnnotationHandler(type.getUnderlyingType(), returnValues, tree); type.replaceAnnotation(returnType); } return null; }
@Override protected void checkMethodInvocability( AnnotatedExecutableType method, MethodInvocationTree node) { if (!TreeUtils.isSelfAccess(node) && // Static methods don't have a receiver method.getReceiverType() != null) { // TODO: should all or some constructors be excluded? // method.getElement().getKind() != ElementKind.CONSTRUCTOR) { Set<AnnotationMirror> recvAnnos = atypeFactory.getReceiverType(node).getAnnotations(); AnnotatedTypeMirror methodReceiver = method.getReceiverType().getErased(); AnnotatedTypeMirror treeReceiver = methodReceiver.shallowCopy(false); AnnotatedTypeMirror rcv = atypeFactory.getReceiverType(node); treeReceiver.addAnnotations(rcv.getEffectiveAnnotations()); // If receiver is Nullable, then we don't want to issue a warning // about method invocability (we'd rather have only the // "dereference.of.nullable" message). if (treeReceiver.hasAnnotation(NULLABLE) || recvAnnos.contains(MONOTONIC_NONNULL)) { return; } } super.checkMethodInvocability(method, node); }
@Override public Void visitNewClass(NewClassTree tree, AnnotatedTypeMirror type) { boolean wrapperClass = TypesUtils.isBoxedPrimitive(type.getUnderlyingType()) || TypesUtils.isDeclaredOfName(type.getUnderlyingType(), "java.lang.String"); if (wrapperClass || (isUnderlyingTypeAValue(type) && methodIsStaticallyExecutable(TreeUtils.elementFromUse(tree)))) { // get arugment values List<? extends ExpressionTree> arguments = tree.getArguments(); ArrayList<List<?>> argValues; if (arguments.size() > 0) { argValues = new ArrayList<List<?>>(); for (ExpressionTree argument : arguments) { AnnotatedTypeMirror argType = getAnnotatedType(argument); List<?> values = getValues(argType, argType.getUnderlyingType()); if (values.isEmpty()) { // values aren't known, so don't try to evaluate the // method return null; } argValues.add(values); } } else { argValues = null; } // Evaluate method List<?> returnValues = evalutator.evaluteConstrutorCall(argValues, tree, type.getUnderlyingType()); AnnotationMirror returnType = resultAnnotationHandler(type.getUnderlyingType(), returnValues, tree); type.replaceAnnotation(returnType); } return null; }
private void handleInitalizers( List<? extends ExpressionTree> initializers, AnnotatedArrayType type) { List<Integer> array = new ArrayList<>(); array.add(initializers.size()); type.replaceAnnotation(createArrayLenAnnotation(array)); boolean singleDem = type.getComponentType().getKind() != TypeKind.ARRAY; if (singleDem) { return; } List<List<Integer>> summarylengths = new ArrayList<>(); for (ExpressionTree init : initializers) { AnnotatedArrayType subArrayType = (AnnotatedArrayType) getAnnotatedType(init); AnnotatedTypeMirror componentType = subArrayType; int count = 0; while (componentType.getKind() == TypeKind.ARRAY) { AnnotationMirror arrayLen = componentType.getAnnotation(ArrayLen.class); List<Integer> currentLengths; if (arrayLen != null) { currentLengths = getArrayLength(arrayLen); } else { currentLengths = (new ArrayList<Integer>()); } if (count == summarylengths.size()) { summarylengths.add(new ArrayList<Integer>()); } summarylengths.get(count).addAll(currentLengths); count++; componentType = ((AnnotatedArrayType) componentType).getComponentType(); } } AnnotatedTypeMirror componentType = type.getComponentType(); int i = 0; while (componentType.getKind() == TypeKind.ARRAY) { componentType.addAnnotation(createArrayLenAnnotation(summarylengths.get(i))); componentType = ((AnnotatedArrayType) componentType).getComponentType(); i++; } }
/** * Processes an element by calling e.accept(this, p); this method may be overridden by subclasses. * * @return the result of visiting {@code type} */ protected R scan(AnnotatedTypeMirror type, P p) { return (type == null ? null : type.accept(this, p)); }
/** * Overloaded method for convenience of dealing with AnnotatedTypeMirrors. See * isClassCovered(TypeMirror type) below */ private boolean isUnderlyingTypeAValue(AnnotatedTypeMirror type) { return coveredClassStrings.contains(type.getUnderlyingType().toString()); }
/** * Issues a 'dereference.of.nullable' if the type is not of a {@link NonNull} type. * * @param tree the tree where the error is to reported * @param errMsg the error message (must be {@link CompilerMessageKey}) */ private void checkForNullability(ExpressionTree tree, /*@CompilerMessageKey*/ String errMsg) { AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(tree); if (!type.hasEffectiveAnnotation(NONNULL)) { checker.report(Result.failure(errMsg, tree), tree); } }