Search in sources :

Example 1 with ChangeDescription

use of org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription in project eclipse.jdt.ls by eclipse.

the class UnresolvedElementsSubProcessor method doEqualNumberOfParameters.

private static void doEqualNumberOfParameters(IInvocationContext context, ASTNode invocationNode, IProblemLocation problem, List<Expression> arguments, ITypeBinding[] argTypes, IMethodBinding methodBinding, Collection<CUCorrectionProposal> proposals) throws CoreException {
    ITypeBinding[] paramTypes = methodBinding.getParameterTypes();
    int[] indexOfDiff = new int[paramTypes.length];
    int nDiffs = 0;
    for (int n = 0; n < argTypes.length; n++) {
        if (!canAssign(argTypes[n], paramTypes[n])) {
            indexOfDiff[nDiffs++] = n;
        }
    }
    ITypeBinding declaringTypeDecl = methodBinding.getDeclaringClass().getTypeDeclaration();
    ICompilationUnit cu = context.getCompilationUnit();
    CompilationUnit astRoot = context.getASTRoot();
    ASTNode nameNode = problem.getCoveringNode(astRoot);
    if (nameNode == null) {
        return;
    }
    if (nDiffs == 0) {
        if (nameNode.getParent() instanceof MethodInvocation) {
            MethodInvocation inv = (MethodInvocation) nameNode.getParent();
            if (inv.getExpression() == null) {
                addQualifierToOuterProposal(context, inv, methodBinding, proposals);
            }
        }
        return;
    }
    if (nDiffs == 1) {
        // one argument mismatching: try to fix
        int idx = indexOfDiff[0];
        Expression nodeToCast = arguments.get(idx);
        ITypeBinding castType = paramTypes[idx];
        castType = Bindings.normalizeTypeBinding(castType);
        if (castType.isWildcardType()) {
            castType = ASTResolving.normalizeWildcardType(castType, false, nodeToCast.getAST());
        }
        if (castType != null) {
            ITypeBinding binding = nodeToCast.resolveTypeBinding();
            ITypeBinding castFixType = null;
            if (binding == null || castType.isCastCompatible(binding)) {
                castFixType = castType;
            } else if (JavaModelUtil.is50OrHigher(cu.getJavaProject())) {
                ITypeBinding boxUnboxedTypeBinding = TypeMismatchSubProcessor.boxUnboxPrimitives(castType, binding, nodeToCast.getAST());
                if (boxUnboxedTypeBinding != castType && boxUnboxedTypeBinding.isCastCompatible(binding)) {
                    castFixType = boxUnboxedTypeBinding;
                }
            }
            if (castFixType != null) {
                ASTRewriteCorrectionProposal proposal = TypeMismatchSubProcessor.createCastProposal(context, castFixType, nodeToCast, IProposalRelevance.CAST_ARGUMENT_1);
                String castTypeName = BindingLabelProvider.getBindingLabel(castFixType, JavaElementLabels.ALL_DEFAULT);
                String[] arg = new String[] { getArgumentName(arguments, idx), castTypeName };
                proposal.setDisplayName(Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addargumentcast_description, arg));
                proposals.add(proposal);
            }
            TypeMismatchSubProcessor.addChangeSenderTypeProposals(context, nodeToCast, castType, false, IProposalRelevance.CAST_ARGUMENT_2, proposals);
        }
    }
    if (nDiffs == 2) {
        // try to swap
        int idx1 = indexOfDiff[0];
        int idx2 = indexOfDiff[1];
        boolean canSwap = canAssign(argTypes[idx1], paramTypes[idx2]) && canAssign(argTypes[idx2], paramTypes[idx1]);
        if (canSwap) {
            Expression arg1 = arguments.get(idx1);
            Expression arg2 = arguments.get(idx2);
            ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
            rewrite.replace(arg1, rewrite.createCopyTarget(arg2), null);
            rewrite.replace(arg2, rewrite.createCopyTarget(arg1), null);
            {
                String[] arg = new String[] { getArgumentName(arguments, idx1), getArgumentName(arguments, idx2) };
                String label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swaparguments_description, arg);
                ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.SWAP_ARGUMENTS);
                proposals.add(proposal);
            }
            if (declaringTypeDecl.isFromSource()) {
                ICompilationUnit targetCU = ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringTypeDecl);
                if (targetCU != null) {
                    ChangeDescription[] changeDesc = new ChangeDescription[paramTypes.length];
                    for (int i = 0; i < nDiffs; i++) {
                        changeDesc[idx1] = new SwapDescription(idx2);
                    }
                    IMethodBinding methodDecl = methodBinding.getMethodDeclaration();
                    ITypeBinding[] declParamTypes = methodDecl.getParameterTypes();
                    ITypeBinding[] swappedTypes = new ITypeBinding[] { declParamTypes[idx1], declParamTypes[idx2] };
                    String[] args = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodDecl), getTypeNames(swappedTypes) };
                    String label;
                    if (methodDecl.isConstructor()) {
                        label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swapparams_constr_description, args);
                    } else {
                        label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swapparams_description, args);
                    }
                    ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_SWAP_PARAMETERS);
                    proposals.add(proposal);
                }
            }
            return;
        }
    }
    if (declaringTypeDecl.isFromSource()) {
        ICompilationUnit targetCU = ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringTypeDecl);
        if (targetCU != null) {
            ChangeDescription[] changeDesc = createSignatureChangeDescription(indexOfDiff, nDiffs, paramTypes, arguments, argTypes);
            if (changeDesc != null) {
                IMethodBinding methodDecl = methodBinding.getMethodDeclaration();
                ITypeBinding[] declParamTypes = methodDecl.getParameterTypes();
                ITypeBinding[] newParamTypes = new ITypeBinding[changeDesc.length];
                for (int i = 0; i < newParamTypes.length; i++) {
                    newParamTypes[i] = changeDesc[i] == null ? declParamTypes[i] : ((EditDescription) changeDesc[i]).type;
                }
                boolean isVarArgs = methodDecl.isVarargs() && newParamTypes.length > 0 && newParamTypes[newParamTypes.length - 1].isArray();
                String[] args = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodDecl), org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodDecl.getName(), newParamTypes, isVarArgs) };
                String label;
                if (methodDecl.isConstructor()) {
                    label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changeparamsignature_constr_description, args);
                } else {
                    label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changeparamsignature_description, args);
                }
                ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_SIGNATURE);
                proposals.add(proposal);
            }
        }
    }
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) SuperMethodInvocation(org.eclipse.jdt.core.dom.SuperMethodInvocation) SwapDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.SwapDescription) EditDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.EditDescription) ThisExpression(org.eclipse.jdt.core.dom.ThisExpression) Expression(org.eclipse.jdt.core.dom.Expression) CastExpression(org.eclipse.jdt.core.dom.CastExpression) ParenthesizedExpression(org.eclipse.jdt.core.dom.ParenthesizedExpression) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ChangeDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite)

