IDEA-125909 Groovy: trait methods accessed via 'super' are not resolved

This commit is contained in:
Max Medvedev
2014-06-18 14:02:40 +04:00
parent e1e345c1b3
commit ccd4158ac9
4 changed files with 103 additions and 11 deletions
@@ -19,7 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
import gnu.trove.THashSet;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -52,7 +52,7 @@ public class PsiIntersectionType extends PsiType.Stub {
private static PsiType[] flattenAndRemoveDuplicates(PsiType[] conjuncts) {
try {
Set<PsiType> flattened = flatten(conjuncts, new THashSet<PsiType>());
Set<PsiType> flattened = flatten(conjuncts, ContainerUtil.<PsiType>newLinkedHashSet());
return flattened.toArray(createArray(flattened.size()));
}
catch (NoSuchElementException e) {
@@ -58,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.*;
@@ -604,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 {
@@ -393,6 +393,89 @@ class foo {
assertInstanceOf(resolved, PsiMethod)
}
void testSuperInTrait1() {
def clazz = resolveByText('''
trait T1 {
void on() {
println "T1"
}
}
trait T2 {
void on() {
println "T2"
}
}
trait LoggingHandler extends T1 implements T2 {
void on() {
super.o<caret>n()
}
}
''', PsiMethod).containingClass
assertEquals("T1", clazz.qualifiedName)
}
void testSuperInTrait2() {
def clazz = resolveByText('''
trait T1 {
void on() {
println "T1"
}
}
trait T2 {
void on() {
println "T2"
}
}
trait LoggingHandler implements T1, T2 {
void on() {
super.o<caret>n()
}
}
''', PsiMethod).containingClass
assertEquals("T2", clazz.qualifiedName)
}
void testSuperInTrait3() {
def clazz = resolveByText('''
trait T1 {
void on() {
println "T1"
}
}
trait LoggingHandler extends T1 {
void on() {
super.o<caret>n()
}
}
''', PsiMethod).containingClass
assertEquals("T1", clazz.qualifiedName)
}
void testSuperInTrait4() {
def clazz = resolveByText('''
trait T1 {
void on() {
println "T1"
}
}
trait LoggingHandler implements T1 {
void on() {
super.o<caret>n()
}
}
''', PsiMethod).containingClass
assertEquals("T1", clazz.qualifiedName)
}
private void doTest(String fileName = getTestName(false) + ".groovy") { resolve(fileName, PsiClass) }
}
@@ -352,7 +352,7 @@ def foo(Integer a) {
<caret>a.substring(2)
}
}
''', '[java.lang.String,java.lang.Integer]')
''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod2() {
@@ -363,7 +363,7 @@ def foo(Integer a) {
bar(a)
<caret>a.substring(2)
}
''', '[java.lang.String,java.lang.Integer]')
''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod3() {
@@ -375,7 +375,7 @@ def foo(Integer a) {
print a
<caret>a.substring(2)
}
''', '[java.lang.String,java.lang.Integer]')
''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod4() {
@@ -389,7 +389,7 @@ def foo(Integer a) {
<caret>a.substring(2)
}
}
''', '[java.lang.String,java.lang.Integer]')
''', '[java.lang.Integer,java.lang.String]')
}
void testEmptyListOrListWithGenerics() {