Skip to content

Commit

Permalink
Add quick assist for deprecated method call (#704)
Browse files Browse the repository at this point in the history
* Add support to wrapper into a fix proposal an InlineMethodRefactoring for deprecated method call that has Javadoc mentioning another method to use and the code actually uses that method and no references to private fields are made
- add new tests to AssistQuickFixTest1d8
  • Loading branch information
jjohnstn authored Aug 11, 2023
1 parent 7e18055 commit f39fa82
Show file tree
Hide file tree
Showing 6 changed files with 520 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corporation and others.
* Copyright (c) 2000, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -183,6 +183,7 @@ private FixMessages() {
public static String StringBufferToStringBuilderFix_convert_msg;
public static String StringConcatToTextBlockFix_convert_msg;
public static String LambdaExpressionAndMethodRefFix_clean_up_expression_msg;
public static String InlineDeprecatedMethod_msg;

static {
// initialize resource bundle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ ReturnExpressionFix_description=Remove variable assignment before return
StringBufferToStringBuilderFix_convert_msg=Convert StringBuffer to StringBuilder
StringConcatToTextBlockFix_convert_msg=Convert String concatenation to Text Block
LambdaExpressionAndMethodRefFix_clean_up_expression_msg=Clean up lambda expression
InlineDeprecatedMethod_msg=Replace with inlined method

OneIfRatherThanDuplicateBlocksThatFallThroughFix_description=Single 'if' statement rather than duplicate blocks that fall through
PullOutIfFromIfElseFix_description=Pull out a duplicate 'if' from an if/else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat Inc. 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:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.fix;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.manipulation.ICleanUpFixCore;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;

import org.eclipse.jdt.internal.corext.refactoring.code.InlineMethodRefactoring;

public class InlineMethodFixCore implements IProposableFix, ICleanUpFixCore {

private final String fName;
private final ICompilationUnit fCompilationUnit;
private final InlineMethodRefactoring fRefactoring;

private InlineMethodFixCore(String name, CompilationUnit compilationUnit, InlineMethodRefactoring refactoring) {
this.fName= name;
this.fCompilationUnit= (ICompilationUnit)compilationUnit.getJavaElement();
this.fRefactoring= refactoring;
}

public static InlineMethodFixCore create(String name, CompilationUnit compilationUnit, MethodInvocation methodInvocation) {
ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement();
InlineMethodRefactoring refactoring= InlineMethodRefactoring.create(cu, compilationUnit,
methodInvocation.getStartPosition(), methodInvocation.getLength());
try {
RefactoringStatus status= refactoring.checkAllConditions(new NullProgressMonitor());
if (!status.isOK()) {
return null;
}
} catch (OperationCanceledException | CoreException e) {
return null;
}
InlineMethodFixCore fix= new InlineMethodFixCore(name, compilationUnit, refactoring);
return fix;
}
@Override
public CompilationUnitChange createChange(IProgressMonitor progressMonitor) throws CoreException {
CompositeChange change= (CompositeChange)fRefactoring.createChange(progressMonitor);
CompilationUnitChange compilationUnitChange= new CompilationUnitChange(fName, fCompilationUnit);
Change[] changes= change.getChildren();
if (changes.length == 1 && changes[0] instanceof TextChange textChange) {
compilationUnitChange.setEdit(textChange.getEdit());
return compilationUnitChange;
}
return null;
}

@Override
public String getDisplayString() {
return fName;
}

@Override
public String getAdditionalProposalInfo() {
// TODO Auto-generated method stub
return null;
}

@Override
public IStatus getStatus() {
// TODO Auto-generated method stub
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6503,5 +6503,284 @@ public void testAssignInTryWithResources_04() throws Exception {
assertExpectedExistInProposals(proposals, new String[] { expected });
}

@Test
public void testInlineDeprecated_1() throws Exception {
Hashtable<String, String> options= JavaCore.getOptions();
options.put(JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD, JavaCore.ENABLED);
JavaCore.setOptions(options);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String src=
"package test1;\n" +
"\n" +
"class E {\n" +
" private class E1 {\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z;\n" +
" return foo(x, k);\n" +
" }\n" +
" }\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" return e1.foo(a, b, c);\n" +
" }\n" +
"}\n";
ICompilationUnit cu= pack1.createCompilationUnit("E.java", src, false, null);
int offset= src.indexOf("e1.foo");
AssistContext context= getCorrectionContext(cu, offset + 3, 3);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);

assertNumberOfProposals(proposals, 1);
assertCorrectLabels(proposals);


String expected=
"package test1;\n" +
"\n" +
"class E {\n" +
" private class E1 {\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z;\n" +
" return foo(x, k);\n" +
" }\n" +
" }\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" int k = 2*b + 3*c;\n" +
" return e1.foo(a, k);\n" +
" }\n" +
"}\n";
assertExpectedExistInProposals(proposals, new String[] { expected });

}

@Test
public void testInlineDeprecated_2() throws Exception {
Hashtable<String, String> options= JavaCore.getOptions();
options.put(JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD, JavaCore.ENABLED);
JavaCore.setOptions(options);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String src=
"package test1;\n" +
"\n" +
"class E {\n" +
" private class E1 {\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z;\n" +
" return k;\n" +
" }\n" +
" }\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" return e1.foo(a, b, c);\n" +
" }\n" +
"}\n";
ICompilationUnit cu= pack1.createCompilationUnit("E.java", src, false, null);
int offset= src.indexOf("e1.foo");
AssistContext context= getCorrectionContext(cu, offset + 3, 3);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);

assertNumberOfProposals(proposals, 0);
}

@Test
public void testInlineDeprecated_3() throws Exception {
Hashtable<String, String> options= JavaCore.getOptions();
options.put(JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD, JavaCore.ENABLED);
JavaCore.setOptions(options);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String src=
"package test1;\n" +
"\n" +
"class E {\n" +
" private class E1 {\n" +
" private int v = 5;\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z + v;\n" +
" return foo(x, k);\n" +
" }\n" +
" }\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" return e1.foo(a, b, c);\n" +
" }\n" +
"}\n";
ICompilationUnit cu= pack1.createCompilationUnit("E.java", src, false, null);
int offset= src.indexOf("e1.foo");
AssistContext context= getCorrectionContext(cu, offset + 3, 3);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);

assertNumberOfProposals(proposals, 1);
assertCorrectLabels(proposals);


String expected=
"package test1;\n" +
"\n" +
"class E {\n" +
" private class E1 {\n" +
" private int v = 5;\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z + v;\n" +
" return foo(x, k);\n" +
" }\n" +
" }\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" int k = 2*b + 3*c + e1.v;\n" +
" return e1.foo(a, k);\n" +
" }\n" +
"}\n";
assertExpectedExistInProposals(proposals, new String[] { expected });
}

@Test
public void testInlineDeprecated_4() throws Exception {
Hashtable<String, String> options= JavaCore.getOptions();
options.put(JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD, JavaCore.ENABLED);
JavaCore.setOptions(options);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String src=
"package test1;\n" +
"\n" +
"public class E1 {\n" +
" private int v = 5;\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z + v;\n" +
" return foo(x, k);\n" +
" }\n" +
"}\n";
pack1.createCompilationUnit("E1.java", src, false, null);
String src1=
"package test1;\n" +
"\n" +
"class E {\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" return e1.foo(a, b, c);\n" +
" }\n" +
"}\n";
ICompilationUnit cu1= pack1.createCompilationUnit("E.java", src1, false, null);
int offset= src1.indexOf("e1.foo");
AssistContext context= getCorrectionContext(cu1, offset + 3, 3);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);

assertNumberOfProposals(proposals, 0);
}

@Test
public void testInlineDeprecated_5() throws Exception {
Hashtable<String, String> options= JavaCore.getOptions();
options.put(JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD, JavaCore.ENABLED);
JavaCore.setOptions(options);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String src=
"package test1;\n" +
"\n" +
"public class E1 {\n" +
" public int v = 5;\n" +
" public int foo(int a, int b) {\n" +
" return a + b;\n" +
" }\n" +
" /**\n" +
" * @deprecated use {@link #foo(int, int)} instead\n" +
" * @param x - x\n" +
" * @param y - y\n" +
" * @param z - z\n" +
" */\n" +
" @Deprecated\n" +
" public int foo(int x, int y, int z) {\n" +
" int k = 2*y + 3*z + v;\n" +
" return foo(x, k);\n" +
" }\n" +
"}\n";
pack1.createCompilationUnit("E1.java", src, false, null);
String src1=
"package test1;\n" +
"\n" +
"class E {\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" return e1.foo(a, b, c);\n" +
" }\n" +
"}\n";
ICompilationUnit cu1= pack1.createCompilationUnit("E.java", src1, false, null);
int offset= src1.indexOf("e1.foo");
AssistContext context= getCorrectionContext(cu1, offset + 3, 3);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);
assertNumberOfProposals(proposals, 1);

String expected=
"package test1;\n" +
"\n" +
"class E {\n" +
" public int callfoo(int a, int b, int c) {\n" +
" E1 e1= new E1();\n" +
" int k = 2*b + 3*c + e1.v;\n" +
" return e1.foo(a, k);\n" +
" }\n" +
"}\n";
assertExpectedExistInProposals(proposals, new String[] { expected });
}

}

Loading

0 comments on commit f39fa82

Please sign in to comment.