Example 2 with ChangeDescription

use of org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription in project eclipse.jdt.ls by eclipse.

the class UnresolvedElementsSubProcessor method doMoreParameters.

private static void doMoreParameters(IInvocationContext context, ASTNode invocationNode, ITypeBinding[] argTypes, IMethodBinding methodBinding, Collection<CUCorrectionProposal> proposals) throws CoreException {
    ITypeBinding[] paramTypes = methodBinding.getParameterTypes();
    int k = 0, nSkipped = 0;
    int diff = paramTypes.length - argTypes.length;
    int[] indexSkipped = new int[diff];
    for (int i = 0; i < paramTypes.length; i++) {
        if (k < argTypes.length && canAssign(argTypes[k], paramTypes[i])) {
            // match
            k++;
        } else {
            if (nSkipped >= diff) {
                // too different
                return;
            }
            indexSkipped[nSkipped++] = i;
        }
    }
    ITypeBinding declaringType = methodBinding.getDeclaringClass();
    ICompilationUnit cu = context.getCompilationUnit();
    CompilationUnit astRoot = context.getASTRoot();
    // add arguments
    {
        String[] arg = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodBinding) };
        String label;
        if (diff == 1) {
            label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addargument_description, arg);
        } else {
            label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addarguments_description, arg);
        }
        AddArgumentCorrectionProposal proposal = new AddArgumentCorrectionProposal(label, context.getCompilationUnit(), invocationNode, indexSkipped, paramTypes, IProposalRelevance.ADD_ARGUMENTS);
        proposals.add(proposal);
    }
    // remove parameters
    if (!declaringType.isFromSource()) {
        return;
    }
    ICompilationUnit targetCU = ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType);
    if (targetCU != null) {
        IMethodBinding methodDecl = methodBinding.getMethodDeclaration();
        ITypeBinding[] declParameterTypes = methodDecl.getParameterTypes();
        ChangeDescription[] changeDesc = new ChangeDescription[declParameterTypes.length];
        ITypeBinding[] changedTypes = new ITypeBinding[diff];
        for (int i = diff - 1; i >= 0; i--) {
            int idx = indexSkipped[i];
            changeDesc[idx] = new RemoveDescription();
            changedTypes[i] = declParameterTypes[idx];
        }
        String[] arg = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodDecl), getTypeNames(changedTypes) };
        String label;
        if (methodDecl.isConstructor()) {
            if (diff == 1) {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_constr_description, arg);
            } else {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_constr_description, arg);
            }
        } else {
            if (diff == 1) {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_description, arg);
            } else {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_description, arg);
            }
        }
        ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_REMOVE_PARAMETER);
        proposals.add(proposal);
    }
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ChangeDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription) RemoveDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.RemoveDescription)

