Skip to content

Commit

Permalink
Merge branch 'master' into Convert_String_concatenation_to_Text_Block
Browse files Browse the repository at this point in the history
  • Loading branch information
carstenartur authored Jul 25, 2024
2 parents b7f6a93 + 56e4b25 commit da4d207
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore
typeMethodReference.setName((SimpleName) rewrite.createCopyTarget(superMethodInvocation.getName()));
ImportRewrite importRewrite= cuRewrite.getImportRewrite();
ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(superMethodInvocation, methodBinding, superQualifier);
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding.getTypeDeclaration(), ast));
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding.getTypeDeclaration().getErasure(), ast));
typeMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
replacement= castMethodRefIfNeeded(cuRewrite, ast, typeMethodReference);
} else {
Expand All @@ -288,7 +288,7 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore
TypeLiteral typeLiteral= ast.newTypeLiteral();
ImportRewrite importRewrite= cuRewrite.getImportRewrite();
ITypeBinding instanceofTypeBinding= instanceofExpression.getRightOperand().resolveBinding();
typeLiteral.setType(importRewrite.addImport(instanceofTypeBinding.getTypeDeclaration(), ast));
typeLiteral.setType(importRewrite.addImport(instanceofTypeBinding.getTypeDeclaration().getErasure(), ast));
expMethodReference.setName(ast.newSimpleName("isInstance")); //$NON-NLS-1$
expMethodReference.setExpression(typeLiteral);
replacement= castMethodRefIfNeeded(cuRewrite, ast, expMethodReference);
Expand All @@ -308,7 +308,7 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore
ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(methodInvocation, methodBinding, invocationQualifier);
invocationTypeBinding= StubUtility2Core.replaceWildcardsAndCaptures(invocationTypeBinding);
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(lambda, importRewrite);
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding, ast, importRewriteContext, TypeLocation.OTHER));
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding.getErasure(), ast, importRewriteContext, TypeLocation.OTHER));
typeMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
replacement= castMethodRefIfNeeded(cuRewrite, ast, typeMethodReference);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,8 @@ public final class RefactoringCoreMessages extends NLS {

public static String MoveInstanceMethodProcessor_method_type_clash;

public static String MoveInstanceMethodProcessor_method_will_override_call_in_inner_subclass;

public static String MoveInstanceMethodProcessor_moved_element_pattern;

public static String MoveInstanceMethodProcessor_name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ MoveInstanceMethodProcessor_no_generic_targets=This method cannot be moved to th
MoveInstanceMethodProcessor_no_binary=Cannot move methods to binary types.
MoveInstanceMethodProcessor_no_interface=This refactoring cannot be used to move interface methods.
MoveInstanceMethodProcessor_no_annotation=This refactoring cannot be used to move annotation methods.
MoveInstanceMethodProcessor_method_will_override_call_in_inner_subclass=Moving method to target will cause logic change in class: ''{0}'' that sub-classes target.
MoveInstanceMethodProcessor_this_reference=A reference to 'this' has been found
MoveInstanceMethodProcessor_no_resolved_target=The target of the method could not be resolved.
MoveInstanceMethodProcessor_no_null_argument=The method invocation ''{0}'' cannot be updated, since it uses null as argument.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.SourceRange;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
Expand All @@ -84,6 +86,7 @@
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
Expand All @@ -100,6 +103,7 @@
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
Expand All @@ -126,8 +130,11 @@
import org.eclipse.jdt.core.refactoring.descriptors.MoveMethodDescriptor;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;

import org.eclipse.jdt.internal.core.manipulation.BindingLabelProviderCore;
import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore;
Expand All @@ -141,6 +148,7 @@
import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.AbortSearchException;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.BodyDeclarationRewrite;
import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
Expand Down Expand Up @@ -1457,6 +1465,131 @@ protected void checkFinalMethod(final RefactoringStatus status) throws JavaModel

}

