From 66203dfe5f2f4547ea186d8485dbe5db4308944a Mon Sep 17 00:00:00 2001 From: Deepak Azad Date: Mon, 12 May 2014 15:47:15 +0200 Subject: [PATCH] Bug 351956: [1.7][clean up][quick assist] Remove unnecessary type arguments (was: Suggest to use <> where applicable) --- .../LocalCorrectionsQuickFixTest.java | 42 ++++ .../internal/corext/fix/CleanUpConstants.java | 49 +++- .../jdt/internal/corext/fix/FixMessages.java | 7 +- .../corext/fix/FixMessages.properties | 6 +- .../corext/fix/TypeParametersFix.java | 224 ++++++++++++++++++ .../jdt/internal/ui/fix/MultiFixMessages.java | 5 +- .../ui/fix/MultiFixMessages.properties | 4 +- .../ui/fix/TypeParametersCleanUp.java | 151 ++++++++++++ .../text/correction/CorrectionMessages.java | 2 - .../correction/CorrectionMessages.properties | 2 - .../LocalCorrectionsSubProcessor.java | 38 +-- .../text/correction/QuickAssistProcessor.java | 56 ++--- 12 files changed, 508 insertions(+), 78 deletions(-) create mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/TypeParametersCleanUp.java diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java index 20ceb98417..07c8b84908 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java @@ -9971,4 +9971,46 @@ public void testGenerateForeachNotAddedForLowVersion() throws Exception { fJProject1.setOptions(saveOptions); } } + + public void testInsertInferredTypeArguments() throws Exception { + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("import java.util.ArrayList;\n"); + buf.append("import java.util.List;\n"); + buf.append("\n"); + buf.append("public class E {\n"); + buf.append("\n"); + buf.append(" private void foo() {\n"); + buf.append(" List al1 = new ArrayList<>();\n"); + buf.append("\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + ArrayList proposals= collectCorrections2(cu, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0); + String preview= getPreviewContent(proposal); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("import java.util.ArrayList;\n"); + buf.append("import java.util.List;\n"); + buf.append("\n"); + buf.append("public class E {\n"); + buf.append("\n"); + buf.append(" private void foo() {\n"); + buf.append(" List al1 = new ArrayList();\n"); + buf.append("\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEqualString(preview, buf.toString()); + + String expected1= buf.toString(); + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java index 69b4c97b45..5c6055d5f7 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -829,6 +829,45 @@ public class CleanUpConstants { */ public static final String REMOVE_UNNECESSARY_NLS_TAGS= "cleanup.remove_unnecessary_nls_tags"; //$NON-NLS-1$ + /** + * Controls the usage of type arguments. For detailed settings use
+ * {@link #INSERT_INFERRED_TYPE_ARGUMENTS}
+ * {@link #REMOVE_REDUNDANT_TYPE_ARGUMENTS}
+ *
+ * Possible values: {TRUE, FALSE}
+ *
+ * + * @see CleanUpOptions#TRUE + * @see CleanUpOptions#FALSE + * @since 3.10 + */ + public static final String USE_TYPE_ARGUMENTS= "cleanup.use_type_arguments"; //$NON-NLS-1$ + + /** + * Insert inferred type arguments for diamonds.
+ *
+ * Possible values: {TRUE, FALSE}
+ *
+ * + * @see CleanUpOptions#TRUE + * @see CleanUpOptions#FALSE + * @since 3.10 + */ + public static final String INSERT_INFERRED_TYPE_ARGUMENTS= "cleanup.insert_inferred_type_arguments"; //$NON-NLS-1$ + + /** + * Removes redundant type arguments from class instance creations and creates a diamond.
+ *
+ * Possible values: {TRUE, FALSE}
+ *
+ * + * @see CleanUpOptions#TRUE + * @see CleanUpOptions#FALSE + * @since 3.10 + */ + public static final String REMOVE_REDUNDANT_TYPE_ARGUMENTS= "cleanup.remove_redundant_type_arguments"; //$NON-NLS-1$ + + /** * Controls whether missing annotations should be added to the code. For detailed settings use:
* {@link #ADD_MISSING_ANNOTATIONS_DEPRECATED}
{@value #ADD_MISSING_ANNOTATIONS_OVERRIDE}
@@ -1048,7 +1087,7 @@ public class CleanUpConstants { /** * Should the Clean Up Wizard be shown when executing the Clean Up Action?
*
- * Possible values: {true, false
+ * Possible values: {true, false}
* Default value: true
*
* @@ -1189,6 +1228,9 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { //Unnecessary Code options.setOption(REMOVE_UNNECESSARY_CASTS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNNECESSARY_NLS_TAGS, CleanUpOptions.TRUE); + options.setOption(USE_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(INSERT_INFERRED_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.TRUE); //Missing Code options.setOption(ADD_MISSING_ANNOTATIONS, CleanUpOptions.TRUE); @@ -1274,6 +1316,9 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { //Unnecessary Code options.setOption(REMOVE_UNNECESSARY_CASTS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNNECESSARY_NLS_TAGS, CleanUpOptions.FALSE); + options.setOption(USE_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(INSERT_INFERRED_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.TRUE); //Missing Code options.setOption(ADD_MISSING_ANNOTATIONS, CleanUpOptions.TRUE); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java index fef13b713a..b4a62fd155 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -136,6 +136,11 @@ private FixMessages() { public static String LambdaExpressionsFix_convert_to_anonymous_class_creation; public static String LambdaExpressionsFix_convert_to_lambda_expression; + public static String TypeParametersFix_insert_inferred_type_arguments_description; + public static String TypeParametersFix_insert_inferred_type_arguments_name; + public static String TypeParametersFix_remove_redundant_type_arguments_description; + public static String TypeParametersFix_remove_redundant_type_arguments_name; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, FixMessages.class); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties index e34d99ede7..e1c4e3d76b 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2013 IBM Corporation and others. +# Copyright (c) 2005, 2014 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 @@ -122,3 +122,7 @@ ExtractToNullCheckedLocalProposal_extractToCheckedLocal_proposalName=Extract to ExtractToNullCheckedLocalProposal_todoHandleNullDescription=handle null value LambdaExpressionsFix_convert_to_anonymous_class_creation=Convert to anonymous class creation LambdaExpressionsFix_convert_to_lambda_expression=Convert to lambda expression +TypeParametersFix_insert_inferred_type_arguments_description=Insert inferred type arguments +TypeParametersFix_insert_inferred_type_arguments_name=Insert inferred type arguments +TypeParametersFix_remove_redundant_type_arguments_description=Remove redundant type arguments +TypeParametersFix_remove_redundant_type_arguments_name=Remove redundant type arguments diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java new file mode 100644 index 0000000000..47576b7b1b --- /dev/null +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2014 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.corext.fix; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; +import org.eclipse.jdt.core.dom.rewrite.ListRewrite; + +import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer; + +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.ui.text.java.IProblemLocation; + +import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; + +public class TypeParametersFix extends CompilationUnitRewriteOperationsFix { + + private static final class InsertTypeArgumentsVisitor extends ASTVisitor { + + private final ArrayList fNodes; + + private InsertTypeArgumentsVisitor(ArrayList nodes) { + fNodes= nodes; + } + + @Override + public boolean visit(ParameterizedType createdType) { + if (createdType == null || createdType.typeArguments().size() != 0) { + return true; + } + + ITypeBinding binding= createdType.resolveBinding(); + if (binding == null) { + return true; + } + + ITypeBinding[] typeArguments= binding.getTypeArguments(); + if (typeArguments.length == 0) { + return true; + } + + fNodes.add(createdType); + return true; + } + } + + private static class InsertTypeArgumentsOperation extends CompilationUnitRewriteOperation { + + private final ParameterizedType[] fCreatedTypes; + + public InsertTypeArgumentsOperation(ParameterizedType[] parameterizedTypes) { + fCreatedTypes= parameterizedTypes; + } + + /** + * {@inheritDoc} + */ + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { + TextEditGroup group= createTextEditGroup(FixMessages.TypeParametersFix_insert_inferred_type_arguments_description, cuRewrite); + + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + AST ast= cuRewrite.getRoot().getAST(); + + for (int i= 0; i < fCreatedTypes.length; i++) { + ParameterizedType createdType= fCreatedTypes[i]; + + ITypeBinding[] typeArguments= createdType.resolveBinding().getTypeArguments(); + ContextSensitiveImportRewriteContext importContext= new ContextSensitiveImportRewriteContext(cuRewrite.getRoot(), createdType.getStartPosition(), importRewrite); + + ListRewrite argumentsRewrite= rewrite.getListRewrite(createdType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY); + for (int j= 0; j < typeArguments.length; j++) { + ITypeBinding typeArgument= typeArguments[j]; + Type argumentNode= importRewrite.addImport(typeArgument, ast, importContext); + argumentsRewrite.insertLast(argumentNode, group); + } + } + } + } + + private static class RemoveTypeArgumentsOperation extends CompilationUnitRewriteOperation { + + private final ParameterizedType fParameterizedType; + + public RemoveTypeArgumentsOperation(ParameterizedType parameterizedType) { + fParameterizedType= parameterizedType; + } + + /** + * {@inheritDoc} + */ + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { + TextEditGroup group= createTextEditGroup(FixMessages.TypeParametersFix_remove_redundant_type_arguments_description, cuRewrite); + + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + rewrite.setTargetSourceRangeComputer(new NoCommentSourceRangeComputer()); + + ListRewrite listRewrite= rewrite.getListRewrite(fParameterizedType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY); + + List typeArguments= fParameterizedType.typeArguments(); + for (Iterator iterator= typeArguments.iterator(); iterator.hasNext();) { + listRewrite.remove(iterator.next(), group); + } + } + } + + public static TypeParametersFix createInsertInferredTypeArgumentsFix(CompilationUnit compilationUnit, ParameterizedType node) { + if (node == null) + return null; + + final ArrayList changedNodes= new ArrayList(); + node.accept(new InsertTypeArgumentsVisitor(changedNodes)); + + if (changedNodes.isEmpty()) + return null; + + CompilationUnitRewriteOperation op= new InsertTypeArgumentsOperation(new ParameterizedType[] { node }); + return new TypeParametersFix(FixMessages.TypeParametersFix_insert_inferred_type_arguments_name, compilationUnit, new CompilationUnitRewriteOperation[] { op }); + } + + public static TypeParametersFix createRemoveRedundantTypeArgumentsFix(CompilationUnit compilationUnit, IProblemLocation problem) { + int id= problem.getProblemId(); + if (id == IProblem.RedundantSpecificationOfTypeArguments) { + ParameterizedType parameterizedType= getParameterizedType(compilationUnit, problem); + if (parameterizedType == null) + return null; + RemoveTypeArgumentsOperation operation= new RemoveTypeArgumentsOperation(parameterizedType); + return new TypeParametersFix(FixMessages.TypeParametersFix_remove_redundant_type_arguments_name, compilationUnit, new CompilationUnitRewriteOperation[] { operation }); + } + return null; + } + + public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean insertInferredTypeArguments, boolean removeRedundantTypeArguments) { + + IProblem[] problems= compilationUnit.getProblems(); + IProblemLocation[] locations= new IProblemLocation[problems.length]; + for (int i= 0; i < problems.length; i++) { + locations[i]= new ProblemLocation(problems[i]); + } + + return createCleanUp(compilationUnit, locations, + insertInferredTypeArguments, + removeRedundantTypeArguments); + } + + public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, boolean insertInferredTypeArguments, boolean removeRedundantTypeArguments) { + + if (insertInferredTypeArguments) { + final ArrayList changedNodes= new ArrayList(); + compilationUnit.accept(new InsertTypeArgumentsVisitor(changedNodes)); + + if (changedNodes.isEmpty()) + return null; + + CompilationUnitRewriteOperation op= new InsertTypeArgumentsOperation(changedNodes.toArray(new ParameterizedType[changedNodes.size()])); + return new TypeParametersFix(FixMessages.TypeParametersFix_insert_inferred_type_arguments_name, compilationUnit, new CompilationUnitRewriteOperation[] { op }); + + } else if (removeRedundantTypeArguments) { + List result= new ArrayList(); + for (int i= 0; i < problems.length; i++) { + IProblemLocation problem= problems[i]; + int id= problem.getProblemId(); + + if (id == IProblem.RedundantSpecificationOfTypeArguments) { + ParameterizedType parameterizedType= getParameterizedType(compilationUnit, problem); + if (parameterizedType == null) + return null; + result.add(new RemoveTypeArgumentsOperation(parameterizedType)); + } + } + if (!result.isEmpty()) { + return new TypeParametersFix(FixMessages.TypeParametersFix_remove_redundant_type_arguments_name, compilationUnit, result.toArray(new CompilationUnitRewriteOperation[result.size()])); + } + } + return null; + } + + private static ParameterizedType getParameterizedType(CompilationUnit compilationUnit, IProblemLocation problem) { + ASTNode selectedNode= problem.getCoveringNode(compilationUnit); + if (selectedNode == null) + return null; + + while (!(selectedNode instanceof ParameterizedType) && !(selectedNode instanceof Statement)) { + selectedNode= selectedNode.getParent(); + } + if (selectedNode instanceof ParameterizedType) { + return (ParameterizedType) selectedNode; + } + return null; + } + + protected TypeParametersFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation[] fixRewriteOperations) { + super(name, compilationUnit, fixRewriteOperations); + } +} diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java index 00066795ed..8a418c8ea9 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -101,6 +101,9 @@ private MultiFixMessages() { public static String NullAnnotationsCleanUp_add_nonnull_annotation; public static String NullAnnotationsCleanUp_remove_redundant_nullness_annotation; + public static String TypeParametersCleanUp_InsertInferredTypeArguments_description; + public static String TypeParametersCleanUp_RemoveRedundantTypeArguments_description; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, MultiFixMessages.class); diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties index 76c4ba560b..07a77d5342 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2012 IBM Corporation and others. +# Copyright (c) 2005, 2014 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 @@ -87,3 +87,5 @@ SortMembersCleanUp_RemoveMarkersWarning0=The file ''{0}'' in project ''{1}'' con NullAnnotationsCleanUp_add_nullable_annotation=Add missing @Nullable annotation NullAnnotationsCleanUp_add_nonnull_annotation=Add missing @NonNull annotation NullAnnotationsCleanUp_remove_redundant_nullness_annotation=Remove redundant nullness annotation +TypeParametersCleanUp_InsertInferredTypeArguments_description=Insert inferred type arguments +TypeParametersCleanUp_RemoveRedundantTypeArguments_description=Remove redundant type arguments diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/TypeParametersCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/TypeParametersCleanUp.java new file mode 100644 index 0000000000..8a0e761de4 --- /dev/null +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/TypeParametersCleanUp.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2014 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.fix; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.CompilationUnit; + +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.TypeParametersFix; + +import org.eclipse.jdt.ui.cleanup.CleanUpRequirements; +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.ui.text.java.IProblemLocation; + +public class TypeParametersCleanUp extends AbstractMultiFix { + + private Map fOptions; + + public TypeParametersCleanUp(Map options) { + super(options); + fOptions= options; + } + + public TypeParametersCleanUp() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public CleanUpRequirements getRequirements() { + boolean requireAST= requireAST(); + Map requiredOptions= requireAST ? getRequiredOptions() : null; + return new CleanUpRequirements(requireAST, false, false, requiredOptions); + } + + private boolean requireAST() { + boolean useTypeArguments= isEnabled(CleanUpConstants.USE_TYPE_ARGUMENTS); + if (!useTypeArguments) + return false; + + return isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS) || + isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS); + } + + private Map getRequiredOptions() { + Map result= new Hashtable(); + + if (isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS)) + result.put(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS, JavaCore.WARNING); + + return result; + } + + /** + * {@inheritDoc} + */ + @Override + protected ICleanUpFix createFix(CompilationUnit compilationUnit) throws CoreException { + if (compilationUnit == null) + return null; + + boolean useTypeParameters= isEnabled(CleanUpConstants.USE_TYPE_ARGUMENTS); + if (!useTypeParameters) + return null; + + return TypeParametersFix.createCleanUp(compilationUnit, + isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS), + isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS)); + } + + @Override + protected ICleanUpFix createFix(CompilationUnit compilationUnit, IProblemLocation[] problems) throws CoreException { + if (compilationUnit == null) + return null; + + boolean useTypeParameters= isEnabled(CleanUpConstants.USE_TYPE_ARGUMENTS); + if (!useTypeParameters) + return null; + + return TypeParametersFix.createCleanUp(compilationUnit, problems, + isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS), + isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS)); + } + + /** + * {@inheritDoc} + */ + @Override + public String[] getStepDescriptions() { + List result= new ArrayList(); + if (isEnabled(CleanUpConstants.USE_TYPE_ARGUMENTS) && isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS)) { + result.add(MultiFixMessages.TypeParametersCleanUp_InsertInferredTypeArguments_description); + } else if (isEnabled(CleanUpConstants.USE_TYPE_ARGUMENTS) && isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS)) { + result.add(MultiFixMessages.TypeParametersCleanUp_RemoveRedundantTypeArguments_description); + } + + return result.toArray(new String[result.size()]); + } + + /** + * {@inheritDoc} + */ + public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem) { + int problemId= problem.getProblemId(); + + if (problemId == IProblem.RedundantSpecificationOfTypeArguments) + return isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS); + if (problemId == IProblem.DiamondNotBelow17) + return isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS); + + + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public int computeNumberOfFixes(CompilationUnit compilationUnit) { + if (fOptions == null) + return 0; + int result= 0; + IProblem[] problems= compilationUnit.getProblems(); + if (isEnabled(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS)) + result= getNumberOfProblems(problems, IProblem.RedundantSpecificationOfTypeArguments); + else if (isEnabled(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS)) + result= getNumberOfProblems(problems, IProblem.DiamondNotBelow17); + return result; + + } + +} 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 a48c51336c..146c1814e7 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 @@ -56,7 +56,6 @@ private CorrectionMessages() { public static String QuickAssistProcessor_convert_to_string_buffer_description; public static String QuickAssistProcessor_exceptiontothrows_description; public static String QuickAssistProcessor_extract_to_constant_description; - public static String QuickAssistProcessor_infer_diamond_description; public static String QuickAssistProcessor_inline_local_description; public static String QuickAssistProcessor_name_extension_from_class; public static String QuickAssistProcessor_name_extension_from_interface; @@ -379,7 +378,6 @@ private CorrectionMessages() { public static String UnresolvedElementsSubProcessor_copy_annotation_jar_info; public static String LocalCorrectionsSubProcessor_remove_allocated_description; public static String LocalCorrectionsSubProcessor_remove_redundant_superinterface; - public static String LocalCorrectionsSubProcessor_remove_type_arguments; public static String LocalCorrectionsSubProcessor_return_allocated_description; public static String LocalCorrectionsSubProcessor_qualify_left_hand_side_description; public static String LocalCorrectionsSubProcessor_qualify_right_hand_side_description; 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 5fa4144189..567ab7c2a5 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 @@ -96,7 +96,6 @@ LocalCorrectionsSubProcessor_uninitializedvariable_description=Initialize variab LocalCorrectionsSubProcessor_removesemicolon_description=Remove semicolon LocalCorrectionsSubProcessor_remove_allocated_description=Remove LocalCorrectionsSubProcessor_remove_redundant_superinterface=Remove super interface -LocalCorrectionsSubProcessor_remove_type_arguments=Remove type arguments LocalCorrectionsSubProcessor_renaming_duplicate_method=Rename method ''{0}'' LocalCorrectionsSubProcessor_removeunreachablecode_description=Remove LocalCorrectionsSubProcessor_removeunreachablecode_including_condition_description=Remove (including condition) @@ -339,7 +338,6 @@ QuickAssistProcessor_replaceelsewithblock_description=Change 'else' statement to QuickAssistProcessor_replacethenelsewithblock_description=Change 'if-else' statements to blocks QuickAssistProcessor_replacebodywithblock_description=Change body statement to block -QuickAssistProcessor_infer_diamond_description=Insert inferred type arguments QuickAssistProcessor_invertequals_description=Invert equals QuickAssistProcessor_inline_local_description=Inline local variable QuickAssistProcessor_convert_anonym_to_nested=Convert anonymous to nested class diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java index 7c2148a677..a91c77ef39 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java @@ -80,7 +80,6 @@ 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.ParameterizedType; import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PrefixExpression; import org.eclipse.jdt.core.dom.PrimitiveType; @@ -123,6 +122,7 @@ import org.eclipse.jdt.internal.corext.fix.IProposableFix; import org.eclipse.jdt.internal.corext.fix.Java50Fix; import org.eclipse.jdt.internal.corext.fix.StringFix; +import org.eclipse.jdt.internal.corext.fix.TypeParametersFix; import org.eclipse.jdt.internal.corext.fix.UnimplementedCodeFix; import org.eclipse.jdt.internal.corext.fix.UnusedCodeFix; import org.eclipse.jdt.internal.corext.refactoring.code.Invocations; @@ -150,6 +150,7 @@ import org.eclipse.jdt.internal.ui.fix.CodeStyleCleanUp; import org.eclipse.jdt.internal.ui.fix.Java50CleanUp; import org.eclipse.jdt.internal.ui.fix.StringCleanUp; +import org.eclipse.jdt.internal.ui.fix.TypeParametersCleanUp; import org.eclipse.jdt.internal.ui.fix.UnimplementedCodeCleanUp; import org.eclipse.jdt.internal.ui.fix.UnnecessaryCodeCleanUp; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; @@ -1501,32 +1502,15 @@ private static void addTypeArgumentsFromContext(IInvocationContext context, IPro } public static void addRemoveRedundantTypeArgumentsProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { - CompilationUnit astRoot= context.getASTRoot(); - ASTNode selectedNode= problem.getCoveringNode(astRoot); - if (selectedNode == null) - return; - - while (!(selectedNode instanceof ParameterizedType) && !(selectedNode instanceof Statement)) { - selectedNode= selectedNode.getParent(); - } - if (!(selectedNode instanceof ParameterizedType)) { - return; - } - ParameterizedType parameterizedType= (ParameterizedType) selectedNode; - - AST ast= astRoot.getAST(); - ASTRewrite rewrite= ASTRewrite.create(ast); - ListRewrite listRewrite= rewrite.getListRewrite(parameterizedType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY); - - List typeArguments= parameterizedType.typeArguments(); - for (Iterator iterator= typeArguments.iterator(); iterator.hasNext();) { - listRewrite.remove(iterator.next(), null); + IProposableFix fix= TypeParametersFix.createRemoveRedundantTypeArgumentsFix(context.getASTRoot(), problem); + if (fix != null) { + Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE); + Map options= new HashMap(); + options.put(CleanUpConstants.USE_TYPE_ARGUMENTS, CleanUpOptions.TRUE); + options.put(CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.TRUE); + FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new TypeParametersCleanUp(options), IProposalRelevance.REMOVE_REDUNDANT_TYPE_ARGUMENTS, image, context); + proposals.add(proposal); } - - Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE); - String label= CorrectionMessages.LocalCorrectionsSubProcessor_remove_type_arguments; - ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.REMOVE_REDUNDANT_TYPE_ARGUMENTS, image); - proposals.add(proposal); } public static void addFallThroughProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { @@ -1618,7 +1602,7 @@ public static void addDeprecatedFieldsToMethodsProposals(IInvocationContext cont ITypeBinding typeArgument= typeArguments[j]; typeArgument= Bindings.normalizeForDeclarationUse(typeArgument, ast); if (! TypeRules.isJavaLangObject(typeArgument)) { - // add all type arguments if at least one is found to be necessary: + // add all type arguments if at least one is found to be necessary: List typeArgumentsList= method.typeArguments(); for (int k= 0; k < typeArguments.length; k++) { typeArgument= typeArguments[k]; 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 b3119875ad..66edbf335a 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 @@ -133,6 +133,7 @@ import org.eclipse.jdt.internal.corext.fix.IProposableFix; import org.eclipse.jdt.internal.corext.fix.LambdaExpressionsFix; import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; +import org.eclipse.jdt.internal.corext.fix.TypeParametersFix; import org.eclipse.jdt.internal.corext.fix.VariableDeclarationFix; import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; import org.eclipse.jdt.internal.corext.refactoring.code.ConvertAnonymousToNestedRefactoring; @@ -161,6 +162,7 @@ import org.eclipse.jdt.internal.ui.fix.ConvertLoopCleanUp; import org.eclipse.jdt.internal.ui.fix.ExpressionsCleanUp; import org.eclipse.jdt.internal.ui.fix.LambdaExpressionsCleanUp; +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.AssignToVariableAssistProposal; @@ -702,8 +704,11 @@ private static boolean isValidExpressionBody(Expression expression) { } public static boolean getInferDiamondArgumentsProposal(IInvocationContext context, ASTNode node, IProblemLocation[] locations, Collection resultingCollections) { + // don't add if already added as quick fix + if (containsMatchingProblem(locations, IProblem.DiamondNotBelow17)) + return false; ParameterizedType createdType= null; - + if (node instanceof Name) { Name name= ASTNodes.getTopMostName((Name) node); if (name.getLocationInParent() == SimpleType.NAME_PROPERTY || @@ -728,48 +733,17 @@ public static boolean getInferDiamondArgumentsProposal(IInvocationContext contex createdType= (ParameterizedType) type; } } - - if (createdType == null || createdType.typeArguments().size() != 0) { - return false; - } - - ITypeBinding binding= createdType.resolveBinding(); - if (binding == null) { - return false; - } - - ITypeBinding[] typeArguments= binding.getTypeArguments(); - if (typeArguments.length == 0) { - return false; - } - - if (resultingCollections == null) { - return true; - } - - // don't add if already added as quick fix - if (containsMatchingProblem(locations, IProblem.DiamondNotBelow17)) - return false; - - AST ast= node.getAST(); - ASTRewrite rewrite= ASTRewrite.create(ast); - ImportRewrite importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true); - ContextSensitiveImportRewriteContext importContext= new ContextSensitiveImportRewriteContext(context.getASTRoot(), createdType.getStartPosition(), importRewrite); - - String label= CorrectionMessages.QuickAssistProcessor_infer_diamond_description; - Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); - int relevance= locations == null ? IProposalRelevance.INSERT_INFERRED_TYPE_ARGUMENTS : IProposalRelevance.INSERT_INFERRED_TYPE_ARGUMENTS_ERROR; // if error -> higher than ReorgCorrectionsSubProcessor.getNeedHigherComplianceProposals() - LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, relevance, image); - ListRewrite argumentsRewrite= rewrite.getListRewrite(createdType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY); - for (int i= 0; i < typeArguments.length; i++) { - ITypeBinding typeArgument= typeArguments[i]; - Type argumentNode= importRewrite.addImport(typeArgument, ast, importContext); - argumentsRewrite.insertLast(argumentNode, null); - proposal.addLinkedPosition(rewrite.track(argumentNode), true, "arg" + i); //$NON-NLS-1$ + IProposableFix fix= TypeParametersFix.createInsertInferredTypeArgumentsFix(context.getASTRoot(), createdType); + if (fix != null && resultingCollections != null) { + Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); + int relevance= locations == null ? IProposalRelevance.INSERT_INFERRED_TYPE_ARGUMENTS : IProposalRelevance.INSERT_INFERRED_TYPE_ARGUMENTS_ERROR; // if error -> higher than ReorgCorrectionsSubProcessor.getNeedHigherComplianceProposals() + Map options= new HashMap(); + options.put(CleanUpConstants.USE_TYPE_ARGUMENTS, CleanUpOptions.TRUE); + options.put(CleanUpConstants.INSERT_INFERRED_TYPE_ARGUMENTS, CleanUpOptions.TRUE); + FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new TypeParametersCleanUp(options), relevance, image, context); + resultingCollections.add(proposal); } - - resultingCollections.add(proposal); return true; }