summaryrefslogtreecommitdiff
path: root/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl')
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java40
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java77
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java240
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java380
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java84
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java45
6 files changed, 445 insertions, 421 deletions
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
index 0cde75af230b..dce723b5f3bc 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
@@ -46,10 +46,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
-import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
-import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
-import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.*;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
@@ -76,6 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
@@ -988,4 +986,38 @@ public class PsiImplUtil {
}
return expr == null;
}
+
+ @Nullable
+ public static PsiType getQualifierType(@NotNull GrReferenceExpression ref) {
+ final GrExpression rtQualifier = getRuntimeQualifier(ref);
+ if (rtQualifier != null) {
+ return rtQualifier.getType();
+ }
+
+ PsiClass containingClass = null;
+ final GrMember member = PsiTreeUtil.getParentOfType(ref, GrMember.class);
+ if (member == null) {
+ final PsiFile file = ref.getContainingFile();
+ if (file instanceof GroovyFileBase && ((GroovyFileBase)file).isScript()) {
+ containingClass = ((GroovyFileBase)file).getScriptClass();
+ }
+ else {
+ return null;
+ }
+ }
+ else if (member instanceof GrMethod) {
+ if (!member.hasModifierProperty(PsiModifier.STATIC)) {
+ containingClass = member.getContainingClass();
+ }
+ }
+
+ if (containingClass != null) {
+ final PsiClassType categoryType = GdkMethodUtil.getCategoryType(containingClass);
+ if (categoryType != null) {
+ return categoryType;
+ }
+ return JavaPsiFacade.getElementFactory(ref.getProject()).createType(containingClass);
+ }
+ return null;
+ }
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
index 40589065654d..4b8a032a5602 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
@@ -46,7 +46,6 @@ 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.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
@@ -59,10 +58,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.*;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer;
-import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
-import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.*;
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.*;
@@ -159,15 +155,15 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
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()]);
+ GroovyResolveResult[] results = GrThisReferenceResolver.resolveThisExpression(this);
+ if (results != null) {
+ return results;
}
}
else if (nameType == GroovyTokenTypes.kSUPER) {
- ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
- if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) {
- return results.toArray(new GroovyResolveResult[results.size()]);
+ GroovyResolveResult[] results = GrSuperReferenceResolver.resolveSuperExpression(this);
+ if (results != null) {
+ return results;
}
}
@@ -178,8 +174,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
GroovyResolveResult[] classCandidates = null;
+ GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this);
+
ResolverProcessor processor = new PropertyResolverProcessor(name, this);
- GrReferenceResolveUtil.resolveImpl(processor, this);
+ resolveRunner.resolveImpl(processor);
final GroovyResolveResult[] fieldCandidates = processor.getCandidates();
if (hasAt()) {
@@ -191,7 +189,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (canBeClassOrPackage && findClassOrPackageAtFirst()) {
ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
- GrReferenceResolveUtil.resolveImpl(classProcessor, this);
+ resolveRunner.resolveImpl(classProcessor);
classCandidates = classProcessor.getCandidates();
if (classCandidates.length > 0 && containsPackage(classCandidates)) return classCandidates;
}
@@ -215,9 +213,8 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
for (String accessorName : accessorNames) {
AccessorResolverProcessor accessorResolver =
- new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, GrReferenceResolveUtil.getQualifierType(this),
- getTypeArguments());
- GrReferenceResolveUtil.resolveImpl(accessorResolver, this);
+ new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, PsiImplUtil.getQualifierType(this), getTypeArguments());
+ resolveRunner.resolveImpl(accessorResolver);
final GroovyResolveResult[] candidates = accessorResolver.getCandidates();
//can be only one correct candidate or some incorrect
@@ -237,9 +234,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (classCandidates == null && canBeClassOrPackage ) {
ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
- GrReferenceResolveUtil.resolveImpl(classProcessor, this);
+ resolveRunner.resolveImpl(classProcessor);
classCandidates = classProcessor.getCandidates();
}
+
if (classCandidates != null && classCandidates.length > 0) return classCandidates;
if (!accessorResults.isEmpty()) return new GroovyResolveResult[]{accessorResults.get(0)};
return GroovyResolveResult.EMPTY_ARRAY;
@@ -258,23 +256,14 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
private void processMethods(@NotNull MethodResolverProcessor methodResolver) {
- GrReferenceResolveUtil.resolveImpl(methodResolver, this);
+ new GrReferenceResolveRunner(this).resolveImpl(methodResolver);
if (methodResolver.hasApplicableCandidates()) {
return;
}
// Search in ClosureMissingMethodContributor
if (!isQualified() && getContext() instanceof GrMethodCall) {
- for (PsiElement e = this.getContext(); e != null; e = e.getContext()) {
- if (e instanceof GrClosableBlock) {
- ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, e);
- for (ClosureMissingMethodContributor contributor : ClosureMissingMethodContributor.EP_NAME.getExtensions()) {
- if (!contributor.processMembers((GrClosableBlock)e, methodResolver, this, state)) {
- return;
- }
- }
- }
- }
+ ClosureMissingMethodContributor.processMethodsFromClosures(this, methodResolver);
}
}
@@ -287,8 +276,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
final String name = getReferenceName();
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
+ GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this);
+
PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this);
- GrReferenceResolveUtil.resolveImpl(propertyResolver, this);
+ resolveRunner.resolveImpl(propertyResolver);
final GroovyResolveResult[] propertyCandidates = propertyResolver.getCandidates();
if (!allVariants) { //search for local variables
@@ -345,8 +336,8 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
//search for getters
for (String getterName : GroovyPropertyUtils.suggestGettersName(name)) {
AccessorResolverProcessor getterResolver =
- new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, GrReferenceResolveUtil.getQualifierType(this), getTypeArguments());
- GrReferenceResolveUtil.resolveImpl(getterResolver, this);
+ new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, PsiImplUtil.getQualifierType(this), getTypeArguments());
+ resolveRunner.resolveImpl(getterResolver);
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
if (!allVariants && candidates.length == 1) {
return candidates;
@@ -424,7 +415,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
argTypes[i] = TypeConversionUtil.erasure(argTypes[i]);
}
}
- PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(this);
+ PsiType qualifierType = PsiImplUtil.getQualifierType(this);
return new MethodResolverProcessor(name, this, false, qualifierType, argTypes, getTypeArguments(), allVariants, byShape);
}
@@ -610,7 +601,19 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return factory.createType((PsiClass)resolved);
}
}
- if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this)) {
+ else if (PsiUtil.isSuperReference(this)) {
+ PsiClass contextClass = PsiUtil.getContextClass(this);
+ if (GrTraitUtil.isTrait(contextClass)) {
+ PsiClassType[] extendsTypes = contextClass.getExtendsListTypes();
+ PsiClassType[] implementsTypes = contextClass.getImplementsListTypes();
+
+ PsiClassType[] superTypes = ArrayUtil.mergeArrays(implementsTypes, extendsTypes, PsiClassType.ARRAY_FACTORY);
+
+ return PsiIntersectionType.createIntersection(ArrayUtil.reverseArray(superTypes));
+ }
+ return factory.createType((PsiClass)resolved);
+ }
+ if (getParent() instanceof GrReferenceExpression) {
return factory.createType((PsiClass)resolved);
}
else {
@@ -637,7 +640,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (containingClass != null &&
CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
"getClass".equals(method.getName())) {
- return TypesUtil.createJavaLangClassType(GrReferenceResolveUtil.getQualifierType(this), getProject(), getResolveScope());
+ return TypesUtil.createJavaLangClassType(PsiImplUtil.getQualifierType(this), getProject(), getResolveScope());
}
return PsiUtil.getSmartReturnType(method);
@@ -701,7 +704,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Nullable
private static PsiType getTypeFromClassRef(@NotNull GrReferenceExpressionImpl ref) {
if ("class".equals(ref.getReferenceName())) {
- return TypesUtil.createJavaLangClassType(GrReferenceResolveUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope());
+ return TypesUtil.createJavaLangClassType(PsiImplUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope());
}
return null;
}
@@ -710,7 +713,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Override
@Nullable
public PsiType fun(GrReferenceExpressionImpl refExpr) {
- if (GrReferenceResolveUtil.isClassReference(refExpr)) {
+ if (ResolveUtil.isClassReference(refExpr)) {
GrExpression qualifier = refExpr.getQualifier();
LOG.assertTrue(qualifier != null);
return TypesUtil.createJavaLangClassType(qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
@@ -783,7 +786,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (incompleteCode) {
ResolverProcessor processor = CompletionProcessor.createRefSameNameProcessor(this, name);
- GrReferenceResolveUtil.resolveImpl(processor, this);
+ new GrReferenceResolveRunner(this).resolveImpl(processor);
GroovyResolveResult[] propertyCandidates = processor.getCandidates();
if (propertyCandidates.length > 0 && !PsiUtil.isSingleBindingVariant(propertyCandidates)) return propertyCandidates;
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java
new file mode 100644
index 000000000000..13159892a3ee
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
+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.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GrTraitType;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
+import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
+import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
+import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
+
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * @author Medvedev Max
+ */
+public class GrReferenceResolveRunner {
+
+ private final GrReferenceExpression place;
+ private ResolverProcessor processor;
+
+ public GrReferenceResolveRunner(@NotNull GrReferenceExpression _place) {
+ place = _place;
+ }
+
+ public boolean resolveImpl(@NotNull ResolverProcessor _processor) {
+ processor = _processor;
+ try {
+ boolean result = doResolve();
+ ProgressManager.checkCanceled();
+ return result;
+ }
+ finally {
+ processor = null;
+ }
+ }
+
+ private boolean doResolve() {
+ GrExpression qualifier = place.getQualifier();
+ if (qualifier == null) {
+ if (!ResolveUtil.treeWalkUp(place, processor, true)) return false;
+ if (!processor.hasCandidates()) {
+ GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(place);
+ if (runtimeQualifier != null) {
+ if (!processQualifier(runtimeQualifier)) return false;
+ }
+ }
+ }
+ else {
+ if (place.getDotTokenType() == GroovyTokenTypes.mSPREAD_DOT) {
+ final PsiType qtype = qualifier.getType();
+ final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qtype, place);
+ if (componentType != null) {
+ final ResolveState state = ResolveState.initial()
+ .put(ClassHint.RESOLVE_CONTEXT, qualifier)
+ .put(SpreadState.SPREAD_STATE, SpreadState.create(qtype, null));
+ if (!processQualifierType(componentType, state)) return false;
+ }
+ }
+ else {
+ if (ResolveUtil.isClassReference(place)) return true;
+ if (!processQualifier(qualifier)) return false;
+ if (!processJavaLangClass(qualifier)) return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean processJavaLangClass(@NotNull GrExpression qualifier) {
+ if (!(qualifier instanceof GrReferenceExpression)) return true;
+
+ //optimization: only 'class' or 'this' in static context can be an alias of java.lang.Class
+ if (!("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
+ PsiUtil.isThisReference(qualifier))) {
+ return true;
+ }
+
+ PsiType type = qualifier.getType();
+ if (!(type instanceof PsiClassType)) return true;
+
+ final PsiClass psiClass = ((PsiClassType)type).resolve();
+ if (psiClass == null || !CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) return true;
+
+ final PsiType[] params = ((PsiClassType)type).getParameters();
+ if (params.length != 1) return true;
+
+ if (!processQualifierType(params[0], ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier))) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean processQualifier(@NotNull GrExpression qualifier) {
+ PsiType qualifierType = qualifier.getType();
+ ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier);
+ if (qualifierType == null || qualifierType == PsiType.VOID) {
+ if (qualifier instanceof GrReferenceExpression) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved != null && !resolved.processDeclarations(processor, state, null, place)) return false;
+ if (!(resolved instanceof PsiPackage)) {
+ PsiType objectQualifier = TypesUtil.getJavaLangObject(place);
+ if (!processQualifierType(objectQualifier, state)) return false;
+ }
+ }
+ }
+ else if (qualifierType instanceof PsiIntersectionType) {
+ for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
+ if (!processQualifierType(conjunct, state)) return false;
+ }
+ }
+ else {
+ if (!processQualifierType(qualifierType, state)) return false;
+ if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved instanceof PsiClass) {
+ if (!processJavaLangClass(qualifierType, state)) return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean processJavaLangClass(@NotNull PsiType qualifierType,
+ @NotNull ResolveState state) {
+ //omitted .class
+ PsiClass javaLangClass = PsiUtil.getJavaLangClass(place, place.getResolveScope());
+ if (javaLangClass == null) return true;
+
+ PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
+ PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
+ if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
+ if (typeParameters.length == 1) {
+ substitutor = substitutor.put(typeParameters[0], qualifierType);
+ state = state.put(PsiSubstitutor.KEY, substitutor);
+ }
+ if (!javaLangClass.processDeclarations(processor, state, null, place)) return false;
+
+ PsiType javaLangClassType = JavaPsiFacade.getElementFactory(place.getProject()).createType(javaLangClass, substitutor);
+
+ if (!ResolveUtil.processNonCodeMembers(javaLangClassType, processor, place, state)) return false;
+
+ return true;
+ }
+
+ private boolean processQualifierType(@NotNull PsiType originalQualifierType,
+ @NotNull ResolveState state) {
+ PsiType qualifierType = originalQualifierType instanceof PsiDisjunctionType
+ ? ((PsiDisjunctionType)originalQualifierType).getLeastUpperBound()
+ : originalQualifierType;
+
+ if (qualifierType instanceof PsiIntersectionType) {
+ for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
+ if (!processQualifierType(conjunct, state)) return false;
+ }
+ return true;
+ }
+
+ if (qualifierType instanceof GrTraitType) {
+ if (!processTraitType((GrTraitType)qualifierType, state)) {
+ return false;
+ }
+ return true;
+ }
+
+ if (qualifierType instanceof PsiClassType) {
+ PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType)qualifierType).resolveGenerics();
+ PsiClass qualifierClass = qualifierResult.getElement();
+ if (qualifierClass != null) {
+ if (!qualifierClass.processDeclarations(processor, state.put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, place)) {
+ return false;
+ }
+ }
+ }
+ else if (qualifierType instanceof PsiArrayType) {
+ final GroovyPsiManager gmanager = GroovyPsiManager.getInstance(place.getProject());
+ final GrTypeDefinition arrayClass = gmanager.getArrayClass(((PsiArrayType)qualifierType).getComponentType());
+ if (arrayClass != null && !arrayClass.processDeclarations(processor, state, null, place)) return false;
+ }
+
+ if (!(place.getParent() instanceof GrMethodCall) && InheritanceUtil.isInheritor(qualifierType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
+ final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qualifierType, place);
+ if (componentType != null) {
+ final SpreadState spreadState = state.get(SpreadState.SPREAD_STATE);
+ processQualifierType(componentType, state.put(SpreadState.SPREAD_STATE, SpreadState.create(qualifierType, spreadState)));
+ }
+ }
+
+ if (!ResolveUtil.processCategoryMembers(place, processor, state)) return false;
+ if (!ResolveUtil.processNonCodeMembers(qualifierType, processor, place, state)) return false;
+ return true;
+ }
+
+ private boolean processTraitType(@NotNull GrTraitType traitType, @NotNull ResolveState state) {
+ GrTypeDefinition mockDefinition = traitType.getMockTypeDefinition();
+ if (mockDefinition != null) {
+ if (!mockDefinition.processDeclarations(processor, state, null, place)) {
+ return false;
+ }
+ }
+ else {
+ PsiClassType exprType = traitType.getExprType();
+
+ if (!processQualifierType(exprType, state)) return false;
+
+ List<PsiClassType> traitTypes = traitType.getTraitTypes();
+ for (ListIterator<PsiClassType> iterator = traitTypes.listIterator(); iterator.hasPrevious(); ) {
+ PsiClassType type = iterator.previous();
+ if (!processQualifierType(type, state)) return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java
deleted file mode 100644
index 4779fb12f25f..000000000000
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.psi.*;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.psi.util.InheritanceUtil;
-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.lexer.GroovyTokenTypes;
-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.GrClassInitializer;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
-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.GrMethodCall;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-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.impl.GrTraitType;
-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.typeEnhancers.ClosureParameterEnhancer;
-import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
-import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
-
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * @author Medvedev Max
- */
-public class GrReferenceResolveUtil {
-
- private GrReferenceResolveUtil() {
- }
-
- static boolean resolveImpl(@NotNull ResolverProcessor processor,
- @NotNull GrReferenceExpression place) {
- boolean b = doResolve(processor, place);
- ProgressManager.checkCanceled();
- return b;
- }
-
- private static boolean doResolve(ResolverProcessor processor, GrReferenceExpression place) {
- GrExpression qualifier = place.getQualifier();
- if (qualifier == null) {
- if (!ResolveUtil.treeWalkUp(place, processor, true)) return false;
- if (!processor.hasCandidates()) {
- GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(place);
- if (runtimeQualifier != null) {
- if (!processQualifier(processor, runtimeQualifier, place)) return false;
- }
- }
- }
- else {
- if (place.getDotTokenType() == GroovyTokenTypes.mSPREAD_DOT) {
- final PsiType qtype = qualifier.getType();
- final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qtype, place);
- if (componentType != null) {
- final ResolveState state = ResolveState.initial()
- .put(ClassHint.RESOLVE_CONTEXT, qualifier)
- .put(SpreadState.SPREAD_STATE, SpreadState.create(qtype, null));
- if (!processQualifierType(processor, componentType, state, place)) return false;
- }
- }
- else {
- if (isClassReference(place)) return true;
- if (!processQualifier(processor, qualifier, place)) return false;
- }
-
- if (qualifier instanceof GrReferenceExpression &&
- ("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier))) {
- if (!processIfJavaLangClass(processor, qualifier.getType(), qualifier, place)) return false;
- }
- }
- return true;
- }
-
- private static boolean processIfJavaLangClass(@NotNull ResolverProcessor processor,
- @Nullable PsiType type,
- @NotNull GroovyPsiElement resolveContext,
- @NotNull GrReferenceExpression place) {
- if (!(type instanceof PsiClassType)) return true;
-
- final PsiClass psiClass = ((PsiClassType)type).resolve();
- if (psiClass == null || !CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) return true;
-
- final PsiType[] params = ((PsiClassType)type).getParameters();
- if (params.length != 1) return true;
-
- if (!processQualifierType(processor, params[0], ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, resolveContext), place)) {
- return false;
- }
- return true;
- }
-
- public static boolean processQualifier(@NotNull PsiScopeProcessor processor,
- @NotNull GrExpression qualifier,
- @NotNull GrReferenceExpression place) {
- PsiType qualifierType = qualifier.getType();
- ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier);
- if (qualifierType == null || qualifierType == PsiType.VOID) {
- if (qualifier instanceof GrReferenceExpression) {
- PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
- if (resolved != null && !resolved.processDeclarations(processor, state, null, place)) return false;
- if (!(resolved instanceof PsiPackage)) {
- PsiType objectQualifier = TypesUtil.getJavaLangObject(place);
- if (!processQualifierType(processor, objectQualifier, state, place)) return false;
- }
- }
- }
- else if (qualifierType instanceof PsiIntersectionType) {
- for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
- if (!processQualifierType(processor, conjunct, state, place)) return false;
- }
- }
- else {
- if (!processQualifierType(processor, qualifierType, state, place)) return false;
- if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
- PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
- if (resolved instanceof PsiClass) {
- if (!processJavaLangClass(qualifierType, processor, state, place)) return false;
- }
- }
- }
- return true;
- }
-
- private static boolean processJavaLangClass(@NotNull PsiType qualifierType,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- //omitted .class
- PsiClass javaLangClass = PsiUtil.getJavaLangClass(place, place.getResolveScope());
- if (javaLangClass == null) return true;
-
- PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
- PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
- if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
- if (typeParameters.length == 1) {
- substitutor = substitutor.put(typeParameters[0], qualifierType);
- state = state.put(PsiSubstitutor.KEY, substitutor);
- }
- if (!javaLangClass.processDeclarations(processor, state, null, place)) return false;
-
- PsiType javaLangClassType = JavaPsiFacade.getElementFactory(place.getProject()).createType(javaLangClass, substitutor);
-
- if (!ResolveUtil.processNonCodeMembers(javaLangClassType, processor, place, state)) return false;
-
- return true;
- }
-
- private static boolean processQualifierType(@NotNull PsiScopeProcessor processor,
- @NotNull PsiType originalQualifierType,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- PsiType qualifierType = originalQualifierType instanceof PsiDisjunctionType
- ? ((PsiDisjunctionType)originalQualifierType).getLeastUpperBound()
- : originalQualifierType;
-
- if (qualifierType instanceof PsiIntersectionType) {
- for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
- if (!processQualifierType(processor, conjunct, state, place)) return false;
- }
- return true;
- }
-
- if (qualifierType instanceof GrTraitType) {
- if (!processTraitType((GrTraitType)qualifierType, processor, state, place)) {
- return false;
- }
- return true;
- }
-
- if (qualifierType instanceof PsiClassType) {
- PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType)qualifierType).resolveGenerics();
- PsiClass qualifierClass = qualifierResult.getElement();
- if (qualifierClass != null) {
- if (!qualifierClass.processDeclarations(processor, state.put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, place)) {
- return false;
- }
- }
- }
- else if (qualifierType instanceof PsiArrayType) {
- final GroovyPsiManager gmanager = GroovyPsiManager.getInstance(place.getProject());
- final GrTypeDefinition arrayClass = gmanager.getArrayClass(((PsiArrayType)qualifierType).getComponentType());
- if (arrayClass != null && !arrayClass.processDeclarations(processor, state, null, place)) return false;
- }
-
- if (!(place.getParent() instanceof GrMethodCall) && InheritanceUtil.isInheritor(qualifierType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
- final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qualifierType, place);
- if (componentType != null) {
- final SpreadState spreadState = state.get(SpreadState.SPREAD_STATE);
- processQualifierType(processor, componentType, state.put(SpreadState.SPREAD_STATE, SpreadState.create(qualifierType, spreadState)), place);
- }
- }
-
- if (!ResolveUtil.processCategoryMembers(place, processor, state)) return false;
- if (!ResolveUtil.processNonCodeMembers(qualifierType, processor, place, state)) return false;
- return true;
- }
-
- private static boolean processTraitType(@NotNull GrTraitType traitType,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- GrTypeDefinition mockDefinition = traitType.getMockTypeDefinition();
- if (mockDefinition != null) {
- if (!mockDefinition.processDeclarations(processor, state, null, place)) {
- return false;
- }
- }
- else {
- PsiClassType exprType = traitType.getExprType();
-
- if (!processQualifierType(processor, exprType, state, place)) return false;
-
- List<PsiClassType> traitTypes = traitType.getTraitTypes();
- for (ListIterator<PsiClassType> iterator = traitTypes.listIterator(); iterator.hasPrevious(); ) {
- PsiClassType type = iterator.previous();
- if (!processQualifierType(processor, type, state, place)) return false;
- }
- }
-
- return true;
- }
-
- @Nullable
- public static PsiType getQualifierType(@NotNull GrReferenceExpression ref) {
- final GrExpression rtQualifier = PsiImplUtil.getRuntimeQualifier(ref);
- if (rtQualifier != null) {
- return rtQualifier.getType();
- }
-
- PsiClass containingClass = null;
- final GrMember member = PsiTreeUtil.getParentOfType(ref, GrMember.class);
- if (member == null) {
- final PsiFile file = ref.getContainingFile();
- if (file instanceof GroovyFileBase && ((GroovyFileBase)file).isScript()) {
- containingClass = ((GroovyFileBase)file).getScriptClass();
- }
- else {
- return null;
- }
- }
- else if (member instanceof GrMethod) {
- if (!member.hasModifierProperty(PsiModifier.STATIC)) {
- containingClass = member.getContainingClass();
- }
- }
-
- if (containingClass != null) {
- final PsiClassType categoryType = GdkMethodUtil.getCategoryType(containingClass);
- if (categoryType != null) {
- return categoryType;
- }
- return JavaPsiFacade.getElementFactory(ref.getProject()).createType(containingClass);
- }
- return null;
- }
-
- public static boolean resolveThisExpression(@NotNull GrReferenceExpression ref,
- @NotNull 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(@NotNull GrReferenceExpression ref,
- @NotNull 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;
- aClass = (PsiClass)resolved;
-
- GrTypeDefinition scopeClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true);
- if (GrTraitUtil.isTrait(aClass) && scopeClass != null && PsiUtil.scopeClassImplementsTrait(aClass, ref)) {
- PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(aClass, scopeClass, PsiSubstitutor.EMPTY);
- results.add(new GroovyResolveResultImpl(aClass, null, null, superClassSubstitutor, true, true));
- return true;
- }
-
- if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
-
- }
- 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;
- }
-
- public static boolean isClassReference(@NotNull GrReferenceExpression ref) {
- GrExpression qualifier = ref.getQualifier();
- return "class".equals(ref.getReferenceName()) &&
- qualifier instanceof GrReferenceExpression &&
- ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass &&
- !PsiUtil.isThisReference(qualifier);
- }
-
- public static boolean isPropertyAccessInStaticMethod(@NotNull GrReferenceExpression referenceExpression) {
- return isInStaticContext(referenceExpression) &&
- !(referenceExpression.getParent() instanceof GrMethodCall) &&
- referenceExpression.getQualifier() == null;
- }
-
- public static boolean isInStaticContext(@NotNull PsiElement place) {
- GrMember context = PsiTreeUtil.getParentOfType(place, GrMember.class, true, GrClosableBlock.class);
- return (context instanceof GrMethod || context instanceof GrClassInitializer) && context.hasModifierProperty(PsiModifier.STATIC);
- }
-}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java
new file mode 100644
index 000000000000..0b45314b34a0
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+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.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * Created by Max Medvedev on 15/06/14
+ */
+public class GrSuperReferenceResolver {
+ @Nullable("null if ref is not 'super' reference")
+ public static GroovyResolveResult[] resolveSuperExpression(@NotNull GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+
+ if (qualifier == null) {
+ final PsiElement parent = ref.getParent();
+ if (parent instanceof GrConstructorInvocation) {
+ return ((GrConstructorInvocation)parent).multiResolve(false);
+ }
+ PsiClass aClass = PsiUtil.getContextClass(ref);
+ if (aClass != null) {
+ return getSuperClass(aClass);
+ }
+ }
+ else if (qualifier instanceof GrReferenceExpression) {
+ GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
+ PsiElement resolved = result.getElement();
+ if (resolved instanceof PsiClass) {
+ PsiClass superClass = (PsiClass)resolved;
+
+ GrTypeDefinition scopeClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true);
+ if (scopeClass != null && GrTraitUtil.isTrait(superClass) && scopeClass.isInheritor(superClass, false)) {
+ PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, scopeClass, PsiSubstitutor.EMPTY);
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)};
+ }
+
+ if (PsiUtil.hasEnclosingInstanceInScope(superClass, ref, false)) {
+ return getSuperClass(superClass);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @NotNull
+ private static GroovyResolveResult[] getSuperClass(@NotNull PsiClass aClass) {
+ PsiClass superClass = aClass.getSuperClass();
+ if (superClass != null) {
+ PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)};
+ }
+ else {
+ return GroovyResolveResult.EMPTY_ARRAY; //no super class, but the reference is definitely super-reference
+ }
+ }
+}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java
new file mode 100644
index 000000000000..c891459ae7de
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java
@@ -0,0 +1,45 @@
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiSubstitutor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+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.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * Created by Max Medvedev on 15/06/14
+ */
+public class GrThisReferenceResolver {
+ @Nullable("null if ref is not actually 'this' reference")
+ public static GroovyResolveResult[] resolveThisExpression(@NotNull GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+
+ if (qualifier == null) {
+ final PsiElement parent = ref.getParent();
+ if (parent instanceof GrConstructorInvocation) {
+ return ((GrConstructorInvocation)parent).multiResolve(false);
+ }
+ else {
+ PsiClass aClass = PsiUtil.getContextClass(ref);
+ if (aClass != null) {
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true)};
+ }
+ }
+ }
+ else if (qualifier instanceof GrReferenceExpression) {
+ GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
+ PsiElement resolved = result.getElement();
+ if (resolved instanceof PsiClass && PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) {
+ return new GroovyResolveResult[]{result};
+ }
+ }
+
+ return null;
+ }
+}