Bug 535690 - [11][quick assist] Convert 'var' to resolved type for
lambda parameters
Change-Id: I051f270ec457a48886a568dde157862e8ae9c837
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
index 94c9d79..474b0fc 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
@@ -289,6 +289,11 @@
public static String QuickAssistProcessor_splitdeclaration_description;
public static String QuickAssistProcessor_joindeclaration_description;
public static String QuickAssistProcessor_add_inferred_lambda_parameter_types;
+ public static String QuickAssistProcessor_replace_var_with_inferred_lambda_parameter_types;
+ public static String QuickAssistProcessor_add_var_lambda_parameter_types;
+ public static String QuickAssistProcessor_replace_inferred_with_var_lambda_parameter_types;
+ public static String QuickAssistProcessor_remove_inferred_lambda_parameter_types;
+ public static String QuickAssistProcessor_remove_var_lambda_parameter_types;
public static String QuickAssistProcessor_addfinallyblock_description;
public static String QuickAssistProcessor_addelseblock_description;
public static String QuickAssistProcessor_addParenthesesInLambda;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
index c00ab77..d3671ba 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
@@ -350,6 +350,11 @@
QuickAssistProcessor_extract_to_constant_description=Extract to constant
QuickAssistProcessor_joindeclaration_description=Join variable declaration
QuickAssistProcessor_add_inferred_lambda_parameter_types=Add inferred lambda parameter types
+QuickAssistProcessor_replace_var_with_inferred_lambda_parameter_types= Replace var types with inferred lambda parameter types
+QuickAssistProcessor_add_var_lambda_parameter_types=Add var lambda parameter types
+QuickAssistProcessor_replace_inferred_with_var_lambda_parameter_types=Replace inferred types with var lambda parameter types
+QuickAssistProcessor_remove_inferred_lambda_parameter_types=Remove inferred lambda parameter types
+QuickAssistProcessor_remove_var_lambda_parameter_types=Remove var lambda parameter types
QuickAssistProcessor_addfinallyblock_description=Add finally block
QuickAssistProcessor_addelseblock_description=Add else block
QuickAssistProcessor_addParenthesesInLambda=Add parentheses around lambda parameter
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
index 19fe0fa..172e852 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
@@ -161,6 +161,7 @@
import org.eclipse.jdt.internal.corext.refactoring.code.ExtractTempRefactoring;
import org.eclipse.jdt.internal.corext.refactoring.code.InlineTempRefactoring;
import org.eclipse.jdt.internal.corext.refactoring.code.PromoteTempToFieldRefactoring;
+import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover;
import org.eclipse.jdt.internal.corext.refactoring.util.TightSourceRangeComputer;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
@@ -183,6 +184,7 @@
import org.eclipse.jdt.internal.ui.fix.TypeParametersCleanUp;
import org.eclipse.jdt.internal.ui.fix.VariableDeclarationCleanUp;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.ASTRewriteRemoveImportsCorrectionProposal;
import org.eclipse.jdt.internal.ui.text.correction.proposals.AssignToVariableAssistProposal;
import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal;
import org.eclipse.jdt.internal.ui.text.correction.proposals.GenerateForLoopAssistProposal;
@@ -256,6 +258,8 @@
|| getChangeLambdaBodyToBlockProposal(context, coveringNode, null)
|| getChangeLambdaBodyToExpressionProposal(context, coveringNode, null)
|| getAddInferredLambdaParameterTypes(context, coveringNode, null)
+ || getAddVarLambdaParameterTypes(context, coveringNode, null)
+ || getRemoveVarOrInferredLambdaParameterTypes(context, coveringNode, null)
|| getConvertMethodReferenceToLambdaProposal(context, coveringNode, null)
|| getConvertLambdaToMethodReferenceProposal(context, coveringNode, null)
|| getFixParenthesesInLambdaExpression(context, coveringNode, null)
@@ -311,6 +315,8 @@
getChangeLambdaBodyToBlockProposal(context, coveringNode, resultingCollections);
getChangeLambdaBodyToExpressionProposal(context, coveringNode, resultingCollections);
getAddInferredLambdaParameterTypes(context, coveringNode, resultingCollections);
+ getAddVarLambdaParameterTypes(context, coveringNode, resultingCollections);
+ getRemoveVarOrInferredLambdaParameterTypes(context, coveringNode, resultingCollections);
getConvertMethodReferenceToLambdaProposal(context, coveringNode, resultingCollections);
getConvertLambdaToMethodReferenceProposal(context, coveringNode, resultingCollections);
getFixParenthesesInLambdaExpression(context, coveringNode, resultingCollections);
@@ -1367,11 +1373,35 @@
public static boolean getAddInferredLambdaParameterTypes(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
LambdaExpression lambda;
+ boolean isvarTypeSingleVariableDeclaration= false;
if (covering instanceof LambdaExpression) {
lambda= (LambdaExpression) covering;
} else if (covering.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY &&
((VariableDeclarationFragment) covering.getParent()).getLocationInParent() == LambdaExpression.PARAMETERS_PROPERTY) {
lambda= (LambdaExpression) covering.getParent().getParent();
+ } else if (covering.getLocationInParent() == SingleVariableDeclaration.NAME_PROPERTY &&
+ ((SingleVariableDeclaration) covering.getParent()).getLocationInParent() == LambdaExpression.PARAMETERS_PROPERTY) {
+ CompilationUnit astRoot= context.getASTRoot();
+ IJavaElement root= astRoot.getJavaElement();
+ ASTNode parent= covering.getParent();
+ if (parent == null || root == null) {
+ return false;
+ }
+ IJavaProject javaProject= root.getJavaProject();
+ if (javaProject == null) {
+ return false;
+ }
+ if (!JavaModelUtil.is11OrHigher(javaProject)) {
+ return false;
+ } else {
+ SingleVariableDeclaration svDecl= (SingleVariableDeclaration) parent;
+ if (svDecl.getType() != null && svDecl.getType().isVar()) {
+ lambda= (LambdaExpression) covering.getParent().getParent();
+ isvarTypeSingleVariableDeclaration= true;
+ } else {
+ return false;
+ }
+ }
} else {
return false;
}
@@ -1381,7 +1411,7 @@
if (noOfLambdaParams == 0)
return false;
- if (lambdaParameters.get(0) instanceof SingleVariableDeclaration)
+ if (lambdaParameters.get(0) instanceof SingleVariableDeclaration && !isvarTypeSingleVariableDeclaration)
return false;
IMethodBinding methodBinding= lambda.resolveMethodBinding();
@@ -1409,6 +1439,9 @@
// add proposal
String label= CorrectionMessages.QuickAssistProcessor_add_inferred_lambda_parameter_types;
+ if (isvarTypeSingleVariableDeclaration) {
+ label= CorrectionMessages.QuickAssistProcessor_replace_var_with_inferred_lambda_parameter_types;
+ }
Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.ADD_INFERRED_LAMBDA_PARAMETER_TYPES, image);
proposal.setImportRewrite(importRewrite);
@@ -1416,6 +1449,191 @@
return true;
}
+ public static boolean getAddVarLambdaParameterTypes(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
+ CompilationUnit astRoot= context.getASTRoot();
+ IJavaElement root= astRoot.getJavaElement();
+ ASTNode parent= covering.getParent();
+ if (parent == null || root == null) {
+ return false;
+ }
+ IJavaProject javaProject= root.getJavaProject();
+ if (javaProject == null) {
+ return false;
+ }
+ if (!JavaModelUtil.is11OrHigher(javaProject)) {
+ return false;
+ }
+
+ LambdaExpression lambda;
+ boolean isvarTypeSingleVariableDeclaration= false;
+ if (covering instanceof LambdaExpression) {
+ lambda= (LambdaExpression) covering;
+ } else if (covering.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY &&
+ ((VariableDeclarationFragment) parent).getLocationInParent() == LambdaExpression.PARAMETERS_PROPERTY) {
+ lambda= (LambdaExpression) covering.getParent().getParent();
+ } else {
+ if (covering.getLocationInParent() == SingleVariableDeclaration.NAME_PROPERTY &&
+ ((SingleVariableDeclaration) parent).getLocationInParent() == LambdaExpression.PARAMETERS_PROPERTY) {
+ SingleVariableDeclaration svDecl= (SingleVariableDeclaration) parent;
+ if (svDecl.getType() != null && !svDecl.getType().isVar()) {
+ lambda= (LambdaExpression) covering.getParent().getParent();
+ isvarTypeSingleVariableDeclaration= true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ List<VariableDeclaration> lambdaParameters= lambda.parameters();
+ int noOfLambdaParams= lambdaParameters.size();
+ if (noOfLambdaParams == 0)
+ return false;
+
+ if (lambdaParameters.get(0) instanceof SingleVariableDeclaration && !isvarTypeSingleVariableDeclaration)
+ return false;
+
+ IMethodBinding methodBinding= lambda.resolveMethodBinding();
+ if (methodBinding == null)
+ return false;
+
+ if (resultingCollections == null)
+ return true;
+
+ String VAR_TYPE= "var"; //$NON-NLS-1$
+ AST ast= lambda.getAST();
+ ASTRewrite rewrite= ASTRewrite.create(ast);
+
+ ImportRemover remover= new ImportRemover(context.getCompilationUnit().getJavaProject(), context.getASTRoot());
+
+ ImportRewrite importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+
+ rewrite.set(lambda, LambdaExpression.PARENTHESES_PROPERTY, Boolean.valueOf(true), null);
+ for (int i= 0; i < noOfLambdaParams; i++) {
+ VariableDeclaration param= lambdaParameters.get(i);
+ Type oldType= null;
+ if (param instanceof SingleVariableDeclaration) {
+ SingleVariableDeclaration curParent= (SingleVariableDeclaration) param;
+ oldType= curParent.getType();
+ if (oldType != null) {
+ rewrite.replace(oldType, ast.newSimpleType(ast.newName(VAR_TYPE)), null);
+ remover.registerRemovedNode(oldType);
+ }
+ }
+ if (oldType == null) {
+ SingleVariableDeclaration newParam= ast.newSingleVariableDeclaration();
+ newParam.setName(ast.newSimpleName(param.getName().getIdentifier()));
+ newParam.setType(ast.newSimpleType(ast.newName(VAR_TYPE)));
+ rewrite.replace(param, newParam, null);
+ }
+ }
+
+ // add proposal
+ ASTRewriteCorrectionProposal proposal;
+ String label= null;
+ Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+ if (isvarTypeSingleVariableDeclaration) {
+ label= CorrectionMessages.QuickAssistProcessor_replace_inferred_with_var_lambda_parameter_types;
+ ASTRewriteRemoveImportsCorrectionProposal newProposal= new ASTRewriteRemoveImportsCorrectionProposal(label, context.getCompilationUnit(), rewrite,
+ IProposalRelevance.ADD_INFERRED_LAMBDA_PARAMETER_TYPES, image);
+ newProposal.setImportRemover(remover);
+ proposal= newProposal;
+
+ } else {
+ label= CorrectionMessages.QuickAssistProcessor_add_var_lambda_parameter_types;
+ proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.ADD_INFERRED_LAMBDA_PARAMETER_TYPES, image);
+ }
+ proposal.setImportRewrite(importRewrite);
+ resultingCollections.add(proposal);
+ return true;
+ }
+
+ public static boolean getRemoveVarOrInferredLambdaParameterTypes(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
+ CompilationUnit astRoot= context.getASTRoot();
+ IJavaElement root= astRoot.getJavaElement();
+ ASTNode parent= covering.getParent();
+ if (parent == null || root == null) {
+ return false;
+ }
+ IJavaProject javaProject= root.getJavaProject();
+ if (javaProject == null) {
+ return false;
+ }
+ boolean checkForVarTypes= false;
+ if (JavaModelUtil.is11OrHigher(javaProject)) {
+ checkForVarTypes= true;
+ }
+
+ LambdaExpression lambda;
+ if (covering instanceof LambdaExpression) {
+ lambda= (LambdaExpression) covering;
+ } else if (covering.getLocationInParent() == SingleVariableDeclaration.NAME_PROPERTY &&
+ ((SingleVariableDeclaration) parent).getLocationInParent() == LambdaExpression.PARAMETERS_PROPERTY) {
+ lambda= (LambdaExpression) covering.getParent().getParent();
+ } else {
+ return false;
+ }
+
+ List<VariableDeclaration> lambdaParameters= lambda.parameters();
+ int noOfLambdaParams= lambdaParameters.size();
+ if (noOfLambdaParams == 0)
+ return false;
+
+ if (!(lambdaParameters.get(0) instanceof SingleVariableDeclaration))
+ return false;
+
+ IMethodBinding methodBinding= lambda.resolveMethodBinding();
+ if (methodBinding == null)
+ return false;
+
+ if (resultingCollections == null)
+ return true;
+
+ AST ast= lambda.getAST();
+ ASTRewrite rewrite= ASTRewrite.create(ast);
+
+ ImportRemover remover= new ImportRemover(context.getCompilationUnit().getJavaProject(), context.getASTRoot());
+
+ ImportRewrite importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+
+ rewrite.set(lambda, LambdaExpression.PARENTHESES_PROPERTY, Boolean.valueOf(true), null);
+ boolean removeImports= false;
+ for (int i= 0; i < noOfLambdaParams; i++) {
+ VariableDeclaration param= lambdaParameters.get(i);
+ Type oldType= null;
+ if (param instanceof SingleVariableDeclaration) {
+ SingleVariableDeclaration curParent= (SingleVariableDeclaration) param;
+ oldType= curParent.getType();
+ if (oldType != null && (!checkForVarTypes || (checkForVarTypes && !oldType.isVar()))) {
+ remover.registerRemovedNode(oldType);
+ removeImports= true;
+ }
+ VariableDeclarationFragment newParam= ast.newVariableDeclarationFragment();
+ newParam.setName(ast.newSimpleName(param.getName().getIdentifier()));
+ rewrite.replace(param, newParam, null);
+ }
+ }
+
+ // add proposal
+ ASTRewriteCorrectionProposal proposal;
+ String label= null;
+ Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+ if (removeImports) {
+ label= CorrectionMessages.QuickAssistProcessor_remove_inferred_lambda_parameter_types;
+ ASTRewriteRemoveImportsCorrectionProposal newProposal= new ASTRewriteRemoveImportsCorrectionProposal(label, context.getCompilationUnit(), rewrite,
+ IProposalRelevance.ADD_INFERRED_LAMBDA_PARAMETER_TYPES, image);
+ newProposal.setImportRemover(remover);
+ proposal= newProposal;
+ } else {
+ label= CorrectionMessages.QuickAssistProcessor_remove_var_lambda_parameter_types;
+ proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.ADD_INFERRED_LAMBDA_PARAMETER_TYPES, image);
+ }
+ proposal.setImportRewrite(importRewrite);
+ resultingCollections.add(proposal);
+ return true;
+ }
+
public static boolean getInferDiamondArgumentsProposal(IInvocationContext context, ASTNode node, IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
// don't add if already added as quick fix
if (containsMatchingProblem(locations, IProblem.DiamondNotBelow17))
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/ASTRewriteRemoveImportsCorrectionProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/ASTRewriteRemoveImportsCorrectionProposal.java
new file mode 100644
index 0000000..9f7f37b
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/ASTRewriteRemoveImportsCorrectionProposal.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2018 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text.correction.proposals;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+
+import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover;
+
+import org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal;
+
+public class ASTRewriteRemoveImportsCorrectionProposal extends ASTRewriteCorrectionProposal{
+
+ private ImportRemover fImportRemover;
+
+ public ASTRewriteRemoveImportsCorrectionProposal(String name, ICompilationUnit cu, ASTRewrite rewrite, int relevance) {
+ super(name, cu, rewrite, relevance);
+ }
+
+ public ASTRewriteRemoveImportsCorrectionProposal(String name, ICompilationUnit cu, ASTRewrite rewrite, int relevance, Image image) {
+ super(name, cu, rewrite, relevance, image);
+ }
+
+ public void setImportRemover(ImportRemover remover) {
+ fImportRemover= remover;
+ }
+
+ @Override
+ protected ASTRewrite getRewrite() throws CoreException {
+ ASTRewrite rewrite= super.getRewrite();
+ ImportRewrite importRewrite= getImportRewrite();
+ if (fImportRemover != null && importRewrite != null) {
+ fImportRemover.applyRemoves(importRewrite);
+ }
+ return rewrite;
+ }
+
+}