Skip to content

Commit

Permalink
Fix for #1014: preview for potential matches during rename refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jan 6, 2020
1 parent f205fad commit a15850d
Show file tree
Hide file tree
Showing 22 changed files with 461 additions and 227 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -672,7 +672,7 @@ public void testExplicitPropertySetterSearch2() throws Exception {
assertEquals(String.valueOf(baz.getContents()).indexOf("'setString'"), matches.get(1).getOffset());
assertEquals(SearchMatch.A_ACCURATE, matches.get(2).getAccuracy());
assertEquals(String.valueOf(baz.getContents()).indexOf("string = "), matches.get(2).getOffset());
assertEquals(SearchMatch.A_ACCURATE, matches.get(3).getAccuracy());
assertEquals(SearchMatch.A_INACCURATE, matches.get(3).getAccuracy());
assertEquals(String.valueOf(baz.getContents()).indexOf("string +="), matches.get(3).getOffset());
assertEquals(SearchMatch.A_INACCURATE, matches.get(4).getAccuracy());
assertEquals(String.valueOf(baz.getContents()).lastIndexOf("setString"), matches.get(4).getOffset());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -425,7 +425,7 @@ private int getAccuracy(TypeConfidence confidence) {
return SearchMatch.A_INACCURATE;
}

private static final Pattern ACCURATE_REQUESTOR = Pattern.compile("\\.(?:callhierarchy|refactoring)\\.");
private static final Pattern ACCURATE_REQUESTOR = Pattern.compile("\\.callhierarchy\\.");

private static boolean supportsOverride(IMethod method) throws JavaModelException {
int flags = method.getFlags();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.StatementMeta;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.transform.trait.Traits;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.jdt.core.Flags;
Expand Down Expand Up @@ -429,6 +430,16 @@ protected TypeLookupResult findTypeForNameWithKnownObjectExpression(final String
declaration = method.getOriginal(); // the trait method
}
}
// compound assignment (i.e., +=, &=, ?=, etc.) may involve separate declarations for read and write
if (confidence.isAtLeast(TypeConfidence.INFERRED) && isLhsExpression && isCompoundAssignment(scope)) {
if (declaration instanceof MethodNode) {
confidence = TypeConfidence.LOOSELY_INFERRED; // setter for write; field or property or accessor for read
} else if (findPropertyAccessorMethod(name, declaringType, false, isStaticObjectExpression, null).filter(getter ->
!isSynthetic(getter) && !(isFieldAccessDirect && declaringType.equals(getter.getDeclaringClass()))
).isPresent()) {
confidence = TypeConfidence.LOOSELY_INFERRED; // field or property for write; accessor for read
}
}
} else if (VariableScope.CLASS_CLASS_NODE.equals(resolvedDeclaringType) && declaration instanceof MethodNode) {
// beware of matching Class methods too aggressively; Arrays.toString(Object[]) vs. Class.toString()
MethodNode classMethod = (MethodNode) declaration;
Expand Down Expand Up @@ -517,6 +528,12 @@ protected TypeLookupResult findTypeForVariable(final VariableExpression var, fin
confidence = TypeConfidence.UNKNOWN; // reference to private method of super class yields MissingMethodException
}
}
// compound assignment (i.e., +=, &=, ?=, etc.) may involve separate declarations for read and write
if (confidence.isAtLeast(TypeConfidence.INFERRED) && isAssignTarget && isCompoundAssignment(scope) &&
(candidate instanceof MethodNode || !candidate.equals(findDeclarationForDynamicVariable(var, resolvedDeclaringType, scope, false, resolveStrategy)))) {
confidence = TypeConfidence.LOOSELY_INFERRED;
}

decl = candidate;
type = getTypeFromDeclaration(decl);
resolvedDeclaringType = getDeclaringTypeFromDeclaration(decl, resolvedDeclaringType);
Expand Down Expand Up @@ -924,6 +941,11 @@ protected static Optional<FieldNode> findTraitField(final String name, final Cla
return Optional.empty();
}

protected static boolean isCompoundAssignment(final VariableScope scope) {
return Optional.ofNullable(scope.getEnclosingAssignment())
.filter(expr -> expr.getOperation().getType() != Types.EQUALS).isPresent();
}

protected static Expression getObjectExpression(final VariableScope scope) {
ASTNode node = scope.getEnclosingNode();
if (node instanceof PropertyExpression) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -59,6 +59,7 @@
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.PropertyNode;
import org.codehaus.groovy.ast.Variable;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.expr.Expression;
Expand Down Expand Up @@ -687,6 +688,15 @@ public int getEnclosingClosureResolveStrategy() {
return null;
}

public BinaryExpression getEnclosingAssignment() {
Object node = getWormhole().get("enclosingAssignment");
if (node instanceof BinaryExpression) {
return (BinaryExpression) node;
} else {
return null;
}
}

/**
* Adds specified variable declaration to this scope.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package p;
import groovy.transform.CompileStatic
package p

class MyBean {
Class foo

public String setBar(Class bar) {
foo = bar
}
}

@CompileStatic
@groovy.transform.CompileStatic
class A {
def f = new MyBean()
def one = new MyBean()

void main() {
MyBean b2 = new MyBean(foo: (new MyBean()).foo)
def two = new MyBean(foo: (new MyBean()).foo)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package p;
import groovy.transform.CompileStatic
package p

class MyBean {
Class baz
Class fooBar

public String setBar(Class bar) {
baz = bar
fooBar = bar
}
}

@CompileStatic
@groovy.transform.CompileStatic
class A {
def f = new MyBean()
def one = new MyBean()

void main() {
MyBean b2 = new MyBean(baz: (new MyBean()).baz)
def two = new MyBean(fooBar: (new MyBean()).fooBar)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package p

class MyBean {
Integer foo = 0

Integer getFoo() {
return foo
}
}

void meth(MyBean bean) {
bean.foo += 1
bean.with { foo += 1 }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package p

class MyBean {
Integer fooBar = 0

Integer getFoo() {
return fooBar
}
}

void meth(MyBean bean) {
bean.fooBar += 1
bean.with { fooBar += 1 }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

void setFoo(Integer foo) {
this.foo = foo
}
}

class B {
void m(A a) {
a.foo += 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

void setFooBar(Integer foo) {
this.foo = foo
}
}

class B {
void m(A a) {
a.fooBar += 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

void setFoo(Integer foo) {
this.foo = foo
}
}

class B {
void m(A a) {
a.with { foo += 1 }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

void setFooBar(Integer foo) {
this.foo = foo
}
}

class B {
void m(A a) {
a.with { fooBar += 1 }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

Integer getFoo() {
return foo
}
}

class B {
void m(A a) {
a.foo += 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

Integer getFooBar() {
return foo
}
}

class B {
void m(A a) {
a.foo += 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

Integer getFoo() {
return foo
}
}

class B {
void m(A a) {
a.with { foo += 1 }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p;

class A {
Integer foo

Integer getFooBar() {
return foo
}
}

class B {
void m(A a) {
a.with { foo += 1 }
}
}
Loading

0 comments on commit a15850d

Please sign in to comment.