/** * For {@link Name} or {@link Type} nodes, returns the topmost {@link Type} node * that shares the same type binding as the given node. * * @param node an ASTNode * @return the normalized {@link Type} node or the original node */ public static ASTNode getNormalizedNode(ASTNode node) { ASTNode current= node; // normalize name if (QualifiedName.NAME_PROPERTY.equals(current.getLocationInParent())) { current= current.getParent(); } // normalize type if (QualifiedType.NAME_PROPERTY.equals(current.getLocationInParent()) || SimpleType.NAME_PROPERTY.equals(current.getLocationInParent()) || NameQualifiedType.NAME_PROPERTY.equals(current.getLocationInParent())) { current= current.getParent(); } // normalize parameterized types if (ParameterizedType.TYPE_PROPERTY.equals(current.getLocationInParent())) { current= current.getParent(); } return current; }
private static void addEnhancedForWithoutTypeProposals(ICompilationUnit cu, ASTNode selectedNode, Collection<CUCorrectionProposal> proposals) { if (selectedNode instanceof SimpleName && (selectedNode.getLocationInParent() == SimpleType.NAME_PROPERTY || selectedNode.getLocationInParent() == NameQualifiedType.NAME_PROPERTY)) { ASTNode type= selectedNode.getParent(); if (type.getLocationInParent() == SingleVariableDeclaration.TYPE_PROPERTY) { SingleVariableDeclaration svd= (SingleVariableDeclaration) type.getParent(); if (svd.getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY) { if (svd.getName().getLength() == 0) { SimpleName simpleName= (SimpleName) selectedNode; String name= simpleName.getIdentifier(); int relevance= StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? 10 : 7; String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_create_loop_variable_description, BasicElementLabels.getJavaElementName(name)); proposals.add(new NewVariableCorrectionProposal(label, cu, NewVariableCorrectionProposal.LOCAL, simpleName, null, relevance)); } } } } }
/** * For {@link Name} or {@link org.eclipse.jdt.core.dom.Type} nodes, returns the topmost {@link * org.eclipse.jdt.core.dom.Type} node that shares the same type binding as the given node. * * @param node an ASTNode * @return the normalized {@link org.eclipse.jdt.core.dom.Type} node or the original node */ public static ASTNode getNormalizedNode(ASTNode node) { ASTNode current = node; // normalize name if (QualifiedName.NAME_PROPERTY.equals(current.getLocationInParent())) { current = current.getParent(); } // normalize type if (QualifiedType.NAME_PROPERTY.equals(current.getLocationInParent()) || SimpleType.NAME_PROPERTY.equals(current.getLocationInParent()) || NameQualifiedType.NAME_PROPERTY.equals(current.getLocationInParent())) { current = current.getParent(); } // normalize parameterized types if (ParameterizedType.TYPE_PROPERTY.equals(current.getLocationInParent())) { current = current.getParent(); } return current; }
public static ITypeBinding guessBindingForTypeReference(ASTNode node) { StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); if (locationInParent == QualifiedName.QUALIFIER_PROPERTY) { return null; // can't guess type for X.A } if (locationInParent == SimpleType.NAME_PROPERTY || locationInParent == NameQualifiedType.NAME_PROPERTY) { node= node.getParent(); } ITypeBinding binding= Bindings.normalizeTypeBinding(getPossibleTypeBinding(node)); if (binding != null) { if (binding.isWildcardType()) { return normalizeWildcardType(binding, true, node.getAST()); } } return binding; }
private static void addEnhancedForWithoutTypeProposals(ICompilationUnit cu, ASTNode selectedNode, Collection<ICommandAccess> proposals) { if (selectedNode instanceof SimpleName && (selectedNode.getLocationInParent() == SimpleType.NAME_PROPERTY || selectedNode.getLocationInParent() == NameQualifiedType.NAME_PROPERTY)) { ASTNode type= selectedNode.getParent(); if (type.getLocationInParent() == SingleVariableDeclaration.TYPE_PROPERTY) { SingleVariableDeclaration svd= (SingleVariableDeclaration) type.getParent(); if (svd.getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY) { if (svd.getName().getLength() == 0) { SimpleName simpleName= (SimpleName) selectedNode; String name= simpleName.getIdentifier(); int relevance= StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? 10 : 7; String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_create_loop_variable_description, BasicElementLabels.getJavaElementName(name)); Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL); proposals.add(new NewVariableCorrectionProposal(label, cu, NewVariableCorrectionProposal.LOCAL, simpleName, null, relevance, image)); } } } } }
@Override public void endVisit(NameQualifiedType node) { if (skipNode(node)) { return; } processSequential(node, node.getQualifier(), node.getName()); }
private static void addEnhancedForWithoutTypeProposals( ICompilationUnit cu, ASTNode selectedNode, Collection<ICommandAccess> proposals) { if (selectedNode instanceof SimpleName && (selectedNode.getLocationInParent() == SimpleType.NAME_PROPERTY || selectedNode.getLocationInParent() == NameQualifiedType.NAME_PROPERTY)) { ASTNode type = selectedNode.getParent(); if (type.getLocationInParent() == SingleVariableDeclaration.TYPE_PROPERTY) { SingleVariableDeclaration svd = (SingleVariableDeclaration) type.getParent(); if (svd.getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY) { if (svd.getName().getLength() == 0) { SimpleName simpleName = (SimpleName) selectedNode; String name = simpleName.getIdentifier(); int relevance = StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? 10 : 7; String label = Messages.format( CorrectionMessages .UnresolvedElementsSubProcessor_create_loop_variable_description, BasicElementLabels.getJavaElementName(name)); Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL); proposals.add( new NewVariableCorrectionProposal( label, cu, NewVariableCorrectionProposal.LOCAL, simpleName, null, relevance, image)); } } } } }
private static SimpleName getSelectedName(CompilationUnit compilationUnit, IProblemLocation problem) { final ASTNode selection= problem.getCoveredNode(compilationUnit); if (selection == null) return null; Name name= null; if (selection instanceof SimpleType) { name= ((SimpleType) selection).getName(); } else if (selection instanceof NameQualifiedType) { name= ((NameQualifiedType) selection).getName(); } else if (selection instanceof QualifiedType) { name= ((QualifiedType) selection).getName(); } else if (selection instanceof ParameterizedType) { final ParameterizedType type= (ParameterizedType) selection; final Type raw= type.getType(); if (raw instanceof SimpleType) name= ((SimpleType) raw).getName(); else if (raw instanceof NameQualifiedType) name= ((NameQualifiedType) raw).getName(); else if (raw instanceof QualifiedType) name= ((QualifiedType) raw).getName(); } else if (selection instanceof Name) { name= (Name) selection; } if (name == null) return null; if (name.isSimpleName()) { return (SimpleName)name; } else { return ((QualifiedName)name).getName(); } }
@Override public boolean visit(NameQualifiedType node) { possibleTypeRefFound(node.getQualifier()); visitAnnotations(node); return false; }
private static void addSimilarTypeProposals(int kind, ICompilationUnit cu, Name node, int relevance, Collection<CUCorrectionProposal> proposals) throws CoreException { SimilarElement[] elements= SimilarElementsRequestor.findSimilarElement(cu, node, kind); // try to resolve type in context -> highest severity String resolvedTypeName= null; ITypeBinding binding= ASTResolving.guessBindingForTypeReference(node); if (binding != null) { ITypeBinding simpleBinding= binding; if (simpleBinding.isArray()) { simpleBinding= simpleBinding.getElementType(); } simpleBinding= simpleBinding.getTypeDeclaration(); if (!simpleBinding.isRecovered()) { resolvedTypeName= simpleBinding.getQualifiedName(); CUCorrectionProposal proposal= createTypeRefChangeProposal(cu, resolvedTypeName, node, relevance + 2, elements.length); proposals.add(proposal); if (proposal instanceof AddImportCorrectionProposal) { proposal.setRelevance(relevance + elements.length + 2); } if (binding.isParameterizedType() && (node.getParent() instanceof SimpleType || node.getParent() instanceof NameQualifiedType) && !(node.getParent().getParent() instanceof Type)) { proposals.add(createTypeRefChangeFullProposal(cu, binding, node, relevance + 5)); } } } else { ASTNode normalizedNode= ASTNodes.getNormalizedNode(node); if (!(normalizedNode.getParent() instanceof Type) && node.getParent() != normalizedNode) { ITypeBinding normBinding= ASTResolving.guessBindingForTypeReference(normalizedNode); if (normBinding != null && !normBinding.isRecovered()) { proposals.add(createTypeRefChangeFullProposal(cu, normBinding, normalizedNode, relevance + 5)); } } } // add all similar elements for (int i= 0; i < elements.length; i++) { SimilarElement elem= elements[i]; if ((elem.getKind() & SimilarElementsRequestor.ALL_TYPES) != 0) { String fullName= elem.getName(); if (!fullName.equals(resolvedTypeName)) { proposals.add(createTypeRefChangeProposal(cu, fullName, node, relevance, elements.length)); } } } }
private static void addSimilarTypeProposals( int kind, ICompilationUnit cu, Name node, int relevance, Collection<ICommandAccess> proposals) throws CoreException { SimilarElement[] elements = SimilarElementsRequestor.findSimilarElement(cu, node, kind); // try to resolve type in context -> highest severity String resolvedTypeName = null; ITypeBinding binding = ASTResolving.guessBindingForTypeReference(node); if (binding != null) { ITypeBinding simpleBinding = binding; if (simpleBinding.isArray()) { simpleBinding = simpleBinding.getElementType(); } simpleBinding = simpleBinding.getTypeDeclaration(); if (!simpleBinding.isRecovered()) { resolvedTypeName = simpleBinding.getQualifiedName(); CUCorrectionProposal proposal = createTypeRefChangeProposal(cu, resolvedTypeName, node, relevance + 2, elements.length); proposals.add(proposal); if (proposal instanceof AddImportCorrectionProposal) proposal.setRelevance(relevance + elements.length + 2); if (binding.isParameterizedType() && (node.getParent() instanceof SimpleType || node.getParent() instanceof NameQualifiedType) && !(node.getParent().getParent() instanceof Type)) { proposals.add(createTypeRefChangeFullProposal(cu, binding, node, relevance + 5)); } } } else { ASTNode normalizedNode = ASTNodes.getNormalizedNode(node); if (!(normalizedNode.getParent() instanceof Type) && node.getParent() != normalizedNode) { ITypeBinding normBinding = ASTResolving.guessBindingForTypeReference(normalizedNode); if (normBinding != null && !normBinding.isRecovered()) { proposals.add( createTypeRefChangeFullProposal(cu, normBinding, normalizedNode, relevance + 5)); } } } // add all similar elements for (int i = 0; i < elements.length; i++) { SimilarElement elem = elements[i]; if ((elem.getKind() & SimilarElementsRequestor.ALL_TYPES) != 0) { String fullName = elem.getName(); if (!fullName.equals(resolvedTypeName)) { proposals.add( createTypeRefChangeProposal(cu, fullName, node, relevance, elements.length)); } } } }
@Override public boolean visit(final NameQualifiedType node) { return false; }
@Override public boolean visit(final NameQualifiedType node) { // not instrumentable, contains no instrumentable nodes return false; }
@Override public void endVisit(NameQualifiedType node) { if (skipNode(node)) return; processSequential(node, node.getQualifier(), node.getName()); }
@Override public void endVisit(NameQualifiedType node) { endVisitNode(node); }
@Override public boolean visit(NameQualifiedType node) { return visitNode(node); }
private static void addTypeArgumentsFromContext(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) { // similar to UnresolvedElementsSubProcessor.getTypeProposals(context, problem, proposals); ICompilationUnit cu= context.getCompilationUnit(); CompilationUnit root= context.getASTRoot(); ASTNode selectedNode= problem.getCoveringNode(root); if (selectedNode == null) { return; } while (selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) { selectedNode= selectedNode.getParent(); } Name node= null; if (selectedNode instanceof SimpleType) { node= ((SimpleType) selectedNode).getName(); } else if (selectedNode instanceof NameQualifiedType) { node= ((NameQualifiedType) selectedNode).getName(); } else if (selectedNode instanceof ArrayType) { Type elementType= ((ArrayType) selectedNode).getElementType(); if (elementType.isSimpleType()) { node= ((SimpleType) elementType).getName(); } else if (elementType.isNameQualifiedType()) { node= ((NameQualifiedType) elementType).getName(); } else { return; } } else if (selectedNode instanceof Name) { node= (Name) selectedNode; } else { return; } // try to resolve type in context ITypeBinding binding= ASTResolving.guessBindingForTypeReference(node); if (binding != null) { ASTNode parent= node.getParent(); if (parent instanceof Type && parent.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY && binding.isInterface()) { //bug 351853 return; } ITypeBinding simpleBinding= binding; if (simpleBinding.isArray()) { simpleBinding= simpleBinding.getElementType(); } simpleBinding= simpleBinding.getTypeDeclaration(); if (!simpleBinding.isRecovered()) { if (binding.isParameterizedType() && (node.getParent() instanceof SimpleType || node.getParent() instanceof NameQualifiedType) && !(node.getParent().getParent() instanceof Type)) { proposals.add(UnresolvedElementsSubProcessor.createTypeRefChangeFullProposal(cu, binding, node, IProposalRelevance.TYPE_ARGUMENTS_FROM_CONTEXT)); } } } else { ASTNode normalizedNode= ASTNodes.getNormalizedNode(node); if (!(normalizedNode.getParent() instanceof Type) && node.getParent() != normalizedNode) { ITypeBinding normBinding= ASTResolving.guessBindingForTypeReference(normalizedNode); if (normBinding != null && !normBinding.isRecovered()) { proposals.add(UnresolvedElementsSubProcessor.createTypeRefChangeFullProposal(cu, normBinding, normalizedNode, IProposalRelevance.TYPE_ARGUMENTS_FROM_CONTEXT)); } } } }
private static boolean getPickoutTypeFromMulticatchProposals(IInvocationContext context, ASTNode node, ArrayList<ASTNode> coveredNodes, Collection<ICommandAccess> resultingCollections) { CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(node, ASTNode.CATCH_CLAUSE); if (catchClause == null) { return false; } Statement statement= ASTResolving.findParentStatement(node); if (statement != catchClause.getParent() && statement != catchClause.getBody()) { return false; // selection is in a statement inside the body } Type type= catchClause.getException().getType(); if (!type.isUnionType()) { return false; } Type selectedMultiCatchType= null; if (type.isUnionType() && node instanceof Name) { Name topMostName= ASTNodes.getTopMostName((Name) node); ASTNode parent= topMostName.getParent(); if (parent instanceof SimpleType || parent instanceof NameQualifiedType) { selectedMultiCatchType= (Type) parent; } } boolean multipleExceptions= coveredNodes.size() > 1; if ((selectedMultiCatchType == null) && (!(node instanceof UnionType) || !multipleExceptions)) { return false; } if (!multipleExceptions) { coveredNodes.add(selectedMultiCatchType); } BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(catchClause); if (!(bodyDeclaration instanceof MethodDeclaration) && !(bodyDeclaration instanceof Initializer)) { return false; } if (resultingCollections == null) { return true; } AST ast= bodyDeclaration.getAST(); ASTRewrite rewrite= ASTRewrite.create(ast); CatchClause newCatchClause= ast.newCatchClause(); SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration(); UnionType newUnionType= ast.newUnionType(); List<Type> types= newUnionType.types(); for (int i= 0; i < coveredNodes.size(); i++) { ASTNode typeNode= coveredNodes.get(i); types.add((Type) rewrite.createCopyTarget(typeNode)); rewrite.remove(typeNode, null); } newSingleVariableDeclaration.setType(newUnionType); newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(catchClause.getException().getName())); newCatchClause.setException(newSingleVariableDeclaration); setCatchClauseBody(newCatchClause, rewrite, catchClause); TryStatement tryStatement= (TryStatement)catchClause.getParent(); ListRewrite listRewrite= rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY); listRewrite.insertAfter(newCatchClause, catchClause, null); Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION); String label= !multipleExceptions ? CorrectionMessages.QuickAssistProcessor_move_exception_to_separate_catch_block : CorrectionMessages.QuickAssistProcessor_move_exceptions_to_separate_catch_block; ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.MOVE_EXCEPTION_TO_SEPERATE_CATCH_BLOCK, image); resultingCollections.add(proposal); return true; }
private static boolean getUnrollMultiCatchProposals(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) { if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject())) return false; CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(covering, ASTNode.CATCH_CLAUSE); if (catchClause == null) { return false; } Statement statement= ASTResolving.findParentStatement(covering); if (statement != catchClause.getParent() && statement != catchClause.getBody()) { return false; // selection is in a statement inside the body } Type type1= catchClause.getException().getType(); Type selectedMultiCatchType= null; if (type1.isUnionType() && covering instanceof Name) { Name topMostName= ASTNodes.getTopMostName((Name) covering); ASTNode parent= topMostName.getParent(); if (parent instanceof SimpleType || parent instanceof NameQualifiedType) { selectedMultiCatchType= (Type) parent; } } if (selectedMultiCatchType != null) return false; SingleVariableDeclaration singleVariableDeclaration= catchClause.getException(); Type type= singleVariableDeclaration.getType(); if (!(type instanceof UnionType)) return false; if (resultingCollections == null) return true; AST ast= covering.getAST(); ASTRewrite rewrite= ASTRewrite.create(ast); TryStatement tryStatement= (TryStatement) catchClause.getParent(); ListRewrite listRewrite= rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY); UnionType unionType= (UnionType) type; List<Type> types= unionType.types(); for (int i= types.size() - 1; i >= 0; i--) { Type type2= types.get(i); CatchClause newCatchClause= ast.newCatchClause(); SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration(); newSingleVariableDeclaration.setType((Type) rewrite.createCopyTarget(type2)); newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(singleVariableDeclaration.getName())); newCatchClause.setException(newSingleVariableDeclaration); setCatchClauseBody(newCatchClause, rewrite, catchClause); listRewrite.insertAfter(newCatchClause, catchClause, null); } rewrite.remove(catchClause, null); Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); String label= CorrectionMessages.QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks; ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.USE_SEPARATE_CATCH_BLOCKS, image); resultingCollections.add(proposal); return true; }
public static void getTypeProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) throws CoreException { ICompilationUnit cu= context.getCompilationUnit(); ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); if (selectedNode == null) { return; } int kind= evauateTypeKind(selectedNode, cu.getJavaProject()); if (kind == SimilarElementsRequestor.REF_TYPES) { addEnhancedForWithoutTypeProposals(cu, selectedNode, proposals); } while (selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) { selectedNode= selectedNode.getParent(); } Name node= null; if (selectedNode instanceof SimpleType) { node= ((SimpleType) selectedNode).getName(); } else if (selectedNode instanceof NameQualifiedType) { node= ((NameQualifiedType) selectedNode).getName(); } else if (selectedNode instanceof ArrayType) { Type elementType= ((ArrayType) selectedNode).getElementType(); if (elementType.isSimpleType()) { node= ((SimpleType) elementType).getName(); } else if (elementType.isNameQualifiedType()) { node= ((NameQualifiedType) elementType).getName(); } else { return; } } else if (selectedNode instanceof Name) { node= (Name) selectedNode; } else { return; } // change to similar type proposals addSimilarTypeProposals(kind, cu, node, IProposalRelevance.SIMILAR_TYPE, proposals); while (node.getParent() instanceof QualifiedName) { node= (Name) node.getParent(); } if (selectedNode != node) { kind= evauateTypeKind(node, cu.getJavaProject()); } if ((kind & (SimilarElementsRequestor.CLASSES | SimilarElementsRequestor.INTERFACES)) != 0) { kind &= ~SimilarElementsRequestor.ANNOTATIONS; // only propose annotations when there are no other suggestions } addNewTypeProposals(cu, node, kind, IProposalRelevance.NEW_TYPE, proposals); ReorgCorrectionsSubProcessor.addProjectSetupFixProposal(context, problem, node.getFullyQualifiedName(), proposals); }
private static void addSimilarTypeProposals(int kind, ICompilationUnit cu, Name node, int relevance, Collection<ICommandAccess> proposals) throws CoreException { SimilarElement[] elements= SimilarElementsRequestor.findSimilarElement(cu, node, kind); // try to resolve type in context -> highest severity String resolvedTypeName= null; ITypeBinding binding= ASTResolving.guessBindingForTypeReference(node); if (binding != null) { ITypeBinding simpleBinding= binding; if (simpleBinding.isArray()) { simpleBinding= simpleBinding.getElementType(); } simpleBinding= simpleBinding.getTypeDeclaration(); if (!simpleBinding.isRecovered()) { resolvedTypeName= simpleBinding.getQualifiedName(); CUCorrectionProposal proposal= createTypeRefChangeProposal(cu, resolvedTypeName, node, relevance + 2, elements.length); proposals.add(proposal); if (proposal instanceof AddImportCorrectionProposal) proposal.setRelevance(relevance + elements.length + 2); if (binding.isParameterizedType() && (node.getParent() instanceof SimpleType || node.getParent() instanceof NameQualifiedType) && !(node.getParent().getParent() instanceof Type)) { proposals.add(createTypeRefChangeFullProposal(cu, binding, node, relevance + 5)); } } } else { ASTNode normalizedNode= ASTNodes.getNormalizedNode(node); if (!(normalizedNode.getParent() instanceof Type) && node.getParent() != normalizedNode) { ITypeBinding normBinding= ASTResolving.guessBindingForTypeReference(normalizedNode); if (normBinding != null && !normBinding.isRecovered()) { proposals.add(createTypeRefChangeFullProposal(cu, normBinding, normalizedNode, relevance + 5)); } } } // add all similar elements for (int i= 0; i < elements.length; i++) { SimilarElement elem= elements[i]; if ((elem.getKind() & SimilarElementsRequestor.ALL_TYPES) != 0) { String fullName= elem.getName(); if (!fullName.equals(resolvedTypeName)) { proposals.add(createTypeRefChangeProposal(cu, fullName, node, relevance, elements.length)); } } } }