mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Convert to Java: this & super refs should have qualifiers if used inside closures
This commit is contained in:
+1
-1
@@ -687,7 +687,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
text = qname + ".this";
|
||||
}
|
||||
}
|
||||
return createReferenceExpressionFromText(text);
|
||||
return createReferenceExpressionFromText(text, psiClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -491,7 +491,7 @@ public class PsiUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isInDummyFile(@NotNull PsiElement context) {
|
||||
public static boolean isInDummyFile(@NotNull PsiElement context) {
|
||||
PsiFile file = context.getContainingFile();
|
||||
if (file == null) return false;
|
||||
|
||||
|
||||
+37
-13
@@ -16,9 +16,7 @@
|
||||
package org.jetbrains.plugins.groovy.refactoring.convertToJava;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -30,7 +28,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
@@ -58,11 +55,16 @@ public class ClosureGenerator {
|
||||
}
|
||||
|
||||
public void generate(@NotNull GrClosableBlock closure) {
|
||||
final String owner = getOwner(closure);
|
||||
builder.append("new ");
|
||||
writeTypeForNew(builder, closure.getType(), closure);
|
||||
builder.append('(');
|
||||
builder.append(owner).append(", ").append(owner).append(") {\n");
|
||||
|
||||
final CharSequence owner = getOwner(closure);
|
||||
builder.append(owner);
|
||||
builder.append(", ");
|
||||
builder.append(owner);
|
||||
|
||||
builder.append(") {\n");
|
||||
|
||||
generateClosureMainMethod(closure);
|
||||
|
||||
@@ -119,17 +121,39 @@ public class ClosureGenerator {
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
private static String getOwner(@NotNull GrClosableBlock closure) {
|
||||
final GroovyPsiElement context = PsiTreeUtil.getParentOfType(closure, GrMember.class, GrClosableBlock.class, GroovyFile.class);
|
||||
private CharSequence getOwner(@NotNull GrClosableBlock closure) {
|
||||
final GroovyPsiElement context = PsiTreeUtil.getParentOfType(closure, GrMember.class, GroovyFile.class);
|
||||
LOG.assertTrue(context != null);
|
||||
|
||||
if (context instanceof GrTypeDefinition) {
|
||||
LOG.error("closure must have member parent");
|
||||
final PsiClass contextClass;
|
||||
if (context instanceof GroovyFile) {
|
||||
contextClass = ((GroovyFile)context).getScriptClass();
|
||||
}
|
||||
else if (context instanceof PsiClass) {
|
||||
contextClass = (PsiClass)context;
|
||||
}
|
||||
else if (context instanceof GrMember) {
|
||||
if (((GrMember)context).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
contextClass = null; //no context class
|
||||
}
|
||||
else {
|
||||
contextClass = ((GrMember)context).getContainingClass();
|
||||
}
|
||||
}
|
||||
else {
|
||||
contextClass = null;
|
||||
}
|
||||
|
||||
if (contextClass == null) return "null";
|
||||
|
||||
final PsiElement implicitClass = GenerationUtil.getWrappingImplicitClass(closure);
|
||||
if (implicitClass == null) {
|
||||
return "this";
|
||||
}
|
||||
if (context instanceof GrMember && ((GrMember)context).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return "null";
|
||||
else {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
GenerationUtil.writeThisReference(contextClass, buffer, this.context);
|
||||
return buffer;
|
||||
}
|
||||
return "this";
|
||||
}
|
||||
}
|
||||
|
||||
+35
-8
@@ -915,12 +915,10 @@ public class ExpressionGenerator extends Generator {
|
||||
final GrExpression qualifier = referenceExpression.getQualifier();
|
||||
final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
|
||||
final PsiElement resolved = resolveResult.getElement();
|
||||
final String referenceName = referenceExpression.getReferenceName();
|
||||
|
||||
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
|
||||
if (!context.isInAnonymousContext() && qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
}
|
||||
builder.append(referenceExpression.getReferenceName());
|
||||
writeThisOrSuperRef(referenceExpression, qualifier, referenceName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -939,8 +937,8 @@ public class ExpressionGenerator extends Generator {
|
||||
}
|
||||
|
||||
//don't try to resolve local vars that are provided my this generator (they are listed in myUsedVarNames)
|
||||
if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceExpression.getReferenceName())) {
|
||||
builder.append(referenceExpression.getReferenceName());
|
||||
if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceName)) {
|
||||
builder.append(referenceName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -965,7 +963,7 @@ public class ExpressionGenerator extends Generator {
|
||||
LOG.assertTrue(qualifier != null);
|
||||
builder.append("new ").append(GroovyCommonClassNames.ORG_CODEHAUS_GROOVY_RUNTIME_METHOD_CLOSURE).append('(');
|
||||
qualifier.accept(this);
|
||||
builder.append(", \"").append(referenceExpression.getReferenceName()).append("\")");
|
||||
builder.append(", \"").append(referenceName).append("\")");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1018,7 +1016,7 @@ public class ExpressionGenerator extends Generator {
|
||||
}
|
||||
else {
|
||||
//unresolved reference
|
||||
final String refName = referenceExpression.getReferenceName();
|
||||
final String refName = referenceName;
|
||||
if (refName != null) {
|
||||
if (PsiUtil.isAccessedForWriting(referenceExpression)) {
|
||||
builder.append(refName);
|
||||
@@ -1057,6 +1055,35 @@ public class ExpressionGenerator extends Generator {
|
||||
|
||||
}
|
||||
|
||||
private void writeThisOrSuperRef(GrReferenceExpression referenceExpression, GrExpression qualifier, String referenceName) {
|
||||
if (!context.isInAnonymousContext() && qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
builder.append('.');
|
||||
builder.append(referenceName);
|
||||
}
|
||||
else if (getWrappingImplicitClass(referenceExpression) != null) {
|
||||
final PsiClass contextClass;
|
||||
if ("this".equals(referenceName)) {
|
||||
final PsiElement _contextClass = referenceExpression.resolve();
|
||||
if (_contextClass instanceof PsiClass) {
|
||||
contextClass = (PsiClass)_contextClass;
|
||||
}
|
||||
else {
|
||||
contextClass = null;
|
||||
}
|
||||
writeThisReference(contextClass, builder, context);
|
||||
}
|
||||
else { //super ref
|
||||
//super ref is used without qualifier. So we should use context class as a qualifier
|
||||
contextClass = PsiUtil.getContextClass(referenceExpression);
|
||||
writeSuperReference(contextClass, builder, context);
|
||||
}
|
||||
}
|
||||
else {
|
||||
builder.append(referenceName);
|
||||
}
|
||||
}
|
||||
|
||||
private String createVarByInitializer(@NotNull GrExpression initializer) {
|
||||
GrExpression inner = initializer;
|
||||
while (inner instanceof GrParenthesizedExpression) inner = ((GrParenthesizedExpression)inner).getOperand();
|
||||
|
||||
+35
@@ -27,6 +27,7 @@ import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrClassSubstitutor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
@@ -648,4 +649,38 @@ public class GenerationUtil {
|
||||
static PsiType getNotNullType(PsiElement context, PsiType type) {
|
||||
return type != null ? type : TypesUtil.getJavaLangObject(context);
|
||||
}
|
||||
|
||||
public static void writeThisReference(@Nullable PsiClass targetClass, StringBuilder buffer, ExpressionContext context) {
|
||||
if (targetClass != null && !(targetClass instanceof PsiAnonymousClass)) {
|
||||
final GrCodeReferenceElement ref = GroovyPsiElementFactory.getInstance(context.project).createCodeReferenceElementFromClass(targetClass);
|
||||
writeCodeReferenceElement(buffer, ref);
|
||||
buffer.append('.');
|
||||
}
|
||||
buffer.append("this");
|
||||
}
|
||||
|
||||
public static void writeSuperReference(@Nullable PsiClass targetClass, StringBuilder buffer, ExpressionContext context) {
|
||||
if (targetClass != null && !(targetClass instanceof PsiAnonymousClass)) {
|
||||
final GrCodeReferenceElement ref = GroovyPsiElementFactory.getInstance(context.project).createCodeReferenceElementFromClass(targetClass);
|
||||
writeCodeReferenceElement(buffer, ref);
|
||||
buffer.append('.');
|
||||
}
|
||||
buffer.append("super");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static PsiElement getWrappingImplicitClass(@NotNull PsiElement place) {
|
||||
PsiElement parent = place.getParent();
|
||||
|
||||
while (parent != null) {
|
||||
if (parent instanceof PsiClass) return null;
|
||||
if (parent instanceof GroovyFile && !(PsiUtil.isInDummyFile(parent))) return null;
|
||||
|
||||
if (parent instanceof GrClosableBlock) return parent;
|
||||
|
||||
parent = parent.getContext();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
print(new java.lang.Runnable() {
|
||||
public void run(java.lang.Object it) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, "foo}");
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(anonymousFromMap.this, "foo}");
|
||||
}
|
||||
public void run() {
|
||||
this.run(null);
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
java.util.ArrayList<java.lang.Integer> list = new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3));
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
public void doCall(java.lang.Object it) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, it);
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(closure.this, it);
|
||||
}
|
||||
|
||||
public void doCall() {
|
||||
|
||||
Vendored
+1
-1
@@ -8,7 +8,7 @@ this.foo = foo;
|
||||
private groovy.lang.Closure<java.lang.Integer> foo = new groovy.lang.Closure<java.lang.Integer>(this, this) {
|
||||
public java.lang.Integer doCall(int x) {
|
||||
final groovy.lang.Reference<java.lang.Integer> i1 = new groovy.lang.Reference<java.lang.Integer>(x);
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.each(1, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.each(1, new groovy.lang.Closure<java.lang.Void>(X.this, X.this) {
|
||||
public void doCall(java.lang.Object it) {
|
||||
i1.set(2);
|
||||
int i = 3;
|
||||
|
||||
plugins/groovy/testdata/refactoring/convertGroovyToJava/file/methodParamInClosureImplicitReturn.java
Vendored
+2
-2
@@ -12,7 +12,7 @@ public void foo(int x) {
|
||||
final groovy.lang.Reference<java.lang.Integer> i = new groovy.lang.Reference<java.lang.Integer>(x);
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure<java.lang.Integer>(this, this) {
|
||||
public java.lang.Integer doCall(java.lang.Object it) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, i.get());
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(methodParamInClosureImplicitReturn.this, i.get());
|
||||
return setGroovyRef(i, i.get() + 1);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ return doCall(null);
|
||||
});
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure<java.lang.Integer>(this, this) {
|
||||
public java.lang.Integer doCall(java.lang.Object it) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, i.get());
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(methodParamInClosureImplicitReturn.this, i.get());
|
||||
i.set(i.get()++);
|
||||
return i.get();
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
public class X {
|
||||
public void foo() {
|
||||
final groovy.lang.Reference<java.lang.Integer> ab = new groovy.lang.Reference<java.lang.Integer>(4);
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(this, new groovy.lang.Closure<java.lang.Object>(this, this) {
|
||||
public java.lang.Object doCall(java.lang.Object it) {
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.each(this, new groovy.lang.Closure<java.lang.Integer>(this, this) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(this, new groovy.lang.Closure<X>(this, this) {
|
||||
public X doCall(java.lang.Object it) {
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.each(X.this, new groovy.lang.Closure<java.lang.Integer>(X.this, X.this) {
|
||||
public java.lang.Integer doCall(java.lang.Object it) {
|
||||
return setGroovyRef(ab, 2);
|
||||
}
|
||||
@@ -15,7 +15,7 @@ return doCall(null);
|
||||
});
|
||||
}
|
||||
|
||||
public java.lang.Object doCall() {
|
||||
public X doCall() {
|
||||
return doCall(null);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ foo.set(foo.get()++);
|
||||
foo.set(foo.get() + 2);
|
||||
foo.set(foo.get() - 1);
|
||||
foo.set(4);
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, foo.get());
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(refInClosureInScript.this, foo.get());
|
||||
}
|
||||
|
||||
public void doCall() {
|
||||
|
||||
Reference in New Issue
Block a user