Example 3 with ChangeDescription

use of org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription in project eclipse.jdt.ls by eclipse.

the class LocalCorrectionsSubProcessor method addUncaughtExceptionProposals.

public static void addUncaughtExceptionProposals(IInvocationContext context, IProblemLocationCore problem, Collection<ChangeCorrectionProposal> proposals) throws CoreException {
    ICompilationUnit cu = context.getCompilationUnit();
    CompilationUnit astRoot = context.getASTRoot();
    ASTNode selectedNode = context.getSelectionLength() > 0 ? context.getCoveredNode() : problem.getCoveringNode(astRoot);
    if (selectedNode == null) {
        return;
    }
    while (selectedNode != null && !(selectedNode instanceof Statement) && !(selectedNode instanceof VariableDeclarationExpression) && !(selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) && !(selectedNode instanceof MethodReference)) {
        selectedNode = selectedNode.getParent();
    }
    if (selectedNode == null) {
        return;
    }
    int offset = selectedNode.getStartPosition();
    int length = selectedNode.getLength();
    int selectionEnd = context.getSelectionOffset() + context.getSelectionLength();
    if (selectionEnd > offset + length) {
        // extend the selection if more than one statement is selected (bug 72149)
        length = selectionEnd - offset;
    }
    // Surround with proposals
    SurroundWithTryCatchRefactoring refactoring = SurroundWithTryCatchRefactoring.create(cu, offset, length);
    if (refactoring == null) {
        return;
    }
    refactoring.setLeaveDirty(true);
    if (refactoring.checkActivationBasics(astRoot).isOK()) {
        String label = CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trycatch_description;
        RefactoringCorrectionProposal proposal = new RefactoringCorrectionProposal(label, CodeActionKind.QuickFix, cu, refactoring, IProposalRelevance.SURROUND_WITH_TRY_CATCH);
        proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
        proposals.add(proposal);
    }
    if (JavaModelUtil.is1d7OrHigher(cu.getJavaProject())) {
        refactoring = SurroundWithTryCatchRefactoring.create(cu, offset, length, true);
        if (refactoring == null) {
            return;
        }
        refactoring.setLeaveDirty(true);
        if (refactoring.checkActivationBasics(astRoot).isOK()) {
            String label = CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description;
            RefactoringCorrectionProposal proposal = new RefactoringCorrectionProposal(label, CodeActionKind.QuickFix, cu, refactoring, IProposalRelevance.SURROUND_WITH_TRY_MULTICATCH);
            proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
            proposals.add(proposal);
        }
    }
    // Surround with try-with
    getTryWithResourceProposals(context, problem, proposals);
    // Catch exception
    BodyDeclaration decl = ASTResolving.findParentBodyDeclaration(selectedNode);
    if (decl == null) {
        return;
    }
    ASTNode enclosingNode = SurroundWithAnalyzer.getEnclosingNode(selectedNode);
    if (enclosingNode == null) {
        return;
    }
    ITypeBinding[] uncaughtExceptions = ExceptionAnalyzer.perform(enclosingNode, Selection.createFromStartLength(offset, length));
    if (uncaughtExceptions.length == 0) {
        return;
    }
    TryStatement surroundingTry = ASTResolving.findParentTryStatement(selectedNode);
    AST ast = astRoot.getAST();
    if (surroundingTry != null && (ASTNodes.isParent(selectedNode, surroundingTry.getBody()) || selectedNode.getLocationInParent() == TryStatement.RESOURCES_PROPERTY)) {
        {
            ASTRewrite rewrite = ASTRewrite.create(surroundingTry.getAST());
            String label = CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalcatch_description;
            LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, CodeActionKind.QuickFix, cu, rewrite, IProposalRelevance.ADD_ADDITIONAL_CATCH);
            ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
            ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
            CodeScopeBuilder.Scope scope = CodeScopeBuilder.perform(decl, Selection.createFromStartLength(offset, length)).findScope(offset, length);
            scope.setCursor(offset);
            ListRewrite clausesRewrite = rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
            for (int i = 0; i < uncaughtExceptions.length; i++) {
                ITypeBinding excBinding = uncaughtExceptions[i];
                String varName = StubUtility.getExceptionVariableName(cu.getJavaProject());
                String name = scope.createName(varName, false);
                SingleVariableDeclaration var = ast.newSingleVariableDeclaration();
                var.setName(ast.newSimpleName(name));
                var.setType(imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION));
                CatchClause newClause = ast.newCatchClause();
                newClause.setException(var);
                String catchBody = StubUtility.getCatchBodyContent(cu, excBinding.getName(), name, selectedNode, String.valueOf('\n'));
                if (catchBody != null) {
                    ASTNode node = rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
                    newClause.getBody().statements().add(node);
                }
                clausesRewrite.insertLast(newClause, null);
                // $NON-NLS-1$
                String typeKey = "type" + i;
                // $NON-NLS-1$
                String nameKey = "name" + i;
                proposal.addLinkedPosition(rewrite.track(var.getType()), false, typeKey);
                proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
                addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
            }
            proposals.add(proposal);
        }
        if (JavaModelUtil.is1d7OrHigher(cu.getJavaProject())) {
            List<CatchClause> catchClauses = surroundingTry.catchClauses();
            if (catchClauses != null && catchClauses.size() == 1) {
                List<ITypeBinding> filteredExceptions = SurroundWithTryCatchRefactoring.filterSubtypeExceptions(uncaughtExceptions);
                String label = filteredExceptions.size() > 1 ? CorrectionMessages.LocalCorrectionsSubProcessor_addexceptionstoexistingcatch_description : CorrectionMessages.LocalCorrectionsSubProcessor_addexceptiontoexistingcatch_description;
                ASTRewrite rewrite = ASTRewrite.create(ast);
                LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, CodeActionKind.QuickFix, cu, rewrite, IProposalRelevance.ADD_EXCEPTIONS_TO_EXISTING_CATCH);
                ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
                ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
                CatchClause catchClause = catchClauses.get(0);
                Type type = catchClause.getException().getType();
                if (type instanceof UnionType) {
                    UnionType unionType = (UnionType) type;
                    ListRewrite listRewrite = rewrite.getListRewrite(unionType, UnionType.TYPES_PROPERTY);
                    for (int i = 0; i < filteredExceptions.size(); i++) {
                        ITypeBinding excBinding = filteredExceptions.get(i);
                        Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
                        listRewrite.insertLast(type2, null);
                        // $NON-NLS-1$
                        String typeKey = "type" + i;
                        proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
                        addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
                    }
                } else {
                    UnionType newUnionType = ast.newUnionType();
                    List<Type> types = newUnionType.types();
                    types.add((Type) rewrite.createCopyTarget(type));
                    for (int i = 0; i < filteredExceptions.size(); i++) {
                        ITypeBinding excBinding = filteredExceptions.get(i);
                        Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
                        types.add(type2);
                        // $NON-NLS-1$
                        String typeKey = "type" + i;
                        proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
                        addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
                    }
                    rewrite.replace(type, newUnionType, null);
                }
                proposals.add(proposal);
            } else if (catchClauses != null && catchClauses.size() == 0) {
                List<ITypeBinding> filteredExceptions = SurroundWithTryCatchRefactoring.filterSubtypeExceptions(uncaughtExceptions);
                if (filteredExceptions.size() > 1) {
                    String label = CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalmulticatch_description;
                    ASTRewrite rewrite = ASTRewrite.create(ast);
                    LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, CodeActionKind.QuickFix, cu, rewrite, IProposalRelevance.ADD_ADDITIONAL_MULTI_CATCH);
                    ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
                    ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
                    CodeScopeBuilder.Scope scope = CodeScopeBuilder.perform(decl, Selection.createFromStartLength(offset, length)).findScope(offset, length);
                    scope.setCursor(offset);
                    CatchClause newCatchClause = ast.newCatchClause();
                    String varName = StubUtility.getExceptionVariableName(cu.getJavaProject());
                    String name = scope.createName(varName, false);
                    SingleVariableDeclaration var = ast.newSingleVariableDeclaration();
                    var.setName(ast.newSimpleName(name));
                    UnionType newUnionType = ast.newUnionType();
                    List<Type> types = newUnionType.types();
                    for (int i = 0; i < filteredExceptions.size(); i++) {
                        ITypeBinding excBinding = filteredExceptions.get(i);
                        Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
                        types.add(type2);
                        // $NON-NLS-1$
                        String typeKey = "type" + i;
                        proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
                        addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
                    }
                    // $NON-NLS-1$
                    String nameKey = "name";
                    proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
                    var.setType(newUnionType);
                    newCatchClause.setException(var);
                    // $NON-NLS-1$
                    String catchBody = StubUtility.getCatchBodyContent(cu, "Exception", name, selectedNode, String.valueOf('\n'));
                    if (catchBody != null) {
                        ASTNode node = rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
                        newCatchClause.getBody().statements().add(node);
                    }
                    ListRewrite listRewrite = rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
                    listRewrite.insertFirst(newCatchClause, null);
                    proposals.add(proposal);
                }
            }
        }
    }
    // Add throws declaration
    if (enclosingNode instanceof MethodDeclaration) {
        MethodDeclaration methodDecl = (MethodDeclaration) enclosingNode;
        IMethodBinding binding = methodDecl.resolveBinding();
        boolean isApplicable = (binding != null);
        if (isApplicable) {
            IMethodBinding overriddenMethod = Bindings.findOverriddenMethod(binding, true);
            if (overriddenMethod != null) {
                isApplicable = overriddenMethod.getDeclaringClass().isFromSource();
                if (!isApplicable) {
                    // bug 349051
                    ITypeBinding[] exceptionTypes = overriddenMethod.getExceptionTypes();
                    ArrayList<ITypeBinding> unhandledExceptions = new ArrayList<>(uncaughtExceptions.length);
                    for (int i = 0; i < uncaughtExceptions.length; i++) {
                        ITypeBinding curr = uncaughtExceptions[i];
                        if (isSubtype(curr, exceptionTypes)) {
                            unhandledExceptions.add(curr);
                        }
                    }
                    uncaughtExceptions = unhandledExceptions.toArray(new ITypeBinding[unhandledExceptions.size()]);
                    isApplicable |= uncaughtExceptions.length > 0;
                }
            }
        }
        if (isApplicable) {
            ITypeBinding[] methodExceptions = binding.getExceptionTypes();
            ArrayList<ITypeBinding> unhandledExceptions = new ArrayList<>(uncaughtExceptions.length);
            for (int i = 0; i < uncaughtExceptions.length; i++) {
                ITypeBinding curr = uncaughtExceptions[i];
                if (!isSubtype(curr, methodExceptions)) {
                    unhandledExceptions.add(curr);
                }
            }
            uncaughtExceptions = unhandledExceptions.toArray(new ITypeBinding[unhandledExceptions.size()]);
            List<Type> exceptions = methodDecl.thrownExceptionTypes();
            int nExistingExceptions = exceptions.size();
            ChangeDescription[] desc = new ChangeDescription[nExistingExceptions + uncaughtExceptions.length];
            for (int i = 0; i < exceptions.size(); i++) {
                Type elem = exceptions.get(i);
                if (isSubtype(elem.resolveBinding(), uncaughtExceptions)) {
                    desc[i] = new RemoveDescription();
                }
            }
            for (int i = 0; i < uncaughtExceptions.length; i++) {
                // $NON-NLS-1$
                desc[i + nExistingExceptions] = new InsertDescription(uncaughtExceptions[i], "");
            }
            String label = CorrectionMessages.LocalCorrectionsSubProcessor_addthrows_description;
            ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, cu, astRoot, binding, null, desc, IProposalRelevance.ADD_THROWS_DECLARATION);
            for (int i = 0; i < uncaughtExceptions.length; i++) {
                addExceptionTypeLinkProposals(proposal, uncaughtExceptions[i], proposal.getExceptionTypeGroupId(i + nExistingExceptions));
            }
            proposals.add(proposal);
        }
    }
}
Also used : IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) UnionType(org.eclipse.jdt.core.dom.UnionType) ImportRewrite(org.eclipse.jdt.core.dom.rewrite.ImportRewrite) InsertDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.InsertDescription) ArrayList(java.util.ArrayList) ListRewrite(org.eclipse.jdt.core.dom.rewrite.ListRewrite) SurroundWithTryCatchRefactoring(org.eclipse.jdt.ls.core.internal.corext.refactoring.surround.SurroundWithTryCatchRefactoring) TryStatement(org.eclipse.jdt.core.dom.TryStatement) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ChangeDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite) List(java.util.List) ArrayList(java.util.ArrayList) RemoveDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.RemoveDescription) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) AST(org.eclipse.jdt.core.dom.AST) Statement(org.eclipse.jdt.core.dom.Statement) ThrowStatement(org.eclipse.jdt.core.dom.ThrowStatement) ExpressionStatement(org.eclipse.jdt.core.dom.ExpressionStatement) TryStatement(org.eclipse.jdt.core.dom.TryStatement) SwitchStatement(org.eclipse.jdt.core.dom.SwitchStatement) IfStatement(org.eclipse.jdt.core.dom.IfStatement) WhileStatement(org.eclipse.jdt.core.dom.WhileStatement) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EmptyStatement(org.eclipse.jdt.core.dom.EmptyStatement) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) CatchClause(org.eclipse.jdt.core.dom.CatchClause) ContextSensitiveImportRewriteContext(org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) UnionType(org.eclipse.jdt.core.dom.UnionType) Type(org.eclipse.jdt.core.dom.Type) ImportRewriteContext(org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext) ContextSensitiveImportRewriteContext(org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) MethodReference(org.eclipse.jdt.core.dom.MethodReference) BodyDeclaration(org.eclipse.jdt.core.dom.BodyDeclaration)

