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 SourceChecker method shouldSuppressWarnings.
/**
* Determines whether all the warnings pertaining to a given tree should be suppressed. Returns
* true if the tree is within the scope of a @SuppressWarnings annotation, one of whose values
* suppresses the checker's warnings. Also, returns true if the {@code errKey} matches a string in
* {@code -AsuppressWarnings}.
*
* @param tree the tree that might be a source of a warning
* @param errKey the error key the checker is emitting
* @return true if no warning should be emitted for the given tree because it is contained by a
* declaration with an appropriately-valued {@literal @}SuppressWarnings annotation; false
* otherwise
*/
public boolean shouldSuppressWarnings(Tree tree, String errKey) {
Collection<String> prefixes = getSuppressWarningsPrefixes();
if (prefixes.isEmpty() || (prefixes.contains(SUPPRESS_ALL_PREFIX) && prefixes.size() == 1)) {
throw new BugInCF("Checker must provide a SuppressWarnings prefix." + " SourceChecker#getSuppressWarningsPrefixes was not overridden correctly.");
}
if (shouldSuppress(getSuppressWarningsStringsFromOption(), errKey)) {
return true;
}
if (shouldSuppress(getSuppressWarningsStringsFromOption(), errKey)) {
// the warning.
return true;
}
// trees.getPath might be slow, but this is only used in error reporting
@Nullable TreePath path = trees.getPath(this.currentRoot, tree);
@Nullable VariableTree var = TreePathUtil.enclosingVariable(path);
if (var != null && shouldSuppressWarnings(TreeUtils.elementFromTree(var), errKey)) {
return true;
}
@Nullable MethodTree method = TreePathUtil.enclosingMethod(path);
if (method != null) {
@Nullable Element elt = TreeUtils.elementFromTree(method);
if (shouldSuppressWarnings(elt, errKey)) {
return true;
}
if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
// because they may not have an @AnnotatedFor.
return false;
}
}
@Nullable ClassTree cls = TreePathUtil.enclosingClass(path);
if (cls != null) {
@Nullable Element elt = TreeUtils.elementFromTree(cls);
if (shouldSuppressWarnings(elt, errKey)) {
return true;
}
if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
// because they may not have an @AnnotatedFor.
return false;
}
}
if (useConservativeDefault("source")) {
// false, we DO suppress the warning.
return true;
}
return false;
}
use of com.sun.source.tree.ClassTree in project error-prone by google.
the class ReferenceEquality method matchArgument.
@Override
protected boolean matchArgument(ExpressionTree tree, VisitorState state) {
Type type = ASTHelpers.getType(tree);
if (!type.isReference()) {
return false;
}
ClassTree classTree = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class);
if (classTree == null) {
return false;
}
Type classType = ASTHelpers.getType(classTree);
if (classType == null) {
return false;
}
if (inEqualsOrCompareTo(classType, type, state)) {
return false;
}
if (ASTHelpers.isSubtype(type, state.getSymtab().enumSym.type, state)) {
return false;
}
if (ASTHelpers.isSubtype(type, state.getSymtab().classType, state)) {
return false;
}
if (!implementsEquals(type, state)) {
return false;
}
return true;
}
use of com.sun.source.tree.ClassTree in project error-prone by google.
the class Util method addPrivateConstructor.
// TODO(dpb): Account for indentation level.
private static SuggestedFix.Builder addPrivateConstructor(ClassTree classTree) {
SuggestedFix.Builder fix = SuggestedFix.builder();
String indent = " ";
for (Tree member : classTree.getMembers()) {
if (member.getKind().equals(METHOD) && !isGeneratedConstructor((MethodTree) member)) {
fix.prefixWith(member, indent + "private " + classTree.getSimpleName() + "() {} // no instances\n" + indent);
break;
}
if (!member.getKind().equals(METHOD)) {
indent = "";
}
}
return fix;
}
Aggregations