use of com.sun.source.tree.VariableTree in project error-prone by google.
the class AssistedParameters method partitionParametersByType.
// Since Type doesn't have strong equality semantics, we have to use Types.isSameType to
// determine which parameters are conflicting with each other.
private Multimap<Type, VariableTree> partitionParametersByType(List<VariableTree> parameters, VisitorState state) {
Types types = state.getTypes();
Multimap<Type, VariableTree> multimap = LinkedListMultimap.create();
variables: for (VariableTree node : parameters) {
// Normalize Integer => int
Type type = types.unboxedTypeOrType(ASTHelpers.getType(node));
for (Type existingType : multimap.keySet()) {
if (types.isSameType(existingType, type)) {
multimap.put(existingType, node);
continue variables;
}
}
// A new type for the map.
multimap.put(type, node);
}
return multimap;
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class MultiVariableDeclaration method checkDeclarations.
private Description checkDeclarations(List<? extends Tree> children, VisitorState state) {
PeekingIterator<Tree> it = Iterators.<Tree>peekingIterator(children.iterator());
while (it.hasNext()) {
if (it.peek().getKind() != Tree.Kind.VARIABLE) {
it.next();
continue;
}
VariableTree variableTree = (VariableTree) it.next();
ArrayList<VariableTree> fragments = new ArrayList<>();
fragments.add(variableTree);
// a distinct end position from the previous declaration.
while (it.hasNext() && it.peek().getKind() == Tree.Kind.VARIABLE && ((JCTree) variableTree).getStartPosition() == ((JCTree) it.peek()).getStartPosition()) {
fragments.add((VariableTree) it.next());
}
if (fragments.size() == 1) {
continue;
}
Fix fix = SuggestedFix.replace(((JCTree) fragments.get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(fragments)), Joiner.on("; ").join(fragments) + ";");
state.reportMatch(describeMatch(fragments.get(0), fix));
}
return NO_MATCH;
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class AnnotatedTypeFactory method fromElement.
// **********************************************************************
// Factories for annotated types that do not account for implicit qualifiers.
// They only include qualifiers explicitly inserted by the user.
// **********************************************************************
/**
* Creates an AnnotatedTypeMirror for {@code elt} that includes: annotations explicitly written
* on the element and annotations from stub files
*
* @param elt the element
* @return AnnotatedTypeMirror of the element with explicitly-written and stub file annotations
*/
public AnnotatedTypeMirror fromElement(Element elt) {
if (shouldCache && elementCache.containsKey(elt)) {
return elementCache.get(elt).deepCopy();
}
if (elt.getKind() == ElementKind.PACKAGE) {
return toAnnotatedType(elt.asType(), false);
}
AnnotatedTypeMirror type;
// Because of a bug in Java 8, annotations on type parameters are not stored in elements,
// so get explicit annotations from the tree. (This bug has been fixed in Java 9.)
// Also, since annotations computed by the AnnotatedTypeFactory are stored in the element,
// the annotations have to be retrived from the tree so that only explicit annotations are
// returned.
Tree decl = declarationFromElement(elt);
if (decl == null && typesFromStubFiles != null && typesFromStubFiles.containsKey(elt)) {
type = typesFromStubFiles.get(elt).deepCopy();
} else if (decl == null && (typesFromStubFiles == null || !typesFromStubFiles.containsKey(elt))) {
type = toAnnotatedType(elt.asType(), ElementUtils.isTypeDeclaration(elt));
ElementAnnotationApplier.apply(type, elt, this);
if (elt instanceof ExecutableElement || elt instanceof VariableElement) {
annotateInheritedFromClass(type);
}
} else if (decl instanceof ClassTree) {
type = fromClass((ClassTree) decl);
} else if (decl instanceof VariableTree) {
type = fromMember(decl);
} else if (decl instanceof MethodTree) {
type = fromMember(decl);
} else if (decl.getKind() == Tree.Kind.TYPE_PARAMETER) {
type = fromTypeTree(decl);
} else {
ErrorReporter.errorAbort("AnnotatedTypeFactory.fromElement: cannot be here! decl: " + decl.getKind() + " elt: " + elt);
// dead code
type = null;
}
// results.
if (shouldCache && typesFromStubFiles != null) {
elementCache.put(elt, type.deepCopy());
}
return type;
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class AnnotatedTypeFactory method getFunctionalInterfaceType.
/**
* Get the AnnotatedDeclaredType for the FunctionalInterface from assignment context of the
* method reference or lambda expression which may be a variable assignment, a method call, or a
* cast.
*
* <p>The assignment context is not always correct, so we must search up the AST. It will
* recursively search for lambdas nested in lambdas.
*
* @param tree the tree of the lambda or method reference
* @return the functional interface type
*/
private AnnotatedDeclaredType getFunctionalInterfaceType(Tree tree) {
Tree parentTree = getPath(tree).getParentPath().getLeaf();
switch(parentTree.getKind()) {
case PARENTHESIZED:
return getFunctionalInterfaceType(parentTree);
case TYPE_CAST:
TypeCastTree cast = (TypeCastTree) parentTree;
assert isFunctionalInterface(trees.getTypeMirror(getPath(cast.getType())), parentTree, tree);
AnnotatedTypeMirror castATM = getAnnotatedType(cast.getType());
if (castATM.getKind() == TypeKind.INTERSECTION) {
AnnotatedIntersectionType itype = (AnnotatedIntersectionType) castATM;
for (AnnotatedTypeMirror t : itype.directSuperTypes()) {
if (TypesUtils.isFunctionalInterface(t.getUnderlyingType(), getProcessingEnv())) {
return (AnnotatedDeclaredType) t;
}
}
// We should never reach here: isFunctionalInterface performs the same check
// and would have raised an error already.
ErrorReporter.errorAbort(String.format("Expected the type of a cast tree in an assignment context to contain a functional interface bound. " + "Found type: %s for tree: %s in lambda tree: %s", castATM, cast, tree));
}
return (AnnotatedDeclaredType) castATM;
case NEW_CLASS:
NewClassTree newClass = (NewClassTree) parentTree;
int indexOfLambda = newClass.getArguments().indexOf(tree);
Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> con = this.constructorFromUse(newClass);
AnnotatedTypeMirror constructorParam = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(con.first, indexOfLambda);
assert isFunctionalInterface(constructorParam.getUnderlyingType(), parentTree, tree);
return (AnnotatedDeclaredType) constructorParam;
case NEW_ARRAY:
NewArrayTree newArray = (NewArrayTree) parentTree;
AnnotatedArrayType newArrayATM = getAnnotatedType(newArray);
AnnotatedTypeMirror elementATM = newArrayATM.getComponentType();
assert isFunctionalInterface(elementATM.getUnderlyingType(), parentTree, tree);
return (AnnotatedDeclaredType) elementATM;
case METHOD_INVOCATION:
MethodInvocationTree method = (MethodInvocationTree) parentTree;
int index = method.getArguments().indexOf(tree);
Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> exe = this.methodFromUse(method);
AnnotatedTypeMirror param = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(exe.first, index);
if (param.getKind() == TypeKind.WILDCARD) {
// param is an uninferred wildcard.
TypeMirror typeMirror = TreeUtils.typeOf(tree);
param = AnnotatedTypeMirror.createType(typeMirror, this, false);
addDefaultAnnotations(param);
}
assert isFunctionalInterface(param.getUnderlyingType(), parentTree, tree);
return (AnnotatedDeclaredType) param;
case VARIABLE:
VariableTree varTree = (VariableTree) parentTree;
assert isFunctionalInterface(TreeUtils.typeOf(varTree), parentTree, tree);
return (AnnotatedDeclaredType) getAnnotatedType(varTree.getType());
case ASSIGNMENT:
AssignmentTree assignmentTree = (AssignmentTree) parentTree;
assert isFunctionalInterface(TreeUtils.typeOf(assignmentTree), parentTree, tree);
return (AnnotatedDeclaredType) getAnnotatedType(assignmentTree.getVariable());
case RETURN:
Tree enclosing = TreeUtils.enclosingOfKind(getPath(parentTree), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
if (enclosing.getKind() == Tree.Kind.METHOD) {
MethodTree enclosingMethod = (MethodTree) enclosing;
return (AnnotatedDeclaredType) getAnnotatedType(enclosingMethod.getReturnType());
} else {
LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) enclosing;
Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
AnnotatedExecutableType methodExe = result.second;
return (AnnotatedDeclaredType) methodExe.getReturnType();
}
case LAMBDA_EXPRESSION:
LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) parentTree;
Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
AnnotatedExecutableType methodExe = result.second;
return (AnnotatedDeclaredType) methodExe.getReturnType();
case CONDITIONAL_EXPRESSION:
ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) parentTree;
final AnnotatedTypeMirror falseType = getAnnotatedType(conditionalExpressionTree.getFalseExpression());
final AnnotatedTypeMirror trueType = getAnnotatedType(conditionalExpressionTree.getTrueExpression());
// Known cases where we must use LUB because falseType/trueType will not be equal:
// a) when one of the types is a type variable that extends a functional interface
// or extends a type variable that extends a functional interface
// b) When one of the two sides of the expression is a reference to a sub-interface.
// e.g. interface ConsumeStr {
// public void consume(String s)
// }
// interface SubConsumer extends ConsumeStr {
// default void someOtherMethod() { ... }
// }
// SubConsumer s = ...;
// ConsumeStr stringConsumer = (someCondition) ? s : System.out::println;
AnnotatedTypeMirror conditionalType = AnnotatedTypes.leastUpperBound(this, trueType, falseType);
assert isFunctionalInterface(conditionalType.getUnderlyingType(), parentTree, tree);
return (AnnotatedDeclaredType) conditionalType;
default:
ErrorReporter.errorAbort("Could not find functional interface from assignment context. " + "Unexpected tree type: " + parentTree.getKind() + " For lambda tree: " + tree);
return null;
}
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class GenericAnnotatedTypeFactory method performFlowAnalysis.
/**
* Perform a org.checkerframework.dataflow analysis over a single class tree and its nested
* classes.
*/
protected void performFlowAnalysis(ClassTree classTree) {
if (flowResult == null) {
regularExitStores = new IdentityHashMap<>();
returnStatementStores = new IdentityHashMap<>();
flowResult = new AnalysisResult<>(flowResultAnalysisCaches);
}
// no need to scan annotations
if (classTree.getKind() == Kind.ANNOTATION_TYPE) {
// Mark finished so that default annotations will be applied.
scannedClasses.put(classTree, ScanState.FINISHED);
return;
}
Queue<ClassTree> queue = new ArrayDeque<>();
List<Pair<VariableElement, Value>> fieldValues = new ArrayList<>();
queue.add(classTree);
while (!queue.isEmpty()) {
ClassTree ct = queue.remove();
scannedClasses.put(ct, ScanState.IN_PROGRESS);
AnnotatedDeclaredType preClassType = visitorState.getClassType();
ClassTree preClassTree = visitorState.getClassTree();
AnnotatedDeclaredType preAMT = visitorState.getMethodReceiver();
MethodTree preMT = visitorState.getMethodTree();
visitorState.setClassType(getAnnotatedType(ct));
visitorState.setClassTree(ct);
visitorState.setMethodReceiver(null);
visitorState.setMethodTree(null);
// start without a initialization store
initializationStaticStore = null;
initializationStore = null;
Queue<Pair<LambdaExpressionTree, Store>> lambdaQueue = new ArrayDeque<>();
try {
List<CFGMethod> methods = new ArrayList<>();
for (Tree m : ct.getMembers()) {
switch(m.getKind()) {
case METHOD:
MethodTree mt = (MethodTree) m;
// Skip abstract and native methods because they have no body.
ModifiersTree modifiers = mt.getModifiers();
if (modifiers != null) {
Set<Modifier> flags = modifiers.getFlags();
if (flags.contains(Modifier.ABSTRACT) || flags.contains(Modifier.NATIVE)) {
break;
}
}
// ABSTRACT flag.
if (mt.getBody() == null) {
break;
}
// Wait with scanning the method until all other members
// have been processed.
CFGMethod met = new CFGMethod(mt, ct);
methods.add(met);
break;
case VARIABLE:
VariableTree vt = (VariableTree) m;
ExpressionTree initializer = vt.getInitializer();
// analyze initializer if present
if (initializer != null) {
boolean isStatic = vt.getModifiers().getFlags().contains(Modifier.STATIC);
analyze(queue, lambdaQueue, new CFGStatement(vt, ct), fieldValues, classTree, true, true, isStatic);
Value value = flowResult.getValue(initializer);
if (value != null) {
// Store the abstract value for the field.
VariableElement element = TreeUtils.elementFromDeclaration(vt);
fieldValues.add(Pair.of(element, value));
}
}
break;
case CLASS:
case ANNOTATION_TYPE:
case INTERFACE:
case ENUM:
// Visit inner and nested class trees.
queue.add((ClassTree) m);
break;
case BLOCK:
BlockTree b = (BlockTree) m;
analyze(queue, lambdaQueue, new CFGStatement(b, ct), fieldValues, ct, true, true, b.isStatic());
break;
default:
assert false : "Unexpected member: " + m.getKind();
break;
}
}
// fields of superclasses.
for (CFGMethod met : methods) {
analyze(queue, lambdaQueue, met, fieldValues, classTree, TreeUtils.isConstructor(met.getMethod()), false, false);
}
while (!lambdaQueue.isEmpty()) {
Pair<LambdaExpressionTree, Store> lambdaPair = lambdaQueue.poll();
analyze(queue, lambdaQueue, new CFGLambda(lambdaPair.first), fieldValues, classTree, false, false, false, lambdaPair.second);
}
// see InitializationVisitor.visitClass
if (initializationStaticStore == null) {
regularExitStores.put(ct, emptyStore);
} else {
regularExitStores.put(ct, initializationStaticStore);
}
} finally {
visitorState.setClassType(preClassType);
visitorState.setClassTree(preClassTree);
visitorState.setMethodReceiver(preAMT);
visitorState.setMethodTree(preMT);
}
scannedClasses.put(ct, ScanState.FINISHED);
}
}
Aggregations