diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/JavadocTagsSubProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/JavadocTagsSubProcessor.java index 14bf7acddb..d48eb130c3 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/JavadocTagsSubProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/JavadocTagsSubProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/ReorgCorrectionsSubProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/ReorgCorrectionsSubProcessor.java index c1e8b5c90f..087c02ca76 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/ReorgCorrectionsSubProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/ReorgCorrectionsSubProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -16,37 +16,25 @@ package org.eclipse.jdt.ls.core.internal.corrections.proposals; import java.util.Collection; -import java.util.List; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageDeclaration; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.JavaConventions; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.Modifier; -import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.manipulation.CUCorrectionProposalCore; import org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore; -import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; import org.eclipse.jdt.core.refactoring.CompilationUnitChange; -import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.fix.IProposableFix; -import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore; -import org.eclipse.jdt.internal.corext.refactoring.changes.MoveCompilationUnitChange; import org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange; -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.corext.util.Messages; +import org.eclipse.jdt.internal.ui.fix.UnusedCodeCleanUp; import org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore; import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; import org.eclipse.jdt.internal.ui.text.correction.IProposalRelevance; +import org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor; +import org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor; import org.eclipse.jdt.internal.ui.text.correction.proposals.CorrectMainTypeNameProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.CorrectPackageDeclarationProposalCore; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; @@ -54,124 +42,135 @@ import org.eclipse.jdt.ls.core.internal.corrections.ProposalKindWrapper; import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler; import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.TextChange; -public class ReorgCorrectionsSubProcessor { +public class ReorgCorrectionsSubProcessor extends ReorgCorrectionsBaseSubProcessor { public static void getWrongTypeNameProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) { - ICompilationUnit cu= context.getCompilationUnit(); - boolean isLinked = cu.getResource().isLinked(); - - IJavaProject javaProject= cu.getJavaProject(); - String sourceLevel= javaProject.getOption(JavaCore.COMPILER_SOURCE, true); - String compliance= javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); - - CompilationUnit root= context.getASTRoot(); - - ASTNode coveredNode= problem.getCoveredNode(root); - if (!(coveredNode instanceof SimpleName)) { - return; - } - - ASTNode parentType= coveredNode.getParent(); - if (!(parentType instanceof AbstractTypeDeclaration)) { - return; - } + new ReorgCorrectionsSubProcessor().addWrongTypeNameProposals(context, problem, proposals); + } - String currTypeName= ((SimpleName) coveredNode).getIdentifier(); - String newTypeName= JavaCore.removeJavaLikeExtension(cu.getElementName()); - - - boolean hasOtherPublicTypeBefore = false; - - boolean found = false; - List types= root.types(); - for (int i= 0; i < types.size(); i++) { - AbstractTypeDeclaration curr= types.get(i); - if (parentType != curr) { - if (newTypeName.equals(curr.getName().getIdentifier())) { - return; - } - if (!found && Modifier.isPublic(curr.getModifiers())) { - hasOtherPublicTypeBefore = true; - } - } else { - found = true; - } - } + public static void getWrongPackageDeclNameProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) throws CoreException { + new ReorgCorrectionsSubProcessor().addWrongPackageDeclNameProposals(context, problem, proposals); + } - if (!JavaConventions.validateJavaTypeName(newTypeName, sourceLevel, compliance).matches(IStatus.ERROR)) { - String title = Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_renametype_description, BasicElementLabels.getJavaElementName(newTypeName)); - CorrectMainTypeNameProposalCore p = new CorrectMainTypeNameProposalCore(title, cu, null, context, currTypeName, newTypeName, IProposalRelevance.RENAME_TYPE); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } + public static void removeImportStatementProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) throws CoreException { + new ReorgCorrectionsSubProcessor().addRemoveImportStatementProposals(context, problem, proposals); + } - if (!hasOtherPublicTypeBefore && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isResourceOperationSupported()) { - String newCUName = JavaModelUtil.getRenamedCUName(cu, currTypeName); - ICompilationUnit newCU = ((IPackageFragment) (cu.getParent())).getCompilationUnit(newCUName); - if (!newCU.exists() && !isLinked && !JavaConventions.validateCompilationUnitName(newCUName, sourceLevel, compliance).matches(IStatus.ERROR)) { - RenameCompilationUnitChange change = new RenameCompilationUnitChange(cu, newCUName); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createRenameCUProposal(java.lang.String, org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange, int) + */ + @Override + public ProposalKindWrapper createRenameCUProposal(String label, RenameCompilationUnitChange change, int relevance) { + ChangeCorrectionProposalCore proposal = new ChangeCorrectionProposalCore(label, change, relevance); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); + } - // rename CU - String label = Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_renamecu_description, BasicElementLabels.getResourceName(newCUName)); - ChangeCorrectionProposalCore proposal = new ChangeCorrectionProposalCore(label, change, IProposalRelevance.RENAME_CU); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createCorrectMainTypeNameProposal(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore, java.lang.String, java.lang.String, int) + */ + @Override + public ProposalKindWrapper createCorrectMainTypeNameProposal(ICompilationUnit cu, IInvocationContextCore context, String currTypeName, String newTypeName, int relevance) { + String title = Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_renametype_description, BasicElementLabels.getJavaElementName(newTypeName)); + CorrectMainTypeNameProposalCore p = new CorrectMainTypeNameProposalCore(title, cu, null, context, currTypeName, newTypeName, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createCorrectPackageDeclarationProposal(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore, int) + */ + @Override + protected ProposalKindWrapper createCorrectPackageDeclarationProposal(ICompilationUnit cu, IProblemLocationCore problem, int relevance) { + return CodeActionHandler.wrap(new CorrectPackageDeclarationProposalCore(cu, problem, relevance), CodeActionKind.QuickFix); } - public static void getWrongPackageDeclNameProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) throws CoreException { - ICompilationUnit cu= context.getCompilationUnit(); - - // correct package declaration - int relevance= cu.getPackageDeclarations().length == 0 ? IProposalRelevance.MISSING_PACKAGE_DECLARATION : IProposalRelevance.CORRECT_PACKAGE_DECLARATION; // bug 38357 - proposals.add(CodeActionHandler.wrap(new CorrectPackageDeclarationProposalCore(cu, problem, relevance), CodeActionKind.QuickFix)); - - // move to package - IPackageDeclaration[] packDecls= cu.getPackageDeclarations(); - String newPackName= packDecls.length > 0 ? packDecls[0].getElementName() : ""; //$NON-NLS-1$ - - IPackageFragmentRoot root= JavaModelUtil.getPackageFragmentRoot(cu); - IPackageFragment newPack= root.getPackageFragment(newPackName); - - ICompilationUnit newCU= newPack.getCompilationUnit(cu.getElementName()); - boolean isLinked= cu.getResource().isLinked(); - if (!newCU.exists() && !isLinked) { - String label; - if (newPack.isDefaultPackage()) { - label= Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_movecu_default_description, BasicElementLabels.getFileName(cu)); - } else { - String packageLabel= JavaElementLabelsCore.getElementLabel(newPack, JavaElementLabelsCore.ALL_DEFAULT); - label= Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_movecu_description, new Object[] { BasicElementLabels.getFileName(cu), packageLabel }); - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createMoveToNewPackageProposal(java.lang.String, org.eclipse.ltk.core.refactoring.CompositeChange, int) + */ + @Override + protected ProposalKindWrapper createMoveToNewPackageProposal(String label, CompositeChange composite, int relevance) { + ChangeCorrectionProposalCore p = new ChangeCorrectionProposalCore(label, composite, IProposalRelevance.MOVE_CU_TO_PACKAGE); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - ChangeCorrectionProposalCore p = new ChangeCorrectionProposalCore(label, new MoveCompilationUnitChange(cu, newPack), IProposalRelevance.MOVE_CU_TO_PACKAGE); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createOrganizeImportsProposal(java.lang.String, org.eclipse.ltk.core.refactoring.Change, org.eclipse.jdt.core.ICompilationUnit, int) + */ + @Override + protected ProposalKindWrapper createOrganizeImportsProposal(String name, Change change, ICompilationUnit cu, int relevance) { + if (change instanceof TextChange tchange) { + CUCorrectionProposalCore proposal = new CUCorrectionProposalCore(name, cu, tchange, relevance); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); } + return null; } - public static void removeImportStatementProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) throws CoreException { - IProposableFix fix = UnusedCodeFixCore.createRemoveUnusedImportFix(context.getASTRoot(), problem); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createRemoveUnusedImportProposal(org.eclipse.jdt.internal.corext.fix.IProposableFix, org.eclipse.jdt.internal.ui.fix.UnusedCodeCleanUp, int, org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore) + */ + @Override + protected ProposalKindWrapper createRemoveUnusedImportProposal(IProposableFix fix, UnusedCodeCleanUp unusedCodeCleanUp, int relevance, IInvocationContextCore context) { if (fix != null) { try { CompilationUnitChange change = fix.createChange(null); - CUCorrectionProposalCore proposal = new CUCorrectionProposalCore(change.getName(), change.getCompilationUnit(), - change, IProposalRelevance.REMOVE_UNUSED_IMPORT); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); + CUCorrectionProposalCore proposal = new CUCorrectionProposalCore(change.getName(), change.getCompilationUnit(), change, relevance); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); } catch (CoreException e) { JavaLanguageServerPlugin.log(e); } } - ICleanUpFixCore removeAllUnusedImportsFix = UnusedCodeFixCore.createCleanUp(context.getASTRoot(), false, false, false, false, false, true, false, false); - if (removeAllUnusedImportsFix != null) { - CompilationUnitChange change = removeAllUnusedImportsFix.createChange(null); - CUCorrectionProposalCore proposal = new CUCorrectionProposalCore(CorrectionMessages.ReorgCorrectionsSubProcessor_remove_all_unused_imports, change.getCompilationUnit(), - change, IProposalRelevance.REMOVE_UNUSED_IMPORT); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createProjectSetupFixProposal(org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore, org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore, java.lang.String, java.util.Collection) + */ + @Override + public ProposalKindWrapper createProjectSetupFixProposal(IInvocationContextCore context, IProblemLocationCore problem, String missingType, Collection proposals) { + // Not yet implemented in jdt.ls, jdt.ui impl is UI-based + return null; } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#getUnresolvedElementsSubProcessor() + */ + @Override + public UnresolvedElementsBaseSubProcessor getUnresolvedElementsSubProcessor() { + return new UnresolvedElementsSubProcessor(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createChangeToRequiredCompilerComplianceProposal(java.lang.String, org.eclipse.jdt.core.IJavaProject, boolean, java.lang.String, int) + */ + @Override + protected ProposalKindWrapper createChangeToRequiredCompilerComplianceProposal(String label1, IJavaProject project, boolean changeOnWorkspace, String requiredVersion, int relevance) { + // Not yet implemented in jdt.ls, jdt.ui impl is UI-based + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createChangeToRequiredCompilerComplianceProposal(java.lang.String, org.eclipse.jdt.core.IJavaProject, boolean, java.lang.String, boolean, int) + */ + @Override + protected ProposalKindWrapper createChangeToRequiredCompilerComplianceProposal(String label2, IJavaProject project, boolean changeOnWorkspace, String requiredVersion, boolean enablePreviews, int relevance) { + // Not yet implemented in jdt.ls, jdt.ui impl is UI-based + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor#createOpenBuildPathCorrectionProposal(org.eclipse.core.resources.IProject, java.lang.String, int, org.eclipse.jdt.core.dom.IBinding) + */ + @Override + protected ProposalKindWrapper createOpenBuildPathCorrectionProposal(IProject project, String label, int relevance, IBinding referencedElement) { + // Not yet implemented in jdt.ls, jdt.ui impl is UI-based + return null; + } + } diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/TypeMismatchSubProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/TypeMismatchSubProcessor.java index f60fb7ea56..a4aef8bd15 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/TypeMismatchSubProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/TypeMismatchSubProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -16,7 +16,6 @@ *******************************************************************************/ package org.eclipse.jdt.ls.core.internal.corrections.proposals; -import java.util.ArrayList; import java.util.Collection; import org.eclipse.core.runtime.CoreException; @@ -24,53 +23,33 @@ import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ArrayInitializer; -import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.BodyDeclaration; -import org.eclipse.jdt.core.dom.CastExpression; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.EnhancedForStatement; import org.eclipse.jdt.core.dom.Expression; -import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.IVariableBinding; -import org.eclipse.jdt.core.dom.InfixExpression; -import org.eclipse.jdt.core.dom.MemberValuePair; import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.Name; -import org.eclipse.jdt.core.dom.NameQualifiedType; import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.SimpleType; -import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation; -import org.eclipse.jdt.internal.core.manipulation.BindingLabelProviderCore; -import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; -import org.eclipse.jdt.internal.core.manipulation.StubUtility; import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; -import org.eclipse.jdt.internal.corext.dom.ASTNodes; -import org.eclipse.jdt.internal.corext.dom.Bindings; -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore; import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; import org.eclipse.jdt.internal.ui.text.correction.IProposalRelevance; +import org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor; import org.eclipse.jdt.internal.ui.text.correction.proposals.CastCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.ChangeDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.InsertDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.RemoveDescription; import org.eclipse.jdt.internal.ui.text.correction.proposals.ImplementInterfaceProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.NewVariableCorrectionProposalCore; +import org.eclipse.jdt.internal.ui.text.correction.proposals.OptionalCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.TypeChangeCorrectionProposalCore; import org.eclipse.jdt.ls.core.internal.Messages; import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages; @@ -80,418 +59,163 @@ import org.eclipse.lsp4j.CodeActionKind; -public class TypeMismatchSubProcessor { +public class TypeMismatchSubProcessor extends TypeMismatchBaseSubProcessor { private TypeMismatchSubProcessor() { } public static void addTypeMismatchProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) throws CoreException { - - ICompilationUnit cu= context.getCompilationUnit(); - - CompilationUnit astRoot= context.getASTRoot(); - AST ast= astRoot.getAST(); - - ASTNode selectedNode= problem.getCoveredNode(astRoot); - if (!(selectedNode instanceof Expression)) { - return; - } - Expression nodeToCast= (Expression) selectedNode; - Name receiverNode= null; - ITypeBinding castTypeBinding= null; - - int parentNodeType= selectedNode.getParent().getNodeType(); - if (parentNodeType == ASTNode.ASSIGNMENT) { - Assignment assign= (Assignment) selectedNode.getParent(); - Expression leftHandSide= assign.getLeftHandSide(); - if (selectedNode.equals(leftHandSide)) { - nodeToCast= assign.getRightHandSide(); - } - castTypeBinding= assign.getLeftHandSide().resolveTypeBinding(); - if (leftHandSide instanceof Name name) { - receiverNode = name; - } else if (leftHandSide instanceof FieldAccess fieldAccess) { - receiverNode = fieldAccess.getName(); - } - } else if (parentNodeType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) { - VariableDeclarationFragment frag= (VariableDeclarationFragment) selectedNode.getParent(); - if (selectedNode.equals(frag.getName()) || selectedNode.equals(frag.getInitializer())) { - nodeToCast= frag.getInitializer(); - castTypeBinding= ASTNodes.getType(frag).resolveBinding(); - receiverNode= frag.getName(); - } - } else if (parentNodeType == ASTNode.MEMBER_VALUE_PAIR) { - receiverNode= ((MemberValuePair) selectedNode.getParent()).getName(); - castTypeBinding= ASTResolving.guessBindingForReference(nodeToCast); - } else if (parentNodeType == ASTNode.SINGLE_MEMBER_ANNOTATION) { - receiverNode= ((SingleMemberAnnotation) selectedNode.getParent()).getTypeName(); // use the type name - castTypeBinding= ASTResolving.guessBindingForReference(nodeToCast); - } else { - // try to find the binding corresponding to 'castTypeName' - castTypeBinding= ASTResolving.guessBindingForReference(nodeToCast); - } - if (castTypeBinding == null) { - return; - } - - ITypeBinding currBinding= nodeToCast.resolveTypeBinding(); - if (currBinding == null && nodeToCast instanceof MethodInvocation methodInvocation) { - IMethodBinding methodBinding = methodInvocation.resolveMethodBinding(); - if (methodBinding != null) { - currBinding= methodBinding.getReturnType(); - } - } - - if (!(nodeToCast instanceof ArrayInitializer)) { - ITypeBinding castFixType= null; - if (currBinding == null || castTypeBinding.isCastCompatible(currBinding) || nodeToCast instanceof CastExpression) { - castFixType= castTypeBinding; - } else if (JavaModelUtil.is50OrHigher(cu.getJavaProject())) { - ITypeBinding boxUnboxedTypeBinding= boxUnboxPrimitives(castTypeBinding, currBinding, ast); - if (boxUnboxedTypeBinding != castTypeBinding && boxUnboxedTypeBinding.isCastCompatible(currBinding)) { - castFixType= boxUnboxedTypeBinding; - } - } - if (castFixType != null) { - proposals.add(createCastProposal(context, castFixType, nodeToCast, IProposalRelevance.CREATE_CAST)); - } - } - - boolean nullOrVoid= currBinding == null || "void".equals(currBinding.getName()); //$NON-NLS-1$ - - // change method return statement to actual type - if (!nullOrVoid && parentNodeType == ASTNode.RETURN_STATEMENT) { - BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode); - if (decl instanceof MethodDeclaration methodDeclaration) { - currBinding= Bindings.normalizeTypeBinding(currBinding); - if (currBinding == null) { - currBinding= ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - } - if (currBinding.isWildcardType()) { - currBinding= ASTResolving.normalizeWildcardType(currBinding, true, ast); - } - - ASTRewrite rewrite= ASTRewrite.create(ast); - - String label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changereturntype_description, BasicElementLabels.getJavaElementName(currBinding.getName())); - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, - IProposalRelevance.CHANGE_METHOD_RETURN_TYPE); - - ImportRewrite imports= proposal.createImportRewrite(astRoot); - ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports); - - Type newReturnType= imports.addImport(currBinding, ast, importRewriteContext, TypeLocation.RETURN_TYPE); - rewrite.replace(methodDeclaration.getReturnType2(), newReturnType, null); - - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - - if (!nullOrVoid && receiverNode != null) { - currBinding= Bindings.normalizeTypeBinding(currBinding); - if (currBinding == null) { - currBinding= ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - } - if (currBinding.isWildcardType()) { - currBinding= ASTResolving.normalizeWildcardType(currBinding, true, ast); - } - addChangeSenderTypeProposals(context, receiverNode, currBinding, true, IProposalRelevance.CHANGE_TYPE_OF_RECEIVER_NODE, proposals); - } - - addChangeSenderTypeProposals(context, nodeToCast, castTypeBinding, false, IProposalRelevance.CHANGE_TYPE_OF_NODE_TO_CAST, proposals); - - if (castTypeBinding == ast.resolveWellKnownType("boolean") && currBinding != null && !currBinding.isPrimitive() && !Bindings.isVoidType(currBinding)) { //$NON-NLS-1$ - String label= CorrectionMessages.TypeMismatchSubProcessor_insertnullcheck_description; - ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); - - InfixExpression expression= ast.newInfixExpression(); - expression.setLeftOperand((Expression) rewrite.createMoveTarget(nodeToCast)); - expression.setRightOperand(ast.newNullLiteral()); - expression.setOperator(InfixExpression.Operator.NOT_EQUALS); - rewrite.replace(nodeToCast, expression, null); - - ASTRewriteCorrectionProposalCore p = new ASTRewriteCorrectionProposalCore(label, context.getCompilationUnit(), rewrite, IProposalRelevance.INSERT_NULL_CHECK); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } - + new TypeMismatchSubProcessor().collectTypeMismatchProposals(context, problem, proposals); } public static ITypeBinding boxUnboxPrimitives(ITypeBinding castType, ITypeBinding toCast, AST ast) { - /* - * e.g: - * void m(toCast var) { - * castType i= var; - * } - */ - if (castType.isPrimitive() && !toCast.isPrimitive()) { - return Bindings.getBoxedTypeBinding(castType, ast); - } else if (!castType.isPrimitive() && toCast.isPrimitive()) { - return Bindings.getUnboxedTypeBinding(castType, ast); - } else { - return castType; - } + return TypeMismatchSubProcessor.boxOrUnboxPrimitives(castType, toCast, ast); } public static void addChangeSenderTypeProposals(IInvocationContextCore context, Expression nodeToCast, ITypeBinding castTypeBinding, boolean isAssignedNode, int relevance, Collection proposals) throws JavaModelException { - IBinding callerBinding= Bindings.resolveExpressionBinding(nodeToCast, false); - - ICompilationUnit cu= context.getCompilationUnit(); - CompilationUnit astRoot= context.getASTRoot(); - - ICompilationUnit targetCu= null; - ITypeBinding declaringType= null; - IBinding callerBindingDecl= callerBinding; - if (callerBinding instanceof IVariableBinding variableBinding) { - if (variableBinding.isEnumConstant()) { - return; - } - if (!variableBinding.isField()) { - targetCu= cu; - } else { - callerBindingDecl= variableBinding.getVariableDeclaration(); - ITypeBinding declaringClass= variableBinding.getDeclaringClass(); - if (declaringClass == null) { - return; // array length - } - declaringType= declaringClass.getTypeDeclaration(); - } - } else if (callerBinding instanceof IMethodBinding methodBinding) { - if (!methodBinding.isConstructor()) { - declaringType= methodBinding.getDeclaringClass().getTypeDeclaration(); - callerBindingDecl= methodBinding.getMethodDeclaration(); - } - } else if (callerBinding instanceof ITypeBinding typeBinding && nodeToCast.getLocationInParent() == SingleMemberAnnotation.TYPE_NAME_PROPERTY) { - declaringType = typeBinding; - callerBindingDecl= Bindings.findMethodInType(declaringType, "value", (String[]) null); //$NON-NLS-1$ - if (callerBindingDecl == null) { - return; - } - } - - if (declaringType != null && declaringType.isFromSource()) { - targetCu= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType); - } - if (targetCu != null && ASTResolving.isUseableTypeInContext(castTypeBinding, callerBindingDecl, false)) { - TypeChangeCorrectionProposalCore p = new TypeChangeCorrectionProposalCore(targetCu, callerBindingDecl, astRoot, castTypeBinding, isAssignedNode, relevance); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } - - // add interface to resulting type - if (!isAssignedNode) { - ITypeBinding nodeType= nodeToCast.resolveTypeBinding(); - if (castTypeBinding.isInterface() && nodeType != null && nodeType.isClass() && !nodeType.isAnonymous() && nodeType.isFromSource()) { - ITypeBinding typeDecl= nodeType.getTypeDeclaration(); - ICompilationUnit nodeCu= ASTResolving.findCompilationUnitForBinding(cu, astRoot, typeDecl); - if (nodeCu != null && ASTResolving.isUseableTypeInContext(castTypeBinding, typeDecl, true)) { - ImplementInterfaceProposalCore p = new ImplementInterfaceProposalCore(nodeCu, typeDecl, astRoot, castTypeBinding, relevance - 1); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } - } - } + new TypeMismatchSubProcessor().collectChangeSenderTypeProposals(context, nodeToCast, castTypeBinding, isAssignedNode, relevance, proposals); } public static ProposalKindWrapper createCastProposal(IInvocationContextCore context, ITypeBinding castTypeBinding, Expression nodeToCast, int relevance) { - ICompilationUnit cu= context.getCompilationUnit(); - - String label; - String castType= BindingLabelProviderCore.getBindingLabel(castTypeBinding, JavaElementLabelsCore.ALL_DEFAULT); - if (nodeToCast.getNodeType() == ASTNode.CAST_EXPRESSION) { - label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changecast_description, castType); - } else { - label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_addcast_description, castType); - } - CastCorrectionProposalCore p = new CastCorrectionProposalCore(label, cu, nodeToCast, castTypeBinding, relevance); - return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + return new TypeMismatchSubProcessor().collectCastProposals(context, castTypeBinding, nodeToCast, relevance); } public static void addIncompatibleReturnTypeProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) throws JavaModelException { - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - if (selectedNode == null) { - return; - } - MethodDeclaration decl= ASTResolving.findParentMethodDeclaration(selectedNode); - if (decl == null) { - return; - } - IMethodBinding methodDeclBinding= decl.resolveBinding(); - if (methodDeclBinding == null) { - return; - } - - ITypeBinding returnType= methodDeclBinding.getReturnType(); - IMethodBinding overridden= Bindings.findOverriddenMethod(methodDeclBinding, false); - if (overridden == null || overridden.getReturnType() == returnType) { - return; - } - - - ICompilationUnit cu= context.getCompilationUnit(); - IMethodBinding methodDecl= methodDeclBinding.getMethodDeclaration(); - ITypeBinding overriddenReturnType= overridden.getReturnType(); - if (! JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) { - overriddenReturnType= overriddenReturnType.getErasure(); - } - TypeChangeCorrectionProposalCore p = new TypeChangeCorrectionProposalCore(cu, methodDecl, astRoot, overriddenReturnType, false, IProposalRelevance.CHANGE_RETURN_TYPE); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - ICompilationUnit targetCu= cu; - - IMethodBinding overriddenDecl= overridden.getMethodDeclaration(); - ITypeBinding overridenDeclType= overriddenDecl.getDeclaringClass(); - - if (overridenDeclType.isFromSource()) { - targetCu= ASTResolving.findCompilationUnitForBinding(cu, astRoot, overridenDeclType); - if (targetCu != null && ASTResolving.isUseableTypeInContext(returnType, overriddenDecl, false)) { - TypeChangeCorrectionProposalCore proposal = new TypeChangeCorrectionProposalCore(targetCu, overriddenDecl, astRoot, returnType, false, IProposalRelevance.CHANGE_RETURN_TYPE_OF_OVERRIDDEN); - if (overridenDeclType.isInterface()) { - proposal.setDisplayName(Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changereturnofimplemented_description, BasicElementLabels.getJavaElementName(overriddenDecl.getName()))); - } else { - proposal.setDisplayName(Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changereturnofoverridden_description, BasicElementLabels.getJavaElementName(overriddenDecl.getName()))); - } - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + new TypeMismatchSubProcessor().collectIncompatibleReturnTypeProposals(context, problem, proposals); } public static void addIncompatibleThrowsProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection 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(); + new TypeMismatchSubProcessor().collectIncompatibleThrowsProposals(context, problem, proposals); + } - ITypeBinding[] methodExceptions= methodDeclBinding.getExceptionTypes(); - ITypeBinding[] definedExceptions= overridden.getExceptionTypes(); + public static void addTypeMismatchInForEachProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) { + new TypeMismatchSubProcessor().collectTypeMismatchInForEachProposals(context, problem, proposals); + } - ArrayList undeclaredExceptions= new ArrayList<>(); - { - ChangeDescription[] changes= new ChangeDescription[methodExceptions.length]; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createInsertNullCheckProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.rewrite.ASTRewrite, int) + */ + @Override + protected ProposalKindWrapper createInsertNullCheckProposal(String label, ICompilationUnit compilationUnit, ASTRewrite rewrite, int relevance) { + ASTRewriteCorrectionProposalCore p = new ASTRewriteCorrectionProposalCore(label, compilationUnit, rewrite, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - 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())); - ChangeMethodSignatureProposalCore p = new ChangeMethodSignatureProposalCore(label, cu, astRoot, methodDeclBinding, null, changes, IProposalRelevance.REMOVE_EXCEPTIONS); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createChangeReturnTypeProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.rewrite.ASTRewrite, int, org.eclipse.jdt.core.dom.ITypeBinding, org.eclipse.jdt.core.dom.AST, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.MethodDeclaration, org.eclipse.jdt.core.dom.BodyDeclaration) + */ + @Override + protected ProposalKindWrapper createChangeReturnTypeProposal(String label, ICompilationUnit cu, ASTRewrite rewrite, int relevance, ITypeBinding currBinding, AST ast, CompilationUnit astRoot, MethodDeclaration methodDeclaration, + BodyDeclaration decl) { + ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, IProposalRelevance.CHANGE_METHOD_RETURN_TYPE); - 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()]; + ImportRewrite imports = proposal.createImportRewrite(astRoot); + ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports); - for (int i= 0; i < undeclaredExceptions.size(); i++) { - changes[i + definedExceptions.length]= new InsertDescription(undeclaredExceptions.get(i), ""); //$NON-NLS-1$ - } - IMethodBinding overriddenDecl= overridden.getMethodDeclaration(); - String[] args= { BasicElementLabels.getJavaElementName(declaringType.getName()), BasicElementLabels.getJavaElementName(overridden.getName()) }; - String label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_addexceptions_description, args); - ChangeMethodSignatureProposalCore p = new ChangeMethodSignatureProposalCore(label, targetCu, astRoot, overriddenDecl, null, changes, IProposalRelevance.ADD_EXCEPTIONS); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - } + Type newReturnType = imports.addImport(currBinding, ast, importRewriteContext, TypeLocation.RETURN_TYPE); + rewrite.replace(methodDeclaration.getReturnType2(), newReturnType, null); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); } - private static boolean isDeclaredException(ITypeBinding curr, ITypeBinding[] declared) { - for (int i= 0; i < declared.length; i++) { - if (Bindings.isSuperType(declared[i], curr)) { - return true; - } - } - return false; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createOptionalProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.Expression, int, int) + */ + @Override + protected ProposalKindWrapper createOptionalProposal(String label, ICompilationUnit cu, Expression nodeToCast, int relevance, int optionalType) { + OptionalCorrectionProposalCore core = new OptionalCorrectionProposalCore(label, cu, nodeToCast, relevance, optionalType); + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - public static void addTypeMismatchInForEachProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) { - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - if (selectedNode == null || selectedNode.getLocationInParent() != EnhancedForStatement.EXPRESSION_PROPERTY) { - return; - } - EnhancedForStatement forStatement= (EnhancedForStatement) selectedNode.getParent(); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createImplementInterfaceProposal(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.ITypeBinding, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.ITypeBinding, int) + */ + @Override + protected ProposalKindWrapper createImplementInterfaceProposal(ICompilationUnit nodeCu, ITypeBinding typeDecl, CompilationUnit astRoot, ITypeBinding castTypeBinding, int relevance) { + ImplementInterfaceProposalCore core = new ImplementInterfaceProposalCore(nodeCu, typeDecl, astRoot, castTypeBinding, relevance); + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); + } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createChangeSenderTypeProposal(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.IBinding, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.ITypeBinding, boolean, int) + */ + @Override + protected ProposalKindWrapper createChangeSenderTypeProposal(ICompilationUnit targetCu, IBinding callerBindingDecl, CompilationUnit astRoot, ITypeBinding castTypeBinding, boolean isAssignedNode, int relevance) { + TypeChangeCorrectionProposalCore p = new TypeChangeCorrectionProposalCore(targetCu, callerBindingDecl, astRoot, castTypeBinding, isAssignedNode, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - ITypeBinding expressionBinding= forStatement.getExpression().resolveTypeBinding(); - if (expressionBinding == null) { - return; - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createCastCorrectionProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.Expression, org.eclipse.jdt.core.dom.ITypeBinding, int) + */ + @Override + protected ProposalKindWrapper createCastCorrectionProposal(String label, ICompilationUnit cu, Expression nodeToCast, ITypeBinding castTypeBinding, int relevance) { + CastCorrectionProposalCore p = new CastCorrectionProposalCore(label, cu, nodeToCast, castTypeBinding, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - ITypeBinding expectedBinding; - if (expressionBinding.isArray()) { - expectedBinding= expressionBinding.getComponentType(); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createChangeReturnTypeOfOverridden(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.IMethodBinding, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.ITypeBinding, boolean, int, org.eclipse.jdt.core.dom.ITypeBinding) + */ + @Override + protected ProposalKindWrapper createChangeReturnTypeOfOverridden(ICompilationUnit targetCu, IMethodBinding overriddenDecl, CompilationUnit astRoot, ITypeBinding returnType, boolean offerSuperTypeProposals, int relevance, + ITypeBinding overridenDeclType) { + TypeChangeCorrectionProposalCore proposal = new TypeChangeCorrectionProposalCore(targetCu, overriddenDecl, astRoot, returnType, false, relevance); + if (overridenDeclType.isInterface()) { + proposal.setDisplayName(Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changereturnofimplemented_description, BasicElementLabels.getJavaElementName(overriddenDecl.getName()))); } else { - IMethodBinding iteratorMethod= Bindings.findMethodInHierarchy(expressionBinding, "iterator", new String[0]); //$NON-NLS-1$ - if (iteratorMethod == null) { - return; - } - ITypeBinding[] typeArguments= iteratorMethod.getReturnType().getTypeArguments(); - if (typeArguments.length != 1) { - return; - } - expectedBinding= typeArguments[0]; + proposal.setDisplayName(Messages.format(CorrectionMessages.TypeMismatchSubProcessor_changereturnofoverridden_description, BasicElementLabels.getJavaElementName(overriddenDecl.getName()))); } - AST ast= astRoot.getAST(); - expectedBinding= Bindings.normalizeForDeclarationUse(expectedBinding, ast); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); + } - SingleVariableDeclaration parameter= forStatement.getParameter(); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createChangeIncompatibleReturnTypeProposal(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.IMethodBinding, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.ITypeBinding, boolean, int) + */ + @Override + protected ProposalKindWrapper createChangeIncompatibleReturnTypeProposal(ICompilationUnit cu, IMethodBinding methodDecl, CompilationUnit astRoot, ITypeBinding overriddenReturnType, boolean offerSuperTypeProposals, int relevance) { + TypeChangeCorrectionProposalCore p = new TypeChangeCorrectionProposalCore(cu, methodDecl, astRoot, overriddenReturnType, false, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - ICompilationUnit cu= context.getCompilationUnit(); - if (parameter.getName().getLength() == 0) { - SimpleName simpleName= null; - if (parameter.getType() instanceof SimpleType type) { - if (type.getName() instanceof SimpleName name) { - simpleName = name; - } - } else if (parameter.getType() instanceof NameQualifiedType type) { - simpleName = type.getName(); - } - if (simpleName != null) { - String name= simpleName.getIdentifier(); - int relevance= StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? 10 : 7; - String label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_create_loop_variable_description, BasicElementLabels.getJavaElementName(name)); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createChangeMethodSignatureProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.IMethodBinding, org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.ChangeDescription[], org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.ChangeDescription[], int) + */ + @Override + protected ProposalKindWrapper createChangeMethodSignatureProposal(String label, ICompilationUnit cu, CompilationUnit astRoot, IMethodBinding methodDeclBinding, ChangeDescription[] paramChanges, ChangeDescription[] changes, + int relevance) { + ChangeMethodSignatureProposalCore p = new ChangeMethodSignatureProposalCore(label, cu, astRoot, methodDeclBinding, null, changes, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - NewVariableCorrectionProposalCore p = new NewVariableCorrectionProposalCore(label, cu, NewVariableCorrectionProposalCore.LOCAL, simpleName, null, relevance); - proposals.add(CodeActionHandler.wrap(p, CodeActionKind.QuickFix)); - return; - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createNewVariableCorrectionProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, int, org.eclipse.jdt.core.dom.SimpleName, org.eclipse.jdt.core.dom.ITypeBinding, int) + */ + @Override + protected ProposalKindWrapper createNewVariableCorrectionProposal(String label, ICompilationUnit cu, int local, SimpleName simpleName, ITypeBinding senderBinding, int relevance) { + NewVariableCorrectionProposalCore p = new NewVariableCorrectionProposalCore(label, cu, NewVariableCorrectionProposalCore.LOCAL, simpleName, null, relevance); + return CodeActionHandler.wrap(p, CodeActionKind.QuickFix); + } - String label= Messages.format(CorrectionMessages.TypeMismatchSubProcessor_incompatible_for_each_type_description, new String[] { BasicElementLabels.getJavaElementName(parameter.getName().getIdentifier()), BindingLabelProviderCore.getBindingLabel(expectedBinding, BindingLabelProviderCore.DEFAULT_TEXTFLAGS) }); - ASTRewrite rewrite= ASTRewrite.create(ast); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor#createIncompatibleForEachTypeProposal(java.lang.String, org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.rewrite.ASTRewrite, int, org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.dom.AST, org.eclipse.jdt.core.dom.ITypeBinding, org.eclipse.jdt.core.dom.ASTNode, org.eclipse.jdt.core.dom.SingleVariableDeclaration) + */ + @Override + protected ProposalKindWrapper createIncompatibleForEachTypeProposal(String label, ICompilationUnit cu, ASTRewrite rewrite, int incompatibleForeachType, CompilationUnit astRoot, AST ast, ITypeBinding expectedBinding, + ASTNode selectedNode, SingleVariableDeclaration parameter) { ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, IProposalRelevance.INCOMPATIBLE_FOREACH_TYPE); - ImportRewrite importRewrite= proposal.createImportRewrite(astRoot); - ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(ASTResolving.findParentBodyDeclaration(selectedNode), importRewrite); - Type newType= importRewrite.addImport(expectedBinding, ast, importRewriteContext, TypeLocation.LOCAL_VARIABLE); + ImportRewrite importRewrite = proposal.createImportRewrite(astRoot); + ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(ASTResolving.findParentBodyDeclaration(selectedNode), importRewrite); + Type newType = importRewrite.addImport(expectedBinding, ast, importRewriteContext, TypeLocation.LOCAL_VARIABLE); rewrite.replace(parameter.getType(), newType, null); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); + return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); } - } diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/UnresolvedElementsSubProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/UnresolvedElementsSubProcessor.java index fe71134c0f..82df044d51 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/UnresolvedElementsSubProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/UnresolvedElementsSubProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -16,1829 +16,248 @@ *******************************************************************************/ package org.eclipse.jdt.ls.core.internal.corrections.proposals; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; -import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeRoot; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.Signature; -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTMatcher; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.Annotation; -import org.eclipse.jdt.core.dom.ArrayType; -import org.eclipse.jdt.core.dom.Assignment; -import org.eclipse.jdt.core.dom.BodyDeclaration; -import org.eclipse.jdt.core.dom.CastExpression; -import org.eclipse.jdt.core.dom.ClassInstanceCreation; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ConstructorInvocation; -import org.eclipse.jdt.core.dom.EnhancedForStatement; -import org.eclipse.jdt.core.dom.Expression; -import org.eclipse.jdt.core.dom.ExpressionMethodReference; -import org.eclipse.jdt.core.dom.FieldAccess; -import org.eclipse.jdt.core.dom.IBinding; -import org.eclipse.jdt.core.dom.IMethodBinding; -import org.eclipse.jdt.core.dom.IPackageBinding; -import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; -import org.eclipse.jdt.core.dom.MemberValuePair; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; -import org.eclipse.jdt.core.dom.NameQualifiedType; -import org.eclipse.jdt.core.dom.NodeFinder; -import org.eclipse.jdt.core.dom.NormalAnnotation; -import org.eclipse.jdt.core.dom.ParenthesizedExpression; -import org.eclipse.jdt.core.dom.QualifiedName; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.SimpleType; -import org.eclipse.jdt.core.dom.SingleMemberAnnotation; -import org.eclipse.jdt.core.dom.SingleVariableDeclaration; -import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; -import org.eclipse.jdt.core.dom.SuperConstructorInvocation; -import org.eclipse.jdt.core.dom.SuperFieldAccess; -import org.eclipse.jdt.core.dom.SuperMethodInvocation; -import org.eclipse.jdt.core.dom.SwitchCase; -import org.eclipse.jdt.core.dom.SwitchExpression; -import org.eclipse.jdt.core.dom.SwitchStatement; -import org.eclipse.jdt.core.dom.ThisExpression; -import org.eclipse.jdt.core.dom.ThrowStatement; -import org.eclipse.jdt.core.dom.Type; -import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; -import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; -import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; -import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; -import org.eclipse.jdt.core.manipulation.CodeStyleConfiguration; -import org.eclipse.jdt.core.manipulation.TypeKinds; -import org.eclipse.jdt.core.refactoring.CompilationUnitChange; -import org.eclipse.jdt.internal.core.manipulation.BindingLabelProviderCore; -import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; -import org.eclipse.jdt.internal.core.manipulation.StubUtility; -import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; -import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; -import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; -import org.eclipse.jdt.internal.corext.dom.ASTNodes; -import org.eclipse.jdt.internal.corext.dom.Bindings; -import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; -import org.eclipse.jdt.internal.corext.util.TypeFilter; +import org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore; import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; -import org.eclipse.jdt.internal.ui.text.correction.IProposalRelevance; -import org.eclipse.jdt.internal.ui.text.correction.NameMatcher; -import org.eclipse.jdt.internal.ui.text.correction.SimilarElement; -import org.eclipse.jdt.internal.ui.text.correction.SimilarElementsRequestor; +import org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor; +import org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor; +import org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor; import org.eclipse.jdt.internal.ui.text.correction.proposals.AddArgumentCorrectionProposalCore; +import org.eclipse.jdt.internal.ui.text.correction.proposals.AddModuleRequiresCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.AddTypeParameterProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.CastCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.ChangeDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.EditDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.InsertDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.RemoveDescription; -import org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore.SwapDescription; +import org.eclipse.jdt.internal.ui.text.correction.proposals.LinkedCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.NewAnnotationMemberProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.NewMethodCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.NewVariableCorrectionProposalCore; +import org.eclipse.jdt.internal.ui.text.correction.proposals.QualifyTypeProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.RenameNodeCorrectionProposalCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.ReplaceCorrectionProposalCore; -import org.eclipse.jdt.ls.core.internal.Messages; -import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages; import org.eclipse.jdt.ls.core.internal.corrections.ProposalKindWrapper; import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler; -import org.eclipse.jdt.ls.core.internal.preferences.PreferenceManager; import org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposalCore; import org.eclipse.lsp4j.CodeActionKind; -public class UnresolvedElementsSubProcessor { +public class UnresolvedElementsSubProcessor extends UnresolvedElementsBaseSubProcessor { public static void getVariableProposals(IInvocationContextCore context, IProblemLocationCore problem, IVariableBinding resolvedField, Collection proposals) throws CoreException { - - ICompilationUnit cu= context.getCompilationUnit(); - - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveredNode(astRoot); - if (selectedNode == null) { - return; - } - - // type that defines the variable - ITypeBinding binding= null; - ITypeBinding declaringTypeBinding= Bindings.getBindingOfParentTypeContext(selectedNode); - if (declaringTypeBinding == null) { - return; - } - - // possible type kind of the node - boolean suggestVariableProposals= true; - int typeKind= 0; - - while (selectedNode instanceof ParenthesizedExpression parenthesizedExpression) { - selectedNode = parenthesizedExpression.getExpression(); - } - - - Name node= null; - - switch (selectedNode.getNodeType()) { - case ASTNode.SIMPLE_NAME: - node= (SimpleName) selectedNode; - ASTNode parent= node.getParent(); - StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); - if (locationInParent == ExpressionMethodReference.EXPRESSION_PROPERTY) { - typeKind= TypeKinds.REF_TYPES; - } else if (locationInParent == MethodInvocation.EXPRESSION_PROPERTY) { - if (JavaModelUtil.is1d8OrHigher(cu.getJavaProject())) { - typeKind= TypeKinds.CLASSES | TypeKinds.INTERFACES | TypeKinds.ENUMS; - } else { - typeKind= TypeKinds.CLASSES; - } - } else if (locationInParent == FieldAccess.NAME_PROPERTY) { - Expression expression= ((FieldAccess) parent).getExpression(); - if (expression != null) { - binding= expression.resolveTypeBinding(); - if (binding == null) { - node= null; - } - } - } else if (parent instanceof SimpleType || parent instanceof NameQualifiedType) { - suggestVariableProposals= false; - typeKind= TypeKinds.REF_TYPES_AND_VAR; - } else if (parent instanceof QualifiedName name) { - Name qualifier = name.getQualifier(); - if (qualifier != node) { - binding= qualifier.resolveTypeBinding(); - } else { - typeKind= TypeKinds.REF_TYPES; - } - ASTNode outerParent= parent.getParent(); - while (outerParent instanceof QualifiedName) { - outerParent= outerParent.getParent(); - } - if (outerParent instanceof SimpleType || outerParent instanceof NameQualifiedType) { - typeKind= TypeKinds.REF_TYPES; - suggestVariableProposals= false; - } - - } else if (locationInParent == SwitchCase.EXPRESSION_PROPERTY || locationInParent == SwitchCase.EXPRESSIONS2_PROPERTY) { - ASTNode caseParent = node.getParent().getParent(); - ITypeBinding switchExp = null; - if (caseParent instanceof SwitchStatement switchStatement) { - switchExp = switchStatement.getExpression().resolveTypeBinding(); - } else if (caseParent instanceof SwitchExpression switchExpression) { - switchExp = switchExpression.getExpression().resolveTypeBinding(); - } - if (switchExp != null && switchExp.isEnum()) { - binding= switchExp; - } - } else if (locationInParent == SuperFieldAccess.NAME_PROPERTY) { - binding= declaringTypeBinding.getSuperclass(); - } - break; - case ASTNode.QUALIFIED_NAME: - QualifiedName qualifierName= (QualifiedName) selectedNode; - ITypeBinding qualifierBinding= qualifierName.getQualifier().resolveTypeBinding(); - if (qualifierBinding != null) { - node= qualifierName.getName(); - binding= qualifierBinding; - } else { - node= qualifierName.getQualifier(); - typeKind= TypeKinds.REF_TYPES; - suggestVariableProposals= node.isSimpleName(); - } - if (selectedNode.getParent() instanceof SimpleType || selectedNode.getParent() instanceof NameQualifiedType) { - typeKind= TypeKinds.REF_TYPES; - suggestVariableProposals= false; - } - break; - case ASTNode.FIELD_ACCESS: - FieldAccess access= (FieldAccess) selectedNode; - Expression expression= access.getExpression(); - if (expression != null) { - binding= expression.resolveTypeBinding(); - if (binding != null) { - node= access.getName(); - } - } - break; - case ASTNode.SUPER_FIELD_ACCESS: - binding= declaringTypeBinding.getSuperclass(); - node= ((SuperFieldAccess) selectedNode).getName(); - break; - default: - } - - if (node == null) { - return; - } - - // add type proposals - if (typeKind != 0) { - if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) { - typeKind &= ~(TypeKinds.ANNOTATIONS | TypeKinds.ENUMS | TypeKinds.VARIABLES); - } - - int relevance= Character.isUpperCase(ASTNodes.getSimpleNameIdentifier(node).charAt(0)) ? IProposalRelevance.VARIABLE_TYPE_PROPOSAL_1 : IProposalRelevance.VARIABLE_TYPE_PROPOSAL_2; - addSimilarTypeProposals(context, typeKind, cu, node, relevance + 1, proposals); - - typeKind &= ~TypeKinds.ANNOTATIONS; - addNewTypeProposals(cu, node, typeKind, relevance, proposals); - } - - if (!suggestVariableProposals) { - return; - } - - SimpleName simpleName= node.isSimpleName() ? (SimpleName) node : ((QualifiedName) node).getName(); - boolean isWriteAccess= ASTResolving.isWriteAccess(node); - - // similar variables - addSimilarVariableProposals(cu, astRoot, binding, resolvedField, simpleName, isWriteAccess, proposals); - - if (binding == null) { - addStaticImportFavoriteProposals(context, simpleName, false, proposals); - } - - if (resolvedField == null || binding == null || resolvedField.getDeclaringClass() != binding.getTypeDeclaration() && Modifier.isPrivate(resolvedField.getModifiers())) { - - // new fields - addNewFieldProposals(cu, astRoot, binding, declaringTypeBinding, simpleName, isWriteAccess, proposals); - - // new parameters and local variables - if (binding == null) { - addNewVariableProposals(cu, node, simpleName, proposals); - } - } - } - - private static void addNewVariableProposals(ICompilationUnit cu, Name node, SimpleName simpleName, - Collection proposals) { - String name= simpleName.getIdentifier(); - BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(node, true); - int type= bodyDeclaration.getNodeType(); - if (type == ASTNode.METHOD_DECLARATION) { - int relevance= StubUtility.hasParameterName(cu.getJavaProject(), name) ? IProposalRelevance.CREATE_PARAMETER_PREFIX_OR_SUFFIX_MATCH : IProposalRelevance.CREATE_PARAMETER; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createparameter_description, BasicElementLabels.getJavaElementName(name)); - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, cu, NewVariableCorrectionProposalCore.PARAM, simpleName, null, relevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - if (type == ASTNode.INITIALIZER || type == ASTNode.METHOD_DECLARATION && !ASTResolving.isInsideConstructorInvocation((MethodDeclaration) bodyDeclaration, node)) { - int relevance= StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? IProposalRelevance.CREATE_LOCAL_PREFIX_OR_SUFFIX_MATCH : IProposalRelevance.CREATE_LOCAL; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createlocal_description, BasicElementLabels.getJavaElementName(name)); - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, cu, NewVariableCorrectionProposalCore.LOCAL, simpleName, null, relevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - if (node.getParent().getNodeType() == ASTNode.ASSIGNMENT) { - Assignment assignment= (Assignment) node.getParent(); - if (assignment.getLeftHandSide() == node && assignment.getParent().getNodeType() == ASTNode.EXPRESSION_STATEMENT) { - ASTNode statement= assignment.getParent(); - ASTRewrite rewrite= ASTRewrite.create(statement.getAST()); - if (ASTNodes.isControlStatementBody(assignment.getParent().getLocationInParent())) { - rewrite.replace(statement, rewrite.getAST().newBlock(), null); - } else { - rewrite.remove(statement, null); - } - String label= CorrectionMessages.UnresolvedElementsSubProcessor_removestatement_description; - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, - IProposalRelevance.REMOVE_ASSIGNMENT); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - } - - private static void addNewFieldProposals(ICompilationUnit cu, CompilationUnit astRoot, ITypeBinding binding, - ITypeBinding declaringTypeBinding, SimpleName simpleName, boolean isWriteAccess, - Collection proposals) throws JavaModelException { - // new variables - ICompilationUnit targetCU; - ITypeBinding senderDeclBinding; - if (binding != null) { - senderDeclBinding= binding.getTypeDeclaration(); - targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, senderDeclBinding); - } else { // binding is null for accesses without qualifier - senderDeclBinding= declaringTypeBinding; - targetCU= cu; - } - - if (!senderDeclBinding.isFromSource() || targetCU == null) { - return; - } - - boolean mustBeConst= ASTResolving.isInsideModifiers(simpleName); - - addNewFieldForType(targetCU, binding, senderDeclBinding, simpleName, isWriteAccess, mustBeConst, proposals); - - if (binding == null && senderDeclBinding.isNested()) { - ASTNode anonymDecl= astRoot.findDeclaringNode(senderDeclBinding); - if (anonymDecl != null) { - ITypeBinding bind= Bindings.getBindingOfParentType(anonymDecl.getParent()); - if (!bind.isAnonymous()) { - addNewFieldForType(targetCU, bind, bind, simpleName, isWriteAccess, mustBeConst, proposals); - } - } - } - } - - private static void addNewFieldForType(ICompilationUnit targetCU, ITypeBinding binding, - ITypeBinding senderDeclBinding, SimpleName simpleName, boolean isWriteAccess, boolean mustBeConst, - Collection proposals) { - String name= simpleName.getIdentifier(); - String nameLabel= BasicElementLabels.getJavaElementName(name); - String label; - if (senderDeclBinding.isEnum() && !isWriteAccess) { - label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createenum_description, - new Object[] { nameLabel, ASTResolving.getTypeSignature(senderDeclBinding) }); - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, targetCU, NewVariableCorrectionProposalCore.ENUM_CONST, simpleName, senderDeclBinding, 10); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } else { - if (!mustBeConst) { - if (binding == null) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createfield_description, nameLabel); - } else { - label = Messages.format( - CorrectionMessages.UnresolvedElementsSubProcessor_createfield_other_description, - new Object[] { nameLabel, ASTResolving.getTypeSignature(senderDeclBinding) }); - } - int fieldRelevance= StubUtility.hasFieldName(targetCU.getJavaProject(), name) ? IProposalRelevance.CREATE_FIELD_PREFIX_OR_SUFFIX_MATCH : IProposalRelevance.CREATE_FIELD; - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, targetCU, NewVariableCorrectionProposalCore.FIELD, simpleName, senderDeclBinding, fieldRelevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - if (!isWriteAccess && !senderDeclBinding.isAnonymous()) { - if (binding == null) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createconst_description, nameLabel); - } else { - label = Messages.format( - CorrectionMessages.UnresolvedElementsSubProcessor_createconst_other_description, - new Object[] { nameLabel, ASTResolving.getTypeSignature(senderDeclBinding) }); - } - int constRelevance= StubUtility.hasConstantName(targetCU.getJavaProject(), name) ? IProposalRelevance.CREATE_CONSTANT_PREFIX_OR_SUFFIX_MATCH : IProposalRelevance.CREATE_CONSTANT; - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, targetCU, NewVariableCorrectionProposalCore.CONST_FIELD, simpleName, senderDeclBinding, constRelevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - } - - private static void addSimilarVariableProposals(ICompilationUnit cu, CompilationUnit astRoot, ITypeBinding binding, - IVariableBinding resolvedField, SimpleName node, boolean isWriteAccess, - Collection proposals) { - int kind= ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY; - if (!isWriteAccess) { - kind |= ScopeAnalyzer.METHODS; // also try to find similar methods - } - - IBinding[] varsAndMethodsInScope= (new ScopeAnalyzer(astRoot)).getDeclarationsInScope(node, kind); - if (varsAndMethodsInScope.length > 0) { - // avoid corrections like int i= i; - String otherNameInAssign= null; - - // help with x.getString() -> y.getString() - String methodSenderName= null; - String fieldSenderName= null; - - ASTNode parent= node.getParent(); - switch (parent.getNodeType()) { - case ASTNode.VARIABLE_DECLARATION_FRAGMENT: - // node must be initializer - otherNameInAssign= ((VariableDeclarationFragment) parent).getName().getIdentifier(); - break; - case ASTNode.ASSIGNMENT: - Assignment assignment= (Assignment) parent; - if (isWriteAccess && assignment.getRightHandSide() instanceof SimpleName name) { - otherNameInAssign = name.getIdentifier(); - } else if (!isWriteAccess && assignment.getLeftHandSide() instanceof SimpleName name) { - otherNameInAssign = name.getIdentifier(); - } - break; - case ASTNode.METHOD_INVOCATION: - MethodInvocation inv= (MethodInvocation) parent; - if (inv.getExpression() == node) { - methodSenderName= inv.getName().getIdentifier(); - } - break; - case ASTNode.QUALIFIED_NAME: - QualifiedName qualName= (QualifiedName) parent; - if (qualName.getQualifier() == node) { - fieldSenderName= qualName.getName().getIdentifier(); - } - break; - } - - - ITypeBinding guessedType= ASTResolving.guessBindingForReference(node); - - ITypeBinding objectBinding= astRoot.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - String identifier= node.getIdentifier(); - boolean isInStaticContext= ASTResolving.isInStaticContext(node); - ArrayList newProposals = new ArrayList<>(51); - - loop: for (int i= 0; i < varsAndMethodsInScope.length && newProposals.size() <= 50; i++) { - IBinding varOrMeth= varsAndMethodsInScope[i]; - if (varOrMeth instanceof IVariableBinding curr) { - String currName= curr.getName(); - if (currName.equals(otherNameInAssign)) { - continue loop; - } - if (resolvedField != null && Bindings.equals(resolvedField, curr)) { - continue loop; - } - boolean isFinal= Modifier.isFinal(curr.getModifiers()); - if (isFinal && curr.isField() && isWriteAccess) { - continue loop; - } - if (isInStaticContext && !Modifier.isStatic(curr.getModifiers()) && curr.isField()) { - continue loop; - } - - int relevance= IProposalRelevance.SIMILAR_VARIABLE_PROPOSAL; - if (NameMatcher.isSimilarName(currName, identifier)) { - relevance += 3; // variable with a similar name than the unresolved variable - } - if (currName.equalsIgnoreCase(identifier)) { - relevance+= 5; - } - ITypeBinding varType= curr.getType(); - if (varType != null) { - if (guessedType != null && guessedType != objectBinding) { // too many result with object - // variable type is compatible with the guessed type - if (!isWriteAccess && canAssign(varType, guessedType) - || isWriteAccess && canAssign(guessedType, varType)) { - relevance += 2; // unresolved variable can be assign to this variable - } - } - if (methodSenderName != null && hasMethodWithName(varType, methodSenderName)) { - relevance += 2; - } - if (fieldSenderName != null && hasFieldWithName(varType, fieldSenderName)) { - relevance += 2; - } - } - - if (relevance > 0) { - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changevariable_description, BasicElementLabels.getJavaElementName(currName)); - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, cu, node.getStartPosition(), node.getLength(), currName, relevance); - newProposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } else if (varOrMeth instanceof IMethodBinding curr) { - if (!curr.isConstructor() && guessedType != null && canAssign(curr.getReturnType(), guessedType)) { - if (NameMatcher.isSimilarName(curr.getName(), identifier)) { - AST ast= astRoot.getAST(); - ASTRewrite rewrite= ASTRewrite.create(ast); - String label = Messages.format( - CorrectionMessages.UnresolvedElementsSubProcessor_changetomethod_description, - ASTResolving.getMethodSignature(curr)); - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, - IProposalRelevance.CHANGE_TO_METHOD); - newProposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - - MethodInvocation newInv= ast.newMethodInvocation(); - newInv.setName(ast.newSimpleName(curr.getName())); - ITypeBinding[] parameterTypes= curr.getParameterTypes(); - for (int k= 0; k < parameterTypes.length; k++) { - ASTNode arg= ASTNodeFactory.newDefaultExpression(ast, parameterTypes[k]); - newInv.arguments().add(arg); - } - rewrite.replace(node, newInv, null); - } - } - } - } - if (newProposals.size() <= 50) { - proposals.addAll(newProposals); - } - } - if (binding != null && binding.isArray()) { - String idLength= "length"; //$NON-NLS-1$ - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changevariable_description, idLength); - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, cu, node.getStartPosition(), node.getLength(), idLength, IProposalRelevance.CHANGE_VARIABLE); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - - private static boolean canAssign(ITypeBinding returnType, ITypeBinding guessedType) { - return returnType.isAssignmentCompatible(guessedType); - } - - private static boolean hasMethodWithName(ITypeBinding typeBinding, String name) { - IVariableBinding[] fields= typeBinding.getDeclaredFields(); - for (int i= 0; i < fields.length; i++) { - if (fields[i].getName().equals(name)) { - return true; - } - } - ITypeBinding superclass= typeBinding.getSuperclass(); - if (superclass != null) { - return hasMethodWithName(superclass, name); - } - return false; + new UnresolvedElementsSubProcessor().collectVariableProposals(context, problem, resolvedField, proposals); } - private static boolean hasFieldWithName(ITypeBinding typeBinding, String name) { - IMethodBinding[] methods= typeBinding.getDeclaredMethods(); - for (int i= 0; i < methods.length; i++) { - if (methods[i].getName().equals(name)) { - return true; - } - } - ITypeBinding superclass= typeBinding.getSuperclass(); - if (superclass != null) { - return hasMethodWithName(superclass, name); - } - return false; - } - - private static int evauateTypeKind(ASTNode node, IJavaProject project) { - int kind = ASTResolving.getPossibleTypeKinds(node, JavaModelUtil.is50OrHigher(project)); - return kind; - } - - public static void getTypeProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) throws CoreException { - ICompilationUnit cu= context.getCompilationUnit(); - ASTNode selectedNode; - if (problem.getProblemId() == IProblem.UndefinedType && cu.getBuffer() != null && cu.getBuffer().getChar(problem.getOffset()) == '@') { - int offset = problem.getOffset() + 1; - int length = problem.getLength() - 1; - while (offset < cu.getBuffer().getLength() && length >= 0 && Character.isWhitespace(cu.getBuffer().getChar(offset))) { - offset++; - length--; - } - NodeFinder finder = new NodeFinder(context.getASTRoot(), offset, length); - selectedNode = finder.getCoveringNode(); - } else { - selectedNode = problem.getCoveringNode(context.getASTRoot()); - } - if (selectedNode == null) { - return; - } - - int kind= evauateTypeKind(selectedNode, cu.getJavaProject()); - - if (kind == TypeKinds.REF_TYPES) { - addEnhancedForWithoutTypeProposals(cu, selectedNode, proposals); - } - - while (selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) { - selectedNode= selectedNode.getParent(); - } - - Name node= null; - if (selectedNode instanceof Annotation annotation) { - selectedNode = annotation.getTypeName(); - } - if (selectedNode instanceof SimpleType simpleType) { - node = simpleType.getName(); - } else if (selectedNode instanceof NameQualifiedType type) { - node = type.getName(); - } else if (selectedNode instanceof ArrayType type) { - Type elementType = type.getElementType(); - if (elementType.isSimpleType()) { - node= ((SimpleType) elementType).getName(); - } else if (elementType.isNameQualifiedType()) { - node= ((NameQualifiedType) elementType).getName(); - } else { - return; - } - } else if (selectedNode instanceof Name name) { - node = name; - } else { - return; - } - - // change to similar type proposals - addSimilarTypeProposals(context, kind, cu, node, IProposalRelevance.SIMILAR_TYPE, proposals); - - while (node.getParent() instanceof QualifiedName parentName) { - node = parentName; - } - - if (selectedNode != node) { - kind= evauateTypeKind(node, cu.getJavaProject()); - } - if ((kind & (TypeKinds.CLASSES | TypeKinds.INTERFACES)) != 0) { - kind &= ~TypeKinds.ANNOTATIONS; // only propose annotations when there are no other suggestions - } - addNewTypeProposals(cu, node, kind, IProposalRelevance.NEW_TYPE, proposals); + new UnresolvedElementsSubProcessor().collectTypeProposals(context, problem, proposals); } - private static void addEnhancedForWithoutTypeProposals(ICompilationUnit cu, ASTNode selectedNode, - Collection proposals) { - if (selectedNode instanceof SimpleName 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) { - 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)); - - NewVariableCorrectionProposalCore proposal = new NewVariableCorrectionProposalCore(label, cu, NewVariableCorrectionProposalCore.LOCAL, simpleName, null, relevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - } - } - } - - static CompilationUnitChange createAddImportChange(ICompilationUnit cu, Name name, String fullyQualifiedName) throws CoreException { - String[] args= { BasicElementLabels.getJavaElementName(Signature.getSimpleName(fullyQualifiedName)), - BasicElementLabels.getJavaElementName(Signature.getQualifier(fullyQualifiedName)) }; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_importtype_description, args); - - CompilationUnitChange cuChange= new CompilationUnitChange(label, cu); - ImportRewrite importRewrite = CodeStyleConfiguration.createImportRewrite((CompilationUnit) name.getRoot(), true); - importRewrite.addImport(fullyQualifiedName); - cuChange.setEdit(importRewrite.rewriteImports(null)); - return cuChange; - } - - private static void addSimilarTypeProposals(IInvocationContextCore context, int kind, ICompilationUnit cu, Name node, int relevance, + public static void addNewTypeProposals(ICompilationUnit cu, Name refNode, int kind, int relevance, Collection 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(); - ProposalKindWrapper proposal = createTypeRefChangeProposal(cu, resolvedTypeName, node, relevance + 2, elements.length); - proposals.add(proposal); - if (proposal.getProposal() instanceof AddImportCorrectionProposal) { - proposal.getProposal().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() & TypeKinds.ALL_TYPES) != 0) { - String fullName= elem.getName(); - if (!fullName.equals(resolvedTypeName)) { - proposals.add(createTypeRefChangeProposal(cu, fullName, node, relevance, elements.length)); - } - } - } - } - - private static ProposalKindWrapper createTypeRefChangeProposal(ICompilationUnit cu, String fullName, Name node, int relevance, int maxProposals) { - ImportRewrite importRewrite= null; - String simpleName= fullName; - String packName= Signature.getQualifier(fullName); - if (packName.length() > 0) { // no imports for primitive types, type variables - importRewrite = CodeStyleConfiguration.createImportRewrite((CompilationUnit) node.getRoot(), true); - BodyDeclaration scope= ASTResolving.findParentBodyDeclaration(node); // can be null in package-info.java - ImportRewriteContext context= new ContextSensitiveImportRewriteContext(scope != null ? scope : node, importRewrite); - simpleName= importRewrite.addImport(fullName, context); - } - - if (!isLikelyTypeName(simpleName)) { - relevance -= 2; - } - - ASTRewriteCorrectionProposalCore proposal; - if (importRewrite != null && node.isSimpleName() && simpleName.equals(((SimpleName) node).getIdentifier())) { // import only - // import only - String[] arg= { BasicElementLabels.getJavaElementName(simpleName), BasicElementLabels.getJavaElementName(packName) }; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_importtype_description, arg); - proposal = new AddImportCorrectionProposal(label, cu, relevance + 100, packName, simpleName, - (SimpleName) node); - } else { - String label; - if (packName.length() == 0) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetype_nopack_description, BasicElementLabels.getJavaElementName(simpleName)); - } else { - String[] arg= { BasicElementLabels.getJavaElementName(simpleName), BasicElementLabels.getJavaElementName(packName) }; - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetype_description, arg); - } - ASTRewrite rewrite= ASTRewrite.create(node.getAST()); - rewrite.replace(node, rewrite.createStringPlaceholder(simpleName, ASTNode.SIMPLE_TYPE), null); - proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, relevance); - } - if (importRewrite != null) { - proposal.setImportRewrite(importRewrite); - } - return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); + new UnresolvedElementsSubProcessor().collectNewTypeProposals(cu, refNode, kind, relevance, null); } - static ProposalKindWrapper createTypeRefChangeFullProposal(ICompilationUnit cu, ITypeBinding binding, ASTNode node, int relevance) { - ASTRewrite rewrite= ASTRewrite.create(node.getAST()); - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_change_full_type_description, BindingLabelProviderCore.getBindingLabel(binding, JavaElementLabelsCore.ALL_DEFAULT)); - - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, relevance); - - ImportRewrite imports= proposal.createImportRewrite((CompilationUnit) node.getRoot()); - Type type= imports.addImport(binding, node.getAST()); - - rewrite.replace(node, type, null); - return CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix); - } - - private static boolean isLikelyTypeName(String name) { - return name.length() > 0 && Character.isUpperCase(name.charAt(0)); + public static void getMethodProposals(IInvocationContextCore context, IProblemLocationCore problem, + boolean isOnlyParameterMismatch, Collection proposals) throws CoreException { + new UnresolvedElementsSubProcessor().collectMethodProposals(context, problem, isOnlyParameterMismatch, proposals); } - private static boolean isLikelyPackageName(String name) { - if (name.length() != 0) { - int i= 0; - do { - if (Character.isUpperCase(name.charAt(i))) { - return false; - } - i= name.indexOf('.', i) + 1; - } while (i != 0 && i < name.length()); - } - return true; + public static void getConstructorProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) throws CoreException { + new UnresolvedElementsSubProcessor().collectConstructorProposals(context, problem, proposals); } - private static boolean isLikelyTypeParameterName(String name) { - return name.length() == 1 && Character.isUpperCase(name.charAt(0)); + public static void getAmbiguousTypeReferenceProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) throws CoreException { + new UnresolvedElementsSubProcessor().collectAmbiguosTypeReferenceProposals(context, problem, proposals); } - private static boolean isLikelyMethodTypeParameterName(String name) { - if (name.length() == 1) { - switch (name.charAt(0)) { - case 'S': - case 'T': - case 'U': - return true; - } - } - return false; + public static void getArrayAccessProposals(IInvocationContextCore context, IProblemLocationCore problem, + Collection proposals) { + new UnresolvedElementsSubProcessor().collectArrayAccessProposals(context, problem, proposals); } - public static void addNewTypeProposals(ICompilationUnit cu, Name refNode, int kind, int relevance, + public static void getAnnotationMemberProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) throws CoreException { - Name node= refNode; - do { - String typeName = ASTNodes.getSimpleNameIdentifier(node); - Name qualifier = null; - // only propose to create types for qualifiers when the name starts with upper case - boolean isPossibleName = isLikelyTypeName(typeName) || node == refNode; - if (isPossibleName) { - IPackageFragment enclosingPackage = null; - IType enclosingType = null; - if (node.isSimpleName()) { - enclosingPackage = (IPackageFragment) cu.getParent(); - // don't suggest member type, user can select it in wizard - } else { - Name qualifierName = ((QualifiedName) node).getQualifier(); - IBinding binding = qualifierName.resolveBinding(); - if (binding != null && binding.isRecovered()) { - binding = null; - } - if (binding instanceof ITypeBinding typeBinding) { - enclosingType = (IType) typeBinding.getJavaElement(); - } else if (binding instanceof IPackageBinding packageBinding) { - qualifier = qualifierName; - enclosingPackage = (IPackageFragment) packageBinding.getJavaElement(); - } else { - IJavaElement[] res = cu.codeSelect(qualifierName.getStartPosition(), qualifierName.getLength()); - if (res != null && res.length > 0 && res[0] instanceof IType type) { - enclosingType = type; - } else { - qualifier = qualifierName; - enclosingPackage = JavaModelUtil.getPackageFragmentRoot(cu).getPackageFragment(ASTResolving.getFullName(qualifierName)); - } - } - } - int rel = relevance; - if (enclosingPackage != null && isLikelyPackageName(enclosingPackage.getElementName())) { - rel += 3; - } - - if (enclosingPackage != null && !enclosingPackage.getCompilationUnit(typeName + JavaModelUtil.DEFAULT_CU_SUFFIX).exists() - || enclosingType != null && !enclosingType.isReadOnly() && !enclosingType.getType(typeName).exists()) { // new member type - IJavaElement enclosing = enclosingPackage != null ? (IJavaElement) enclosingPackage : enclosingType; - - if ((kind & TypeKinds.CLASSES) != 0) { - NewCUProposal proposal = new NewCUProposal(cu, node, NewCUProposal.K_CLASS, enclosing, rel + 3); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - if ((kind & TypeKinds.INTERFACES) != 0) { - NewCUProposal proposal = new NewCUProposal(cu, node, NewCUProposal.K_INTERFACE, enclosing, rel + 3); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - if ((kind & TypeKinds.ENUMS) != 0) { - NewCUProposal proposal = new NewCUProposal(cu, node, NewCUProposal.K_ENUM, enclosing, rel + 3); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - if ((kind & TypeKinds.ANNOTATIONS) != 0) { - NewCUProposal proposal = new NewCUProposal(cu, node, NewCUProposal.K_ANNOTATION, enclosing, rel + 3); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - // TODO: addNullityAnnotationTypesProposals(cu, node, proposals); - } - } - } - node = qualifier; - } while (node != null); - - // type parameter proposals - if (refNode.isSimpleName() && (kind & TypeKinds.VARIABLES) != 0) { - CompilationUnit root= (CompilationUnit) refNode.getRoot(); - String name= ((SimpleName) refNode).getIdentifier(); - BodyDeclaration declaration= ASTResolving.findParentBodyDeclaration(refNode); - int baseRel= relevance; - if (isLikelyTypeParameterName(name)) { - baseRel += 8; - } - while (declaration != null) { - IBinding binding= null; - int rel= baseRel; - if (declaration instanceof MethodDeclaration methodDeclaration) { - binding = methodDeclaration.resolveBinding(); - if (isLikelyMethodTypeParameterName(name)) { - rel+= 2; - } - } else if (declaration instanceof TypeDeclaration typeDeclaration) { - binding = typeDeclaration.resolveBinding(); - rel++; - } - if (binding != null) { - AddTypeParameterProposalCore proposal = new AddTypeParameterProposalCore(cu, binding, root, name, null, rel); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - if (!Modifier.isStatic(declaration.getModifiers())) { - declaration= ASTResolving.findParentBodyDeclaration(declaration.getParent()); - } else { - declaration= null; - } - } - } + new UnresolvedElementsSubProcessor().collectAnnotationMemberProposals(context, problem, proposals); } - public static void getMethodProposals(IInvocationContextCore context, IProblemLocationCore problem, - boolean isOnlyParameterMismatch, Collection proposals) throws CoreException { - - ICompilationUnit cu= context.getCompilationUnit(); - - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - - if (!(selectedNode instanceof SimpleName)) { - return; - } - SimpleName nameNode= (SimpleName) selectedNode; - - List arguments; - Expression sender; - boolean isSuperInvocation; - - ASTNode invocationNode= nameNode.getParent(); - if (invocationNode instanceof MethodInvocation methodImpl) { - arguments= methodImpl.arguments(); - sender= methodImpl.getExpression(); - isSuperInvocation= false; - } else if (invocationNode instanceof SuperMethodInvocation methodImpl) { - arguments= methodImpl.arguments(); - sender= methodImpl.getQualifier(); - isSuperInvocation= true; - } else { - return; - } - - String methodName= nameNode.getIdentifier(); - int nArguments= arguments.size(); - - // corrections - IBinding[] bindings= (new ScopeAnalyzer(astRoot)).getDeclarationsInScope(nameNode, ScopeAnalyzer.METHODS); - - HashSet suggestedRenames= new HashSet<>(); - for (int i= 0; i < bindings.length; i++) { - IMethodBinding binding= (IMethodBinding) bindings[i]; - String curr= binding.getName(); - if (!curr.equals(methodName) && binding.getParameterTypes().length == nArguments && NameMatcher.isSimilarName(methodName, curr) && suggestedRenames.add(curr)) { - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changemethod_description, BasicElementLabels.getJavaElementName(curr)); - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, context.getCompilationUnit(), problem.getOffset(), problem.getLength(), curr, IProposalRelevance.CHANGE_METHOD); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - suggestedRenames= null; - - if (isOnlyParameterMismatch) { - ArrayList parameterMismatchs= new ArrayList<>(); - for (int i= 0; i < bindings.length; i++) { - IMethodBinding binding= (IMethodBinding) bindings[i]; - if (binding.getName().equals(methodName)) { - parameterMismatchs.add(binding); - } - } - addParameterMissmatchProposals(context, problem, parameterMismatchs, invocationNode, arguments, proposals); - } - - if (sender == null) { - addStaticImportFavoriteProposals(context, nameNode, true, proposals); - } - - // new method - addNewMethodProposals(cu, astRoot, sender, arguments, isSuperInvocation, invocationNode, methodName, proposals); - - if (!isOnlyParameterMismatch && !isSuperInvocation && sender != null) { - addMissingCastParentsProposal(cu, (MethodInvocation) invocationNode, proposals); - } - - if (!isSuperInvocation && sender == null && invocationNode.getParent() instanceof ThrowStatement) { - String str= "new "; //$NON-NLS-1$ // do it the manual way, copting all the arguments is nasty - String label= CorrectionMessages.UnresolvedElementsSubProcessor_addnewkeyword_description; - int relevance= Character.isUpperCase(methodName.charAt(0)) ? IProposalRelevance.ADD_NEW_KEYWORD_UPPERCASE : IProposalRelevance.ADD_NEW_KEYWORD; - ReplaceCorrectionProposalCore proposal = new ReplaceCorrectionProposalCore(label, cu, invocationNode.getStartPosition(), 0, str, relevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#addNewTypeProposalsInteractiveInnerLoop(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.Name, org.eclipse.jdt.core.IJavaElement, int, int, org.eclipse.jdt.core.dom.Name, java.util.Collection) + */ + @Override + protected void addNewTypeProposalsInteractiveInnerLoop(ICompilationUnit cu, Name node, IJavaElement enclosing, int rel, int kind, Name refNode, Collection proposals) throws CoreException { + // TODO not yet implemented, UI version uses a wizard } - private static void addStaticImportFavoriteProposals(IInvocationContextCore context, SimpleName node, boolean isMethod, - Collection proposals) throws JavaModelException { - IJavaProject project= context.getCompilationUnit().getJavaProject(); - if (JavaModelUtil.is50OrHigher(project)) { - String[] favourites = PreferenceManager.getPrefs(context.getCompilationUnit().getResource()) - .getJavaCompletionFavoriteMembers(); - if (favourites.length == 0) { - return; - } - - CompilationUnit root= context.getASTRoot(); - AST ast= root.getAST(); - - String name= node.getIdentifier(); - String[] staticImports= JavaModelUtil.getStaticImportFavorites(context.getCompilationUnit(), name, isMethod, favourites); - for (int i= 0; i < staticImports.length; i++) { - String curr= staticImports[i]; - - ImportRewrite importRewrite = CodeStyleConfiguration.createImportRewrite(root, true); - ASTRewrite astRewrite= ASTRewrite.create(ast); - - String label; - String qualifiedTypeName= Signature.getQualifier(curr); - String elementLabel= BasicElementLabels.getJavaElementName(JavaModelUtil.concatenateName(Signature.getSimpleName(qualifiedTypeName), name)); - - String res= importRewrite.addStaticImport(qualifiedTypeName, name, isMethod, new ContextSensitiveImportRewriteContext(root, node.getStartPosition(), importRewrite)); - int dot= res.lastIndexOf('.'); - if (dot != -1) { - String usedTypeName= importRewrite.addImport(qualifiedTypeName); - Name newName= ast.newQualifiedName(ast.newName(usedTypeName), ast.newSimpleName(name)); - astRewrite.replace(node, newName, null); - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_change_to_static_import_description, elementLabel); - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_add_static_import_description, elementLabel); - } - - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, - context.getCompilationUnit(), astRewrite, IProposalRelevance.ADD_STATIC_IMPORT); - proposal.setImportRewrite(importRewrite); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#getReorgSubProcessor() + */ + @Override + protected ReorgCorrectionsBaseSubProcessor getReorgSubProcessor() { + return new ReorgCorrectionsSubProcessor(); } - - private static void addNewMethodProposals(ICompilationUnit cu, CompilationUnit astRoot, Expression sender, - List arguments, boolean isSuperInvocation, ASTNode invocationNode, String methodName, - Collection proposals) throws JavaModelException { - ITypeBinding nodeParentType= Bindings.getBindingOfParentType(invocationNode); - ITypeBinding binding= null; - if (sender != null) { - binding= sender.resolveTypeBinding(); - } else { - binding= nodeParentType; - if (isSuperInvocation && binding != null) { - binding= binding.getSuperclass(); - } - } - if (binding != null && binding.isFromSource()) { - ITypeBinding senderDeclBinding= binding.getTypeDeclaration(); - - ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, senderDeclBinding); - if (targetCU != null) { - String label; - ITypeBinding[] parameterTypes= getParameterTypes(arguments); - if (parameterTypes != null) { - String sig = ASTResolving.getMethodSignature(methodName, parameterTypes, false); - boolean is1d8OrHigher= JavaModelUtil.is1d8OrHigher(targetCU.getJavaProject()); - - boolean isSenderBindingInterface= senderDeclBinding.isInterface(); - if (nodeParentType == senderDeclBinding) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_description, sig); - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_other_description, new Object[] { sig, BasicElementLabels.getJavaElementName(senderDeclBinding.getName()) } ); - } - if (is1d8OrHigher || !isSenderBindingInterface - || (nodeParentType != senderDeclBinding && (!(sender instanceof SimpleName) || !((SimpleName) sender).getIdentifier().equals(senderDeclBinding.getName())))) { - NewMethodCorrectionProposalCore proposal = new NewMethodCorrectionProposalCore(label, targetCU, invocationNode, arguments, senderDeclBinding, IProposalRelevance.CREATE_METHOD); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - if (senderDeclBinding.isNested() && cu.equals(targetCU) && sender == null && Bindings.findMethodInHierarchy(senderDeclBinding, methodName, (ITypeBinding[]) null) == null) { // no covering method - ASTNode anonymDecl= astRoot.findDeclaringNode(senderDeclBinding); - if (anonymDecl != null) { - senderDeclBinding= Bindings.getBindingOfParentType(anonymDecl.getParent()); - isSenderBindingInterface= senderDeclBinding.isInterface(); - if (!senderDeclBinding.isAnonymous()) { - if (is1d8OrHigher || !isSenderBindingInterface) { - String[] args = new String[] { sig, - ASTResolving.getTypeSignature(senderDeclBinding) }; - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_other_description, args); - NewMethodCorrectionProposalCore proposal = new NewMethodCorrectionProposalCore(label, targetCU, invocationNode, arguments, senderDeclBinding, IProposalRelevance.CREATE_METHOD); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - } - } - } - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#getTypeMismatchSubProcessor() + */ + @Override + protected TypeMismatchBaseSubProcessor getTypeMismatchSubProcessor() { + // TODO Not yet implemented + return null; } - private static void addMissingCastParentsProposal(ICompilationUnit cu, MethodInvocation invocationNode, - Collection proposals) { - Expression sender= invocationNode.getExpression(); - if (sender instanceof ThisExpression) { - return; - } - - ITypeBinding senderBinding= sender.resolveTypeBinding(); - if (senderBinding == null || Modifier.isFinal(senderBinding.getModifiers())) { - return; - } - - if (sender instanceof Name name && name.resolveBinding() instanceof ITypeBinding) { - return; // static access - } - - ASTNode parent= invocationNode.getParent(); - while (parent instanceof Expression && parent.getNodeType() != ASTNode.CAST_EXPRESSION) { - parent= parent.getParent(); - } - boolean hasCastProposal= false; - if (parent instanceof CastExpression castExpression) { - // (TestCase) x.getName() -> ((TestCase) x).getName - hasCastProposal = useExistingParentCastProposal(cu, castExpression, sender, invocationNode.getName(), getArgumentTypes(invocationNode.arguments()), proposals); - } - if (!hasCastProposal) { - // x.getName() -> ((TestCase) x).getName - - Expression target= sender; - while (target instanceof ParenthesizedExpression parenthesizedExpression) { - target = parenthesizedExpression.getExpression(); - } - - String label; - if (target.getNodeType() != ASTNode.CAST_EXPRESSION) { - String targetName= null; - if (target.getLength() <= 18) { - targetName= ASTNodes.asString(target); - } - if (targetName == null) { - label= CorrectionMessages.UnresolvedElementsSubProcessor_methodtargetcast_description; - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_methodtargetcast2_description, BasicElementLabels.getJavaCodeString(targetName)); - } - } else { - String targetName= null; - if (target.getLength() <= 18) { - targetName= ASTNodes.asString(((CastExpression)target).getExpression()); - } - if (targetName == null) { - label= CorrectionMessages.UnresolvedElementsSubProcessor_changemethodtargetcast_description; - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changemethodtargetcast2_description, BasicElementLabels.getJavaCodeString(targetName)); - } - } - CastCorrectionProposalCore proposal = new CastCorrectionProposalCore(label, cu, target, (ITypeBinding) null, IProposalRelevance.CHANGE_CAST); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#getOriginalProposalFromT(java.lang.Object) + */ + @Override + protected ChangeCorrectionProposalCore getOriginalProposalFromT(ProposalKindWrapper proposal) { + return proposal.getProposal(); } - private static boolean useExistingParentCastProposal(ICompilationUnit cu, CastExpression expression, - Expression accessExpression, SimpleName accessSelector, ITypeBinding[] paramTypes, - Collection proposals) { - ITypeBinding castType= expression.getType().resolveBinding(); - if (castType == null) { - return false; - } - if (paramTypes != null) { - if (Bindings.findMethodInHierarchy(castType, accessSelector.getIdentifier(), paramTypes) == null) { - return false; - } - } else if (Bindings.findFieldInHierarchy(castType, accessSelector.getIdentifier()) == null) { - return false; - } - ITypeBinding bindingToCast= accessExpression.resolveTypeBinding(); - if (bindingToCast != null && !bindingToCast.isCastCompatible(castType)) { - return false; - } - - IMethodBinding res= Bindings.findMethodInHierarchy(castType, accessSelector.getIdentifier(), paramTypes); - if (res != null) { - AST ast= expression.getAST(); - ASTRewrite rewrite= ASTRewrite.create(ast); - CastExpression newCast= ast.newCastExpression(); - newCast.setType((Type) ASTNode.copySubtree(ast, expression.getType())); - newCast.setExpression((Expression) rewrite.createCopyTarget(accessExpression)); - ParenthesizedExpression parents= ast.newParenthesizedExpression(); - parents.setExpression(newCast); - - ASTNode node= rewrite.createCopyTarget(expression.getExpression()); - rewrite.replace(expression, node, null); - rewrite.replace(accessExpression, parents, null); - - String label= CorrectionMessages.UnresolvedElementsSubProcessor_missingcastbrackets_description; - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, - IProposalRelevance.ADD_PARENTHESES_AROUND_CAST); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - return true; - } - return false; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#newVariableCorrectionProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.NewVariableCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper newVariableCorrectionProposalToT(NewVariableCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static void addParameterMissmatchProposals(IInvocationContextCore context, IProblemLocationCore problem, - List similarElements, ASTNode invocationNode, List arguments, - Collection proposals) throws CoreException { - int nSimilarElements= similarElements.size(); - ITypeBinding[] argTypes= getArgumentTypes(arguments); - if (argTypes == null || nSimilarElements == 0) { - return; - } - - for (int i= 0; i < nSimilarElements; i++) { - IMethodBinding elem = similarElements.get(i); - int diff= elem.getParameterTypes().length - argTypes.length; - if (diff == 0) { - int nProposals= proposals.size(); - doEqualNumberOfParameters(context, invocationNode, problem, arguments, argTypes, elem, proposals); - if (nProposals != proposals.size()) { - return; // only suggest for one method (avoid duplicated proposals) - } - } else if (diff > 0) { - doMoreParameters(context, invocationNode, argTypes, elem, proposals); - } else { - doMoreArguments(context, invocationNode, arguments, argTypes, elem, proposals); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#renameNodeCorrectionProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.RenameNodeCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper renameNodeCorrectionProposalToT(RenameNodeCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static void doMoreParameters(IInvocationContextCore context, ASTNode invocationNode, ITypeBinding[] argTypes, - IMethodBinding methodBinding, Collection 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])) { - k++; // match - } else { - if (nSkipped >= diff) { - return; // too different - } - indexSkipped[nSkipped++]= i; - } - } - ITypeBinding declaringType= methodBinding.getDeclaringClass(); - ICompilationUnit cu= context.getCompilationUnit(); - CompilationUnit astRoot= context.getASTRoot(); - - // add arguments - { - String[] arg = new String[] { 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); - } - AddArgumentCorrectionProposalCore proposal = new AddArgumentCorrectionProposalCore(label, context.getCompilationUnit(), invocationNode, indexSkipped, paramTypes, IProposalRelevance.ADD_ARGUMENTS); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - // 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[] { 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); - } - } - - ChangeMethodSignatureProposalCore proposal = new ChangeMethodSignatureProposalCore(label, targetCU, invocationNode, - methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_REMOVE_PARAMETER); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#compositeProposalToT(org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper compositeProposalToT(ChangeCorrectionProposalCore compositeProposal, int uid) { + return CodeActionHandler.wrap(compositeProposal, CodeActionKind.QuickFix); } - private static String getTypeNames(ITypeBinding[] types) { - StringBuffer buf= new StringBuffer(); - for (int i= 0; i < types.length; i++) { - if (i > 0) { - buf.append(", "); //$NON-NLS-1$ - } - buf.append(ASTResolving.getTypeSignature(types[i])); - } - return BasicElementLabels.getJavaElementName(buf.toString()); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#getQualifiedTypeNameHistoryBoost(java.lang.String, int, int) + */ + @Override + protected int getQualifiedTypeNameHistoryBoost(String qualifiedName, int min, int max) { + return 0; } - private static String getArgumentName(List arguments, int index) { - String def= String.valueOf(index + 1); - - ASTNode expr= arguments.get(index); - if (expr.getLength() > 18) { - return def; - } - ASTMatcher matcher= new ASTMatcher(); - for (int i= 0; i < arguments.size(); i++) { - if (i != index && matcher.safeSubtreeMatch(expr, arguments.get(i))) { - return def; - } - } - return '\'' + BasicElementLabels.getJavaElementName(ASTNodes.asString(expr)) + '\''; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#linkedProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.LinkedCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper linkedProposalToT(LinkedCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static void doMoreArguments(IInvocationContextCore context, ASTNode invocationNode, List arguments, - ITypeBinding[] argTypes, IMethodBinding methodRef, Collection proposals) - throws CoreException { - ITypeBinding[] paramTypes= methodRef.getParameterTypes(); - int k= 0, nSkipped= 0; - int diff= argTypes.length - paramTypes.length; - int[] indexSkipped= new int[diff]; - for (int i= 0; i < argTypes.length; i++) { - if (k < paramTypes.length && canAssign(argTypes[i], paramTypes[k])) { - k++; // match - } else { - if (nSkipped >= diff) { - return; // too different - } - indexSkipped[nSkipped++]= i; - } - } - - ICompilationUnit cu= context.getCompilationUnit(); - CompilationUnit astRoot= context.getASTRoot(); - - // remove arguments - { - ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); - - for (int i= diff - 1; i >= 0; i--) { - rewrite.remove(arguments.get(indexSkipped[i]), null); - } - String[] arg = new String[] { ASTResolving.getMethodSignature(methodRef) }; - String label; - if (diff == 1) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeargument_description, arg); - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removearguments_description, arg); - } - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, rewrite, - IProposalRelevance.REMOVE_ARGUMENTS); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - IMethodBinding methodDecl= methodRef.getMethodDeclaration(); - ITypeBinding declaringType= methodDecl.getDeclaringClass(); - - // add parameters - if (!declaringType.isFromSource()) { - return; - } - ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType); - if (targetCU != null) { - - if (isImplicitConstructor(methodDecl)) { - return; - } - - ChangeMethodSignatureProposalCore.ChangeDescription[] changeDesc = new ChangeMethodSignatureProposalCore.ChangeDescription[argTypes.length]; - ITypeBinding[] changeTypes= new ITypeBinding[diff]; - for (int i= diff - 1; i >= 0; i--) { - int idx= indexSkipped[i]; - Expression arg= arguments.get(idx); - String name= getExpressionBaseName(arg); - ITypeBinding newType= Bindings.normalizeTypeBinding(argTypes[idx]); - if (newType == null) { - newType= astRoot.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - } - if (newType.isWildcardType()) { - newType= ASTResolving.normalizeWildcardType(newType, true, astRoot.getAST()); - } - if (!ASTResolving.isUseableTypeInContext(newType, methodDecl, false)) { - return; - } - changeDesc[idx]= new InsertDescription(newType, name); - changeTypes[i]= newType; - } - String[] arg = new String[] { ASTResolving.getMethodSignature(methodDecl), getTypeNames(changeTypes) }; - String label; - if (methodDecl.isConstructor()) { - if (diff == 1) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparam_constr_description, arg); - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparams_constr_description, arg); - } - } else { - if (diff == 1) { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparam_description, arg); - } else { - label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparams_description, arg); - } - } - ChangeMethodSignatureProposalCore proposal = new ChangeMethodSignatureProposalCore(label, targetCU, invocationNode, - methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_ADD_PARAMETER); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#changeCorrectionProposalToT(org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper changeCorrectionProposalToT(ChangeCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static boolean isImplicitConstructor(IMethodBinding meth) { - return meth.isDefaultConstructor(); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#qualifyTypeProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.QualifyTypeProposalCore, int) + */ + @Override + protected ProposalKindWrapper qualifyTypeProposalToT(QualifyTypeProposalCore core, int uid) { + // Guessing on the kind here, as this was not in the jdt.ls version + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static ITypeBinding[] getParameterTypes(List args) { - ITypeBinding[] params= new ITypeBinding[args.size()]; - for (int i= 0; i < args.size(); i++) { - Expression expr= args.get(i); - ITypeBinding curr= Bindings.normalizeTypeBinding(expr.resolveTypeBinding()); - if (curr != null && curr.isWildcardType()) { - curr= ASTResolving.normalizeWildcardType(curr, true, expr.getAST()); - } - if (curr == null) { - curr= expr.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - } - params[i]= curr; - } - return params; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#addTypeParametersToT(org.eclipse.jdt.internal.ui.text.correction.proposals.AddTypeParameterProposalCore, int) + */ + @Override + protected ProposalKindWrapper addTypeParametersToT(AddTypeParameterProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static void doEqualNumberOfParameters(IInvocationContextCore context, ASTNode invocationNode, - IProblemLocationCore problem, List arguments, ITypeBinding[] argTypes, IMethodBinding methodBinding, - Collection 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 inv) { - 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) { - ProposalKindWrapper proposal = TypeMismatchSubProcessor.createCastProposal(context, castFixType, nodeToCast, IProposalRelevance.CAST_ARGUMENT_1); - String castTypeName= BindingLabelProviderCore.getBindingLabel(castFixType, JavaElementLabelsCore.ALL_DEFAULT); - String[] arg= new String[] { getArgumentName(arguments, idx), castTypeName}; - proposal.getProposal().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); - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, - context.getCompilationUnit(), rewrite, IProposalRelevance.SWAP_ARGUMENTS); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - - 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[] { 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); - } - ChangeMethodSignatureProposalCore proposal = new ChangeMethodSignatureProposalCore(label, targetCU, - invocationNode, methodDecl, changeDesc, null, - IProposalRelevance.CHANGE_METHOD_SWAP_PARAMETERS); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - 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[] { ASTResolving.getMethodSignature(methodDecl), 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); - } - ChangeMethodSignatureProposalCore proposal = new ChangeMethodSignatureProposalCore(label, targetCU, - invocationNode, methodDecl, changeDesc, null, IProposalRelevance.CHANGE_METHOD_SIGNATURE); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#addModuleRequiresProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.AddModuleRequiresCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper addModuleRequiresProposalToT(AddModuleRequiresCorrectionProposalCore core, int uid) { + // Guessing on the kind here, as this was not in the jdt.ls version + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static ChangeDescription[] createSignatureChangeDescription(int[] indexOfDiff, int nDiffs, ITypeBinding[] paramTypes, List arguments, ITypeBinding[] argTypes) { - ChangeDescription[] changeDesc= new ChangeDescription[paramTypes.length]; - for (int i= 0; i < nDiffs; i++) { - int diffIndex= indexOfDiff[i]; - Expression arg= arguments.get(diffIndex); - String name= getExpressionBaseName(arg); - ITypeBinding argType= argTypes[diffIndex]; - if (argType.isWildcardType()) { - argType= ASTResolving.normalizeWildcardType(argType, true, arg.getAST()); - if (argType== null) { - return null; - } - } - changeDesc[diffIndex]= new EditDescription(argType, name); - } - return changeDesc; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#replaceCorrectionProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.ReplaceCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper replaceCorrectionProposalToT(ReplaceCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static String getExpressionBaseName(Expression expr) { - IBinding argBinding= Bindings.resolveExpressionBinding(expr, true); - if (argBinding instanceof IVariableBinding argVariableBinding) { - IJavaProject project= null; - ASTNode root= expr.getRoot(); - if (root instanceof CompilationUnit unit) { - ITypeRoot typeRoot = unit.getTypeRoot(); - if (typeRoot != null) { - project= typeRoot.getJavaProject(); - } - } - return StubUtility.getBaseName(argVariableBinding, project); - } - if (expr instanceof SimpleName name) { - return name.getIdentifier(); - } - return null; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#castCorrectionProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.CastCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper castCorrectionProposalToT(CastCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static ITypeBinding[] getArgumentTypes(List arguments) { - ITypeBinding[] res= new ITypeBinding[arguments.size()]; - for (int i= 0; i < res.length; i++) { - Expression expression= arguments.get(i); - ITypeBinding curr= expression.resolveTypeBinding(); - if (curr == null) { - return null; - } - if (!curr.isNullType()) { // don't normalize null type - curr= Bindings.normalizeTypeBinding(curr); - if (curr == null) { - curr= expression.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ - } - } - res[i]= curr; - } - return res; + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#addArgumentCorrectionProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.AddArgumentCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper addArgumentCorrectionProposalToT(AddArgumentCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - private static void addQualifierToOuterProposal(IInvocationContextCore context, MethodInvocation invocationNode, - IMethodBinding binding, Collection proposals) { - ITypeBinding declaringType= binding.getDeclaringClass(); - ITypeBinding parentType= Bindings.getBindingOfParentType(invocationNode); - ITypeBinding currType= parentType; - - boolean isInstanceMethod= !Modifier.isStatic(binding.getModifiers()); - - while (currType != null && !Bindings.isSuperType(declaringType, currType)) { - if (isInstanceMethod && Modifier.isStatic(currType.getModifiers())) { - return; - } - currType= currType.getDeclaringClass(); - } - if (currType == null || currType == parentType) { - return; - } - - ASTRewrite rewrite= ASTRewrite.create(invocationNode.getAST()); - - String label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetoouter_description, - ASTResolving.getTypeSignature(currType)); - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, context.getCompilationUnit(), - rewrite, IProposalRelevance.QUALIFY_WITH_ENCLOSING_TYPE); - - ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot()); - ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(invocationNode, imports); - AST ast= invocationNode.getAST(); - - String qualifier= imports.addImport(currType, importRewriteContext); - Name name= ASTNodeFactory.newName(ast, qualifier); - - Expression newExpression; - if (isInstanceMethod) { - ThisExpression expr= ast.newThisExpression(); - expr.setQualifier(name); - newExpression= expr; - } else { - newExpression= name; - } - - rewrite.set(invocationNode, MethodInvocation.EXPRESSION_PROPERTY, newExpression, null); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#changeMethodSignatureProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeMethodSignatureProposalCore, int) + */ + @Override + protected ProposalKindWrapper changeMethodSignatureProposalToT(ChangeMethodSignatureProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - - public static void getConstructorProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) throws CoreException { - ICompilationUnit cu= context.getCompilationUnit(); - - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - if (selectedNode == null) { - return; - } - - ITypeBinding targetBinding= null; - List arguments= null; - IMethodBinding recursiveConstructor= null; - - int type= selectedNode.getNodeType(); - if (type == ASTNode.CLASS_INSTANCE_CREATION) { - ClassInstanceCreation creation= (ClassInstanceCreation) selectedNode; - - IBinding binding= creation.getType().resolveBinding(); - if (binding instanceof ITypeBinding typeBinding) { - targetBinding = typeBinding; - arguments= creation.arguments(); - } - } else if (type == ASTNode.SUPER_CONSTRUCTOR_INVOCATION) { - ITypeBinding typeBinding= Bindings.getBindingOfParentType(selectedNode); - if (typeBinding != null && !typeBinding.isAnonymous()) { - targetBinding= typeBinding.getSuperclass(); - arguments= ((SuperConstructorInvocation) selectedNode).arguments(); - } - } else if (type == ASTNode.CONSTRUCTOR_INVOCATION) { - ITypeBinding typeBinding= Bindings.getBindingOfParentType(selectedNode); - if (typeBinding != null && !typeBinding.isAnonymous()) { - targetBinding= typeBinding; - arguments= ((ConstructorInvocation) selectedNode).arguments(); - recursiveConstructor= ASTResolving.findParentMethodDeclaration(selectedNode).resolveBinding(); - } - } - if (targetBinding == null) { - return; - } - IMethodBinding[] methods= targetBinding.getDeclaredMethods(); - ArrayList similarElements= new ArrayList<>(); - for (int i= 0; i < methods.length; i++) { - IMethodBinding curr= methods[i]; - if (curr.isConstructor() && recursiveConstructor != curr) { - similarElements.add(curr); // similar elements can contain a implicit default constructor - } - } - - addParameterMissmatchProposals(context, problem, similarElements, selectedNode, arguments, proposals); - - if (targetBinding.isFromSource()) { - ITypeBinding targetDecl= targetBinding.getTypeDeclaration(); - - ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, targetDecl); - if (targetCU != null) { - String[] args = new String[] { - ASTResolving.getMethodSignature(ASTResolving.getTypeSignature(targetDecl), getParameterTypes(arguments), false) }; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createconstructor_description, args); - NewMethodCorrectionProposalCore proposal = new NewMethodCorrectionProposalCore(label, targetCU, selectedNode, arguments, targetDecl, IProposalRelevance.CREATE_CONSTRUCTOR); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#newMethodProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.NewMethodCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper newMethodProposalToT(NewMethodCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - public static void getAmbiguousTypeReferenceProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) throws CoreException { - final ICompilationUnit cu= context.getCompilationUnit(); - int offset= problem.getOffset(); - int len= problem.getLength(); - - IJavaElement[] elements= cu.codeSelect(offset, len); - for (int i= 0; i < elements.length; i++) { - IJavaElement curr= elements[i]; - if (curr instanceof IType type && !TypeFilter.isFiltered(type)) { - String qualifiedTypeName = type.getFullyQualifiedName('.'); - - CompilationUnit root= context.getASTRoot(); - - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_importexplicit_description, BasicElementLabels.getJavaElementName(qualifiedTypeName)); - ASTRewriteCorrectionProposalCore proposal = new ASTRewriteCorrectionProposalCore(label, cu, ASTRewrite.create(root.getAST()), IProposalRelevance.IMPORT_EXPLICIT); - - ImportRewrite imports= proposal.createImportRewrite(root); - imports.addImport(qualifiedTypeName); - - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#rewriteProposalToT(org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper rewriteProposalToT(ASTRewriteCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - public static void getArrayAccessProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) { - - CompilationUnit root= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(root); - if (!(selectedNode instanceof MethodInvocation)) { - return; - } - - MethodInvocation decl= (MethodInvocation) selectedNode; - SimpleName nameNode= decl.getName(); - String methodName= nameNode.getIdentifier(); - - IBinding[] bindings= (new ScopeAnalyzer(root)).getDeclarationsInScope(nameNode, ScopeAnalyzer.METHODS); - for (int i= 0; i < bindings.length; i++) { - String currName= bindings[i].getName(); - if (NameMatcher.isSimilarName(methodName, currName)) { - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_arraychangetomethod_description, BasicElementLabels.getJavaElementName(currName)); - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, context.getCompilationUnit(), nameNode.getStartPosition(), nameNode.getLength(), currName, IProposalRelevance.ARRAY_CHANGE_TO_METHOD); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - // always suggest 'length' - String lengthId= "length"; //$NON-NLS-1$ - String label= CorrectionMessages.UnresolvedElementsSubProcessor_arraychangetolength_description; - int offset= nameNode.getStartPosition(); - int length= decl.getStartPosition() + decl.getLength() - offset; - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, context.getCompilationUnit(), offset, length, lengthId, IProposalRelevance.ARRAY_CHANGE_TO_LENGTH); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#newAnnotationProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.NewAnnotationMemberProposalCore, int) + */ + @Override + protected ProposalKindWrapper newAnnotationProposalToT(NewAnnotationMemberProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - public static void getAnnotationMemberProposals(IInvocationContextCore context, IProblemLocationCore problem, - Collection proposals) throws CoreException { - CompilationUnit astRoot= context.getASTRoot(); - ICompilationUnit cu= context.getCompilationUnit(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - - Annotation annotation; - String memberName; - if (selectedNode.getLocationInParent() == MemberValuePair.NAME_PROPERTY) { - if (selectedNode.getParent().getLocationInParent() != NormalAnnotation.VALUES_PROPERTY) { - return; - } - annotation= (Annotation) selectedNode.getParent().getParent(); - memberName= ((SimpleName) selectedNode).getIdentifier(); - } else if (selectedNode.getLocationInParent() == SingleMemberAnnotation.VALUE_PROPERTY) { - annotation= (Annotation) selectedNode.getParent(); - memberName= "value"; //$NON-NLS-1$ - } else { - return; - } - - ITypeBinding annotBinding= annotation.resolveTypeBinding(); - if (annotBinding == null) { - return; - } - - - if (annotation instanceof NormalAnnotation) { - // similar names - IMethodBinding[] otherMembers= annotBinding.getDeclaredMethods(); - for (int i= 0; i < otherMembers.length; i++) { - IMethodBinding binding= otherMembers[i]; - String curr= binding.getName(); - int relevance= NameMatcher.isSimilarName(memberName, curr) ? IProposalRelevance.CHANGE_TO_ATTRIBUTE_SIMILAR_NAME : IProposalRelevance.CHANGE_TO_ATTRIBUTE; - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_UnresolvedElementsSubProcessor_changetoattribute_description, BasicElementLabels.getJavaElementName(curr)); - RenameNodeCorrectionProposalCore proposal = new RenameNodeCorrectionProposalCore(label, cu, problem.getOffset(), problem.getLength(), curr, relevance); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } - - if (annotBinding.isFromSource()) { - ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, annotBinding); - if (targetCU != null) { - String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_UnresolvedElementsSubProcessor_createattribute_description, BasicElementLabels.getJavaElementName(memberName)); - NewAnnotationMemberProposalCore proposal = new NewAnnotationMemberProposalCore(label, targetCU, selectedNode, annotBinding, IProposalRelevance.CREATE_ATTRIBUTE); - proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix)); - } - } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#renameNodeProposalToT(org.eclipse.jdt.internal.ui.text.correction.proposals.RenameNodeCorrectionProposalCore, int) + */ + @Override + protected ProposalKindWrapper renameNodeProposalToT(RenameNodeCorrectionProposalCore core, int uid) { + return CodeActionHandler.wrap(core, CodeActionKind.QuickFix); } - }