private class CheckOuterMethodConflictVisitor extends ASTVisitor {
private final IMethod fMethodMoved;
private final TypeDeclaration fInnerType;

public CheckOuterMethodConflictVisitor(IMethod iMethod, TypeDeclaration innerType) {
this.fMethodMoved= iMethod;
this.fInnerType= innerType;
}

@Override
public boolean visit(MethodInvocation node) {
if (node.getName().getFullyQualifiedName().equals(fMethodMoved.getElementName())) {
IMethodBinding binding= node.resolveMethodBinding();
if (binding != null) {
if (fInnerType != null) {
String declaringClassName= binding.getDeclaringClass().getQualifiedName();
ITypeBinding innerTypeBinding= fInnerType.resolveBinding();
if (innerTypeBinding == null) {
return true;
}
while (innerTypeBinding != null) {
if (innerTypeBinding.getQualifiedName().equals(declaringClassName)) {
return true;
}
innerTypeBinding= innerTypeBinding.getSuperclass();
}
}
ITypeBinding[] parameterBindings= binding.getParameterTypes();
if (parameterBindings.length == fMethodMoved.getNumberOfParameters()) {
String[] methodParameterTypes= fMethodMoved.getParameterTypes();
boolean matches= true;
for (int i= 0; i < parameterBindings.length; ++i) {
String methodParameterType= new String(Signature.toCharArray(methodParameterTypes[i].toCharArray()));
if (!parameterBindings[i].getQualifiedName().equals(methodParameterType)) {
matches= false;
break;
}
}
if (matches) {
throw new AbortSearchException();
}
}
}
}
return true;
}
}
protected void checkOverrideOuterMethod(final IProgressMonitor monitor, final RefactoringStatus status) {
Assert.isNotNull(monitor);
Assert.isNotNull(status);

String typeName= fTargetType.getFullyQualifiedName();
SearchPattern pattern = SearchPattern.createPattern(typeName, IJavaSearchConstants.TYPE, IJavaSearchConstants.IMPLEMENTORS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
TypeExtendsSearchRequestor requestor= new TypeExtendsSearchRequestor();
try {
search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] {fMethod.getJavaProject()}), requestor);
} catch (CoreException e) {
return;
}
List<SearchMatch> results= requestor.getResults();
for (SearchMatch result : results) {
Object obj= result.getElement();
if (obj instanceof IType resultType) {
try {
ASTNode typeDecl= null;
if (resultType.isLocal() || resultType.isAnonymous()) {
ICompilationUnit icu= resultType.getCompilationUnit();
typeDecl= getTypeDeclaration(resultType, icu);
}
if (typeDecl != null) {
CheckOuterMethodConflictVisitor visitor= new CheckOuterMethodConflictVisitor(fMethod, typeDecl instanceof TypeDeclaration ? (TypeDeclaration)typeDecl : null);
try {
typeDecl.accept(visitor);
} catch (AbortSearchException e) {
status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_will_override_call_in_inner_subclass, resultType.getFullyQualifiedName('.')), JavaStatusContext.create(fMethod)));
}
}
} catch (JavaModelException e) {
// do nothing
}
}
}
}

private ASTNode getTypeDeclaration(IType iType, ICompilationUnit icu) throws JavaModelException {
ASTParser parser= ASTParser.newParser(AST.getJLSLatest());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(icu);
parser.setResolveBindings(true);
CompilationUnit compilationUnit= (CompilationUnit) parser.createAST(null);
ASTNode perform= NodeFinder.perform(compilationUnit, iType.getSourceRange());
if (perform instanceof TypeDeclaration && ((TypeDeclaration) perform).resolveBinding() != null) {
return perform;
} else if (perform instanceof AnonymousClassDeclaration && ((AnonymousClassDeclaration) perform).resolveBinding() != null) {
return perform;
}
return null;
}

private class TypeExtendsSearchRequestor extends SearchRequestor {

public List<SearchMatch> results= new ArrayList<>();

public List<SearchMatch> getResults() {
return results;
}

@Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
results.add(match);
}
}

}

private void search(SearchPattern searchPattern, IJavaSearchScope scope, SearchRequestor requestor) throws CoreException {
new SearchEngine().search(
searchPattern,
new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
scope,
requestor,
null);
}

