KT-59732 [FIR] Do not perform an actual resolve during IMPORTS phase
Use `FirSymbolProvider` to find the longest existing package, and assume that the rest of the import is class name
This commit is contained in:
committed by
Space Team
parent
476a0b6783
commit
cd62f2f7a4
+2
-23
@@ -5,18 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirImport
|
import org.jetbrains.kotlin.fir.declarations.FirImport
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildErrorImport
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
||||||
import org.jetbrains.kotlin.fir.lookupTracker
|
import org.jetbrains.kotlin.fir.lookupTracker
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeImportFromSingleton
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
|
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
|
||||||
@@ -76,25 +72,8 @@ open class FirImportResolveTransformer protected constructor(
|
|||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
private fun transformImportForFqName(fqName: FqName, delegate: FirImport): FirImport {
|
private fun transformImportForFqName(fqName: FqName, delegate: FirImport): FirImport {
|
||||||
val (packageFqName, relativeClassFqName, classSymbol) = when (val result = resolveToPackageOrClass(symbolProvider, fqName)) {
|
val (packageFqName, relativeClassFqName) = findLongestExistingPackage(symbolProvider, fqName)
|
||||||
is PackageResolutionResult.Error ->
|
|
||||||
return if (delegate.source?.kind == KtFakeSourceElementKind.ImplicitImport) {
|
|
||||||
delegate
|
|
||||||
} else {
|
|
||||||
buildErrorImport {
|
|
||||||
this.delegate = delegate
|
|
||||||
this.diagnostic = result.diagnostic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is PackageResolutionResult.PackageOrClass -> result
|
|
||||||
}
|
|
||||||
val firClass = classSymbol?.fir as? FirRegularClass
|
|
||||||
if (delegate.isAllUnder && firClass?.classKind?.isSingleton == true) {
|
|
||||||
return buildErrorImport {
|
|
||||||
this.delegate = delegate
|
|
||||||
this.diagnostic = ConeImportFromSingleton(firClass.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buildResolvedImport {
|
return buildResolvedImport {
|
||||||
this.delegate = delegate
|
this.delegate = delegate
|
||||||
this.packageFqName = packageFqName
|
this.packageFqName = packageFqName
|
||||||
|
|||||||
+20
-2
@@ -12,7 +12,16 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName): PackageResolutionResult {
|
/**
|
||||||
|
* Compared to [resolveToPackageOrClass], does not perform the actual resolve.
|
||||||
|
*
|
||||||
|
* Instead of it, it just looks for the longest existing package name prefix in the [fqName],
|
||||||
|
* and assumes that the rest of the name (if present) is a relative class name.
|
||||||
|
*
|
||||||
|
* Given that [FqName.ROOT] package is always present in any [FirSymbolProvider],
|
||||||
|
* this function **can never fail**.
|
||||||
|
*/
|
||||||
|
fun findLongestExistingPackage(symbolProvider: FirSymbolProvider, fqName: FqName): PackageAndClass {
|
||||||
var currentPackage = fqName
|
var currentPackage = fqName
|
||||||
|
|
||||||
val pathSegments = fqName.pathSegments()
|
val pathSegments = fqName.pathSegments()
|
||||||
@@ -25,9 +34,18 @@ fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName):
|
|||||||
prefixSize--
|
prefixSize--
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPackage == fqName) return PackageResolutionResult.PackageOrClass(currentPackage, null, null)
|
if (currentPackage == fqName) return PackageAndClass(currentPackage, relativeClassFqName = null)
|
||||||
val relativeClassFqName = FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
|
val relativeClassFqName = FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
|
||||||
|
|
||||||
|
return PackageAndClass(currentPackage, relativeClassFqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PackageAndClass(val packageFqName: FqName, val relativeClassFqName: FqName?)
|
||||||
|
|
||||||
|
fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName): PackageResolutionResult {
|
||||||
|
val (currentPackage, relativeClassFqName) = findLongestExistingPackage(symbolProvider, fqName)
|
||||||
|
if (relativeClassFqName == null) return PackageResolutionResult.PackageOrClass(currentPackage, null, null)
|
||||||
|
|
||||||
val classId = ClassId(currentPackage, relativeClassFqName, isLocal = false)
|
val classId = ClassId(currentPackage, relativeClassFqName, isLocal = false)
|
||||||
val symbol = symbolProvider.getClassLikeSymbolByClassId(classId) ?: return PackageResolutionResult.Error(
|
val symbol = symbolProvider.getClassLikeSymbolByClassId(classId) ?: return PackageResolutionResult.Error(
|
||||||
ConeUnresolvedParentInImport(classId)
|
ConeUnresolvedParentInImport(classId)
|
||||||
|
|||||||
Reference in New Issue
Block a user