Skip to content

Commit

Permalink
Bug 351956: [1.7][clean up][quick assist] Remove unnecessary type arg…
Browse files Browse the repository at this point in the history
…uments (was: Suggest to use <> where applicable)
  • Loading branch information
Deepak Azad authored and mkeller committed May 13, 2014
1 parent 43269e6 commit 66203df
Show file tree
Hide file tree
Showing 12 changed files with 508 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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<String> al1 = new ArrayList<String>();\n");
buf.append("\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());

String expected1= buf.toString();
assertExpectedExistInProposals(proposals, new String[] { expected1 });
}

}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<br>
* {@link #INSERT_INFERRED_TYPE_ARGUMENTS}<br>
* {@link #REMOVE_REDUNDANT_TYPE_ARGUMENTS}<br>
* <br>
* Possible values: {TRUE, FALSE}<br>
* <br>
*
* @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.<br>
* <br>
* Possible values: {TRUE, FALSE}<br>
* <br>
*
* @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.<br>
* <br>
* Possible values: {TRUE, FALSE}<br>
* <br>
*
* @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:<br>
* {@link #ADD_MISSING_ANNOTATIONS_DEPRECATED}<br> {@value #ADD_MISSING_ANNOTATIONS_OVERRIDE} <br>
Expand Down Expand Up @@ -1048,7 +1087,7 @@ public class CleanUpConstants {
/**
* Should the Clean Up Wizard be shown when executing the Clean Up Action? <br>
* <br>
* Possible values: {<code><b>true</b></code>, <code><b>false</b></code> <br>
* Possible values: {<code><b>true</b></code>, <code><b>false</b></code>} <br>
* Default value: <code><b>true</b></code><br>
* <br>
*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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<ASTNode> fNodes;

private InsertTypeArgumentsVisitor(ArrayList<ASTNode> 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<Type> typeArguments= fParameterizedType.typeArguments();
for (Iterator<Type> 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<ASTNode> changedNodes= new ArrayList<ASTNode>();
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<ASTNode> changedNodes= new ArrayList<ASTNode>();
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<CompilationUnitRewriteOperation> result= new ArrayList<CompilationUnitRewriteOperation>();
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);
}
}
Loading

0 comments on commit 66203df

Please sign in to comment.