mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-66202: Groovy Extract Method Broken: Nested Closures drop 'it' reference
This commit is contained in:
+4
-13
@@ -48,7 +48,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
@@ -437,8 +436,9 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
|
||||
"getClass".equals(method.getName())) {
|
||||
if (seemsToBeQualifiedClassName(getQualifierExpression())) {
|
||||
result = createJavaLangClassType(facade, facade.getElementFactory().createTypeFromText(getQualifier().getText(), this));
|
||||
final GrExpression qualifier = getQualifier();
|
||||
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
|
||||
result = createJavaLangClassType(facade, facade.getElementFactory().createTypeFromText(qualifier.getText(), this));
|
||||
}
|
||||
else {
|
||||
result = getTypeForObjectGetClass(facade, method);
|
||||
@@ -464,7 +464,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
else if (resolved == null) {
|
||||
GrExpression qualifier = getQualifierExpression();
|
||||
if ("class".equals(getReferenceName())) {
|
||||
if (seemsToBeQualifiedClassName(qualifier)) {
|
||||
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
|
||||
assert qualifier != null;
|
||||
result = createJavaLangClassType(facade, facade.getElementFactory().createTypeFromText(qualifier.getText(), this));
|
||||
} else {
|
||||
@@ -502,15 +502,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
|
||||
if (qualifier == null) return false;
|
||||
while (qualifier instanceof GrReferenceExpression) {
|
||||
if (((GrReferenceExpression)qualifier).getReferenceNameElement() instanceof GrLiteral) return false;
|
||||
qualifier = ((GrReferenceExpression)qualifier).getQualifierExpression();
|
||||
}
|
||||
return qualifier == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiType createJavaLangClassType(JavaPsiFacade facade, @Nullable PsiType type) {
|
||||
PsiType result = null;
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection;
|
||||
@@ -304,41 +305,59 @@ public class PsiUtil {
|
||||
|
||||
public static <Qualifier extends PsiElement> boolean shortenReference(GrQualifiedReference<Qualifier> ref) {
|
||||
final Qualifier qualifier = ref.getQualifier();
|
||||
if (qualifier != null && !(qualifier instanceof GrSuperReferenceExpression) &&
|
||||
(PsiTreeUtil.getParentOfType(ref, GrDocMemberReference.class) != null ||
|
||||
PsiTreeUtil.getParentOfType(ref, GrDocComment.class) == null) &&
|
||||
PsiTreeUtil.getParentOfType(ref, GrImportStatement.class) == null &&
|
||||
PsiTreeUtil.getParentOfType(ref, GroovyCodeFragment.class) == null) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved != null) {
|
||||
ref.setQualifier(null);
|
||||
if (ref.isReferenceTo(resolved)) return true;
|
||||
if (qualifier == null || qualifier instanceof GrSuperReferenceExpression || cannotShortenInContext(ref)) {
|
||||
return false;
|
||||
}
|
||||
if (!canShorten(qualifier)) return false;
|
||||
|
||||
if (resolved instanceof PsiClass) {
|
||||
final GroovyFileBase file = (GroovyFileBase)ref.getContainingFile();
|
||||
final PsiClass clazz = (PsiClass)resolved;
|
||||
final String qName = clazz.getQualifiedName();
|
||||
if (qName != null) {
|
||||
if (mayInsertImport(ref)) {
|
||||
final GrImportStatement added = file.addImportForClass(clazz);
|
||||
if (!ref.isReferenceTo(resolved)) {
|
||||
file.removeImport(added);
|
||||
}
|
||||
}
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved == null) return false;
|
||||
|
||||
ref.setQualifier(null);
|
||||
if (ref.isReferenceTo(resolved)) return true;
|
||||
|
||||
if (resolved instanceof PsiClass) {
|
||||
final GroovyFileBase file = (GroovyFileBase)ref.getContainingFile();
|
||||
final PsiClass clazz = (PsiClass)resolved;
|
||||
final String qName = clazz.getQualifiedName();
|
||||
if (qName != null) {
|
||||
if (mayInsertImport(ref)) {
|
||||
final GrImportStatement added = file.addImportForClass(clazz);
|
||||
if (!ref.isReferenceTo(resolved)) {
|
||||
file.removeImport(added);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ref.isReferenceTo(resolved)) {
|
||||
ref.setQualifier((Qualifier)qualifier.copy());
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
if (!ref.isReferenceTo(resolved)) {
|
||||
ref.setQualifier((Qualifier)qualifier.copy());
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static <Qualifier extends PsiElement> boolean canShorten(Qualifier qualifier) {
|
||||
if (qualifier instanceof GrCodeReferenceElement) return true;
|
||||
if (qualifier instanceof GrExpression) {
|
||||
if (qualifier instanceof GrThisReferenceExpression) return true;
|
||||
if (seemsToBeQualifiedClassName((GrExpression)qualifier)) {
|
||||
final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
|
||||
if (resolved instanceof PsiClass || resolved instanceof PsiPackage) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static <Qualifier extends PsiElement> boolean cannotShortenInContext(GrQualifiedReference<Qualifier> ref) {
|
||||
return (PsiTreeUtil.getParentOfType(ref, GrDocMemberReference.class) == null &&
|
||||
PsiTreeUtil.getParentOfType(ref, GrDocComment.class) != null) ||
|
||||
PsiTreeUtil.getParentOfType(ref, GrImportStatement.class) != null ||
|
||||
PsiTreeUtil.getParentOfType(ref, GroovyCodeFragment.class) != null;
|
||||
}
|
||||
|
||||
private static <Qualifier extends PsiElement> boolean mayInsertImport(GrQualifiedReference<Qualifier> ref) {
|
||||
return PsiTreeUtil.getParentOfType(ref, GrDocComment.class) == null &&
|
||||
!(ref.getContainingFile() instanceof GroovyCodeFragment) &&
|
||||
@@ -1069,4 +1088,13 @@ public class PsiUtil {
|
||||
|
||||
return ((GrListOrMap)firstArg).getNamedArguments();
|
||||
}
|
||||
|
||||
public static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
|
||||
if (qualifier == null) return false;
|
||||
while (qualifier instanceof GrReferenceExpression) {
|
||||
if (((GrReferenceExpression)qualifier).getReferenceNameElement() instanceof GrLiteral) return false;
|
||||
qualifier = ((GrReferenceExpression)qualifier).getQualifierExpression();
|
||||
}
|
||||
return qualifier == null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -96,4 +96,5 @@ public class ExtractMethodTest extends LightGroovyTestCase {
|
||||
public void testMultiOutput4() {doTest();}
|
||||
public void testMultiOutput5() {doTest();}
|
||||
|
||||
public void testDontShortenRefsIncorrect() {doTest();}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<begin>print 1.getClass()<end>
|
||||
-----
|
||||
testMethod()
|
||||
|
||||
private def testMethod() {
|
||||
print 1.getClass()
|
||||
}
|
||||
Reference in New Issue
Block a user