use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitBindingPattern17.
/**
* Visit a BindingPatternTree
*
* @param bindingPatternTree a BindingPatternTree, typed as Tree to be backward-compatible
* @param p parameter
* @return the result of visiting the binding pattern tree
*/
public Node visitBindingPattern17(Tree bindingPatternTree, Void p) {
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
TypeElement classElem = TreeUtils.elementFromDeclaration(enclosingClass);
Node receiver = new ImplicitThisNode(classElem.asType());
VariableTree varTree = TreeUtils.bindingPatternTreeGetVariable(bindingPatternTree);
LocalVariableNode varNode = new LocalVariableNode(varTree, receiver);
extendWithNode(varNode);
return varNode;
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class CFGTranslationPhaseOne method findOwner.
/**
* Find nearest owner element (Method or Class) which holds current tree.
*
* @return nearest owner element of current tree
*/
private Element findOwner() {
Tree enclosingMethodOrLambda = TreePathUtil.enclosingMethodOrLambda(getCurrentPath());
if (enclosingMethodOrLambda != null) {
if (enclosingMethodOrLambda.getKind() == Kind.METHOD) {
return TreeUtils.elementFromDeclaration((MethodTree) enclosingMethodOrLambda);
} else {
// The current path is in a lambda tree. In this case the owner is either a method or
// an initializer block.
LambdaExpressionTree lambdaTree = (LambdaExpressionTree) enclosingMethodOrLambda;
if (!lambdaTree.getParameters().isEmpty()) {
// If there is a lambda parameter, use the same owner.
return TreeUtils.elementFromDeclaration(lambdaTree.getParameters().get(0)).getEnclosingElement();
}
// If there are no lambda parameters then if the lambda is enclosed in a method, that's the
// owner.
MethodTree enclosingMethod = TreePathUtil.enclosingMethod(getCurrentPath());
if (enclosingMethod != null) {
return TreeUtils.elementFromDeclaration(enclosingMethod);
}
// If the lambda is not enclosed in a method, then the owner should be a constructor. javac
// seems to use the last constructor in the list. (If the lambda is in an initializer of a
// static field then the owner should be a static initializer block, but there doesn't seem
// to be a way to get a reference to the static initializer element.)
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
TypeElement typeElement = TreeUtils.elementFromDeclaration(enclosingClass);
ExecutableElement constructor = null;
for (Element enclosing : typeElement.getEnclosedElements()) {
if (enclosing.getKind() == ElementKind.CONSTRUCTOR) {
constructor = (ExecutableElement) enclosing;
}
}
return constructor;
}
} else {
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
return TreeUtils.elementFromDeclaration(enclosingClass);
}
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class BaseTypeVisitor method checkFieldInvariantDeclarations.
/**
* Check that the field invariant declaration annotations meet the following requirements:
*
* <ol>
* <!-- The item numbering is referred to in the body of the method.-->
* <li value="1">If the superclass of {@code classTree} has a field invariant, then the field
* invariant for {@code classTree} must include all the fields in the superclass invariant
* and those fields' annotations must be a subtype (or equal) to the annotations for those
* fields in the superclass.
* <li value="2">The fields in the invariant must be a.) final and b.) declared in a superclass
* of {@code classTree}.
* <li value="3">The qualifier for each field must be a subtype of the annotation on the
* declaration of that field.
* <li value="4">The field invariant has an equal number of fields and qualifiers, or it has one
* qualifier and at least one field.
* </ol>
*
* @param classTree class that might have a field invariant
* @checker_framework.manual #field-invariants Field invariants
*/
protected void checkFieldInvariantDeclarations(ClassTree classTree) {
TypeElement elt = TreeUtils.elementFromDeclaration(classTree);
FieldInvariants invariants = atypeFactory.getFieldInvariants(elt);
if (invariants == null) {
// No invariants to check
return;
}
// Where to issue an error, if any.
Tree errorTree = atypeFactory.getFieldInvariantAnnotationTree(classTree.getModifiers().getAnnotations());
if (errorTree == null) {
// If the annotation was inherited, then there is no annotation tree, so issue the
// error on the class.
errorTree = classTree;
}
// Checks #4 (see method Javadoc)
if (!invariants.isWellFormed()) {
checker.reportError(errorTree, "field.invariant.not.wellformed");
return;
}
TypeMirror superClass = elt.getSuperclass();
List<String> fieldsNotFound = new ArrayList<>(invariants.getFields());
Set<VariableElement> fieldElts = ElementUtils.findFieldsInTypeOrSuperType(superClass, fieldsNotFound);
// Checks that fields are declared in super class. (#2b)
if (!fieldsNotFound.isEmpty()) {
String notFoundString = String.join(", ", fieldsNotFound);
checker.reportError(errorTree, "field.invariant.not.found", notFoundString);
}
FieldInvariants superInvar = atypeFactory.getFieldInvariants(TypesUtils.getTypeElement(superClass));
if (superInvar != null) {
// Checks #3 (see method Javadoc)
DiagMessage superError = invariants.isSuperInvariant(superInvar, atypeFactory);
if (superError != null) {
checker.report(errorTree, superError);
}
}
List<String> notFinal = new ArrayList<>();
for (VariableElement field : fieldElts) {
String fieldName = field.getSimpleName().toString();
if (!ElementUtils.isFinal(field)) {
notFinal.add(fieldName);
}
AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(field);
List<AnnotationMirror> annos = invariants.getQualifiersFor(field.getSimpleName());
for (AnnotationMirror invariantAnno : annos) {
AnnotationMirror declaredAnno = type.getEffectiveAnnotationInHierarchy(invariantAnno);
if (declaredAnno == null) {
// invariant anno isn't in this hierarchy
continue;
}
if (!atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, declaredAnno)) {
// Checks #3
checker.reportError(errorTree, "field.invariant.not.subtype", fieldName, invariantAnno, declaredAnno);
}
}
}
// Checks #2a
if (!notFinal.isEmpty()) {
String notFinalString = String.join(", ", notFinal);
checker.reportError(errorTree, "field.invariant.not.final", notFinalString);
}
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class BaseTypeVisitor method checkQualifierParameter.
/**
* Issues an error if {@code classTree} has polymorphic fields but is not annotated with
* {@code @HasQualifierParameter}. Always issue a warning if the type of a static field is
* annotated with a polymorphic qualifier.
*
* <p>Issues an error if {@code classTree} extends or implements a class/interface that has a
* qualifier parameter, but this class does not.
*
* @param classTree the ClassTree to check for polymorphic fields
*/
protected void checkQualifierParameter(ClassTree classTree) {
// Set of polymorphic qualifiers for hierarchies that do not have a qualifier parameter and
// therefor cannot appear on a field.
Set<AnnotationMirror> illegalOnFieldsPolyQual = AnnotationUtils.createAnnotationSet();
// Set of polymorphic annotations for all hierarchies
Set<AnnotationMirror> polys = AnnotationUtils.createAnnotationSet();
TypeElement classElement = TreeUtils.elementFromDeclaration(classTree);
for (AnnotationMirror top : atypeFactory.getQualifierHierarchy().getTopAnnotations()) {
AnnotationMirror poly = atypeFactory.getQualifierHierarchy().getPolymorphicAnnotation(top);
if (poly != null) {
polys.add(poly);
}
if (atypeFactory.hasExplicitQualifierParameterInHierarchy(classElement, top) && atypeFactory.hasExplicitNoQualifierParameterInHierarchy(classElement, top)) {
checker.reportError(classTree, "conflicting.qual.param", top);
}
if (atypeFactory.hasQualifierParameterInHierarchy(classElement, top)) {
continue;
}
if (poly != null) {
illegalOnFieldsPolyQual.add(poly);
}
Element extendsEle = TypesUtils.getTypeElement(classElement.getSuperclass());
if (extendsEle != null && atypeFactory.hasQualifierParameterInHierarchy(extendsEle, top)) {
checker.reportError(classTree, "missing.has.qual.param", top);
} else {
for (TypeMirror interfaceType : classElement.getInterfaces()) {
Element interfaceEle = TypesUtils.getTypeElement(interfaceType);
if (atypeFactory.hasQualifierParameterInHierarchy(interfaceEle, top)) {
checker.reportError(classTree, "missing.has.qual.param", top);
// only issue error once
break;
}
}
}
}
for (Tree mem : classTree.getMembers()) {
if (mem.getKind() == Tree.Kind.VARIABLE) {
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(mem);
List<DiagMessage> hasIllegalPoly;
if (ElementUtils.isStatic(TreeUtils.elementFromDeclaration((VariableTree) mem))) {
// A polymorphic qualifier is not allowed on a static field even if the class
// has a qualifier parameter.
hasIllegalPoly = polyScanner.visit(fieldType, polys);
} else {
hasIllegalPoly = polyScanner.visit(fieldType, illegalOnFieldsPolyQual);
}
for (DiagMessage dm : hasIllegalPoly) {
checker.report(mem, dm);
}
}
}
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class UpperBoundVisitor method visitAnnotation.
/**
* Warns about LTLengthOf annotations with arguments whose lengths do not match.
*/
@Override
public Void visitAnnotation(AnnotationTree node, Void p) {
AnnotationMirror anno = TreeUtils.annotationFromAnnotationTree(node);
if (atypeFactory.areSameByClass(anno, LTLengthOf.class)) {
List<? extends ExpressionTree> args = node.getArguments();
if (args.size() == 2) {
// If offsets are provided, there must be the same number of them as there are arrays.
List<String> sequences = AnnotationUtils.getElementValueArray(anno, atypeFactory.ltLengthOfValueElement, String.class);
List<String> offsets = AnnotationUtils.getElementValueArray(anno, atypeFactory.ltLengthOfOffsetElement, String.class, Collections.emptyList());
if (sequences.size() != offsets.size() && !offsets.isEmpty()) {
checker.reportError(node, "different.length.sequences.offsets", sequences.size(), offsets.size());
return null;
}
}
} else if (atypeFactory.areSameByClass(anno, HasSubsequence.class)) {
// Check that the arguments to a HasSubsequence annotation are valid JavaExpressions,
// and issue an error if one of them is not.
String seq = atypeFactory.hasSubsequenceSubsequenceValue(anno);
String from = atypeFactory.hasSubsequenceFromValue(anno);
String to = atypeFactory.hasSubsequenceToValue(anno);
// check that each expression is parsable at the declaration of this class
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
checkEffectivelyFinalAndParsable(seq, enclosingClass, node);
checkEffectivelyFinalAndParsable(from, enclosingClass, node);
checkEffectivelyFinalAndParsable(to, enclosingClass, node);
}
return super.visitAnnotation(node, p);
}
Aggregations