KT IDE: fix fully-qualified type resolving

This commit is contained in:
Ilya Kirillov
2020-07-11 01:01:51 +03:00
parent 50951fdfc3
commit ea3b2d8310
8 changed files with 86 additions and 16 deletions
@@ -308,6 +308,21 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv
runTest("idea/testData/resolve/references/ResolvePackageInProperty.kt");
}
@TestMetadata("ResolvePackageInTheEndInProperty.kt")
public void testResolvePackageInTheEndInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt");
}
@TestMetadata("ResolvePackageInTheMiddleInProperty.kt")
public void testResolvePackageInTheMiddleInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt");
}
@TestMetadata("ResolvePackageInTheTypeNameInProperty.kt")
public void testResolvePackageInTheTypeNameInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt");
}
@TestMetadata("SamAdapter.kt")
public void testSamAdapter() throws Exception {
runTest("idea/testData/resolve/references/SamAdapter.kt");
@@ -86,8 +86,16 @@ internal object FirReferenceResolveHelper {
}
}
private fun getPackageSymbolFor(expression: KtSimpleNameExpression, symbolBuilder: KtSymbolByFirBuilder): KtFirPackageSymbol? {
val fqName = when (val qualified = expression.getQualifiedExpressionForSelector()) {
private fun getPackageSymbolFor(
expression: KtSimpleNameExpression,
symbolBuilder: KtSymbolByFirBuilder,
forQualifiedType: Boolean
): KtFirPackageSymbol? {
val qualified = when {
forQualifiedType -> expression.parent?.takeIf { it is KtUserType && it.referenceExpression === expression }
else -> expression.getQualifiedExpressionForSelector()
}
val fqName = when (qualified) {
null -> FqName(expression.getReferencedName())
else -> {
qualified
@@ -96,10 +104,28 @@ internal object FirReferenceResolveHelper {
.let(::FqName)
}
}
return symbolBuilder.createPackageSymbolIfOneExists(fqName)
}
private fun KtSimpleNameExpression.isPartOfQualifiedExpression(): Boolean {
var parent = parent
while (parent is KtDotQualifiedExpression) {
if (parent.selectorExpression !== this) return true
parent = parent.parent
}
return false
}
private fun KtSimpleNameExpression.isPartOfUserTypeRefQualifier(): Boolean {
var parent = parent
while (parent is KtUserType) {
if (parent.referenceExpression !== this) return true
parent = parent.parent
}
return false
}
internal fun resolveSimpleNameReference(
ref: KtFirSimpleNameReference,
analysisSession: KtFirAnalysisSession
@@ -124,6 +150,9 @@ internal object FirReferenceResolveHelper {
return listOfNotNull(calleeReference.toTargetSymbol(session, symbolBuilder))
}
is FirResolvedTypeRef -> {
if (expression.isPartOfUserTypeRefQualifier()) {
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = true))
}
return listOfNotNull(fir.toTargetSymbol(session, symbolBuilder))
}
is FirResolvedQualifier -> {
@@ -150,14 +179,8 @@ internal object FirReferenceResolveHelper {
return listOfNotNull(type.toTargetSymbol(session, symbolBuilder))
}
is FirResolvedImport -> {
var parent = expression.parent
while (parent is KtDotQualifiedExpression) {
if (parent.selectorExpression !== expression) {
// Special: package reference in the middle of import directive
// import a.<caret>b.c.SomeClass
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder)?.let { return listOf(it) })
}
parent = parent.parent
if (expression.isPartOfQualifiedExpression()) {
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false))
}
val classId = fir.resolvedClassId
@@ -181,7 +204,7 @@ internal object FirReferenceResolveHelper {
is FirFile -> {
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
// Special: package reference in the middle of package directive
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder))
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false))
}
return listOf(symbolBuilder.buildSymbol(fir))
}
@@ -1,5 +1,3 @@
// IGNORE_FIR
package test1.test2
class Some()
@@ -0,0 +1,7 @@
package test1.test2.test3
class Some()
val test : test1.test2.<caret>test3.Some = Some()
// REF: test3
@@ -0,0 +1,7 @@
package test1.test2.test3
class Some()
val test : test1.<caret>test2.test3.Some = Some()
// REF: test2
@@ -0,0 +1,7 @@
package test1.test2.test3
class Some()
val test : test1.test2.test3.<caret>Some = Some()
// REF: (test1.test2.test3).Some
@@ -1,5 +1,3 @@
// IGNORE_FIR
class Foo {
operator fun invoke(a: Any) {}
}
@@ -308,6 +308,21 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
runTest("idea/testData/resolve/references/ResolvePackageInProperty.kt");
}
@TestMetadata("ResolvePackageInTheEndInProperty.kt")
public void testResolvePackageInTheEndInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt");
}
@TestMetadata("ResolvePackageInTheMiddleInProperty.kt")
public void testResolvePackageInTheMiddleInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt");
}
@TestMetadata("ResolvePackageInTheTypeNameInProperty.kt")
public void testResolvePackageInTheTypeNameInProperty() throws Exception {
runTest("idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt");
}
@TestMetadata("SamAdapter.kt")
public void testSamAdapter() throws Exception {
runTest("idea/testData/resolve/references/SamAdapter.kt");