/**
* Checks whether a method with the proposed name already exists in the
* target type.
Expand All @@ -1470,9 +1603,7 @@ protected void checkFinalMethod(final RefactoringStatus status) throws JavaModel
* retrieved
*/
protected void checkConflictingMethod(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
Assert.isNotNull(monitor);
Assert.isNotNull(status);
final IMethod[] methods= fTargetType.getMethods();
final IMethod[] methods= fTargetType.getMethods();
int newParamCount= fMethod.getParameterTypes().length;
if (!fTarget.isField())
newParamCount--; // moving to a parameter
Expand Down Expand Up @@ -1539,7 +1670,7 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
final RefactoringStatus status= new RefactoringStatus();
fChangeManager= new TextChangeManager();
try {
monitor.beginTask("", 4); //$NON-NLS-1$
monitor.beginTask("", 5); //$NON-NLS-1$
monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
status.merge(Checks.checkIfCuBroken(fMethod));
if (!status.hasError()) {
Expand All @@ -1556,6 +1687,7 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary, JavaStatusContext.create(fMethod)));
checkConflictingTarget(Progress.subMonitor(monitor, 1), status);
checkConflictingMethod(Progress.subMonitor(monitor, 1), status);
checkOverrideOuterMethod(Progress.subMonitor(monitor, 1), status);
checkFinalMethod(status);

Checks.addModifiedFilesToChecker(computeModifiedFiles(fMethod.getCompilationUnit(), type.getCompilationUnit()), context);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package p1;

public class A {
public B b;

public void m() {
System.out.println("d");
}
}

class B {

}

class C {

public void m() {
System.out.println("c");
}

public void foo() {
class D extends B {
public void t() {
m();
}
}
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,12 @@ public void testFail17() throws Exception {
failHelper1(new String[] { "p1.A", "p2.B"}, "p1.A", 13, 16, 13, 24, FIELD, "a1", true, true);
}

// Issue 1517
@Test
public void testFail18() throws Exception {
failHelper1(new String[] { "p1.A" }, "p1.A", 6, 17, 6, 18, FIELD, "b", true, true);
}

// Cannot move static method
@Test
public void testFail2() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4783,7 +4783,7 @@ public class E3<T> extends SuperE3<Number> {
Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);
Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);
Function<E3<Integer>, String> p1 = E3<Integer>::<Float>method2;
Function<E3<Integer>, String> p1 = E3::<Float>method2;
Function<E3, String> p2 = t -> /*[10]*/t.method2();
<V> String method2() { return "m2"; }
Expand Down Expand Up @@ -5075,6 +5075,55 @@ public boolean foo() {
assertExpectedExistInProposals(proposals, new String[] { expected1 });
}

@Test
public void testIssue1520() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String str= """
package test1;
import java.util.Optional;
import java.util.function.Supplier;
public class E6 {
public static void main(String[] args) {
create("Hello").map(c -> c.get()).map(s -> s.concat("World"));
}
public static <X> Optional<Supplier<X>> create(X value) {
if (value == null) {
return Optional.empty();
}
return Optional.of(() -> value);
}
}
""";
ICompilationUnit cu= pack1.createCompilationUnit("E6.java", str, false, null);

int offset= str.indexOf("c ->");
AssistContext context= getCorrectionContext(cu, offset, 4);
assertNoErrors(context);
List<IJavaCompletionProposal> proposals= collectAssists(context, false);
assertCorrectLabels(proposals);
String expected1= """
package test1;
import java.util.Optional;
import java.util.function.Supplier;
public class E6 {
public static void main(String[] args) {
create("Hello").map(Supplier::get).map(s -> s.concat("World"));
}
public static <X> Optional<Supplier<X>> create(X value) {
if (value == null) {
return Optional.empty();
}
return Optional.of(() -> value);
}
}
""";
assertExpectedExistInProposals(proposals, new String[] { expected1 });
}

@Test
public void testIssue1498() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
Expand Down Expand Up @@ -5794,7 +5843,7 @@ interface Source<U extends ArrayList<Number>> {
}
void f(Source<?> source) {
source.sendTo(ArrayList<Number>::size);
source.sendTo(ArrayList::size);
}
}
""";
Expand Down

0 comments on commit da4d207

Please sign in to comment.