Example 4 with ChangeDescription

use of org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription in project eclipse.jdt.ls by eclipse.

the class UnresolvedElementsSubProcessor method doMoreParameters.

private static void doMoreParameters(IInvocationContext context, ASTNode invocationNode, ITypeBinding[] argTypes, IMethodBinding methodBinding, Collection<ChangeCorrectionProposal> proposals) throws CoreException {
    ITypeBinding[] paramTypes = methodBinding.getParameterTypes();
    int k = 0, nSkipped = 0;
    int diff = paramTypes.length - argTypes.length;
    int[] indexSkipped = new int[diff];
    for (int i = 0; i < paramTypes.length; i++) {
        if (k < argTypes.length && canAssign(argTypes[k], paramTypes[i])) {
            // match
            k++;
        } else {
            if (nSkipped >= diff) {
                // too different
                return;
            }
            indexSkipped[nSkipped++] = i;
        }
    }
    ITypeBinding declaringType = methodBinding.getDeclaringClass();
    ICompilationUnit cu = context.getCompilationUnit();
    CompilationUnit astRoot = context.getASTRoot();
    // add arguments
    {
        String[] arg = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodBinding) };
        String label;
        if (diff == 1) {
            label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addargument_description, arg);
        } else {
            label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addarguments_description, arg);
        }
        AddArgumentCorrectionProposal proposal = new AddArgumentCorrectionProposal(label, context.getCompilationUnit(), invocationNode, indexSkipped, paramTypes, IProposalRelevance.ADD_ARGUMENTS);
        proposals.add(proposal);
    }
    // remove parameters
    if (!declaringType.isFromSource()) {
        return;
    }
    ICompilationUnit targetCU = ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType);
    if (targetCU != null) {
        IMethodBinding methodDecl = methodBinding.getMethodDeclaration();
        ITypeBinding[] declParameterTypes = methodDecl.getParameterTypes();
        ChangeDescription[] changeDesc = new ChangeDescription[declParameterTypes.length];
        ITypeBinding[] changedTypes = new ITypeBinding[diff];
        for (int i = diff - 1; i >= 0; i--) {
            int idx = indexSkipped[i];
            changeDesc[idx] = new RemoveDescription();
            changedTypes[i] = declParameterTypes[idx];
        }
        String[] arg = new String[] { org.eclipse.jdt.ls.core.internal.corrections.ASTResolving.getMethodSignature(methodDecl), getTypeNames(changedTypes) };
        String label;
        if (methodDecl.isConstructor()) {
            if (diff == 1) {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_constr_description, arg);
            } else {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_constr_description, arg);
            }
        } else {
            if (diff == 1) {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_description, arg);
            } else {
                label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_description, arg);
            }
        }
        ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_REMOVE_PARAMETER);
        proposals.add(proposal);
    }
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ChangeDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription) RemoveDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.RemoveDescription)

