FIR IDE: fix reference resolve in import statement
This commit is contained in:
committed by
TeamCityServer
parent
55621b7aad
commit
b81ef157b2
Generated
+58
@@ -716,6 +716,64 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/inImport")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InImport extends AbstractFirReferenceResolveTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInImport() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/inImport"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("javaClass.kt")
|
||||
public void testJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPackageFirstQualifier.kt")
|
||||
public void testJavaPackageFirstQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaPackageFirstQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPackageSecondQualifier.kt")
|
||||
public void testJavaPackageSecondQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaPackageSecondQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinClass.kt")
|
||||
public void testKotlinClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinPackageFirstQualifier.kt")
|
||||
public void testKotlinPackageFirstQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinPackageFirstQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinPackageSecondQualifier.kt")
|
||||
public void testKotlinPackageSecondQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinPackageSecondQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinTopLevelFunction.kt")
|
||||
public void testKotlinTopLevelFunction() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinTopLevelFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("staticMethodFromJavaClass.kt")
|
||||
public void testStaticMethodFromJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/staticMethodFromJavaClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("staticMethodFromJavaClassJavaClass.kt")
|
||||
public void testStaticMethodFromJavaClassJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/staticMethodFromJavaClassJavaClass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/invoke")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+35
-23
@@ -6,18 +6,25 @@
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildImport
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOperatorAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
@@ -39,6 +46,7 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
internal object FirReferenceResolveHelper {
|
||||
fun FirResolvedTypeRef.toTargetSymbol(session: FirSession, symbolBuilder: KtSymbolByFirBuilder): KtSymbol? {
|
||||
@@ -116,11 +124,18 @@ internal object FirReferenceResolveHelper {
|
||||
symbolBuilder: KtSymbolByFirBuilder,
|
||||
forQualifiedType: Boolean
|
||||
): KtFirPackageSymbol? {
|
||||
return symbolBuilder.createPackageSymbolIfOneExists(getQualifierSelected(expression, forQualifiedType))
|
||||
}
|
||||
|
||||
private fun getQualifierSelected(
|
||||
expression: KtSimpleNameExpression,
|
||||
forQualifiedType: Boolean
|
||||
): FqName {
|
||||
val qualified = when {
|
||||
forQualifiedType -> expression.parent?.takeIf { it is KtUserType && it.referenceExpression === expression }
|
||||
else -> expression.getQualifiedExpressionForSelector()
|
||||
}
|
||||
val fqName = when (qualified) {
|
||||
return when (qualified) {
|
||||
null -> FqName(expression.getReferencedName())
|
||||
else -> {
|
||||
qualified
|
||||
@@ -130,7 +145,6 @@ internal object FirReferenceResolveHelper {
|
||||
.let(::FqName)
|
||||
}
|
||||
}
|
||||
return symbolBuilder.createPackageSymbolIfOneExists(fqName)
|
||||
}
|
||||
|
||||
private fun KtSimpleNameExpression.isPartOfQualifiedExpression(): Boolean {
|
||||
@@ -313,32 +327,30 @@ internal object FirReferenceResolveHelper {
|
||||
return listOf(symbolBuilder.buildSymbol(fir))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun getSymbolsByResolvedImport(
|
||||
expression: KtSimpleNameExpression,
|
||||
symbolBuilder: KtSymbolByFirBuilder,
|
||||
builder: KtSymbolByFirBuilder,
|
||||
fir: FirResolvedImport,
|
||||
session: FirSession
|
||||
): List<KtSymbol> {
|
||||
if (expression.isPartOfQualifiedExpression()) {
|
||||
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false))
|
||||
val fullFqName = fir.importedFqName
|
||||
val selectedFqName = getQualifierSelected(expression, forQualifiedType = false)
|
||||
val rawImportForSelectedFqName = buildImport {
|
||||
importedFqName = selectedFqName
|
||||
isAllUnder = false
|
||||
}
|
||||
|
||||
val classId = fir.resolvedClassId
|
||||
if (classId != null) {
|
||||
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
||||
}
|
||||
val name = fir.importedName ?: return emptyList()
|
||||
val symbolProvider = session.symbolProvider
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
val resolvedImport = FirImportResolveTransformer(session).transformImport(rawImportForSelectedFqName, null) as FirResolvedImport
|
||||
val scope = FirExplicitSimpleImportingScope(listOf(resolvedImport), session, ScopeSession())
|
||||
val selectedName = resolvedImport.importedName ?: return emptyList()
|
||||
return buildList {
|
||||
symbolProvider.getTopLevelCallableSymbols(fir.packageFqName, name)
|
||||
.mapTo(this) { it.fir.buildSymbol(symbolBuilder) }
|
||||
symbolProvider
|
||||
.getClassLikeSymbolByFqName(ClassId(fir.packageFqName, name))
|
||||
?.fir
|
||||
?.buildSymbol(symbolBuilder)
|
||||
?.let(::add)
|
||||
if (selectedFqName == fullFqName) {
|
||||
// callables cannot be used as receiver expressions in imports
|
||||
scope.processFunctionsByName(selectedName) { add(it.fir.buildSymbol(builder)) }
|
||||
scope.processPropertiesByName(selectedName) { add(it.fir.buildSymbol(builder)) }
|
||||
}
|
||||
scope.processClassifiersByName(selectedName) { addIfNotNull(it.fir.buildSymbol(builder)) }
|
||||
builder.createPackageSymbolIfOneExists(selectedFqName)?.let(::add)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import java.util.Ha<caret>shMap
|
||||
|
||||
// REF: (java.util).HashMap
|
||||
@@ -0,0 +1,2 @@
|
||||
import jav<caret>a.util.ArrayList
|
||||
// REF: java
|
||||
@@ -0,0 +1,2 @@
|
||||
import java.uti<caret>l.ArrayList
|
||||
// REF: util
|
||||
@@ -0,0 +1,4 @@
|
||||
import kotlin.collections.Mutab<caret>leList
|
||||
// MULTIRESOLVE
|
||||
// REF: (kotlin.collections).MutableList
|
||||
// REF: (kotlin.collections).MutableList(kotlin.Int, (kotlin.Int) -> T)
|
||||
@@ -0,0 +1,2 @@
|
||||
import kotli<caret>n.text.toString
|
||||
// REF: kotlin
|
||||
@@ -0,0 +1,2 @@
|
||||
import kotlin.tex<caret>t.toString
|
||||
// REF: text
|
||||
@@ -0,0 +1,4 @@
|
||||
import kotlin.collections.mut<caret>ableListOf
|
||||
// MULTIRESOLVE
|
||||
// REF: (kotlin.collections).mutableListOf()
|
||||
// REF: (kotlin.collections).mutableListOf(vararg T)
|
||||
@@ -0,0 +1,2 @@
|
||||
import java.lang.Math.si<caret>n
|
||||
// REF: (in java.lang.Math).sin(double)
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import java.lang.M<caret>ath.sin
|
||||
// REF: (java.lang).Math
|
||||
+58
@@ -716,6 +716,64 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/inImport")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InImport extends AbstractReferenceResolveTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInImport() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/inImport"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("javaClass.kt")
|
||||
public void testJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPackageFirstQualifier.kt")
|
||||
public void testJavaPackageFirstQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaPackageFirstQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPackageSecondQualifier.kt")
|
||||
public void testJavaPackageSecondQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/javaPackageSecondQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinClass.kt")
|
||||
public void testKotlinClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinPackageFirstQualifier.kt")
|
||||
public void testKotlinPackageFirstQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinPackageFirstQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinPackageSecondQualifier.kt")
|
||||
public void testKotlinPackageSecondQualifier() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinPackageSecondQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinTopLevelFunction.kt")
|
||||
public void testKotlinTopLevelFunction() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/kotlinTopLevelFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("staticMethodFromJavaClass.kt")
|
||||
public void testStaticMethodFromJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/staticMethodFromJavaClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("staticMethodFromJavaClassJavaClass.kt")
|
||||
public void testStaticMethodFromJavaClassJavaClass() throws Exception {
|
||||
runTest("idea/testData/resolve/references/inImport/staticMethodFromJavaClassJavaClass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/invoke")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user