/** * In the first enclosing class, find the top-level member that contains tree. TODO: should we * look whether these elements are enclosed within another class that is itself under * construction. * * <p>Are there any other type of top level objects? */ private Tree findTopLevelClassMemberForTree(TreePath path) { ClassTree enclosingClass = TreeUtils.enclosingClass(path); if (enclosingClass != null) { List<? extends Tree> classMembers = enclosingClass.getMembers(); TreePath searchPath = path; while (searchPath.getParentPath() != null && searchPath.getParentPath() != enclosingClass) { searchPath = searchPath.getParentPath(); if (classMembers.contains(searchPath.getLeaf())) { return searchPath.getLeaf(); } } } return null; }
private static List<? extends TypeMirror> computeUnary( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { UnaryTree tree = (UnaryTree) parent.getLeaf(); if (tree.getExpression() == error) { List<? extends TypeMirror> parentTypes = resolveType(types, info, parent.getParentPath(), tree, offset, null, null); if (parentTypes != null) { // may contain only "void", ignore: if (parentTypes.size() != 1) { return parentTypes; } if (parentTypes.get(0).getKind() != TypeKind.VOID) { return parentTypes; } } types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.INT)); } return null; }
private static List<? extends TypeMirror> computeVariableDeclaration( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { VariableTree vt = (VariableTree) parent.getLeaf(); if (vt.getInitializer() == error) { types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return Collections.singletonList( info.getTrees().getTypeMirror(new TreePath(parent, vt.getType()))); } TreePath context = parent.getParentPath(); if (vt.getType() != error || context == null) { return null; } switch (context.getLeaf().getKind()) { case ENHANCED_FOR_LOOP: ExpressionTree iterableTree = ((EnhancedForLoopTree) context.getLeaf()).getExpression(); TreePath iterablePath = new TreePath(context, iterableTree); TypeMirror type = getIterableGenericType(info, iterablePath); types.add(ElementKind.LOCAL_VARIABLE); return Collections.singletonList(type); default: types.add(ElementKind.CLASS); return Collections.<TypeMirror>emptyList(); } }
private static List<? extends TypeMirror> computeParametrizedType( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset, TypeMirror[] typeParameterBound, int[] numTypeParameters) { ParameterizedTypeTree ptt = (ParameterizedTypeTree) parent.getLeaf(); if (ptt.getType() == error) { Tree gpt = parent.getParentPath().getLeaf(); if (TreeUtilities.CLASS_TREE_KINDS.contains(gpt.getKind()) && ((ClassTree) gpt).getExtendsClause() == ptt) { types.add(ElementKind.CLASS); } else if (TreeUtilities.CLASS_TREE_KINDS.contains(gpt.getKind()) && ((ClassTree) gpt).getImplementsClause().contains(ptt)) { types.add(ElementKind.INTERFACE); } else { types.add(ElementKind.CLASS); types.add(ElementKind.INTERFACE); } if (numTypeParameters != null) { numTypeParameters[0] = ptt.getTypeArguments().size(); } return null; } TypeMirror resolved = info.getTrees().getTypeMirror(parent); DeclaredType resolvedDT = null; if (resolved != null && resolved.getKind() == TypeKind.DECLARED) { resolvedDT = (DeclaredType) resolved; } int index = 0; for (Tree t : ptt.getTypeArguments()) { if (t == error) { if (resolvedDT != null && typeParameterBound != null) { List<? extends TypeMirror> typeArguments = ((DeclaredType) resolvedDT.asElement().asType()).getTypeArguments(); if (typeArguments.size() > index) { typeParameterBound[0] = ((TypeVariable) typeArguments.get(index)).getUpperBound(); } } types.add(ElementKind.CLASS); // XXX: class/interface/enum/annotation? return null; } index++; } return null; }
private static TreePath findMethod(TreePath tp) { while (!STOP_LOOKING_FOR_METHOD.contains(tp.getLeaf().getKind())) { tp = tp.getParentPath(); } if (tp.getLeaf().getKind() == Kind.METHOD) { return tp; } return null; }
/** * Search up the hierarchy of elements for one of the given kind. * * @param kind the element's kind to search for * @param path the starting element * @return {@code null} if no element was found. */ static TreePath getParentElementOfKind(Tree.Kind kind, TreePath path) { if (path != null) { TreePath tpath = path; while (tpath != null) { if (kind == tpath.getLeaf().getKind()) { return tpath; } tpath = tpath.getParentPath(); } } return null; }
/** {@inheritDoc} */ @Override public boolean isSatisfiedBy(TreePath path) { do { Tree.Kind kind = path.getLeaf().getKind(); if (kind == Tree.Kind.METHOD) return false; if (ASTPath.isClassEquiv(kind)) { return true; } path = path.getParentPath(); } while (path != null && path.getLeaf() != null); return true; }
private static List<? extends TypeMirror> computeParenthesis( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { ParenthesizedTree pt = (ParenthesizedTree) parent.getLeaf(); if (pt.getExpression() != error) { return null; } TreePath parentParent = parent.getParentPath(); List<? extends TypeMirror> upperTypes = resolveType(types, info, parentParent, pt, offset, null, null); if (upperTypes == null) { return null; } return upperTypes; }
private static List<? extends TypeMirror> computeArrayAccess( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { ArrayAccessTree aat = (ArrayAccessTree) parent.getLeaf(); if (aat.getExpression() == error) { TreePath parentParent = parent.getParentPath(); List<? extends TypeMirror> upperTypes = resolveType(types, info, parentParent, aat, offset, null, null); if (upperTypes == null) { return null; } List<TypeMirror> arrayTypes = new ArrayList<TypeMirror>(); for (TypeMirror tm : upperTypes) { if (tm == null) continue; switch (tm.getKind()) { case VOID: case EXECUTABLE: case WILDCARD: case PACKAGE: continue; } arrayTypes.add(info.getTypes().getArrayType(tm)); } if (arrayTypes.isEmpty()) return null; return arrayTypes; } if (aat.getIndex() == error) { types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.INT)); } return null; }
private static List<? extends TypeMirror> computeNewClass( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { NewClassTree nct = (NewClassTree) parent.getLeaf(); boolean errorInRealArguments = false; for (Tree param : nct.getArguments()) { errorInRealArguments |= param == error; } if (errorInRealArguments) { TypeMirror[] proposedType = new TypeMirror[1]; int[] proposedIndex = new int[1]; ExecutableElement ee = org.netbeans.modules.editor.java.Utilities.fuzzyResolveMethodInvocation( info, parent, proposedType, proposedIndex); if (ee == null) { // cannot be resolved return null; } types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return Collections.singletonList(proposedType[0]); } Tree id = nct.getIdentifier(); if (id.getKind() == Kind.PARAMETERIZED_TYPE) { id = ((ParameterizedTypeTree) id).getType(); } if (id == error) { return resolveType( EnumSet.noneOf(ElementKind.class), info, parent.getParentPath(), nct, offset, null, null); } return null; }
private static List<? extends TypeMirror> computeConditionalExpression( Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) { ConditionalExpressionTree cet = (ConditionalExpressionTree) parent.getLeaf(); if (cet.getCondition() == error) { types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.BOOLEAN)); } if (cet.getTrueExpression() == error || cet.getFalseExpression() == error) { types.add(ElementKind.PARAMETER); types.add(ElementKind.LOCAL_VARIABLE); types.add(ElementKind.FIELD); return resolveType(types, info, parent.getParentPath(), cet, offset, null, null); } return null; }
/** * Given a TreePath, walks up the tree until it finds a node of the given type and returns the * path from that node to the top-level node in the path (typically a {@code * CompilationUnitTree}). */ public static <T> TreePath findPathFromEnclosingNodeToTopLevel(TreePath path, Class<T> klass) { while (path != null && !(klass.isInstance(path.getLeaf()))) { path = path.getParentPath(); } return path; }