Example 5 with ChangeDescription

use of org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription in project eclipse.jdt.ls by eclipse.

the class TypeMismatchSubProcessor method addIncompatibleThrowsProposals.

public static void addIncompatibleThrowsProposals(IInvocationContext context, IProblemLocationCore problem, Collection<ChangeCorrectionProposal> proposals) throws JavaModelException {
    CompilationUnit astRoot = context.getASTRoot();
    ASTNode selectedNode = problem.getCoveringNode(astRoot);
    if (!(selectedNode instanceof MethodDeclaration)) {
        return;
    }
    MethodDeclaration decl = (MethodDeclaration) selectedNode;
    IMethodBinding methodDeclBinding = decl.resolveBinding();
    if (methodDeclBinding == null) {
        return;
    }
    IMethodBinding overridden = Bindings.findOverriddenMethod(methodDeclBinding, false);
    if (overridden == null) {
        return;
    }
    ICompilationUnit cu = context.getCompilationUnit();
    ITypeBinding[] methodExceptions = methodDeclBinding.getExceptionTypes();
    ITypeBinding[] definedExceptions = overridden.getExceptionTypes();
    ArrayList<ITypeBinding> undeclaredExceptions = new ArrayList<>();
    {
        ChangeDescription[] changes = new ChangeDescription[methodExceptions.length];
        for (int i = 0; i < methodExceptions.length; i++) {
            if (!isDeclaredException(methodExceptions[i], definedExceptions)) {
                changes[i] = new RemoveDescription();
                undeclaredExceptions.add(methodExceptions[i]);
            }
        }
        if (undeclaredExceptions.size() == 0) {
            return;
        }
        String label = Messages.format(CorrectionMessages.TypeMismatchSubProcessor_removeexceptions_description, BasicElementLabels.getJavaElementName(methodDeclBinding.getName()));
        proposals.add(new ChangeMethodSignatureProposal(label, cu, astRoot, methodDeclBinding, null, changes, IProposalRelevance.REMOVE_EXCEPTIONS));
    }
    ITypeBinding declaringType = overridden.getDeclaringClass();
    ICompilationUnit targetCu = null;
    if (declaringType.isFromSource()) {
        targetCu = ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType);
    }
    if (targetCu != null) {
        ChangeDescription[] changes = new ChangeDescription[definedExceptions.length + undeclaredExceptions.size()];
        for (int i = 0; i < undeclaredExceptions.size(); i++) {
            // $NON-NLS-1$
            changes[i + definedExceptions.length] = new InsertDescription(undeclaredExceptions.get(i), "");
        }
        IMethodBinding overriddenDecl = overridden.getMethodDeclaration();
        String[] args = { BasicElementLabels.getJavaElementName(declaringType.getName()), BasicElementLabels.getJavaElementName(overridden.getName()) };
        String label = Messages.format(CorrectionMessages.TypeMismatchSubProcessor_addexceptions_description, args);
        proposals.add(new ChangeMethodSignatureProposal(label, targetCu, astRoot, overriddenDecl, null, changes, IProposalRelevance.ADD_EXCEPTIONS));
    }
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) InsertDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.InsertDescription) ArrayList(java.util.ArrayList) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ChangeDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription) RemoveDescription(org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.RemoveDescription)

Aggregations

ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)9 ChangeDescription (org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.ChangeDescription)9 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)8 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)8 IMethodBinding (org.eclipse.jdt.core.dom.IMethodBinding)8 ASTNode (org.eclipse.jdt.core.dom.ASTNode)6 RemoveDescription (org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.RemoveDescription)6 ArrayList (java.util.ArrayList)4 MethodDeclaration (org.eclipse.jdt.core.dom.MethodDeclaration)4 ASTRewrite (org.eclipse.jdt.core.dom.rewrite.ASTRewrite)4 InsertDescription (org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeMethodSignatureProposal.InsertDescription)4 CastExpression (org.eclipse.jdt.core.dom.CastExpression)3 Expression (org.eclipse.jdt.core.dom.Expression)3 ParenthesizedExpression (org.eclipse.jdt.core.dom.ParenthesizedExpression)3 ThisExpression (org.eclipse.jdt.core.dom.ThisExpression)3 List (java.util.List)2 AST (org.eclipse.jdt.core.dom.AST)2 BodyDeclaration (org.eclipse.jdt.core.dom.BodyDeclaration)2 CatchClause (org.eclipse.jdt.core.dom.CatchClause)2 EmptyStatement (org.eclipse.jdt.core.dom.EmptyStatement)2