mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] resolve method references with top level type as receiver
Support top-level type for reference expressions and index property expressions. This fixes cycle when operator resolution wanted receiver type and receiver type required inference from context, i.e. from resolved operator. GitOrigin-RevId: 2c2818e2b5689ddf0c65aac2d87b76d11f1f2ebc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dccdf09d73
commit
28fcfceaaf
+14
-12
@@ -11,6 +11,7 @@ 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.expressions.path.GrIndexProperty
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil.getQualifierType
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter
|
||||
@@ -24,22 +25,23 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint
|
||||
import org.jetbrains.plugins.groovy.lang.typing.devoid
|
||||
|
||||
fun getTopLevelType(expression: GrExpression): PsiType? {
|
||||
if (expression is GrMethodCall) {
|
||||
val resolved = expression.advancedResolve() as? GroovyMethodResult
|
||||
resolved?.candidate?.let {
|
||||
val session = GroovyInferenceSessionBuilder(expression, it, resolved.contextSubstitutor)
|
||||
.resolveMode(false)
|
||||
.build()
|
||||
return session.inferSubst().substitute(PsiUtil.getSmartReturnType(it.method).devoid(expression))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
if (expression is GrFunctionalExpression) {
|
||||
return TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, expression)
|
||||
}
|
||||
|
||||
return expression.type
|
||||
val result = when (expression) {
|
||||
is GrMethodCall -> expression.advancedResolve() as? GroovyMethodResult
|
||||
is GrReferenceExpression -> expression.rValueReference?.advancedResolve() as? GroovyMethodResult ?: return expression.type
|
||||
is GrIndexProperty -> expression.rValueReference?.advancedResolve() as? GroovyMethodResult ?: return expression.type
|
||||
else -> return expression.type
|
||||
}
|
||||
|
||||
return result?.candidate?.let {
|
||||
val session = GroovyInferenceSessionBuilder(expression, it, result.contextSubstitutor)
|
||||
.resolveMode(false)
|
||||
.build()
|
||||
session.inferSubst().substitute(PsiUtil.getSmartReturnType(it.method).devoid(expression))
|
||||
}
|
||||
}
|
||||
|
||||
fun buildQualifier(ref: GrReferenceExpression?, state: ResolveState): Argument {
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint.STATIC_CONTEXT
|
||||
|
||||
fun Argument.processReceiver(processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
|
||||
val receiverType: PsiType = type ?: TypesUtil.getJavaLangObject(place) ?: return true
|
||||
val receiverType: PsiType = topLevelType ?: TypesUtil.getJavaLangObject(place) ?: return true
|
||||
return receiverType.doProcessReceiverType0(processor, state.put(ClassHint.RECEIVER, this), place)
|
||||
}
|
||||
|
||||
|
||||
+36
@@ -9,6 +9,7 @@ import org.jetbrains.plugins.groovy.GroovyProjectDescriptors
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
import org.jetbrains.plugins.groovy.util.LightProjectTest
|
||||
import org.jetbrains.plugins.groovy.util.ResolveTest
|
||||
@@ -49,6 +50,9 @@ class IdCallable {
|
||||
class GenericPropertyContainer {
|
||||
def <T> I<T> getGenericProperty() {}
|
||||
def <T> void setGenericProperty(I<T> c) {}
|
||||
|
||||
def <T> List<T> getGenericList() {}
|
||||
def <T> void setGenericList(List<T> l) {}
|
||||
}
|
||||
|
||||
class Files {
|
||||
@@ -242,6 +246,38 @@ static <T> T ppp(Producer<T> p) {}
|
||||
assertSubstitutor(op.reference.advancedResolve(), 'java.io.File')
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'plus assignment generic property r-value'() {
|
||||
def ref = elementUnderCaret('new GenericPropertyContainer().<caret>genericList += new ArrayList<String>()', GrReferenceExpression)
|
||||
assertSubstitutor(ref.RValueReference.advancedResolve(), JAVA_LANG_STRING)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'plus assignment generic property'() {
|
||||
def op = elementUnderCaret('new GenericPropertyContainer().genericList <caret>+= new ArrayList<String>()', GrAssignmentExpression)
|
||||
assertSubstitutor(op.reference.advancedResolve(), JAVA_LANG_STRING)
|
||||
}
|
||||
|
||||
@Ignore("we don't yet infer l-value substitutors")
|
||||
@Test
|
||||
void 'plus assignment generic property l-value'() {
|
||||
def ref = elementUnderCaret('new GenericPropertyContainer().<caret>genericList += new ArrayList<String>()', GrReferenceExpression)
|
||||
assertSubstitutor(ref.LValueReference.advancedResolve(), JAVA_LANG_STRING)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'plus assignment with index r-value'() {
|
||||
def op = elementUnderCaret('Map<Number, String> mns; mns<caret>[42] += "foo"', GrIndexProperty)
|
||||
assertSubstitutor(op.RValueReference.advancedResolve(), JAVA_LANG_NUMBER, JAVA_LANG_STRING)
|
||||
}
|
||||
|
||||
@Ignore("we don't yet infer l-value substitutors")
|
||||
@Test
|
||||
void 'plus assignment with index l-value'() {
|
||||
def op = elementUnderCaret('Map<Number, String> mns; mns<caret>[42] += "foo"', GrIndexProperty)
|
||||
assertSubstitutor(op.LValueReference.advancedResolve(), JAVA_LANG_NUMBER, JAVA_LANG_STRING)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'same method nested'() {
|
||||
def call = elementUnderCaret '''\
|
||||
|
||||
Reference in New Issue
Block a user