diff options
| author | Fabrice-TIERCELIN | 2019-08-09 05:30:31 +0000 |
|---|---|---|
| committer | Jeff Johnston | 2019-08-13 20:19:30 +0000 |
| commit | f35cbbf702eca4e4cbbc3c34eda461b9e697e9e5 (patch) | |
| tree | f6be009dd824b15c330f00c91cbeaabc9c9f4385 | |
| parent | 6083bf5d64c52e97f96e57bf9b118e57001b5f0c (diff) | |
| download | eclipse.jdt.ui-f35cbbf702eca4e4cbbc3c34eda461b9e697e9e5.tar.gz eclipse.jdt.ui-f35cbbf702eca4e4cbbc3c34eda461b9e697e9e5.tar.xz eclipse.jdt.ui-f35cbbf702eca4e4cbbc3c34eda461b9e697e9e5.zip | |
Bug 549899 - [cleanup & saveaction] Use Autoboxing and UnboxingI20190813-1800
- add new AutoboxingCleanUp and UnboxingCleanup classes
- add new usesGivenSignature() static method to ASTNodes class
- add UI support for autoboxing/unboxing to UnnecessaryCodeTabPage
- add new tests to CleanUpTest
Change-Id: Ib859dde76aead8905ab73d53b6e69589b2d2dfb0
Signed-off-by: Fabrice-TIERCELIN <fabrice.tiercelin@yahoo.fr>
12 files changed, 1470 insertions, 122 deletions
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java index beee013383..be72b929b1 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java @@ -112,6 +112,8 @@ public class MultiFixMessages extends NLS { public static String TypeParametersCleanUp_RemoveUnnecessaryTypeArguments_description; public static String RedundantModifiersCleanup_description; + public static String AutoboxingCleanup_description; + public static String UnboxingCleanup_description; public static String RedundantSemicolonsCleanup_description; static { diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties index 195f267027..ae4de91a95 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties @@ -95,4 +95,6 @@ TypeParametersCleanUp_InsertInferredTypeArguments_description=Insert inferred ty TypeParametersCleanUp_RemoveUnnecessaryTypeArguments_description=Remove redundant type arguments RedundantModifiersCleanup_description = Remove redundant modifiers +AutoboxingCleanup_description = Use Autoboxing +UnboxingCleanup_description = Use Unboxing RedundantSemicolonsCleanup_description= Remove redundant semicolons diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java index 3b2d33b30e..59724c2e6d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java @@ -55,6 +55,7 @@ import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.ArrayInitializer; +import org.eclipse.jdt.core.dom.ArrayAccess; import org.eclipse.jdt.core.dom.ArrayType; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.BodyDeclaration; @@ -76,10 +77,10 @@ import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ForStatement; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IExtendedModifier; +import org.eclipse.jdt.core.dom.IfStatement; 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.IfStatement; import org.eclipse.jdt.core.dom.InfixExpression; import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MemberValuePair; @@ -104,6 +105,7 @@ import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperMethodInvocation; +import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.UnionType; import org.eclipse.jdt.core.dom.VariableDeclaration; @@ -236,7 +238,7 @@ public class ASTNodes { * To improve type-safety, callers can add the expected element type as explicit type argument, e.g.: * <p> * {@code ASTNodes.<BodyDeclaration>getChildListProperty(typeDecl, bodyDeclarationsProperty)} - * + * * @param node the node * @param propertyDescriptor the child list property to get * @return the child list @@ -320,7 +322,7 @@ public class ASTNodes { /** * Returns the type node for the given declaration. - * + * * @param declaration the declaration * @return the type node or <code>null</code> if the given declaration represents a type * inferred parameter in lambda expression @@ -422,7 +424,7 @@ public class ASTNodes { /** * Returns the structural property descriptor for the "bodyDeclarations" property * of this node (element type: {@link BodyDeclaration}). - * + * * @param node the node, either an {@link AbstractTypeDeclaration} or an {@link AnonymousClassDeclaration} * @return the property descriptor */ @@ -442,7 +444,7 @@ public class ASTNodes { * Skips qualifiers, type arguments, and type annotations. * <p> * Does <b>not</b> work for WildcardTypes, etc.! - * + * * @param type a type that has a simple name * @return the simple name, followed by array dimensions * @see #getSimpleNameIdentifier(Name) @@ -490,7 +492,7 @@ public class ASTNodes { /** * Returns the (potentially qualified) name of a type, followed by array dimensions. * Skips type arguments and type annotations. - * + * * @param type a type that has a name * @return the name, followed by array dimensions * @since 3.10 @@ -532,7 +534,7 @@ public class ASTNodes { type.accept(visitor); return buffer.toString(); } - + public static InfixExpression.Operator convertToInfixOperator(Assignment.Operator operator) { if (operator.equals(Assignment.Operator.PLUS_ASSIGN)) return InfixExpression.Operator.PLUS; @@ -591,7 +593,7 @@ public class ASTNodes { /** * Returns the type to which an inlined variable initializer should be cast, or * <code>null</code> if no cast is necessary. - * + * * @param initializer the initializer expression of the variable to inline * @param reference the reference to the variable (which is to be inlined) * @return a type binding to which the initializer should be cast, or <code>null</code> iff no cast is necessary @@ -602,22 +604,22 @@ public class ASTNodes { ITypeBinding referenceType= reference.resolveTypeBinding(); if (initializerType == null || referenceType == null) return null; - + if (initializerType.isPrimitive() && referenceType.isPrimitive() && ! referenceType.isEqualTo(initializerType)) { return referenceType; - + } else if (initializerType.isPrimitive() && ! referenceType.isPrimitive()) { // initializer is autoboxed ITypeBinding unboxedReferenceType= Bindings.getUnboxedTypeBinding(referenceType, reference.getAST()); if (!unboxedReferenceType.isEqualTo(initializerType)) return unboxedReferenceType; else if (needsExplicitBoxing(reference)) return referenceType; - + } else if (! initializerType.isPrimitive() && referenceType.isPrimitive()) { // initializer is autounboxed ITypeBinding unboxedInitializerType= Bindings.getUnboxedTypeBinding(initializerType, reference.getAST()); if (!unboxedInitializerType.isEqualTo(referenceType)) return referenceType; - + } else if (initializerType.isRawType() && referenceType.isParameterizedType()) { return referenceType; // don't lose the unchecked conversion @@ -635,7 +637,7 @@ public class ASTNodes { if (!Bindings.containsTypeVariables(referenceType)) return referenceType; } - + return null; } @@ -643,13 +645,13 @@ public class ASTNodes { * Checks whether overloaded methods can result in an ambiguous method call or a semantic change when the * <code>expression</code> argument is replaced with a poly expression form of the functional * interface instance. - * + * * @param expression the method argument, which is a functional interface instance * @param expressionIsExplicitlyTyped <code>true</code> iff the intended replacement for <code>expression</code> * is an explicitly typed lambda expression (JLS8 15.27.1) * @return <code>true</code> if overloaded methods can result in an ambiguous method call or a semantic change, * <code>false</code> otherwise - * + * * @since 3.10 */ public static boolean isTargetAmbiguous(Expression expression, boolean expressionIsExplicitlyTyped) { @@ -661,7 +663,7 @@ public class ASTNodes { expression= (Expression) expression.getParent(); locationInParent= expression.getLocationInParent(); } - + ASTNode parent= expression.getParent(); IMethodBinding methodBinding; int argumentIndex; @@ -717,7 +719,7 @@ public class ASTNodes { /** * Returns the binding of the type which declares the method being invoked. - * + * * @param invocationNode the method invocation node * @param methodBinding binding of the method being invoked * @param invocationQualifier the qualifier used for method invocation, or <code>null</code> if @@ -801,7 +803,7 @@ public class ASTNodes { if (fOriginalMethod.getName().equals(candidate.getName()) && !fOriginalMethod.overrides(candidate)) { ITypeBinding[] originalParameterTypes= fOriginalMethod.getParameterTypes(); ITypeBinding[] candidateParameterTypes= candidate.getParameterTypes(); - + boolean couldBeAmbiguous; if (originalParameterTypes.length == candidateParameterTypes.length) { couldBeAmbiguous= true; @@ -847,12 +849,12 @@ public class ASTNodes { /** * Derives the target type defined at the location of the given expression if the target context * supports poly expressions. - * + * * @param expression the expression at whose location the target type is required * @return the type binding of the target type defined at the location of the given expression * if the target context supports poly expressions, or <code>null</code> if the target * type could not be derived - * + * * @since 3.10 */ public static ITypeBinding getTargetType(Expression expression) { @@ -871,6 +873,24 @@ public class ASTNodes { } else if (locationInParent == ArrayInitializer.EXPRESSIONS_PROPERTY) { return getTargetTypeForArrayInitializer((ArrayInitializer) parent); + } else if (locationInParent == ArrayAccess.INDEX_PROPERTY) { + return parent.getAST().resolveWellKnownType(int.class.getSimpleName()); + + } else if (locationInParent == ConditionalExpression.EXPRESSION_PROPERTY + || locationInParent == IfStatement.EXPRESSION_PROPERTY + || locationInParent == WhileStatement.EXPRESSION_PROPERTY + || locationInParent == DoStatement.EXPRESSION_PROPERTY) { + return parent.getAST().resolveWellKnownType(boolean.class.getSimpleName()); + + } else if (locationInParent == SwitchStatement.EXPRESSION_PROPERTY) { + final ITypeBinding discriminentType= expression.resolveTypeBinding(); + if (discriminentType.isPrimitive() || discriminentType.isEnum() + || discriminentType.getQualifiedName().equals(String.class.getCanonicalName())) { + return discriminentType; + } else { + return Bindings.getUnboxedTypeBinding(discriminentType, parent.getAST()); + } + } else if (locationInParent == MethodInvocation.ARGUMENTS_PROPERTY) { MethodInvocation methodInvocation= (MethodInvocation) parent; IMethodBinding methodBinding= methodInvocation.resolveMethodBinding(); @@ -969,7 +989,7 @@ public class ASTNodes { /** * Returns whether an expression at the given location needs explicit boxing. - * + * * @param expression the expression * @return <code>true</code> iff an expression at the given location needs explicit boxing * @since 3.6 @@ -978,18 +998,18 @@ public class ASTNodes { StructuralPropertyDescriptor locationInParent= expression.getLocationInParent(); if (locationInParent == ParenthesizedExpression.EXPRESSION_PROPERTY) return needsExplicitBoxing((ParenthesizedExpression) expression.getParent()); - + if (locationInParent == ClassInstanceCreation.EXPRESSION_PROPERTY || locationInParent == FieldAccess.EXPRESSION_PROPERTY || locationInParent == MethodInvocation.EXPRESSION_PROPERTY) return true; - + return false; } /** * Checks whether the given expression is a lambda expression with explicitly typed parameters. - * + * * @param expression the expression to check * @return <code>true</code> if the expression is a lambda expression with explicitly typed * parameters or no parameters, <code>false</code> otherwise @@ -1060,7 +1080,7 @@ public class ASTNodes { /** * For {@link Name} or {@link Type} nodes, returns the topmost {@link Type} node * that shares the same type binding as the given node. - * + * * @param node an ASTNode * @return the normalized {@link Type} node or the original node */ @@ -1086,7 +1106,7 @@ public class ASTNodes { /** * Returns <code>true</code> iff <code>parent</code> is a true ancestor of <code>node</code> * (i.e. returns <code>false</code> if <code>parent == node</code>). - * + * * @param node node to test * @param parent assumed parent * @return <code>true</code> iff <code>parent</code> is a true ancestor of <code>node</code> @@ -1281,7 +1301,7 @@ public class ASTNodes { * Returns the topmost ancestor of <code>name</code> that is still a {@link Name}. * <p> * <b>Note:</b> The returned node may resolve to a different binding than the given <code>name</code>! - * + * * @param name a name node * @return the topmost name * @see #getNormalizedNode(ASTNode) @@ -1298,7 +1318,7 @@ public class ASTNodes { * Returns the topmost ancestor of <code>node</code> that is a {@link Type} (but not a {@link UnionType}). * <p> * <b>Note:</b> The returned node often resolves to a different binding than the given <code>node</code>! - * + * * @param node the starting node, can be <code>null</code> * @return the topmost type or <code>null</code> if the node is not a descendant of a type node * @see #getNormalizedNode(ASTNode) @@ -1312,10 +1332,10 @@ public class ASTNodes { result= node; node= node.getParent(); } - + if (result instanceof Type) return (Type) result; - + return null; } @@ -1361,6 +1381,51 @@ public class ASTNodes { } } + /** + * Returns whether the provided method invocation invokes a method with the + * provided method signature. The method signature is compared against the + * erasure of the invoked method. + * + * @param node the method invocation to compare + * @param typeQualifiedName the qualified name of the type declaring + * the method + * @param methodName the method name + * @param parameterTypesQualifiedNames the qualified names of the parameter + * types + * @return true if the provided method invocation matches the provided method + * signature, false otherwise + */ + public static boolean usesGivenSignature(MethodInvocation node, String typeQualifiedName, String methodName, + String... parameterTypesQualifiedNames) { + if (node == null + || node.resolveMethodBinding() == null + || !node.resolveMethodBinding().getDeclaringClass().getQualifiedName().equals(typeQualifiedName) + || !node.getName().getIdentifier().equals(methodName)) { + return false; + } + + if (node.arguments() == null && parameterTypesQualifiedNames == null) { + return true; + } + + if (node.arguments() == null || parameterTypesQualifiedNames == null) { + return true; + } + + if (node.arguments().size() == parameterTypesQualifiedNames.length) { + return true; + } + + for (int i= 0; i < parameterTypesQualifiedNames.length; i++) { + if (((Type) node.typeArguments().get(i)).resolveBinding() == null + || ((Type) node.typeArguments().get(i)).resolveBinding().getQualifiedName() != parameterTypesQualifiedNames[i]) { + return false; + } + } + + return true; + } + public static Modifier findModifierNode(int flag, List<IExtendedModifier> modifiers) { for (int i= 0; i < modifiers.size(); i++) { Object curr= modifiers.get(i); @@ -1396,7 +1461,7 @@ public class ASTNodes { /** * Escapes a string value to a literal that can be used in Java source. - * + * * @param stringValue the string value * @return the escaped string * @see StringLiteral#getEscapedValue() @@ -1409,7 +1474,7 @@ public class ASTNodes { /** * Escapes a character value to a literal that can be used in Java source. - * + * * @param ch the character value * @return the escaped string * @see CharacterLiteral#getEscapedValue() @@ -1424,7 +1489,7 @@ public class ASTNodes { * If the given <code>node</code> has already been rewritten, undo that rewrite and return the * replacement version of the node. Otherwise, return the result of * {@link ASTRewrite#createCopyTarget(ASTNode)}. - * + * * @param rewrite ASTRewrite for the given node * @param node the node to get the replacement or to create a copy placeholder for * @param group the edit group which collects the corresponding text edits, or <code>null</code> @@ -1444,7 +1509,7 @@ public class ASTNodes { /** * Type-safe variant of {@link ASTRewrite#createMoveTarget(ASTNode)}. - * + * * @param rewrite ASTRewrite for the given node * @param node the node to create a move placeholder for * @return the new placeholder node @@ -1458,7 +1523,7 @@ public class ASTNodes { /** * Type-safe variant of {@link ASTNode#copySubtree(AST, ASTNode)}. - * + * * @param target the AST that is to own the nodes in the result * @param node the node to copy, or <code>null</code> if none * @return the copied node, or <code>null</code> if <code>node</code> @@ -1490,7 +1555,7 @@ public class ASTNodes { /** * Checks whether the given <code>exprStatement</code> has a semicolon at the end. - * + * * @param exprStatement the {@link ExpressionStatement} to check the semicolon * @param cu the compilation unit * @return <code>true</code> if the given <code>exprStatement</code> has a semicolon at the end, diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java index 98e09792fd..44a7b5a15d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java @@ -862,6 +862,30 @@ public class CleanUpConstants { */ public static final String REMOVE_REDUNDANT_MODIFIERS= "cleanup.remove_redundant_modifiers"; //$NON-NLS-1$ + /** + * Uses Autoboxing.<br> + * <br> + * Possible values: {TRUE, FALSE}<br> + * <br> + * + * @see CleanUpOptionsCore#TRUE + * @see CleanUpOptionsCore#FALSE + * @since 4.13 + */ + public static final String USE_AUTOBOXING= "cleanup.use_autoboxing"; //$NON-NLS-1$ + + /** + * Uses unboxing.<br> + * <br> + * Possible values: {TRUE, FALSE}<br> + * <br> + * + * @see CleanUpOptionsCore#TRUE + * @see CleanUpOptionsCore#FALSE + * @since 4.13 + */ + public static final String USE_UNBOXING= "cleanup.use_unboxing"; //$NON-NLS-1$ + /** * Removes redundant semicolons.<br> diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java index ba08cfe0be..8a81f01638 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java @@ -13,6 +13,7 @@ * Alex Blewitt - https://bugs.eclipse.org/bugs/show_bug.cgi?id=168954 * Chris West (Faux) <eclipse@goeswhere.com> - [clean up] "Use modifier 'final' where possible" can introduce compile errors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=272532 * Red Hat Inc. - redundant semicolons test + * Fabrice TIERCELIN - Autoboxing and Unboxing test *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; @@ -74,7 +75,7 @@ public class CleanUpTest extends CleanUpTestCase { // } }); } - + public static Test setUpTest(Test test) { return new ProjectTestSetup(test); } @@ -1003,7 +1004,7 @@ public class CleanUpTest extends CleanUpTestCase { public void testUnusedCodeBug371078_2() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); - + buf.append("package test1;\n"); buf.append("public class NestedCasts {\n"); buf.append(" void foo(Integer i) {\n"); @@ -1011,9 +1012,9 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("NestedCasts.java", buf.toString(), false, null); - + enable(CleanUpConstants.REMOVE_UNNECESSARY_CASTS); - + buf= new StringBuffer(); buf.append("package test1;\n"); buf.append("public class NestedCasts {\n"); @@ -1022,10 +1023,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testJava5001() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -1443,7 +1444,7 @@ public class CleanUpTest extends CleanUpTestCase { assertTrue(cleanUp.canFix(cu1, location)); } } - + public void testAddOverride15() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -1489,7 +1490,7 @@ public class CleanUpTest extends CleanUpTestCase { try { JavaProjectHelper.addRTJar16(project); IPackageFragmentRoot src= JavaProjectHelper.addSourceContainer(project, "src"); - + IPackageFragment pack1= src.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); buf.append("package test1;\n"); @@ -1534,13 +1535,13 @@ public class CleanUpTest extends CleanUpTestCase { JavaProjectHelper.delete(project); } } - + public void testAddOverride16_no_interface_methods() throws Exception { IJavaProject project= JavaProjectHelper.createJavaProject("CleanUpTestProject", "bin"); try { JavaProjectHelper.addRTJar16(project); IPackageFragmentRoot src= JavaProjectHelper.addSourceContainer(project, "src"); - + IPackageFragment pack1= src.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); buf.append("package test1;\n"); @@ -1556,10 +1557,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public int hashCode() { return 0; }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("I.java", buf.toString(), false, null); - + enable(CleanUpConstants.ADD_MISSING_ANNOTATIONS); enable(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE); - + buf= new StringBuffer(); buf.append("package test1;\n"); buf.append("interface I {\n"); @@ -1575,7 +1576,7 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public int hashCode() { return 0; }\n"); buf.append("}\n"); String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); } finally { JavaProjectHelper.delete(project); @@ -1586,7 +1587,7 @@ public class CleanUpTest extends CleanUpTestCase { * Tests if CleanUp works when the number of problems in a single CU is greater than the * Compiler option {@link JavaCore#COMPILER_PB_MAX_PER_UNIT} which has a default value of 100, * see http://bugs.eclipse.org/322543 for details. - * + * * @throws Exception if the something fails while executing this test * @since 3.7 */ @@ -3546,13 +3547,13 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS); enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS_INSTANCE_ACCESS); - + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } - + public void testRemoveNonStaticQualifier_Bug219204_1() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -3677,10 +3678,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS); enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS_INSTANCE_ACCESS); - + buf= new StringBuffer(); buf.append("package test1;\n"); buf.append("class Singleton {\n"); @@ -3704,7 +3705,7 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } @@ -4151,9 +4152,9 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); - + buf= new StringBuffer(); buf.append("package test1;\n"); buf.append("import java.util.List;\n"); @@ -4165,10 +4166,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); } - + public void testJava50ForLoopBug154939() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuilder buf= new StringBuilder(); @@ -4838,7 +4839,7 @@ public class CleanUpTest extends CleanUpTestCase { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testJava50ForLoop374264() throws Exception { //https://bugs.eclipse.org/bugs/show_bug.cgi?id=374264 IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -5943,6 +5944,871 @@ public class CleanUpTest extends CleanUpTestCase { assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); } + public void testAutoboxing() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void bar() {\n"); + bld.append(" Character c = Character.valueOf('*');\n"); + bld.append(" Byte by = Byte.valueOf((byte) 0);\n"); + bld.append(" Boolean bo = Boolean.valueOf(true);\n"); + bld.append(" Integer i = Integer.valueOf(42);\n"); + bld.append(" Long l1 = Long.valueOf(42L);\n"); + bld.append(" Long l2 = Long.valueOf(42);\n"); + bld.append(" Short s = Short.valueOf((short) 42);\n"); + bld.append(" Float f = Float.valueOf(42.42F);\n"); + bld.append(" Double d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_AUTOBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void bar() {\n"); + bld.append(" Character c = '*';\n"); + bld.append(" Byte by = (byte) 0;\n"); + bld.append(" Boolean bo = true;\n"); + bld.append(" Integer i = 42;\n"); + bld.append(" Long l1 = 42L;\n"); + bld.append(" Long l2 = (long) 42;\n"); + bld.append(" Short s = (short) 42;\n"); + bld.append(" Float f = 42.42F;\n"); + bld.append(" Double d = 42.42;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testAutoboxingSpecialCases() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void removeUnnecessaryValueOfCallsInPrimitiveDeclaration() {\n"); + bld.append(" char c = Character.valueOf('*');\n"); + bld.append(" byte by = Byte.valueOf((byte) 0);\n"); + bld.append(" boolean bo = Boolean.valueOf(true);\n"); + bld.append(" int i = Integer.valueOf(42);\n"); + bld.append(" long l1 = Long.valueOf(42L);\n"); + bld.append(" long l2 = Long.valueOf(42);\n"); + bld.append(" short s = Short.valueOf((short) 42);\n"); + bld.append(" float f = Float.valueOf(42.42F);\n"); + bld.append(" double d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void doNotUseAutoboxingWithObjectDeclaration() {\n"); + bld.append(" Object c = Character.valueOf('*');\n"); + bld.append(" Object by = Byte.valueOf((byte) 0);\n"); + bld.append(" Object bo = Boolean.valueOf(true);\n"); + bld.append(" Object i = Integer.valueOf(42);\n"); + bld.append(" Object l1 = Long.valueOf(42L);\n"); + bld.append(" Object l2 = Long.valueOf(42);\n"); + bld.append(" Object s = Short.valueOf((short) 42);\n"); + bld.append(" Object f = Float.valueOf(42.42F);\n"); + bld.append(" Object d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void directlyReturnWrapperParameter(Character c, Byte by, Boolean bo, Integer i, Long l, Short s,\n"); + bld.append(" Float f, Double d) {\n"); + bld.append(" Object myObject = null;\n"); + bld.append("\n"); + bld.append(" // Keep this comment\n"); + bld.append(" myObject = Character.valueOf(c);\n"); + bld.append(" myObject = Byte.valueOf(by);\n"); + bld.append(" myObject = Boolean.valueOf(bo);\n"); + bld.append(" myObject = Integer.valueOf(i);\n"); + bld.append(" myObject = Long.valueOf(l);\n"); + bld.append(" myObject = Short.valueOf(s);\n"); + bld.append(" myObject = Float.valueOf(f);\n"); + bld.append(" myObject = Double.valueOf(d);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void useAutoboxingOnAssignment() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" Character c;\n"); + bld.append(" c = Character.valueOf('*');\n"); + bld.append(" Byte by;\n"); + bld.append(" by = Byte.valueOf((byte) 0);\n"); + bld.append(" Boolean bo1;\n"); + bld.append(" bo1 = Boolean.valueOf(true);\n"); + bld.append(" Integer i;\n"); + bld.append(" i = Integer.valueOf(42);\n"); + bld.append(" Long l1;\n"); + bld.append(" l1 = Long.valueOf(42L);\n"); + bld.append(" Long l2;\n"); + bld.append(" l2 = Long.valueOf(42);\n"); + bld.append(" Short s;\n"); + bld.append(" s = Short.valueOf((short) 42);\n"); + bld.append(" Float f;\n"); + bld.append(" f = Float.valueOf(42.42F);\n"); + bld.append(" Double d;\n"); + bld.append(" d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void removeUnnecessaryValueOfCallsInPrimitiveAssignment() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c;\n"); + bld.append(" c = Character.valueOf('*');\n"); + bld.append(" byte by;\n"); + bld.append(" by = Byte.valueOf((byte) 0);\n"); + bld.append(" boolean bo1;\n"); + bld.append(" bo1 = Boolean.valueOf(true);\n"); + bld.append(" int i;\n"); + bld.append(" i = Integer.valueOf(42);\n"); + bld.append(" long l1;\n"); + bld.append(" l1 = Long.valueOf(42L);\n"); + bld.append(" long l2;\n"); + bld.append(" l2 = Long.valueOf(42);\n"); + bld.append(" short s;\n"); + bld.append(" s = Short.valueOf((short) 42);\n"); + bld.append(" float f;\n"); + bld.append(" f = Float.valueOf(42.42F);\n"); + bld.append(" double d;\n"); + bld.append(" d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void doNotUseAutoboxingWithObjectAssignment() {\n"); + bld.append(" Object c;\n"); + bld.append(" c = Character.valueOf('*');\n"); + bld.append(" Object by;\n"); + bld.append(" by = Byte.valueOf((byte) 0);\n"); + bld.append(" Object bo1;\n"); + bld.append(" bo1 = Boolean.valueOf(true);\n"); + bld.append(" Object i;\n"); + bld.append(" i = Integer.valueOf(42);\n"); + bld.append(" Object l1;\n"); + bld.append(" l1 = Long.valueOf(42L);\n"); + bld.append(" Object l2;\n"); + bld.append(" l2 = Long.valueOf(42);\n"); + bld.append(" Object s;\n"); + bld.append(" s = Short.valueOf((short) 42);\n"); + bld.append(" Object f;\n"); + bld.append(" f = Float.valueOf(42.42F);\n"); + bld.append(" Object d;\n"); + bld.append(" d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Character removeUnnecessaryValueOfCallsInCharacterWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Character.valueOf('*');\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Byte removeUnnecessaryValueOfCallsInByteWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Byte.valueOf((byte) 0);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Boolean removeUnnecessaryValueOfCallsInBooleanWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Boolean.valueOf(true);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Integer removeUnnecessaryValueOfCallsInIntegerWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Integer.valueOf(42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Long removeUnnecessaryValueOfCallsInLongWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Long.valueOf(42L);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Short removeUnnecessaryValueOfCallsInShortWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Short.valueOf((short) 42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Float removeUnnecessaryValueOfCallsInFloatWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Float.valueOf(42.42F);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Double removeUnnecessaryValueOfCallsInDoubleWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static char removeUnnecessaryValueOfCallsInCharacterPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Character.valueOf('*');\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static byte removeUnnecessaryValueOfCallsInBytePrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Byte.valueOf((byte) 0);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static boolean removeUnnecessaryValueOfCallsInBooleanPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Boolean.valueOf(true);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static int removeUnnecessaryValueOfCallsInIntegerPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Integer.valueOf(42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static long removeUnnecessaryValueOfCallsInLongPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Long.valueOf(42L);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static short removeUnnecessaryValueOfCallsInShortPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Short.valueOf((short) 42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static float removeUnnecessaryValueOfCallsInFloatPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Float.valueOf(42.42F);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static double removeUnnecessaryValueOfCallsInDoublePrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Object doNotUseAutoboxingReturningObject() {\n"); + bld.append(" return Character.valueOf('a');\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_AUTOBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void removeUnnecessaryValueOfCallsInPrimitiveDeclaration() {\n"); + bld.append(" char c = '*';\n"); + bld.append(" byte by = (byte) 0;\n"); + bld.append(" boolean bo = true;\n"); + bld.append(" int i = 42;\n"); + bld.append(" long l1 = 42L;\n"); + bld.append(" long l2 = 42;\n"); + bld.append(" short s = (short) 42;\n"); + bld.append(" float f = 42.42F;\n"); + bld.append(" double d = 42.42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void doNotUseAutoboxingWithObjectDeclaration() {\n"); + bld.append(" Object c = Character.valueOf('*');\n"); + bld.append(" Object by = Byte.valueOf((byte) 0);\n"); + bld.append(" Object bo = Boolean.valueOf(true);\n"); + bld.append(" Object i = Integer.valueOf(42);\n"); + bld.append(" Object l1 = Long.valueOf(42L);\n"); + bld.append(" Object l2 = Long.valueOf(42);\n"); + bld.append(" Object s = Short.valueOf((short) 42);\n"); + bld.append(" Object f = Float.valueOf(42.42F);\n"); + bld.append(" Object d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void directlyReturnWrapperParameter(Character c, Byte by, Boolean bo, Integer i, Long l, Short s,\n"); + bld.append(" Float f, Double d) {\n"); + bld.append(" Object myObject = null;\n"); + bld.append("\n"); + bld.append(" // Keep this comment\n"); + bld.append(" myObject = c;\n"); + bld.append(" myObject = by;\n"); + bld.append(" myObject = bo;\n"); + bld.append(" myObject = i;\n"); + bld.append(" myObject = l;\n"); + bld.append(" myObject = s;\n"); + bld.append(" myObject = f;\n"); + bld.append(" myObject = d;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void useAutoboxingOnAssignment() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" Character c;\n"); + bld.append(" c = '*';\n"); + bld.append(" Byte by;\n"); + bld.append(" by = (byte) 0;\n"); + bld.append(" Boolean bo1;\n"); + bld.append(" bo1 = true;\n"); + bld.append(" Integer i;\n"); + bld.append(" i = 42;\n"); + bld.append(" Long l1;\n"); + bld.append(" l1 = 42L;\n"); + bld.append(" Long l2;\n"); + bld.append(" l2 = (long) 42;\n"); + bld.append(" Short s;\n"); + bld.append(" s = (short) 42;\n"); + bld.append(" Float f;\n"); + bld.append(" f = 42.42F;\n"); + bld.append(" Double d;\n"); + bld.append(" d = 42.42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void removeUnnecessaryValueOfCallsInPrimitiveAssignment() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c;\n"); + bld.append(" c = '*';\n"); + bld.append(" byte by;\n"); + bld.append(" by = (byte) 0;\n"); + bld.append(" boolean bo1;\n"); + bld.append(" bo1 = true;\n"); + bld.append(" int i;\n"); + bld.append(" i = 42;\n"); + bld.append(" long l1;\n"); + bld.append(" l1 = 42L;\n"); + bld.append(" long l2;\n"); + bld.append(" l2 = 42;\n"); + bld.append(" short s;\n"); + bld.append(" s = (short) 42;\n"); + bld.append(" float f;\n"); + bld.append(" f = 42.42F;\n"); + bld.append(" double d;\n"); + bld.append(" d = 42.42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static void doNotUseAutoboxingWithObjectAssignment() {\n"); + bld.append(" Object c;\n"); + bld.append(" c = Character.valueOf('*');\n"); + bld.append(" Object by;\n"); + bld.append(" by = Byte.valueOf((byte) 0);\n"); + bld.append(" Object bo1;\n"); + bld.append(" bo1 = Boolean.valueOf(true);\n"); + bld.append(" Object i;\n"); + bld.append(" i = Integer.valueOf(42);\n"); + bld.append(" Object l1;\n"); + bld.append(" l1 = Long.valueOf(42L);\n"); + bld.append(" Object l2;\n"); + bld.append(" l2 = Long.valueOf(42);\n"); + bld.append(" Object s;\n"); + bld.append(" s = Short.valueOf((short) 42);\n"); + bld.append(" Object f;\n"); + bld.append(" f = Float.valueOf(42.42F);\n"); + bld.append(" Object d;\n"); + bld.append(" d = Double.valueOf(42.42);\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Character removeUnnecessaryValueOfCallsInCharacterWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return '*';\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Byte removeUnnecessaryValueOfCallsInByteWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return (byte) 0;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Boolean removeUnnecessaryValueOfCallsInBooleanWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return true;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Integer removeUnnecessaryValueOfCallsInIntegerWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Long removeUnnecessaryValueOfCallsInLongWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42L;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Short removeUnnecessaryValueOfCallsInShortWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return (short) 42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Float removeUnnecessaryValueOfCallsInFloatWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42.42F;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Double removeUnnecessaryValueOfCallsInDoubleWrapper() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42.42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static char removeUnnecessaryValueOfCallsInCharacterPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return '*';\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static byte removeUnnecessaryValueOfCallsInBytePrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return (byte) 0;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static boolean removeUnnecessaryValueOfCallsInBooleanPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return true;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static int removeUnnecessaryValueOfCallsInIntegerPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static long removeUnnecessaryValueOfCallsInLongPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42L;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static short removeUnnecessaryValueOfCallsInShortPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return (short) 42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static float removeUnnecessaryValueOfCallsInFloatPrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42.42F;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static double removeUnnecessaryValueOfCallsInDoublePrimitive() {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return 42.42;\n"); + bld.append(" }\n"); + bld.append("\n"); + bld.append(" public static Object doNotUseAutoboxingReturningObject() {\n"); + bld.append(" return Character.valueOf('a');\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUseUnboxingOnPrimitiveDeclaration() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void useUnboxingOnPrimitiveDeclaration(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c = cObject.charValue();\n"); + bld.append(" byte by = byObject.byteValue();\n"); + bld.append(" boolean bo = boObject.booleanValue();\n"); + bld.append(" int i = iObject.intValue();\n"); + bld.append(" short s = sObject.shortValue();\n"); + bld.append(" long l = lObject.longValue();\n"); + bld.append(" float f = fObject.floatValue();\n"); + bld.append(" double d = dObject.doubleValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void useUnboxingOnPrimitiveDeclaration(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c = cObject;\n"); + bld.append(" byte by = byObject;\n"); + bld.append(" boolean bo = boObject;\n"); + bld.append(" int i = iObject;\n"); + bld.append(" short s = sObject;\n"); + bld.append(" long l = lObject;\n"); + bld.append(" float f = fObject;\n"); + bld.append(" double d = dObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); + } + + public void testDoNotUseUnboxingOnNarrowingType() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E1 {\n"); + bld.append(" public static void doNotUseUnboxingOnNarrowingType(Character cObject, Byte byObject,\n"); + bld.append(" Integer iObject, Short sObject, Float fObject) {\n"); + bld.append(" int c = cObject.charValue();\n"); + bld.append(" int by = byObject.byteValue();\n"); + bld.append(" long i = iObject.intValue();\n"); + bld.append(" int s = sObject.shortValue();\n"); + bld.append(" double f = fObject.floatValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + + public void testDoNotUseUnboxingWhenTypesDontMatch() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E1 {\n"); + bld.append(" public static void doNotUseUnboxingWhenTypesDontMatch(Byte byObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" short by = byObject.shortValue();\n"); + bld.append(" short i = iObject.shortValue();\n"); + bld.append(" byte s = sObject.byteValue();\n"); + bld.append(" short l = lObject.shortValue();\n"); + bld.append(" short f = fObject.shortValue();\n"); + bld.append(" short d = dObject.shortValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + + public void testUnboxing2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void reuseWrapper(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" Character c = cObject.charValue();\n"); + bld.append(" Byte by = byObject.byteValue();\n"); + bld.append(" Boolean bo = boObject.booleanValue();\n"); + bld.append(" Integer i = iObject.intValue();\n"); + bld.append(" Short s = sObject.shortValue();\n"); + bld.append(" Long l = lObject.longValue();\n"); + bld.append(" Float f = fObject.floatValue();\n"); + bld.append(" Double d = dObject.doubleValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void reuseWrapper(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" Character c = cObject;\n"); + bld.append(" Byte by = byObject;\n"); + bld.append(" Boolean bo = boObject;\n"); + bld.append(" Integer i = iObject;\n"); + bld.append(" Short s = sObject;\n"); + bld.append(" Long l = lObject;\n"); + bld.append(" Float f = fObject;\n"); + bld.append(" Double d = dObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void useUnboxingOnPrimitiveAssignment(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c;\n"); + bld.append(" c = cObject.charValue();\n"); + bld.append(" byte by;\n"); + bld.append(" by = byObject.byteValue();\n"); + bld.append(" boolean bo;\n"); + bld.append(" bo = boObject.booleanValue();\n"); + bld.append(" int i;\n"); + bld.append(" i = iObject.intValue();\n"); + bld.append(" short s;\n"); + bld.append(" s = sObject.shortValue();\n"); + bld.append(" long l;\n"); + bld.append(" l = lObject.longValue();\n"); + bld.append(" float f;\n"); + bld.append(" f = fObject.floatValue();\n"); + bld.append(" double d;\n"); + bld.append(" d = dObject.doubleValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static void useUnboxingOnPrimitiveAssignment(Character cObject, Byte byObject, Boolean boObject,\n"); + bld.append(" Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" char c;\n"); + bld.append(" c = cObject;\n"); + bld.append(" byte by;\n"); + bld.append(" by = byObject;\n"); + bld.append(" boolean bo;\n"); + bld.append(" bo = boObject;\n"); + bld.append(" int i;\n"); + bld.append(" i = iObject;\n"); + bld.append(" short s;\n"); + bld.append(" s = sObject;\n"); + bld.append(" long l;\n"); + bld.append(" l = lObject;\n"); + bld.append(" float f;\n"); + bld.append(" f = fObject;\n"); + bld.append(" double d;\n"); + bld.append(" d = dObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing4() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static char useUnboxingOnPrimitiveReturn(Character cObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return cObject.charValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static char useUnboxingOnPrimitiveReturn(Character cObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return cObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing5() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static byte useUnboxingOnPrimitiveReturn(Byte byObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return byObject.byteValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static byte useUnboxingOnPrimitiveReturn(Byte byObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return byObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing6() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static boolean useUnboxingOnPrimitiveReturn(Boolean boObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return boObject.booleanValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static boolean useUnboxingOnPrimitiveReturn(Boolean boObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return boObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing7() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static int useUnboxingOnPrimitiveReturn(Integer iObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return iObject.intValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static int useUnboxingOnPrimitiveReturn(Integer iObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return iObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing8() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static short useUnboxingOnPrimitiveReturn(Short sObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return sObject.shortValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static short useUnboxingOnPrimitiveReturn(Short sObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return sObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing9() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static long useUnboxingOnPrimitiveReturn(Long lObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return lObject.longValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static long useUnboxingOnPrimitiveReturn(Long lObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return lObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing10() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static float useUnboxingOnPrimitiveReturn(Float fObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return fObject.floatValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static float useUnboxingOnPrimitiveReturn(Float fObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return fObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxing11() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static double useUnboxingOnPrimitiveReturn(Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return dObject.doubleValue();\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static double useUnboxingOnPrimitiveReturn(Double dObject) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return dObject;\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}); + } + + public void testUnboxingInArrayAccess() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static String useUnboxingOnArrayAccess(String[] strings, Integer i) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return strings[i.intValue()];\n"); + bld.append(" }\n"); + bld.append("}\n"); + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", bld.toString(), false, null); + + enable(CleanUpConstants.USE_UNBOXING); + + bld= new StringBuilder(); + bld.append("package test1;\n"); + bld.append("public class E {\n"); + bld.append(" public static String useUnboxingOnArrayAccess(String[] strings, Integer i) {\n"); + bld.append(" // Keep this comment\n"); + bld.append(" return strings[i];\n"); + bld.append(" }\n"); + bld.append("}\n"); + String expected1= bld.toString(); + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); + } + public void testAddParentheses01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -7122,7 +7988,7 @@ public class CleanUpTest extends CleanUpTestCase { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testRemoveQualifier01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -7454,15 +8320,15 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", buf.toString(), false, null); - + enable(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_FIELD_USE_THIS); enable(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_FIELD_USE_THIS_IF_NECESSARY); - + String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testAddFinal01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -7748,13 +8614,13 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" private transient int field= 0;\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL); enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PRIVATE_FIELDS); - + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } - + public void testAddFinalBug157276_1() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -8212,7 +9078,7 @@ public class CleanUpTest extends CleanUpTestCase { assertRefactoringHasNoChange(new ICompilationUnit[] {cu1}); } - + public void testAddFinalBug297566() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuilder buf= new StringBuilder(); @@ -8227,10 +9093,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL); enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PRIVATE_FIELDS); - + assertRefactoringHasNoChange(new ICompilationUnit[] {cu1}); } @@ -8251,13 +9117,13 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null); - + enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL); enable(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PRIVATE_FIELDS); - + assertRefactoringHasNoChange(new ICompilationUnit[] {cu1}); } - + public void testRemoveBlockReturnThrows01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -8526,9 +9392,9 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" static int anotherInt = someInt;\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("SM263173.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class SM263173 {\n"); @@ -8539,10 +9405,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" static int anotherInt = someInt;\n"); buf.append("}\n"); String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testSortMembersBug434941() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuilder buf= new StringBuilder(); @@ -8552,15 +9418,15 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public static void main(final String[] args) { }\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("A.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); enable(CleanUpConstants.SORT_MEMBERS_ALL); - + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); - + enable(CleanUpConstants.SORT_MEMBERS); disable(CleanUpConstants.SORT_MEMBERS_ALL); - + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } @@ -8575,10 +9441,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public final int D = 4;\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("A.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); disable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class A {\n"); @@ -8587,12 +9453,12 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public final int A = 2;\n"); buf.append(" public final int D = 4;\n"); buf.append("}\n"); - + String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testSortMembersMixedFieldsInterface() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -8604,14 +9470,14 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public final int D = 4;\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("A.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); disable(CleanUpConstants.SORT_MEMBERS_ALL); - + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); - + enable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public interface A {\n"); @@ -8620,12 +9486,12 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" public static final int C = 3;\n"); buf.append(" public final int D = 4;\n"); buf.append("}\n"); - + String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testSortMembersBug407759() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -8643,10 +9509,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" void foo() {}\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("A.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); disable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class A {\n"); @@ -8661,14 +9527,14 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" void foo2() {}\n"); buf.append(" void foo3() {}\n"); buf.append("}\n"); - + String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); - + enable(CleanUpConstants.SORT_MEMBERS); enable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class A {\n"); @@ -8683,16 +9549,16 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" void foo2() {}\n"); buf.append(" void foo3() {}\n"); buf.append("}\n"); - + expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } - + public void testSortMembersVisibility() throws Exception { JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER, true); JavaPlugin.getDefault().getPreferenceStore().setToDefault(PreferenceConstants.APPEARANCE_VISIBILITY_SORT_ORDER); - + try { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -8708,10 +9574,10 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" protected final int D = 4;\n"); buf.append("}\n"); ICompilationUnit cu1= pack1.createCompilationUnit("A.java", buf.toString(), false, null); - + enable(CleanUpConstants.SORT_MEMBERS); disable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class A {\n"); @@ -8724,14 +9590,14 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" final int C = 3;\n"); buf.append(" protected final int D = 4;\n"); buf.append("}\n"); - + String expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); - + enable(CleanUpConstants.SORT_MEMBERS); enable(CleanUpConstants.SORT_MEMBERS_ALL); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public class A {\n"); @@ -8744,15 +9610,15 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" protected final int D = 4;\n"); buf.append(" final int C = 3;\n"); buf.append("}\n"); - + expected1= buf.toString(); - + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }); } finally { JavaPlugin.getDefault().getPreferenceStore().setToDefault(PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER); } } - + public void testOrganizeImports01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); @@ -9145,7 +10011,7 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu2= pack1.createCompilationUnit("Sealed.java", buf.toString(), false, null); - + buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public final class Sealed {\n"); @@ -9155,7 +10021,7 @@ public class CleanUpTest extends CleanUpTestCase { buf.append(" }\n"); buf.append("}\n"); String expected2 = buf.toString(); - + // Anonymous class within an interface: // public keyword must not be removed (see bug#536612) buf= new StringBuffer(); @@ -9173,7 +10039,7 @@ public class CleanUpTest extends CleanUpTestCase { String expected3 = buf.toString(); ICompilationUnit cu3= pack1.createCompilationUnit("AnonymousNestedInInterface.java", buf.toString(), false, null); - // public modifier must not be removed from enum methods + // public modifier must not be removed from enum methods buf= new StringBuffer(); buf.append("package test;\n"); buf.append("public interface A {\n"); @@ -9186,16 +10052,16 @@ public class CleanUpTest extends CleanUpTestCase { // nested enum type is implicitly static // Bug#538459 'public' modified must not be removed from static method in nested enum String expected4 = buf.toString().replace("static enum", "enum"); - + enable(CleanUpConstants.REMOVE_REDUNDANT_MODIFIERS); assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1, cu2, cu3, cu4 }, new String[] { expected1, expected2, expected3, expected4 }); } - + public void testRemoveRedundantSemicolons () throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); StringBuffer buf= new StringBuffer(); - + // Ensure various extra semi-colons are removed and required ones are left intact. // This includes a lambda expression. buf.append("package test; ;\n"); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java index 47c68c1205..d4e33bc78e 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java @@ -83,6 +83,8 @@ public class CleanUpConstantsOptions extends CleanUpConstants { options.setOption(REMOVE_UNNECESSARY_NLS_TAGS, CleanUpOptions.TRUE); options.setOption(INSERT_INFERRED_TYPE_ARGUMENTS, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(USE_AUTOBOXING, CleanUpOptions.FALSE); + options.setOption(USE_UNBOXING, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_MODIFIERS, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_SEMICOLONS, CleanUpOptions.FALSE); @@ -172,6 +174,8 @@ public class CleanUpConstantsOptions extends CleanUpConstants { options.setOption(REMOVE_UNNECESSARY_NLS_TAGS, CleanUpOptions.FALSE); options.setOption(INSERT_INFERRED_TYPE_ARGUMENTS, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.FALSE); + options.setOption(USE_AUTOBOXING, CleanUpOptions.FALSE); + options.setOption(USE_UNBOXING, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_MODIFIERS, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_SEMICOLONS, CleanUpOptions.FALSE); diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml index 61d233411e..ed3252612a 100644 --- a/org.eclipse.jdt.ui/plugin.xml +++ b/org.eclipse.jdt.ui/plugin.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.0"?> <!-- - Copyright (c) 2000, 2006 IBM Corporation and others. + Copyright (c) 2000, 2019 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 @@ -7011,6 +7011,16 @@ id="org.eclipse.jdt.ui.cleanup.type_parameters" runAfter="org.eclipse.jdt.ui.cleanup.strings"> </cleanUp> + <cleanUp + class="org.eclipse.jdt.internal.ui.fix.AutoboxingCleanUp" + id="org.eclipse.jdt.ui.cleanup.autoboxing" + runAfter="org.eclipse.jdt.ui.cleanup.type_parameters"> + </cleanUp> + <cleanUp + class="org.eclipse.jdt.internal.ui.fix.UnboxingCleanUp" + id="org.eclipse.jdt.ui.cleanup.unboxing" + runAfter="org.eclipse.jdt.ui.cleanup.autoboxing"> + </cleanUp> </extension> <extension diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/AutoboxingCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/AutoboxingCleanUp.java new file mode 100644 index 0000000000..7ad973212f --- /dev/null +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/AutoboxingCleanUp.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2019 Fabrice TIERCELIN and others. + * + * 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 + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Fabrice TIERCELIN - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.ICompilationUnit; +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.CastExpression; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.PrimitiveType; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; + +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; + +import org.eclipse.jdt.ui.cleanup.CleanUpRequirements; +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.ui.text.java.IProblemLocation; + +/** + * A fix that uses Autoboxing: + * <ul> + * <li>As of Java 5, Integer.valueOf(int) can be replaced the int expression directly. + * And it is the case for all the primitive types. The method call is automatically added at compile time.</li> + * </ul> + */ +public class AutoboxingCleanUp extends AbstractMultiFix { + private static final String VALUE_OF_METHOD= "valueOf"; //$NON-NLS-1$ + + public AutoboxingCleanUp() { + this(Collections.emptyMap()); + } + + public AutoboxingCleanUp(Map<String, String> options) { + super(options); + } + + @Override + public CleanUpRequirements getRequirements() { + boolean requireAST= isEnabled(CleanUpConstants.USE_AUTOBOXING); + Map<String, String> requiredOptions= null; + return new CleanUpRequirements(requireAST, false, false, requiredOptions); + } + + @Override + public String[] getStepDescriptions() { + if (isEnabled(CleanUpConstants.USE_AUTOBOXING)) { + return new String[] { MultiFixMessages.AutoboxingCleanup_description }; + } + return new String[0]; + } + + @SuppressWarnings("nls") + @Override + public String getPreview() { + StringBuilder bld= new StringBuilder(); + bld.append("\n"); + bld.append("public class Foo {\n"); + bld.append(" public static void bar() {\n"); + if (isEnabled(CleanUpConstants.USE_AUTOBOXING)) { + bld.append(" Character c = '*';\n"); + } else { + bld.append(" Character c = Character.valueOf('*');\n"); + } + bld.append(" }\n"); + bld.append("}\n"); + + return bld.toString(); + } + + @Override + protected ICleanUpFix createFix(CompilationUnit unit) throws CoreException { + if (!isEnabled(CleanUpConstants.USE_AUTOBOXING) || !JavaModelUtil.is50OrHigher(unit.getJavaElement().getJavaProject())) { + return null; + } + + final List<CompilationUnitRewriteOperation> rewriteOperations= new ArrayList<>(); + + unit.accept(new ASTVisitor() { + @Override + public boolean visit(MethodInvocation node) { + if ((ASTNodes.usesGivenSignature(node, Boolean.class.getCanonicalName(), VALUE_OF_METHOD, boolean.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Byte.class.getCanonicalName(), VALUE_OF_METHOD, byte.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Character.class.getCanonicalName(), VALUE_OF_METHOD, char.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Short.class.getCanonicalName(), VALUE_OF_METHOD, short.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Integer.class.getCanonicalName(), VALUE_OF_METHOD, int.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Long.class.getCanonicalName(), VALUE_OF_METHOD, long.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Float.class.getCanonicalName(), VALUE_OF_METHOD, float.class.getSimpleName()) + || ASTNodes.usesGivenSignature(node, Double.class.getCanonicalName(), VALUE_OF_METHOD, double.class.getSimpleName()) + )) { + final ITypeBinding primitiveType= node.resolveMethodBinding().getParameterTypes()[0]; + final ITypeBinding wrapperClass= node.resolveMethodBinding().getDeclaringClass(); + + final ITypeBinding actualResultType= ASTNodes.getTargetType(node); + final ITypeBinding actualParameterType= ((Expression) node.arguments().get(0)).resolveTypeBinding(); + + if (actualParameterType != null + && (actualResultType != null + && (actualResultType.equals(primitiveType) || actualResultType.equals(wrapperClass))) + || Objects.equals(actualParameterType, wrapperClass)) { + rewriteOperations.add(new AutoboxingOperation(node, primitiveType, wrapperClass, actualParameterType, actualResultType)); + return false; + } + } + + return true; + } + }); + + if (rewriteOperations.isEmpty()) { + return null; + } + + return new CompilationUnitRewriteOperationsFix(MultiFixMessages.AutoboxingCleanup_description, unit, + rewriteOperations.toArray(new CompilationUnitRewriteOperation[rewriteOperations.size()])); + } + + @Override + public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem) { + return false; + } + + @Override + protected ICleanUpFix createFix(CompilationUnit unit, IProblemLocation[] problems) throws CoreException { + return null; + } + + private static class AutoboxingOperation extends CompilationUnitRewriteOperation { + private final ASTNode node; + + private final ITypeBinding primitiveType; + + private final ITypeBinding wrapperClass; + + private final ITypeBinding actualParameterType; + + private final ITypeBinding actualResultType; + + public AutoboxingOperation(ASTNode node, final ITypeBinding primitiveType, + final ITypeBinding wrapperClass, final ITypeBinding actualParameterType, + final ITypeBinding actualResultType) { + this.node= node; + this.primitiveType= primitiveType; + this.wrapperClass= wrapperClass; + this.actualParameterType= actualParameterType; + this.actualResultType= actualResultType; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel linkedModel) throws CoreException { + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + AST ast= cuRewrite.getRoot().getAST(); + Expression arg0= (Expression) rewrite.createCopyTarget((Expression) ((MethodInvocation) node).arguments().get(0)); + + if (primitiveType != null && !primitiveType.equals(actualParameterType) + && !primitiveType.equals(actualResultType) + && (wrapperClass == null || !wrapperClass.equals(actualParameterType))) { + CastExpression newCastExpression= ast.newCastExpression(); + newCastExpression.setType(ast.newPrimitiveType(PrimitiveType.toCode(primitiveType.getName()))); + newCastExpression.setExpression(arg0); + + rewrite.replace(node, newCastExpression, null); + } else { + rewrite.replace(node, arg0, null); + } + } + } +} diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/UnboxingCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/UnboxingCleanUp.java new file mode 100644 index 0000000000..cd6df1321b --- /dev/null +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/UnboxingCleanUp.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2019 Fabrice TIERCELIN and others. + * + * 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 + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Fabrice TIERCELIN - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import java.util.ArrayList; +import java.util.Collections; +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.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; + +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; + +import org.eclipse.jdt.ui.cleanup.CleanUpRequirements; +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.ui.text.java.IProblemLocation; + +/** + * A fix that uses Unboxing: + * <ul> + * <li>As of Java 5, intValue() call can be replaced the Integer wrapper expression directly. + * And it is the case for all the primitive wrappers. The method call is automatically added at compile time.</li> + * </ul> + */ +public class UnboxingCleanUp extends AbstractMultiFix { + private static final String DOUBLE_VALUE= "doubleValue"; //$NON-NLS-1$ + private static final String FLOAT_VALUE= "floatValue"; //$NON-NLS-1$ + private static final String LONG_VALUE= "longValue"; //$NON-NLS-1$ + private static final String INT_VALUE= "intValue"; //$NON-NLS-1$ + private static final String SHORT_VALUE= "shortValue"; //$NON-NLS-1$ + private static final String CHAR_VALUE= "charValue"; //$NON-NLS-1$ + private static final String BYTE_VALUE= "byteValue"; //$NON-NLS-1$ + private static final String BOOLEAN_VALUE= "booleanValue"; //$NON-NLS-1$ + + public UnboxingCleanUp() { + this(Collections.emptyMap()); + } + + public UnboxingCleanUp(Map<String, String> options) { + super(options); + } + + @Override + public CleanUpRequirements getRequirements() { + boolean requireAST= isEnabled(CleanUpConstants.USE_UNBOXING); + Map<String, String> requiredOptions= null; + return new CleanUpRequirements(requireAST, false, false, requiredOptions); + } + + @Override + public String[] getStepDescriptions() { + if (isEnabled(CleanUpConstants.USE_UNBOXING)) { + return new String[] { MultiFixMessages.UnboxingCleanup_description }; + } + return new String[0]; + } + + @SuppressWarnings("nls") + @Override + public String getPreview() { + StringBuilder bld= new StringBuilder(); + bld.append("\n"); + bld.append("public class Foo {\n"); + bld.append(" public static void bar(Character cObject) {\n"); + if (isEnabled(CleanUpConstants.USE_UNBOXING)) { + bld.append(" char c = cObject;\n"); + } else { + bld.append(" char c = cObject.charValue();\n"); + } + bld.append(" }\n"); + bld.append("}\n"); + + return bld.toString(); + } + + @Override + protected ICleanUpFix createFix(CompilationUnit unit) throws CoreException { + if (!isEnabled(CleanUpConstants.USE_UNBOXING) || !JavaModelUtil.is50OrHigher(unit.getJavaElement().getJavaProject())) { + return null; + } + + final List<CompilationUnitRewriteOperation> rewriteOperations= new ArrayList<>(); + + unit.accept(new ASTVisitor() { + @Override + public boolean visit(MethodInvocation node) { + if (node.getExpression() != null + && node.getExpression().resolveTypeBinding().isClass() + && (ASTNodes.usesGivenSignature(node, Boolean.class.getCanonicalName(), BOOLEAN_VALUE) || ASTNodes.usesGivenSignature(node, Byte.class.getCanonicalName(), BYTE_VALUE) + || ASTNodes.usesGivenSignature(node, Character.class.getCanonicalName(), CHAR_VALUE) + || ASTNodes.usesGivenSignature(node, Short.class.getCanonicalName(), SHORT_VALUE) + || ASTNodes.usesGivenSignature(node, Integer.class.getCanonicalName(), INT_VALUE) + || ASTNodes.usesGivenSignature(node, Long.class.getCanonicalName(), LONG_VALUE) + || ASTNodes.usesGivenSignature(node, Float.class.getCanonicalName(), FLOAT_VALUE) + || ASTNodes.usesGivenSignature(node, Double.class.getCanonicalName(), DOUBLE_VALUE))) { + final ITypeBinding actualResultType= ASTNodes.getTargetType(node); + + if (actualResultType != null && actualResultType.isAssignmentCompatible(node.resolveTypeBinding())) { + rewriteOperations.add(new UnboxingOperation(node)); + return false; + } + } + return true; + } + }); + + if (rewriteOperations.isEmpty()) { + return null; + } + + return new CompilationUnitRewriteOperationsFix(MultiFixMessages.UnboxingCleanup_description, unit, + rewriteOperations.toArray(new CompilationUnitRewriteOperation[rewriteOperations.size()])); + } + + @Override + public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem) { + return false; + } + + @Override + protected ICleanUpFix createFix(CompilationUnit unit, IProblemLocation[] problems) throws CoreException { + return null; + } + + private static class UnboxingOperation extends CompilationUnitRewriteOperation { + private final MethodInvocation node; + + public UnboxingOperation(MethodInvocation node) { + this.node= node; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel linkedModel) throws CoreException { + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + Expression copyOfWrapper= (Expression) rewrite.createCopyTarget(node.getExpression()); + rewrite.replace(node, copyOfWrapper, null); + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java index 1dfbe2d955..1aea5b551f 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java @@ -107,6 +107,8 @@ public class CleanUpMessages extends NLS { public static String UnnecessaryCodeTabPage_CheckboxName_UnnecessaryCasts; public static String UnnecessaryCodeTabPage_CheckboxName_UnnecessaryNLSTags; public static String UnnecessaryCodeTabPage_CheckboxName_RedundantTypeArguments; + public static String UnnecessaryCodeTabPage_CheckboxName_Autoboxing; + public static String UnnecessaryCodeTabPage_CheckboxName_Unboxing; public static String UnnecessaryCodeTabPage_CheckboxName_RedundantModifiers; public static String UnnecessaryCodeTabPage_CheckboxName_RedundantModifiers_description; public static String UnnecessaryCodeTabPage_CheckboxName_RedundantSemicolons; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties index 62ca9cc5c1..c0187a1388 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties @@ -95,6 +95,8 @@ UnnecessaryCodeTabPage_GroupName_UnnecessaryCode=Unnecessary code UnnecessaryCodeTabPage_CheckboxName_UnnecessaryCasts=Remove unnecessar&y casts UnnecessaryCodeTabPage_CheckboxName_UnnecessaryNLSTags=Remove unnecessary '$NON-NLS$' ta&gs UnnecessaryCodeTabPage_CheckboxName_RedundantTypeArguments=Remove redundant type &arguments (1.7 or higher) +UnnecessaryCodeTabPage_CheckboxName_Autoboxing=Use Autobo&xing (1.5 or higher) +UnnecessaryCodeTabPage_CheckboxName_Unboxing=Use Un&boxing (1.5 or higher) UnnecessaryCodeTabPage_CheckboxName_RedundantModifiers=R&emove redundant modifiers UnnecessaryCodeTabPage_CheckboxName_RedundantModifiers_description=Removes unnecessary modifiers on fields and methods UnnecessaryCodeTabPage_CheckboxName_RedundantSemicolons=Remove redundant semicolons diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/UnnecessaryCodeTabPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/UnnecessaryCodeTabPage.java index 26d327916f..0a6944c2a5 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/UnnecessaryCodeTabPage.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/UnnecessaryCodeTabPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Fabrice TIERCELIN - AutoBoxing usage *******************************************************************************/ package org.eclipse.jdt.internal.ui.preferences.cleanup; @@ -21,8 +22,10 @@ import org.eclipse.swt.widgets.Group; import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; import org.eclipse.jdt.internal.ui.fix.AbstractCleanUp; +import org.eclipse.jdt.internal.ui.fix.AutoboxingCleanUp; import org.eclipse.jdt.internal.ui.fix.StringCleanUp; import org.eclipse.jdt.internal.ui.fix.TypeParametersCleanUp; +import org.eclipse.jdt.internal.ui.fix.UnboxingCleanUp; import org.eclipse.jdt.internal.ui.fix.UnnecessaryCodeCleanUp; import org.eclipse.jdt.internal.ui.fix.RedundantModifiersCleanUp; import org.eclipse.jdt.internal.ui.fix.RedundantSemicolonsCleanUp; @@ -43,6 +46,8 @@ public final class UnnecessaryCodeTabPage extends AbstractCleanUpTabPage { new UnnecessaryCodeCleanUp(values), new StringCleanUp(values), new TypeParametersCleanUp(values), + new AutoboxingCleanUp(values), + new UnboxingCleanUp(values), new RedundantModifiersCleanUp(values), new RedundantSemicolonsCleanUp(values) }; @@ -78,6 +83,12 @@ public final class UnnecessaryCodeTabPage extends AbstractCleanUpTabPage { CheckboxPreference typeArgs= createCheckboxPref(unnecessaryGroup, numColumns, CleanUpMessages.UnnecessaryCodeTabPage_CheckboxName_RedundantTypeArguments, CleanUpConstants.REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpModifyDialog.FALSE_TRUE); registerPreference(typeArgs); + CheckboxPreference autoboxing= createCheckboxPref(unnecessaryGroup, numColumns, CleanUpMessages.UnnecessaryCodeTabPage_CheckboxName_Autoboxing, CleanUpConstants.USE_AUTOBOXING, CleanUpModifyDialog.FALSE_TRUE); + registerPreference(autoboxing); + + CheckboxPreference unboxing= createCheckboxPref(unnecessaryGroup, numColumns, CleanUpMessages.UnnecessaryCodeTabPage_CheckboxName_Unboxing, CleanUpConstants.USE_UNBOXING, CleanUpModifyDialog.FALSE_TRUE); + registerPreference(unboxing); + CheckboxPreference modifiers= createCheckboxPref(unnecessaryGroup, numColumns, CleanUpMessages.UnnecessaryCodeTabPage_CheckboxName_RedundantModifiers, CleanUpConstants.REMOVE_REDUNDANT_MODIFIERS, CleanUpModifyDialog.FALSE_TRUE); registerPreference(modifiers); |
