IDEA-93455 this/super references are reference expressions

This commit is contained in:
Max Medvedev
2012-10-23 18:09:57 +04:00
parent 48aba342ad
commit 320dde0c5c
94 changed files with 594 additions and 428 deletions
@@ -36,6 +36,11 @@ public class ConvertToJavaAction extends BaseRefactoringAction {
return isEnabledOnElements(new PsiElement[]{element});
}
@Override
protected boolean isEnabledOnDataContext(DataContext dataContext) {
return super.isEnabledOnDataContext(dataContext);
}
@Override
protected boolean isAvailableInEditorOnly() {
return false;
@@ -104,6 +104,8 @@ public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPa
}
else if (token == GroovyTokenTypes.kDEF && element.getParent() instanceof GrAnnotationNameValuePair) return false;
else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) {
if (token == GroovyTokenTypes.kSUPER && ((GrReferenceExpression)parent).getQualifier() == null) return true;
if (token == GroovyTokenTypes.kTHIS && ((GrReferenceExpression)parent).getQualifier() == null) return true;
return false; //don't highlight foo.def
}
@@ -288,6 +288,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
@Override
public void visitReferenceExpression(final GrReferenceExpression referenceExpression) {
checkStringNameIdentifier(referenceExpression);
checkThisOrSuperReferenceExpression(referenceExpression, myHolder);
}
private void checkStringNameIdentifier(GrReferenceExpression ref) {
@@ -955,7 +956,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
final PsiClass clazz = invocation.getDelegatedClass();
if (clazz != null) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true);
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getInvokedExpression(), true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.apply.default.constructor", clazz.getName());
myHolder.createWarningAnnotation(argList, message);
@@ -1030,23 +1031,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
final GrReferenceExpression qualifier = superExpression.getQualifier();
if (qualifier == null) {
final GrMember container = PsiTreeUtil.getParentOfType(superExpression, GrMethod.class, GrClassInitializer.class);
if (container != null && container.hasModifierProperty(STATIC)) {
myHolder.createErrorAnnotation(superExpression, GroovyBundle.message("super.cannot.be.used.in.static.context"));
}
}
checkThisOrSuperReferenceExpression(superExpression, myHolder);
}
@Override
public void visitThisExpression(GrThisReferenceExpression thisExpression) {
checkThisOrSuperReferenceExpression(thisExpression, myHolder);
}
@Override
public void visitLiteralExpression(GrLiteral literal) {
final IElementType elementType = literal.getFirstChild().getNode().getElementType();
@@ -1416,32 +1400,43 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
return PsiTreeUtil.getParentOfType(statement, GrLoopStatement.class, true, GrClosableBlock.class, GrMember.class, GroovyFile.class);
}
private static void checkThisOrSuperReferenceExpression(GrThisSuperReferenceExpression expression, AnnotationHolder holder) {
final GrReferenceExpression qualifier = expression.getQualifier();
if (qualifier != null) {
GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(expression, GrTypeDefinition.class, true, GroovyFile.class);
if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) {
holder.createErrorAnnotation(expression, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes", expression.getReferenceName()));
return;
}
private static void checkThisOrSuperReferenceExpression(GrReferenceExpression ref, AnnotationHolder holder) {
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return;
final PsiElement resolved = qualifier.resolve();
IElementType elementType = nameElement.getNode().getElementType();
if (!(elementType == GroovyTokenTypes.kSUPER || elementType == GroovyTokenTypes.kTHIS)) return;
final GrExpression qualifier = ref.getQualifier();
if (qualifier instanceof GrReferenceExpression) {
final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) {
if (PsiTreeUtil.isAncestor(resolved, expression, true)) {
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, expression, true)) {
Annotation annotation =
holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText()));
annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS);
GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true, GroovyFile.class);
if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) {
holder.createErrorAnnotation(ref, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes",
nameElement.getText()));
return;
}
if (PsiTreeUtil.isAncestor(resolved, ref, true)) {
if (PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, true)) {
holder.createInfoAnnotation(nameElement, null).setTextAttributes(DefaultHighlighter.KEYWORD);
}
}
else {
String qname = ((PsiClass)resolved).getQualifiedName();
assert qname != null;
holder.createErrorAnnotation(expression, GroovyBundle.message("is.not.enclosing.class", qname));
holder.createErrorAnnotation(ref, GroovyBundle.message("is.not.enclosing.class", qname));
}
}
else {
holder.createErrorAnnotation(qualifier, GroovyBundle.message("cannot.resolve", qualifier.getText()));
}
else if (qualifier == null) {
if (elementType == GroovyTokenTypes.kSUPER) {
final GrMember container = PsiTreeUtil.getParentOfType(ref, GrMethod.class, GrClassInitializer.class);
if (container != null && container.hasModifierProperty(STATIC)) {
holder.createErrorAnnotation(ref, GroovyBundle.message("super.cannot.be.used.in.static.context"));
}
}
}
}
@@ -58,6 +58,7 @@ public class GrReassignedLocalVarsChecker {
return null;
}
assert resolved != null;
return getLeastUpperBoundByVar((GrVariable)resolved);
}
@@ -548,7 +548,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitConstructorInvocation(GrConstructorInvocation invocation) {
super.visitConstructorInvocation(invocation);
checkConstructorCall(invocation, invocation.getThisOrSuperKeyword());
checkConstructorCall(invocation, invocation.getInvokedExpression());
}
@Override
@@ -209,7 +209,9 @@ public class GroovyAccessibilityInspection extends BaseInspection {
@Override
public void visitReferenceExpression(GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
checkRef(ref);
if (!(ref.getParent() instanceof GrConstructorInvocation)) { //constructor invocation is checked in separate place
checkRef(ref);
}
}
@Override
@@ -229,7 +231,7 @@ public class GroovyAccessibilityInspection extends BaseInspection {
refElement = ((GrNewExpression)call).getReferenceElement();
}
else if (call instanceof GrConstructorInvocation) {
refElement = ((GrConstructorInvocation)call).getThisOrSuperKeyword();
refElement = ((GrConstructorInvocation)call).getInvokedExpression();
}
if (refElement == null) {
refElement = call;
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.BoolUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition;
@@ -36,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrC
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.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@SuppressWarnings({"OverlyComplexClass"})
class RecursionUtils {
@@ -45,7 +47,7 @@ class RecursionUtils {
}
public static boolean statementMayReturnBeforeRecursing(
GrStatement statement, GrMethod method) {
@Nullable GrStatement statement, GrMethod method) {
if (statement == null) {
return true;
}
@@ -183,7 +185,7 @@ class RecursionUtils {
}
private static boolean codeBlockMayReturnBeforeRecursing(
GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) {
@Nullable GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) {
if (block == null) {
return true;
}
@@ -205,14 +207,12 @@ class RecursionUtils {
return recursionVisitor.isRecursive();
}
private static boolean expressionDefinitelyRecurses(GrExpression exp,
private static boolean expressionDefinitelyRecurses(@Nullable GrExpression exp,
GrMethod method) {
if (exp == null) {
return false;
}
if (exp instanceof GrLiteral ||
exp instanceof GrThisReferenceExpression ||
exp instanceof GrSuperReferenceExpression) {
if (exp instanceof GrLiteral) {
return false;
}
if (exp instanceof GrMethodCallExpression) {
@@ -399,7 +399,7 @@ class RecursionUtils {
method.hasModifierProperty(PsiModifier.PRIVATE)) {
return true;
}
if (qualifier == null || qualifier instanceof GrThisReferenceExpression) {
if (qualifier == null || qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) {
return true;
}
}
@@ -410,7 +410,7 @@ class RecursionUtils {
return callExpressionDefinitelyRecurses(exp, method);
}
private static boolean statementDefinitelyRecurses(GrStatement statement,
private static boolean statementDefinitelyRecurses(@Nullable GrStatement statement,
GrMethod method) {
if (statement == null) {
return false;
@@ -137,7 +137,7 @@ public class GroovyPointlessBooleanInspection extends BaseInspection {
return lhs.getText() + negatedComparison + rhs.getText();
} else {
final String baseText = exp.getText();
if (ParenthesesUtils.getPrecendence(exp) >
if (ParenthesesUtils.getPrecedence(exp) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + baseText + ')';
} else {
@@ -35,12 +35,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import javax.swing.*;
@@ -172,8 +172,14 @@ public class GrMethodMayBeStaticInspection extends BaseInspection {
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
if (referenceExpression.getParent() instanceof GrReferenceExpression) return;
registerInstanceRefs();
return;
}
GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null || qualifier instanceof GrThisSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
GroovyResolveResult result = referenceExpression.advancedResolve();
PsiElement element = result.getElement();
if (isPrintOrPrintln(element)) return; //print & println are resolved in all places
@@ -190,13 +196,6 @@ public class GrMethodMayBeStaticInspection extends BaseInspection {
}
}
@Override
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) {
if (expression.getParent() instanceof GrReferenceExpression) return;
registerInstanceRefs();
}
private void registerInstanceRefs() {
if (myIsInClosure > 0) {
myHaveNoInstanceRefsInClosure = false;
@@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspection {
@@ -98,7 +97,7 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio
if (!(methodExpression instanceof GrReferenceExpression)) {
return;
}
final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
final GrReferenceExpression referenceExpression = (GrReferenceExpression)methodExpression;
final String name = referenceExpression.getReferenceName();
if (name == null || !name.startsWith(GET_PREFIX)) {
return;
@@ -112,11 +111,8 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio
return;
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
return;
}
if (qualifier == null) return;
if (PsiUtil.isThisOrSuperRef(qualifier)) return;
registerMethodCallError(grMethodCallExpression);
}
}
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection {
@@ -106,9 +105,7 @@ public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection {
@@ -107,9 +106,7 @@ public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection {
@@ -106,9 +105,7 @@ public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection {
private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix();
@@ -108,9 +107,7 @@ public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspection {
private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix();
@@ -116,9 +115,7 @@ public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspectio
return;
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
registerMethodCallError(grMethodCallExpression);
@@ -27,8 +27,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyAccessToStaticFieldLockedOnInstanceInspection
extends BaseInspection {
@@ -79,29 +79,26 @@ public class GroovyAccessToStaticFieldLockedOnInstanceInspection
}
PsiElement elementToCheck = expression;
while (true) {
final GrSynchronizedStatement syncStatement =
PsiTreeUtil.getParentOfType(elementToCheck,
GrSynchronizedStatement.class);
final GrSynchronizedStatement syncStatement = PsiTreeUtil.getParentOfType(elementToCheck, GrSynchronizedStatement.class);
if (syncStatement == null) {
break;
}
final GrExpression lockExpression =
syncStatement.getMonitor();
if (lockExpression instanceof GrReferenceExpression) {
final GrReferenceExpression reference =
(GrReferenceExpression) lockExpression;
final GrExpression lockExpression = syncStatement.getMonitor();
if (lockExpression instanceof GrReferenceExpression && PsiUtil.isThisReference(lockExpression)) {
isLockedOnInstance = true;
}
else if (lockExpression instanceof GrReferenceExpression) {
final GrReferenceExpression reference = (GrReferenceExpression) lockExpression;
final PsiElement referent = reference.resolve();
if (referent instanceof PsiField) {
final PsiField referentField = (PsiField) referent;
if (referentField.hasModifierProperty(
PsiModifier.STATIC)) {
if (referentField.hasModifierProperty(PsiModifier.STATIC)) {
isLockedOnClass = true;
} else {
isLockedOnInstance = true;
}
}
} else if (lockExpression instanceof GrThisReferenceExpression) {
isLockedOnInstance = true;
}
elementToCheck = syncStatement;
}
@@ -22,7 +22,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovySynchronizationOnThisInspection extends BaseInspection {
@@ -52,7 +53,7 @@ public class GroovySynchronizationOnThisInspection extends BaseInspection {
public void visitSynchronizedStatement(GrSynchronizedStatement synchronizedStatement) {
super.visitSynchronizedStatement(synchronizedStatement);
final GrExpression lock = synchronizedStatement.getMonitor();
if (lock == null || !(lock instanceof GrThisReferenceExpression)) {
if (lock == null || !(lock instanceof GrReferenceExpression && PsiUtil.isThisReference(lock))) {
return;
}
registerError(lock);
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.codeInspection.utils;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils;
import org.jetbrains.plugins.groovy.intentions.utils.ParenthesesUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
@@ -38,7 +39,7 @@ public class BoolUtils {
return GroovyTokenTypes.mBNOT.equals(sign);
}
public static boolean isTrue(GrCondition condition) {
public static boolean isTrue(@Nullable GrCondition condition) {
if (condition == null) {
return false;
}
@@ -68,7 +69,7 @@ public class BoolUtils {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -54,10 +54,8 @@ public class EquivalenceChecker {
super();
}
private static final int THIS_EXPRESSION = 0;
private static final int LITERAL_EXPRESSION = 1;
private static final int REFERENCE_EXPRESSION = 3;
private static final int SUPER_EXPRESSION = 4;
private static final int CALL_EXPRESSION = 5;
private static final int NEW_EXPRESSION = 6;
private static final int ARRAY_LITERAL_EXPRESSION = 7;
@@ -355,7 +353,9 @@ public class EquivalenceChecker {
return openBlocksAreEquivalent(block1, block2);
}
private static boolean openBlocksAreEquivalent(GrOpenBlock block1, GrOpenBlock block2) {
private static boolean openBlocksAreEquivalent(@Nullable GrOpenBlock block1, @Nullable GrOpenBlock block2) {
if (block1 == null || block2 == null) return false;
final GrStatement[] statements1 = block1.getStatements();
final GrStatement[] statements2 = block2.getStatements();
if (statements1.length != statements2.length) {
@@ -418,9 +418,6 @@ public class EquivalenceChecker {
return false;
}
switch (type1) {
case THIS_EXPRESSION:
case SUPER_EXPRESSION:
return true;
case LITERAL_EXPRESSION:
case REFERENCE_EXPRESSION:
final String text1 = expToCompare1.getText();
@@ -460,8 +457,8 @@ public class EquivalenceChecker {
return typecastExpressionsAreEquivalent((GrTypeCastExpression) expToCompare1,
(GrTypeCastExpression) expToCompare2);
case SAFE_CAST_EXPRESSION:
return safecastExpressionsAreEquivalent((GrSafeCastExpression) expToCompare1,
(GrSafeCastExpression) expToCompare2);
return safeCastExpressionsAreEquivalent((GrSafeCastExpression)expToCompare1,
(GrSafeCastExpression)expToCompare2);
case INSTANCEOF_EXPRESSION:
return instanceofExpressionsAreEquivalent((GrInstanceOfExpression) expToCompare1,
(GrInstanceOfExpression) expToCompare2);
@@ -538,8 +535,12 @@ public class EquivalenceChecker {
if (!expressionsAreEquivalent(operand1, operand2)) {
return false;
}
final PsiType type1 = expression1.getTypeElement().getType();
final PsiType type2 = expression2.getTypeElement().getType();
GrTypeElement typeElement1 = expression1.getTypeElement();
GrTypeElement typeElement2 = expression2.getTypeElement();
if (typeElement1 == null || typeElement2 == null) return false;
final PsiType type1 = typeElement1.getType();
final PsiType type2 = typeElement2.getType();
return typesAreEquivalent(type1, type2);
}
@@ -561,7 +562,7 @@ public class EquivalenceChecker {
return typesAreEquivalent(type1, type2);
}
private static boolean safecastExpressionsAreEquivalent(GrSafeCastExpression expression1,
private static boolean safeCastExpressionsAreEquivalent(GrSafeCastExpression expression1,
GrSafeCastExpression expression2) {
final GrExpression operand1 = expression1.getOperand();
final GrExpression operand2 = expression2.getOperand();
@@ -591,7 +592,7 @@ public class EquivalenceChecker {
return argumentListsAreEquivalent(methodExp1.getArgumentList(), methodExp2.getArgumentList());
}
private static boolean argumentListsAreEquivalent(GrArgumentList list1, GrArgumentList list2) {
private static boolean argumentListsAreEquivalent(@Nullable GrArgumentList list1, @Nullable GrArgumentList list2) {
if (list1 == null && list2 == null) {
return true;
}
@@ -773,12 +774,6 @@ public class EquivalenceChecker {
}
private static int getExpressionType(@Nullable GrExpression exp) {
if (exp instanceof GrThisReferenceExpression) {
return THIS_EXPRESSION;
}
if (exp instanceof GrSuperReferenceExpression) {
return SUPER_EXPRESSION;
}
if (exp instanceof GrArrayDeclaration) {
return ARRAY_LITERAL_EXPRESSION;
}
@@ -830,7 +825,7 @@ public class EquivalenceChecker {
if (exp instanceof GrClosableBlock) {
return CLOSABLE_BLOCK_EXPRESSION;
}
return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846
return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846
}
private static int getStatementType(@Nullable GrStatement statement) {
@@ -880,6 +875,6 @@ public class EquivalenceChecker {
return ASSERT_STATEMENT;
}
return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846
return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846
}
}
@@ -41,8 +41,6 @@ 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.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
@@ -124,7 +122,10 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
//javaText.append("System.out.println(java.util.Arrays.toString(new Exception().getStackTrace()));\n");
//javaText.append("System.out.println(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), |.+com\\\\.springsource\\\\.loaded\\\\.).+\")\n");
javaText.append("if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n");
javaText.append(
"if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(")
.append(s)
.append(":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n");
javaText.append(" |thiz0 = thiz;\n");
javaText.append(" } else {\n");
javaText.append(" |thiz0 = this;\n");
@@ -144,9 +145,8 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
javaText.append("final java.lang.ClassLoader |parentLoader = |clazz.getClassLoader();\n" +
" final groovy.lang.GroovyClassLoader |loader = new groovy.lang.GroovyClassLoader(|parentLoader);\n" +
" final java.lang.Class |c = |loader.parseClass(");
javaText.append("\"" + IMPORTS + "class DUMMY" + new Random().nextInt(239) + " { " +
"public groovy.lang.Closure " +
EVAL_NAME + " = {" + TEXT + "}}\"");
javaText.append("\"" + IMPORTS + "class DUMMY").append(new Random().nextInt(239)).append(" { ").append("public groovy.lang.Closure ")
.append(EVAL_NAME).append(" = {").append(TEXT).append("}}\"");
javaText.append(", \"DUMMY.groovy\");\n" +
" int |i;\n" +
" java.lang.reflect.Field[] |fields = |c.getFields();\n" +
@@ -197,6 +197,16 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
super.visitReferenceExpression(referenceExpression);
PsiElement resolved = referenceExpression.resolve();
if (PsiUtil.isThisReference(referenceExpression)) {
replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner");
return;
}
if (PsiUtil.isSuperReference(referenceExpression)) {
replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner");
return;
}
if (resolved instanceof PsiMethod && "getDelegate".equals(((PsiMethod) resolved).getName()) && closure != null) {
replaceWithReference(referenceExpression, "owner");
return;
@@ -235,18 +245,6 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
}
@Override
public void visitThisExpression(final GrThisReferenceExpression thisExpression) {
super.visitThisExpression(thisExpression);
replaceWithReference(thisExpression, closure == null ? "delegate" : "owner");
}
@Override
public void visitSuperExpression(final GrSuperReferenceExpression superExpression) {
super.visitSuperExpression(superExpression);
replaceWithReference(superExpression, closure == null ? "delegate" : "owner");
}
private void replaceWithReference(GrExpression expr, final String exprText) {
replacements.put(expr, exprText);
}
@@ -29,7 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
/**
@@ -77,9 +76,6 @@ public class GroovyEditorTextProvider implements EditorTextProvider {
}
}
if (parent instanceof GrThisReferenceExpression) {
return parent;
}
return null;
}
@@ -381,7 +381,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
final GrConstructorInvocation invocation = (GrConstructorInvocation)statements[0];
if (invocation.isThisCall() == processThisRefs &&
invocation.getManager().areElementsEquivalent(invocation.resolveMethod(), searchedConstructor) &&
!consumer.process(invocation.getThisOrSuperKeyword())) {
!consumer.process(invocation.getInvokedExpression())) {
return false;
}
}
@@ -97,7 +97,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention {
private static String convertLeafExpression(GrExpression condition) {
if (BoolUtils.isNegation(condition)) {
final GrExpression negated = BoolUtils.getNegated(condition);
if (ParenthesesUtils.getPrecendence(negated) >
if (ParenthesesUtils.getPrecedence(negated) >
ParenthesesUtils.OR_PRECEDENCE) {
return '(' + negated.getText() + ')';
}
@@ -112,7 +112,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -48,7 +48,7 @@ public class MergeIfAndIntention extends Intention {
final GrExpression childCondition = childStatement.getCondition();
final String childConditionText;
if (ParenthesesUtils.getPrecendence(childCondition)
if (ParenthesesUtils.getPrecedence(childCondition)
> ParenthesesUtils.AND_PRECEDENCE) {
childConditionText = '(' + childCondition.getText() + ')';
} else {
@@ -57,7 +57,7 @@ public class MergeIfAndIntention extends Intention {
final GrExpression parentCondition = parentStatement.getCondition();
final String parentConditionText;
if (ParenthesesUtils.getPrecendence(parentCondition)
if (ParenthesesUtils.getPrecedence(parentCondition)
> ParenthesesUtils.AND_PRECEDENCE) {
parentConditionText = '(' + parentCondition.getText() + ')';
} else {
@@ -93,7 +93,7 @@ public class SimplifyTernaryOperatorIntention extends Intention {
@NotNull
private static String getStringToPutIntoAndExpression(GrExpression expression) {
String expressionText = expression.getText();
if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) {
if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) {
expressionText = "(" + expressionText + ")";
}
return expressionText;
@@ -102,7 +102,7 @@ public class SimplifyTernaryOperatorIntention extends Intention {
@NotNull
private static String getStringToPutIntoOrExpression(GrExpression expression) {
String expressionText = expression.getText();
if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) {
if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) {
expressionText = "(" + expressionText + ")";
}
return expressionText;
@@ -33,10 +33,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnState
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.ArrayList;
@@ -112,7 +112,7 @@ public class ConvertGStringToStringIntention extends Intention {
}
private static String prepareExpression(GrExpression expr) {
if (expr instanceof GrThisSuperReferenceExpression) return expr.getText();
if (PsiUtil.isThisOrSuperRef(expr)) return expr.getText();
String text = expr.getText();
final PsiType type = expr.getType();
@@ -19,8 +19,10 @@ import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -100,7 +102,7 @@ public class BoolUtils {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -82,18 +82,16 @@ public class ParenthesesUtils {
s_binaryOperatorPrecedence.put(GroovyTokenTypes.mCOMPARE_TO, EQUALITY_PRECEDENCE);
}
public static int getPrecendence(GrExpression expression) {
if (expression instanceof GrThisReferenceExpression ||
expression instanceof GrLiteral ||
expression instanceof GrSuperReferenceExpression ) {
public static int getPrecedence(GrExpression expression) {
if (expression instanceof GrLiteral) {
return LITERAL_PRECEDENCE;
}
if (expression instanceof GrReferenceExpression) {
final GrReferenceExpression referenceExpression =
(GrReferenceExpression) expression;
final GrReferenceExpression referenceExpression = (GrReferenceExpression)expression;
if (referenceExpression.getQualifierExpression() != null) {
return METHOD_CALL_PRECEDENCE;
} else {
}
else {
return LITERAL_PRECEDENCE;
}
}
@@ -105,11 +103,10 @@ public class ParenthesesUtils {
return TYPE_CAST_PRECEDENCE;
}
if (expression instanceof GrUnaryExpression) {
return ((GrUnaryExpression)expression).isPostfix()?POSTFIX_PRECEDENCE:PREFIX_PRECEDENCE;
return ((GrUnaryExpression)expression).isPostfix() ? POSTFIX_PRECEDENCE : PREFIX_PRECEDENCE;
}
if (expression instanceof GrBinaryExpression) {
final GrBinaryExpression binaryExpression =
(GrBinaryExpression) expression;
final GrBinaryExpression binaryExpression = (GrBinaryExpression) expression;
final IElementType sign = binaryExpression.getOperationTokenType();
return precedenceForBinaryOperator(sign);
}
@@ -28,11 +28,14 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrReferenceElementImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Max Medvedev
@@ -63,7 +66,7 @@ public class GrReferenceAdjuster {
if (element instanceof GrQualifiedReference<?> && ((GrQualifiedReference)element).resolve() instanceof PsiClass) {
result = shortenReferenceInner((GrQualifiedReference<?>)element, addImports, incomplete);
}
else if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() instanceof GrThisSuperReferenceExpression) {
else if (element instanceof GrReferenceExpression && PsiUtil.isSuperReference(((GrReferenceExpression)element).getQualifier())) {
result = shortenReferenceInner((GrReferenceExpression)element, addImports, incomplete);
}
@@ -81,7 +84,7 @@ public class GrReferenceAdjuster {
private static <Qualifier extends PsiElement> boolean shortenReferenceInner(GrQualifiedReference<Qualifier> ref, boolean addImports, boolean incomplete) {
final Qualifier qualifier = ref.getQualifier();
if (qualifier == null || qualifier instanceof GrSuperReferenceExpression || cannotShortenInContext(ref)) {
if (qualifier == null || PsiUtil.isSuperReference(qualifier) || cannotShortenInContext(ref)) {
return false;
}
@@ -173,7 +176,7 @@ public class GrReferenceAdjuster {
}
if (qualifier instanceof GrExpression) {
if (qualifier instanceof GrThisReferenceExpression) return true;
if (qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) return true;
if (qualifier instanceof GrReferenceExpression && seemsToBeQualifiedClassName((GrExpression)qualifier)) {
final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass || resolved instanceof PsiPackage) return true;
@@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.Map;
@@ -67,16 +68,20 @@ public class GroovyChangeUtilSupport implements TreeCopyHandler {
public void encodeInformation(final TreeElement element, final ASTNode original, final Map<Object, Object> encodingState) {
if (original instanceof CompositeElement) {
if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT || original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) {
final GroovyResolveResult result = ((GrReferenceElement)original.getPsi()).advancedResolve();
if (result != null) {
final PsiElement target = result.getElement();
if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT ||
original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) {
PsiElement psi = original.getPsi();
if (!PsiUtil.isThisOrSuperRef(psi)) {
final GroovyResolveResult result = ((GrReferenceElement)psi).advancedResolve();
if (result != null) {
final PsiElement target = result.getElement();
if (target instanceof PsiClass ||
(target instanceof PsiMethod || target instanceof PsiField) &&
((PsiMember) target).hasModifierProperty(PsiModifier.STATIC) &&
result.getCurrentFileResolveContext() instanceof GrImportStatement) {
element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember) target);
if (target instanceof PsiClass ||
(target instanceof PsiMethod || target instanceof PsiField) &&
((PsiMember)target).hasModifierProperty(PsiModifier.STATIC) &&
result.getCurrentFileResolveContext() instanceof GrImportStatement) {
element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember)target);
}
}
}
}
@@ -235,8 +235,6 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy
GroovyElementType SPREAD_ARGUMENT = new GroovyElementType("Spread argument");
GroovyElementType ARGUMENT_LABEL = new GroovyElementType("Argument label");
GroovyElementType REFERENCE_EXPRESSION = new GroovyElementType("Reference expressions");
GroovyElementType THIS_REFERENCE_EXPRESSION = new GroovyElementType("This reference expressions");
GroovyElementType SUPER_REFERENCE_EXPRESSION = new GroovyElementType("Super reference expressions");
GroovyElementType NEW_EXPRESSION = new GroovyElementType("New expressions");
@@ -232,8 +232,6 @@ public class GroovyPsiCreator implements GroovyElementTypes {
if (elem == REGEX) return new GrRegexImpl(node);
if (elem == GSTRING_INJECTION) return new GrStringInjectionImpl(node);
if (elem == REFERENCE_EXPRESSION) return new GrReferenceExpressionImpl(node);
if (elem == THIS_REFERENCE_EXPRESSION) return new GrThisReferenceExpressionImpl(node);
if (elem == SUPER_REFERENCE_EXPRESSION) return new GrSuperReferenceExpressionImpl(node);
if (elem == PARENTHESIZED_EXPRESSION) return new GrParenthesizedExpressionImpl(node);
if (elem == NEW_EXPRESSION) return new GrNewExpressionImpl(node);
if (elem == ANONYMOUS_CLASS_DEFINITION) return new GrAnonymousClassDefinitionImpl(node);
@@ -70,13 +70,13 @@ public class ConstructorBody implements GroovyElementTypes {
if (ParserUtils.lookAhead(builder, kTHIS, mLPAREN)) {
final PsiBuilder.Marker marker = builder.mark();
ParserUtils.getToken(builder, kTHIS);
marker.done(THIS_REFERENCE_EXPRESSION);
marker.done(REFERENCE_EXPRESSION);
result = true;
}
if (ParserUtils.lookAhead(builder, kSUPER, mLPAREN)) {
final PsiBuilder.Marker marker = builder.mark();
ParserUtils.getToken(builder, kSUPER);
marker.done(SUPER_REFERENCE_EXPRESSION);
marker.done(REFERENCE_EXPRESSION);
result = true;
}
@@ -41,7 +41,7 @@ import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expres
public class PathExpression implements GroovyElementTypes {
public static boolean parse(PsiBuilder builder, GroovyParser parser) {
return parsePathExprQualifierForExprStatement(builder, parser) != PathExpression.Result.WRONG_WAY;
return parsePathExprQualifierForExprStatement(builder, parser) != WRONG_WAY;
}
public enum Result {INVOKED_EXPR, METHOD_CALL, WRONG_WAY, LITERAL}
@@ -70,10 +70,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, qualifierType, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -102,10 +102,9 @@ public class PathExpression implements GroovyElementTypes {
private static final TokenSet DOTS = TokenSet.create(mSPREAD_DOT, mOPTIONAL_DOT, mMEMBER_POINTER, mDOT);
private static Result pathElementParse(PsiBuilder builder,
PsiBuilder.Marker marker,
GroovyParser parser,
IElementType qualifierType,
Result result) {
PsiBuilder.Marker marker,
GroovyParser parser,
Result result) {
GroovyElementType res;
@@ -117,12 +116,7 @@ public class PathExpression implements GroovyElementTypes {
ParserUtils.getToken(builder, DOTS);
ParserUtils.getToken(builder, mNLS);
TypeArguments.parseTypeArguments(builder, true);
if (kTHIS.equals(builder.getTokenType()) || kSUPER.equals(builder.getTokenType())) {
res = parseThisSuperExpression(builder, qualifierType);
}
else {
res = namePartParse(builder, parser);
}
res = namePartParse(builder, parser);
if (!res.equals(WRONGWAY)) {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(res);
@@ -130,10 +124,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, res, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, res, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -145,12 +139,12 @@ public class PathExpression implements GroovyElementTypes {
PrimaryExpression.methodCallArgsParse(builder, parser);
if (checkForLCurly(builder)) {
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, marker, parser, METHOD_CALL);
}
else {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(PATH_METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
}
else if (checkForLCurly(builder)) {
@@ -158,12 +152,12 @@ public class PathExpression implements GroovyElementTypes {
appendedBlockParse(builder, parser);
if (checkForLCurly(builder)) {
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, marker, parser, METHOD_CALL);
}
else {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(PATH_METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, PATH_METHOD_CALL, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
}
else if (checkForArrayAccess(builder)) {
@@ -174,10 +168,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -196,23 +190,6 @@ public class PathExpression implements GroovyElementTypes {
!ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON);
}
private static GroovyElementType parseThisSuperExpression(PsiBuilder builder, IElementType qualifierType) {
if (qualifierType != REFERENCE_EXPRESSION) {
return WRONGWAY;
}
final IElementType tokenType = builder.getTokenType();
builder.advanceLexer();
final GroovyElementType type;
if (kTHIS.equals(tokenType)) {
type = THIS_REFERENCE_EXPRESSION;
}
else {
type = SUPER_REFERENCE_EXPRESSION;
}
return type;
}
/**
* Property selector parsing
*
@@ -47,21 +47,13 @@ public class PrimaryExpression implements GroovyElementTypes {
ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
return BUILT_IN_TYPE_EXPRESSION;
}
if (kTHIS == tokenType) {
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
return THIS_REFERENCE_EXPRESSION;
}
if (kSUPER == tokenType) {
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
return SUPER_REFERENCE_EXPRESSION;
}
if (kNEW == tokenType) {
PsiBuilder.Marker marker = builder.mark();
final GroovyElementType type = newExprParse(builder, parser);
marker.done(type);
return type;
}
if (mIDENT == tokenType) {
if (mIDENT == tokenType || kSUPER == tokenType || kTHIS == tokenType) {
ParserUtils.eatElement(builder, REFERENCE_EXPRESSION);
return REFERENCE_EXPRESSION;
}
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilder.Marker;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
@@ -60,18 +61,13 @@ public class StringConstructorExpression implements GroovyElementTypes {
final Marker injection = builder.mark();
ParserUtils.getToken(builder, mDOLLAR);
ParserUtils.getToken(builder, mSTAR);
if (mIDENT.equals(builder.getTokenType())) {
IElementType tokenType = builder.getTokenType();
if (mIDENT == tokenType || kTHIS==tokenType || kSUPER==tokenType) {
PathExpression.parse(builder, parser);
}
else if (mLCURLY.equals(builder.getTokenType())) {
else if (mLCURLY == tokenType) {
OpenOrClosableBlock.parseClosableBlock(builder, parser);
}
else if (kTHIS.equals(builder.getTokenType())) {
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
}
else if (kSUPER.equals(builder.getTokenType())) {
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
}
else {
ParserUtils.wrapError(builder, GroovyBundle.message("identifier.or.block.expected"));
}
@@ -184,18 +184,6 @@ public abstract class GroovyElementVisitor {
visitExpression(referenceExpression);
}
public void visitThisExpression(GrThisReferenceExpression thisExpression) {
visitThisSuperReferenceExpression(thisExpression);
}
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
visitThisSuperReferenceExpression(superExpression);
}
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) {
visitExpression(expression);
}
public void visitCastExpression(GrTypeCastExpression typeCastExpression) {
visitExpression(typeCastExpression);
}
@@ -37,7 +37,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArg
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
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.params.GrParameter;
@@ -62,7 +65,7 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory {
public abstract GrCodeReferenceElement createCodeReferenceElementFromText(String text);
public abstract GrThisReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass);
public abstract GrReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass);
public abstract GrBlockStatement createBlockStatementFromText(String text, @Nullable PsiElement context);
@@ -27,14 +27,15 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
public final class SpreadState {
public static final Key<SpreadState> SPREAD_STATE = Key.create("Spread state");
private final PsiType containerType;
@Nullable private final PsiType containerType;
@Nullable private final SpreadState innerState;
public SpreadState(PsiType type, @Nullable SpreadState state) {
public SpreadState(@Nullable PsiType type, @Nullable SpreadState state) {
containerType = type;
innerState = state;
}
@Nullable
public PsiType getContainerType() {
return containerType;
}
@@ -48,7 +49,8 @@ public final class SpreadState {
return new SpreadState(type, state);
}
public static PsiType apply(PsiType item, @Nullable SpreadState state, Project project) {
@Nullable
public static PsiType apply(@Nullable PsiType item, @Nullable SpreadState state, Project project) {
if (state == null) return item;
return apply(TypesUtil.createSimilarCollection(state.getContainerType(), project, item), state.getInnerState(), project);
}
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
/**
* User: Dmitry.Krasilschikov
@@ -31,7 +31,7 @@ public interface GrConstructorInvocation extends GrStatement, GrConstructorCall
boolean isThisCall();
GrThisSuperReferenceExpression getThisOrSuperKeyword();
GrReferenceExpression getInvokedExpression();
@Nullable
PsiClass getDelegatedClass();
@@ -15,11 +15,20 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
/**
* @author Maxim.Medvedev
*/
public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference, GrQualifiedReference<GrReferenceExpression> {
@NotNull
@Override
PsiElement getReferenceNameElement();
@NotNull
@Override
String getReferenceName();
}
@@ -671,7 +671,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
}
@Override
public GrThisReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) {
public GrReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) {
final String text;
if (psiClass == null) {
text = "this";
@@ -679,8 +679,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
else {
text = psiClass.getQualifiedName() + ".this";
}
final GroovyFileImpl dummy = createDummyFile(text);
return (GrThisReferenceExpression)dummy.getStatements()[0];
return createReferenceExpressionFromText(text);
}
@Override
@@ -17,16 +17,16 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrCallImpl;
@@ -52,18 +52,25 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
}
public boolean isSuperCall() {
return findChildByType(GroovyElementTypes.SUPER_REFERENCE_EXPRESSION) != null;
return getKeywordType() == GroovyTokenTypes.kSUPER;
}
public boolean isThisCall() {
return findChildByType(GroovyElementTypes.THIS_REFERENCE_EXPRESSION) != null;
return getKeywordType() == GroovyTokenTypes.kTHIS;
}
private static final TokenSet THIS_OR_SUPER_SET =
TokenSet.create(GroovyElementTypes.THIS_REFERENCE_EXPRESSION, GroovyElementTypes.SUPER_REFERENCE_EXPRESSION);
@Nullable
private IElementType getKeywordType() {
GrReferenceExpression keyword = getInvokedExpression();
PsiElement refElement = keyword.getReferenceNameElement();
if (refElement == null) return null;
public GrThisSuperReferenceExpression getThisOrSuperKeyword() {
return (GrThisSuperReferenceExpression)findNotNullChildByType(THIS_OR_SUPER_SET);
return refElement.getNode().getElementType();
}
public GrReferenceExpression getInvokedExpression() {
return findNotNullChildByClass(GrReferenceExpression.class);
}
@NotNull
@@ -75,7 +82,8 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
PsiSubstitutor substitutor;
if (isThisCall()) {
substitutor = PsiSubstitutor.EMPTY;
} else {
}
else {
PsiClass enclosing = PsiUtil.getContextClass(this);
assert enclosing != null;
substitutor = TypeConversionUtil.getSuperClassSubstitutor(clazz, enclosing, PsiSubstitutor.EMPTY);
@@ -85,7 +93,7 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
incompleteCode, false);
final ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
clazz.processDeclarations(processor, state, null, this);
ResolveUtil.processNonCodeMembers(thisType, processor, getThisOrSuperKeyword(), state);
ResolveUtil.processNonCodeMembers(thisType, processor, getInvokedExpression(), state);
return processor.getCandidates();
}
@@ -118,11 +126,6 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
return null;
}
@NotNull
public String getCanonicalText() {
return getText(); //TODO
}
@NotNull
@Override
public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) {
@@ -46,7 +46,6 @@ 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.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
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;
@@ -133,8 +132,8 @@ public class CompleteReferenceExpression {
if (refExpr.getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
getVariantsFromQualifier(refExpr, processor, qualifier);
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
qualifier instanceof GrThisReferenceExpression) {
if (qualifier instanceof GrReferenceExpression &&
("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier))) {
processIfJavaLangClass(refExpr, processor, qualifier.getType());
}
}
@@ -261,7 +260,7 @@ public class CompleteReferenceExpression {
}
else {
getVariantsFromQualifierType(refExpr, processor, qualifierType, project);
if (qualifier instanceof GrReferenceExpression) {
if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) { ////omitted .class
GlobalSearchScope scope = refExpr.getResolveScope();
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.Pair;
@@ -43,6 +44,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.codeInsight.GrReassignedLocalVarsChecker;
import org.jetbrains.plugins.groovy.codeInsight.GroovyTargetElementEvaluator;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -81,6 +83,8 @@ import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mMEMBER_P
*/
public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpression> implements GrReferenceExpression {
private static final Logger LOG = Logger.getInstance(GrReferenceExpressionImpl.class);
public GrReferenceExpressionImpl(@NotNull ASTNode node) {
super(node);
}
@@ -145,9 +149,25 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
private GroovyResolveResult[] resolveTypeOrPropertyInner() {
PsiElement nameElement = getReferenceNameElement();
String name = getReferenceName();
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
if (name == null || nameElement == null) return GroovyResolveResult.EMPTY_ARRAY;
IElementType nameType = nameElement.getNode().getElementType();
if (nameType == GroovyTokenTypes.kTHIS) {
ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
if (GrReferenceResolveUtil.resolveThisExpression(this, results)) {
return results.toArray(new GroovyResolveResult[results.size()]);
}
}
else if (nameType == GroovyTokenTypes.kSUPER) {
ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) {
return results.toArray(new GroovyResolveResult[results.size()]);
}
}
EnumSet<ClassHint.ResolveKind> kinds = getParent() instanceof GrReferenceExpression
? ResolverProcessor.RESOLVE_KINDS_CLASS_PACKAGE
@@ -213,11 +233,12 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return GroovyResolveResult.EMPTY_ARRAY;
}
private boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) {
private static boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) {
boolean preferVar = false;
if (fieldCandidates.length > 0) {
for (GroovyResolveResult candidate : fieldCandidates) {
PsiElement element = candidate.getElement();
LOG.assertTrue(element != null, candidate);
if (GroovyRefactoringUtil.isLocalVariable(element)) {
preferVar = true;
break;
@@ -335,7 +356,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return doResolveByShape(allVariants, upToArgument);
}
assert upToArgument == null;
LOG.assertTrue(upToArgument == null);
return TypeInferenceHelper.getCurrentContext().getCachedValue(this, new NullableComputable<Pair<Boolean, GroovyResolveResult[]>>() {
@Override
@@ -347,7 +368,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
private Pair<Boolean, GroovyResolveResult[]> doResolveByShape(boolean allVariants, @Nullable GrExpression upToArgument) {
final String name = getReferenceName();
assert name != null;
LOG.assertTrue(name != null);
final MethodResolverProcessor shapeProcessor = createMethodProcessor(allVariants, name, true, upToArgument);
processMethods(shapeProcessor);
@@ -359,7 +380,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
private static void assertAllAreValid(GroovyResolveResult[] candidates) {
for (GroovyResolveResult candidate : candidates) {
final PsiElement element = candidate.getElement();
assert element == null || element.isValid();
LOG.assertTrue(element == null || element.isValid());
}
}
@@ -425,6 +446,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
newElementName = name;
}
}
if (PsiUtil.isThisOrSuperRef(this)) return this;
return handleElementRenameSimple(newElementName);
}
@@ -530,7 +552,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (resolved instanceof PsiClass) {
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
if (getParent() instanceof GrReferenceExpression) {
if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this) || PsiUtil.isInstanceThisRef(this)) {
return factory.createType((PsiClass)resolved);
}
else {
@@ -611,7 +633,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Nullable
public PsiType fun(GrReferenceExpressionImpl refExpr) {
PsiType result = GrReassignedLocalVarsChecker.checkReassignedVar(refExpr, true);
if (result!=null) return result;
if (result != null) return result;
final PsiElement resolved = refExpr.resolve();
final PsiType inferred = getInferredTypes(refExpr, resolved);
@@ -620,7 +642,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (nominal == null) {
//inside nested closure we could still try to infer from variable initializer. Not sound, but makes sense
if (resolved instanceof GrVariable) {
assert resolved.isValid();
LOG.assertTrue(resolved.isValid());
return ((GrVariable)resolved).getTypeGroovy();
}
}
@@ -639,7 +661,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
@Nullable
private static PsiType getInferredTypes(GrReferenceExpressionImpl refExpr, PsiElement resolved) {
private static PsiType getInferredTypes(GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
final GrExpression qualifier = refExpr.getQualifier();
if (qualifier == null && !(resolved instanceof PsiClass)) {
return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
@@ -683,7 +705,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
ASTNode node = nameElement.getNode();
ASTNode newNameNode = GroovyPsiElementFactory.getInstance(getProject()).createReferenceNameFromText(name).getNode();
assert newNameNode != null && node != null;
LOG.assertTrue(newNameNode != null && node != null);
node.getTreeParent().replaceChild(node, newNameNode);
return this;
@@ -19,21 +19,24 @@ import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
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.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -41,6 +44,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
import java.util.List;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mSPREAD_DOT;
/**
@@ -84,8 +89,8 @@ public class GrReferenceResolveUtil {
if (!processQualifier(processor, qualifier, place)) return false;
}
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
qualifier instanceof GrThisReferenceExpression) {
if (qualifier instanceof GrReferenceExpression &&
("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier))) {
if (!processIfJavaLangClass(processor, qualifier.getType(), qualifier, place)) return false;
}
}
@@ -105,7 +110,7 @@ public class GrReferenceResolveUtil {
}
private static boolean processIfJavaLangClass(ResolverProcessor processor,
PsiType type,
@Nullable PsiType type,
GroovyPsiElement resolveContext,
GrReferenceExpression place) {
if (!(type instanceof PsiClassType)) return true;
@@ -163,7 +168,7 @@ public class GrReferenceResolveUtil {
}
else {
if (!processQualifierType(processor, qualifierType, state, place)) return false;
if (qualifier instanceof GrReferenceExpression) {
if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) { //omitted .class
PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, place.getResolveScope());
@@ -266,4 +271,66 @@ public class GrReferenceResolveUtil {
return TypesUtil.getJavaLangObject(ref);
}
public static boolean resolveThisExpression(GrReferenceExpression ref, List<GroovyResolveResult> results) {
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
final PsiElement parent = ref.getParent();
if (parent instanceof GrConstructorInvocation) {
GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
ContainerUtil.addAll(results, res);
return true;
}
PsiClass aClass = PsiUtil.getContextClass(ref);
if (aClass == null) return false;
results.add(new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true));
return true;
}
else {
if (!(qualifier instanceof GrReferenceExpression)) return false;
GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
PsiElement resolved = result.getElement();
if (!(resolved instanceof PsiClass)) return false;
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
results.add(result);
return true;
}
}
public static boolean resolveSuperExpression(GrReferenceExpression ref, List<GroovyResolveResult> results) {
GrExpression qualifier = ref.getQualifier();
PsiClass aClass;
if (qualifier == null) {
final PsiElement parent = ref.getParent();
if (parent instanceof GrConstructorInvocation) {
GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
ContainerUtil.addAll(results, res);
return true;
}
aClass = PsiUtil.getContextClass(ref);
if (aClass == null) return false;
}
else {
if (!(qualifier instanceof GrReferenceExpression)) return false;
GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
PsiElement resolved = result.getElement();
if (!(resolved instanceof PsiClass)) return false;
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
aClass = (PsiClass)resolved;
}
PsiClass superClass = aClass.getSuperClass();
if (superClass == null) return true; //no super class, but the reference is definitely super-reference
PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
results.add(new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true));
return true;
}
}
@@ -76,7 +76,6 @@ public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressi
}
public void accept(GroovyElementVisitor visitor) {
visitor.visitSuperExpression(this);
}
public String toString() {
@@ -78,7 +78,6 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio
}
public void accept(GroovyElementVisitor visitor) {
visitor.visitThisExpression(this);
}
public String toString() {
@@ -11,14 +11,15 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
/**
* @author Maxim.Medvedev
@@ -40,6 +41,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp
PsiImplUtil.setQualifier(this, newQualifier);
}
@NotNull
@Override
public PsiElement getReferenceNameElement() {
return getLastChild();
@@ -52,7 +54,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp
@Override
public TextRange getRangeInElement() {
final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyElementTypes.kTHIS, GroovyElementTypes.kSUPER));
final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER));
return TextRange.from(token.getStartOffsetInParent(), token.getTextLength());
}
@@ -52,7 +52,10 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.util.LightCacheKey;
import java.util.*;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import static com.intellij.psi.CommonClassNames.*;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
@@ -716,7 +719,7 @@ public class TypesUtil {
}
@Nullable
public static PsiClassType createSimilarCollection(PsiType collection, Project project, PsiType... itemType) {
public static PsiClassType createSimilarCollection(@Nullable PsiType collection, Project project, PsiType... itemType) {
if (InheritanceUtil.isInheritor(collection, "java.util.SortedSet")) {
return createCollection(project, "java.util.SortedSet", itemType);
}
@@ -376,8 +376,17 @@ public class PsiUtil {
}
}
}
}
else if (isThisOrSuperRef(qualifier)) {
//static members may be invoked from this.<...>
final boolean isInStatic = isInStaticContext((GrReferenceExpression)qualifier);
if (isThisReference(qualifier) && isInStatic) {
return member.hasModifierProperty(PsiModifier.STATIC);
}
return !isStatic || !filterStaticAfterInstanceQualifier || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE;
}
PsiElement qualifierResolved = ((GrReferenceExpression)qualifier).resolve();
if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) { //static context
if (member instanceof PsiClass) {
@@ -412,14 +421,6 @@ public class PsiUtil {
return false;
}
}
else if (qualifier instanceof GrThisReferenceExpression && ((GrThisReferenceExpression)qualifier).getQualifier() == null) {
//static members may be invoked from this.<...>
final boolean isInStatic = isInStaticContext((GrThisReferenceExpression)qualifier);
if (containingClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(containingClass.getQualifiedName())) {
return !filterStaticAfterInstanceQualifier || !member.hasModifierProperty(PsiModifier.STATIC) || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE;
}
else if (isInStatic) return member.hasModifierProperty(PsiModifier.STATIC);
}
//instance context
if (member instanceof PsiClass) {
@@ -517,24 +518,31 @@ public class PsiUtil {
}
public static boolean isInStaticContext(GrQualifiedReference refExpression) {
return isInStaticContext(refExpression, null);
PsiClass targetClass = null;
if (isThisReference(refExpression) && refExpression.getQualifier() != null) {
targetClass = (PsiClass)((GrReferenceExpression)refExpression.getQualifier()).resolve();
}
return isInStaticContext(refExpression, targetClass);
}
public static boolean isInStaticContext(GrQualifiedReference refExpression, @Nullable PsiClass targetClass) {
if (refExpression.getQualifier() != null) {
PsiElement qualifier = refExpression.getQualifier();
if (qualifier instanceof GrReferenceExpression) return ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
PsiElement qualifier = refExpression.getQualifier();
if (qualifier != null && !isThisOrSuperRef(refExpression)) {
return qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
}
else {
PsiElement run = refExpression;
while (run != null && run != targetClass) {
if (targetClass == null && run instanceof PsiClass) return false;
if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true;
run = run.getParent();
}
if (isSuperReference(refExpression)) return false;
//this reference should be checked as all other refs
PsiElement run = refExpression;
while (run != null && run != targetClass) {
if (targetClass == null && run instanceof PsiClass) return false;
if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true;
run = run.getParent();
}
return false;
}
public static Iterable<PsiClass> iterateSupers(final @NotNull PsiClass psiClass, final boolean includeSelf) {
@@ -661,7 +669,7 @@ public class PsiUtil {
return true;
}
if ((expr instanceof GrThisReferenceExpression || expr instanceof GrSuperReferenceExpression) &&
if ((isThisOrSuperRef(expr)) &&
GroovyConfigUtils.getInstance().isVersionAtLeast(expr, GroovyConfigUtils.GROOVY1_8)) {
return true;
}
@@ -864,7 +872,7 @@ public class PsiUtil {
public static boolean hasEnclosingInstanceInScope(@NotNull PsiClass clazz, @Nullable PsiElement scope, boolean isSuperClassAccepted) {
PsiElement place = scope;
while (place != null && place != clazz && !(place instanceof PsiFile)) {
while (place != null && place != clazz && !(place instanceof PsiFile && place.isPhysical())) {
if (place instanceof PsiClass) {
if (isSuperClassAccepted) {
if (InheritanceUtil.isInheritorOrSelf((PsiClass)place, clazz, true)) return true;
@@ -874,8 +882,9 @@ public class PsiUtil {
}
}
if (place instanceof PsiModifierListOwner && ((PsiModifierListOwner)place).hasModifierProperty(PsiModifier.STATIC)) return false;
place = place.getParent();
place = place.getContext();
}
if (clazz instanceof GroovyScriptClass) return place == clazz.getContainingFile();
return place == clazz;
}
@@ -951,7 +960,7 @@ public class PsiUtil {
public static boolean isMethodUsage(PsiElement element) {
if (element instanceof GrEnumConstant) return true;
if (!(element instanceof GrReferenceElement || element instanceof GrThisSuperReferenceExpression)) return false;
if (!(element instanceof GrReferenceElement)) return false;
PsiElement parent = element.getParent();
if (parent instanceof GrCall) {
return true;
@@ -1184,7 +1193,7 @@ public class PsiUtil {
return null;
}
@Nullable
public static GrCall getCallByNamedParameter(GrNamedArgument namedArgument) {
PsiElement parent = namedArgument.getParent();
@@ -1282,7 +1291,7 @@ public class PsiUtil {
@NotNull
public static ResolveResult getAccessObjectClass(GrExpression expression) {
if (expression instanceof GrSuperReferenceExpression || expression instanceof GrThisReferenceExpression) return GroovyResolveResult.EMPTY_RESULT;
if (isThisOrSuperRef(expression)) return GroovyResolveResult.EMPTY_RESULT;
PsiType type = expression.getType();
if (type instanceof PsiClassType) {
return ((PsiClassType)type).resolveGenerics();
@@ -1373,4 +1382,60 @@ public class PsiUtil {
if (type instanceof PsiArrayType) return ((PsiArrayType)type).getComponentType();
return com.intellij.psi.util.PsiUtil.extractIterableTypeParameter(type, true);
}
public static boolean isThisReference(@Nullable PsiElement expression) {
if (!(expression instanceof GrReferenceExpression)) return false;
GrReferenceExpression ref = (GrReferenceExpression)expression;
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return false;
IElementType type = nameElement.getNode().getElementType();
if (type != GroovyTokenTypes.kTHIS) return false;
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
return true;
}
else {
PsiElement resolved = ref.resolve();
return resolved instanceof PsiClass && hasEnclosingInstanceInScope((PsiClass)resolved, ref, false);
}
}
public static boolean isSuperReference(@Nullable PsiElement expression) {
if (!(expression instanceof GrReferenceExpression)) return false;
GrReferenceExpression ref = (GrReferenceExpression)expression;
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return false;
IElementType type = nameElement.getNode().getElementType();
if (type != GroovyTokenTypes.kSUPER) return false;
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
return true;
}
else {
PsiElement resolved = ref.resolve();
return resolved instanceof PsiClass && hasEnclosingInstanceInScope(((PsiClass)resolved), ref, true);
}
}
public static boolean isThisOrSuperRef(@Nullable PsiElement qualifier) {
return qualifier instanceof GrReferenceExpression && (isThisReference(qualifier) || isSuperReference(qualifier));
}
public static boolean isInstanceThisRef(GrExpression qualifier) {
if (isThisReference(qualifier)) {
GrReferenceExpression ref = (GrReferenceExpression)qualifier;
PsiElement resolved = ref.resolve();
if (resolved == null) return false;
return hasEnclosingInstanceInScope((PsiClass)resolved, qualifier, false);
}
return false;
}
}
@@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
@@ -575,7 +574,6 @@ public class ResolveUtil {
public static boolean mayBeKeyOfMap(GrReferenceExpression ref) {
final GrExpression qualifier = getSelfOrWithQualifier(ref);
if (qualifier == null) return false;
if (qualifier instanceof GrThisSuperReferenceExpression) return false;
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass) return false;
return InheritanceUtil.isInheritor(qualifier.getType(), CommonClassNames.JAVA_UTIL_MAP);
}
@@ -24,8 +24,8 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Maxim.Medvedev
@@ -45,8 +45,8 @@ public class GroovyChangeContextUtil {
public static void encodeContextInfo(PsiElement element, PsiElement scope) {
if (!(element instanceof GroovyPsiElement)) return;
if (element instanceof GrThisReferenceExpression) {
GrThisReferenceExpression thisExpr = (GrThisReferenceExpression)element;
if (PsiUtil.isThisReference(element)) {
GrReferenceExpression thisExpr = (GrReferenceExpression)element;
final PsiClass containingClass = PsiTreeUtil.getParentOfType(thisExpr, PsiClass.class);
element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED);
thisExpr.putCopyableUserData(QUALIFIER_CLASS_KEY, containingClass);
@@ -94,7 +94,7 @@ public class GroovyChangeContextUtil {
if (element.getCopyableUserData(KEY_ENCODED) != null) {
element.putCopyableUserData(KEY_ENCODED, null);
final PsiManager manager = element.getManager();
if (element instanceof GrThisReferenceExpression) {
if (PsiUtil.isThisReference(element)) {
final PsiClass thisQualClass = element.getCopyableUserData(QUALIFIER_CLASS_KEY);
element.putCopyableUserData(QUALIFIER_CLASS_KEY, null);
if (thisAccessExpr != null && !manager.areElementsEquivalent(thisClass, thisQualClass)) {
@@ -28,10 +28,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
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.util.PsiUtil;
import java.util.ArrayList;
import java.util.Collections;
@@ -94,13 +93,13 @@ public class GroovyNameSuggestionUtil {
}
private static void generateNameByExpr(GrExpression expr, Set<String> possibleNames, NameValidator validator, boolean forStaticVariable) {
if (expr instanceof GrThisReferenceExpression) {
possibleNames.add(validator.validateName("thisInstance", true));
}
if (expr instanceof GrSuperReferenceExpression) {
possibleNames.add(validator.validateName("superInstance", true));
}
if (expr instanceof GrReferenceExpression && ((GrReferenceExpression) expr).getName() != null) {
if (PsiUtil.isThisReference(expr)) {
possibleNames.add(validator.validateName("thisInstance", true));
}
if (PsiUtil.isSuperReference(expr)) {
possibleNames.add(validator.validateName("superInstance", true));
}
GrReferenceExpression refExpr = (GrReferenceExpression) expr;
String name = refExpr.getName();
if (name != null && name.toUpperCase().equals(name)) {
@@ -196,7 +196,7 @@ public abstract class GroovyRefactoringUtil {
});
}
public static boolean isLocalVariable(PsiElement variable) {
public static boolean isLocalVariable(@Nullable PsiElement variable) {
return variable instanceof GrVariable && !(variable instanceof GrField || variable instanceof GrParameter);
}
@@ -460,7 +460,7 @@ public abstract class GroovyRefactoringUtil {
int result = EXPR_COPY_SAFE;
if (element == null) return result;
if (element instanceof GrThisReferenceExpression || element instanceof GrSuperReferenceExpression || element instanceof GrNamedElement) {
if (element instanceof GrNamedElement) {
return EXPR_COPY_SAFE;
}
@@ -449,7 +449,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
GrConstructorInvocation invocation =
GroovyPsiElementFactory.getInstance(constructor.getProject()).createConstructorInvocation("super()");
invocation = (GrConstructorInvocation)block.addStatementBefore(invocation, getFirstStatement(block));
processMethodUsage(invocation.getThisOrSuperKeyword(), changeInfo,
processMethodUsage(invocation.getInvokedExpression(), changeInfo,
changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(),
changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.<PsiElement>empty_array(), substitutor);
}
@@ -44,7 +44,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
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.GrMethod;
@@ -163,7 +163,7 @@ public class CodeBlockGenerator extends Generator {
GenerationUtil.writeStatement(builder, context, invocation, new StatementWriter() {
@Override
public void writeStatement(StringBuilder builder, ExpressionContext context) {
final GrThisSuperReferenceExpression thisOrSuperKeyword = invocation.getThisOrSuperKeyword();
final GrReferenceExpression thisOrSuperKeyword = invocation.getInvokedExpression();
final GrArgumentList argumentList = invocation.getArgumentList();
final GroovyResolveResult resolveResult = invocation.advancedResolve();
if (thisOrSuperKeyword.getQualifier() == null) {
@@ -59,6 +59,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightLocalVariable;
@@ -436,13 +437,16 @@ public class ExpressionGenerator extends Generator {
else if (resolved == null || resolved instanceof GrLightLocalVariable) {
//write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value)
final GrExpression qualifier = ((GrReferenceExpression)realLValue).getQualifier();
final PsiType type = qualifier != null ? qualifier.getType() : factory.createExpressionFromText("this", expression).getType();
final PsiType type = GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)realLValue);
final GrExpression[] args = new GrExpression[2];
args[0] = factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\"");
args[1] = getRValue(expression);
final PsiElement method = PsiImplUtil
.extractUniqueElement(ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType()));
final GrExpression[] args = {
factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""),
getRValue(expression)
};
GroovyResolveResult[] candidates = type != null
? ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType())
: GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method instanceof PsiMethod) {
writeAssignmentWithSetter(qualifier, (PsiMethod)method, args, GrNamedArgument.EMPTY_ARRAY, EMPTY_ARRAY, PsiSubstitutor.EMPTY,
@@ -870,6 +874,16 @@ public class ExpressionGenerator extends Generator {
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
GrExpression qualifier = referenceExpression.getQualifier();
if (!context.isInAnonymousContext() && qualifier != null) {
qualifier.accept(this);
}
builder.append(referenceExpression.getReferenceName());
return;
}
final GrExpression qualifier = referenceExpression.getQualifier();
final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
@@ -967,7 +981,19 @@ public class ExpressionGenerator extends Generator {
builder.append(refName);
}
else {
builder.append("getProperty(\"").append(refName).append("\")");
PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(referenceExpression);
GroovyResolveResult[] candidates = qualifierType != null
? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression,
stringType)
: GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method != null) {
builder.append("getProperty(\"").append(refName).append("\")");
}
else {
builder.append(refName);
}
}
}
else {
@@ -1010,15 +1036,6 @@ public class ExpressionGenerator extends Generator {
return name;
}
@Override
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expr) {
GrReferenceExpression qualifier = expr.getQualifier();
if (!context.isInAnonymousContext() && qualifier != null) {
qualifier.accept(this);
}
builder.append(expr.getReferenceName());
}
@Override
public void visitCastExpression(GrTypeCastExpression typeCastExpression) {
final GrTypeElement typeElement = typeCastExpression.getCastTypeElement();
@@ -47,10 +47,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.extract.ExtractUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.AnySupers;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.FieldConflictsResolver;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrExpressionWrapper;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterSettings;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -96,7 +96,7 @@ public class ExtractClosureFromMethodProcessor extends ExtractClosureProcessorBa
for (GrStatement statement : statements) {
statement.accept(anySupers);
}
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
if (!PsiTreeUtil.isAncestor(myMethod.getContainingClass(), usageInfo.getElement(), false)) {
@@ -23,7 +23,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
@@ -40,7 +39,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
@@ -51,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
@@ -63,6 +60,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.NameValidator;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -107,14 +105,9 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
}
}
}
final Ref<Boolean> hasSuper = new Ref<Boolean>(false);
info.expression.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
hasSuper.set(true);
}
});
if (hasSuper.get()) {
AnySupers visitor = new AnySupers();
info.expression.accept(visitor);
if (visitor.containsSupers()) {
conflicts.putValue(info.expression, GroovyRefactoringBundle.message("super.reference.is.used"));
}
}
@@ -104,7 +104,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
public static boolean expressionIsIncorrect(GrExpression expression, boolean acceptVoidCalls) {
if (expression instanceof GrParenthesizedExpression) return true;
if (expression instanceof GrSuperReferenceExpression) return true;
if (PsiUtil.isSuperReference(expression)) return true;
if (expression instanceof GrAssignmentExpression) return true;
if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrCall) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)expression).advancedResolve();
@@ -30,7 +30,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.ArrayList;
@@ -130,8 +129,7 @@ public class FieldConflictsResolver {
LOG.assertTrue(parentClass != null);
expressionFromText = factory.createReferenceExpressionFromText("A.this." + member.getName());
//noinspection ConstantConditions
((GrThisReferenceExpression)expressionFromText.getQualifier()).getQualifier().replace(
factory.createReferenceElementForClass(parentClass));
((GrReferenceExpression)expressionFromText.getQualifier()).getQualifier().replace(factory.createReferenceElementForClass(parentClass));
}
else {
expressionFromText = (GrReferenceExpression)factory.createExpressionFromText("this." + member.getName());
@@ -69,6 +69,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.FieldConflictsResolver;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.OldReferencesResolver;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.BitSet;
@@ -125,7 +126,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
if (expression != null && toSearchFor instanceof PsiMember) {
final AnySupers anySupers = new AnySupers();
expression.accept(anySupers);
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
final PsiElement containingClass = PsiUtil.getFileOrClassContext(toReplaceIn);
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
@@ -123,7 +123,7 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me
if (scopes.size() == 0) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("there.is.no.method.or.closure"));
}
else if (scopes.size() == 1) {
else if (scopes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
final GrParametersOwner owner = scopes.get(0);
final PsiElement toSearchFor;
if (owner instanceof GrMethod) {
@@ -42,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -97,7 +98,7 @@ public class GrIntroduceParameterProcessor extends BaseRefactoringProcessor impl
if (mySettings.getExpression() != null && !toReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) {
final AnySupers anySupers = new AnySupers();
mySettings.getExpression().accept(anySupers);
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
if (!PsiTreeUtil.isAncestor(toReplaceIn.getContainingClass(), usageInfo.getElement(), false)) {
@@ -52,7 +52,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -390,7 +389,7 @@ public class GroovyIntroduceParameterUtil {
public void visitReferenceExpression(GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
final GrExpression qualifier = ref.getQualifier();
if (qualifier != null && !(qualifier instanceof GrThisReferenceExpression)) return;
if (!PsiUtil.isThisReference(qualifier)) return;
final PsiElement resolved = ref.resolve();
if (!(resolved instanceof PsiField)) return;
@@ -29,6 +29,7 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
@@ -147,6 +148,13 @@ public class OldReferencesResolver {
PsiElement newExpr = expr; // references continue being resolved in the children of newExpr
if (oldExpr instanceof GrReferenceExpression) {
if (isThisReferenceToContainingClass(oldExpr) || isSimpleSuperReference(oldExpr)) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
return;
}
final GrReferenceExpression oldRef = (GrReferenceExpression)oldExpr;
newExpr = newExpr.replace(decodeReferenceExpression((GrReferenceExpression)newExpr, oldRef));
//newExpr = ((GrReferenceExpression)newExpr).getReferenceNameElement();
@@ -208,12 +216,6 @@ public class OldReferencesResolver {
}
}
}
else if (isThisReferenceToContainingClass(oldExpr) || isSimpleSuperReference(oldExpr)) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
return;
}
else {
PsiClass refClass = oldExpr.getCopyableUserData(REF_CLASS_KEY);
if (refClass != null && refClass.isValid()) {
@@ -302,13 +304,22 @@ public class OldReferencesResolver {
}
private static boolean isSimpleSuperReference(PsiElement oldExpr) {
return oldExpr instanceof GrSuperReferenceExpression && ((GrSuperReferenceExpression)oldExpr).getQualifier() == null;
if (oldExpr instanceof GrReferenceExpression) {
GrReferenceExpression ref = (GrReferenceExpression)oldExpr;
if (ref.getQualifier() == null) {
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement != null) {
return nameElement.getNode().getElementType() == GroovyTokenTypes.kSUPER;
}
}
}
return false;
}
private boolean isThisReferenceToContainingClass(PsiElement oldExpr) {
if (!(oldExpr instanceof GrThisReferenceExpression)) return false;
if (!(oldExpr instanceof GrReferenceExpression && PsiUtil.isThisReference(oldExpr))) return false;
final GrReferenceExpression qualifier = ((GrThisReferenceExpression)oldExpr).getQualifier();
final GrReferenceExpression qualifier = (GrReferenceExpression)((GrReferenceExpression)oldExpr).getQualifier();
if (qualifier == null) return true;
final PsiClass contextClass = PsiUtil.getContextClass(myToReplaceIn);
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
package org.jetbrains.plugins.groovy.refactoring.util;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Medvedev Max
@@ -25,12 +26,14 @@ public class AnySupers extends GroovyRecursiveElementVisitor {
boolean myContainsSupers = false;
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
super.visitSuperExpression(superExpression);
myContainsSupers = true;
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
super.visitReferenceExpression(referenceExpression);
if (PsiUtil.isSuperReference(referenceExpression)) {
myContainsSupers = true;
}
}
public boolean isResult() {
public boolean containsSupers() {
return myContainsSupers;
}
}
@@ -55,7 +55,7 @@ public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase {
public void testSuperWithNotEnclosingClass() { doTest() }
public void testThisWithWrongQualifier() { doTest() }
public void _testThisWithWrongQualifier() { doTest() }
public void testImplicitEnumCoercion1_6() { doTest(new GroovyAssignabilityCheckInspection()) }
@@ -135,7 +135,8 @@ class B {
new B().fo<caret>o([''])
''')
def parameters = resolved.parameterList.parameters
assertInstanceOf(resolved, PsiMethod)
def parameters = (resolved as PsiMethod).parameterList.parameters
assertEquals 'java.util.List<java.lang.String>', parameters[0].type.canonicalText
}
@@ -150,6 +150,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
public void testMethodCallInvokedOnArrayAccess() {
final GrReferenceExpression reference = (GrReferenceExpression)configureByFile("A.groovy");
assertNotNull(reference)
assertNotNull(reference.type)
assertEquals("java.lang.Integer", reference.type.canonicalText);
}
@@ -190,6 +190,10 @@ public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, "field <b><code>Test.i</code></b> is not accessible from method <b><code>XTest.n()</code></b>. Value for introduced parameter in that method call will be incorrect.");
}
public void testQualifiedThisSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null);
}
public void testFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
@@ -616,4 +616,30 @@ class Bar {
checkResult("def 'import'() {}")
}
}
void testConstructorAndSuper() {
myFixture.with {
configureByText(GroovyFileType.GROOVY_FILE_TYPE, '''\
class B<caret>ase {
def Base() {}
}
class Inheritor extends Base {
def Inheritor() {
super()
}
}
''')
renameElementAtCaret('Bassse')
checkResult('''\
class Bassse {
def Bassse() {}
}
class Inheritor extends Bassse {
def Inheritor() {
super()
}
}
''')
}
}
}
@@ -7,7 +7,7 @@ Groovy script
PsiWhiteSpace(' ')
Command arguments
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(final)('final')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'super' reference expression
Reference expression
Reference expression
PsiElement(identifier)('X')
PsiElement(.)('.')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'super' reference expression
Reference expression
PsiElement(super)('super')
PsiElement(.)('.')
PsiElement(identifier)('foo')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'this' reference expression
Reference expression
Reference expression
PsiElement(identifier)('X')
PsiElement(.)('.')
@@ -34,7 +34,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(identifier)('doo')
@@ -32,7 +32,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiWhiteSpace(' ')
Arguments
@@ -56,7 +56,7 @@ Groovy script
PsiElement(;)(';')
PsiWhiteSpace(' ')
Method call
'super' reference expression
Reference expression
PsiElement(super)('super')
PsiWhiteSpace(' ')
Arguments
@@ -53,7 +53,7 @@ Groovy script
PsiWhiteSpace('\n ')
Assignment expression
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(identifier)('value')
@@ -90,7 +90,7 @@ Groovy script
PsiElement(()('(')
Additive expression
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(identifier)('value')
@@ -34,7 +34,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'super' reference expression
Reference expression
PsiElement(super)('super')
Arguments
PsiElement(()('(')
@@ -32,7 +32,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
Arguments
PsiElement(()('(')
@@ -63,7 +63,7 @@ Groovy script
Open block
PsiElement({)('{')
Method call
'this' reference expression
Reference expression
PsiElement(this)('this')
Arguments
PsiElement(()('(')
@@ -39,7 +39,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiWhiteSpace(' ')
Arguments
@@ -33,7 +33,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
Arguments
PsiElement(()('(')
@@ -39,7 +39,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiWhiteSpace(' ')
Arguments
@@ -43,7 +43,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiWhiteSpace(' ')
Arguments
@@ -52,7 +52,7 @@ Groovy script
PsiElement({)('{')
PsiWhiteSpace('\n ')
Constructor invocation
'this' reference expression
Reference expression
PsiElement(this)('this')
Arguments
PsiElement(()('(')
@@ -1,5 +1,5 @@
public class Base extends groovy.lang.GroovyObjectSupport implements groovy.lang.GroovyObject {
public Base(java.lang.Object a) {
public Base(java.lang.Integer a) {
}
}
public class Inheritor extends Base implements groovy.lang.GroovyObject {
@@ -6,7 +6,7 @@ java.lang.String s = "a";
s.bar = 4;
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar = 5);
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, getProperty("bar"));
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.getProperty("bar"));
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar);
}
private static <Value>Value setProperty0(groovy.lang.GroovyObjectSupport propOwner, java.lang.String property, Value newValue) {
@@ -0,0 +1,2 @@
final Upper.Foo foo = new Upper.Foo()
foo.abr(foo)
@@ -0,0 +1,9 @@
class Upper {
class Foo {
def x = 4
def abr() {
print <selection>Foo.this</selection>.x
}
}
}