K2 IC: refactor and optimize lookup tracking
- encapsulate semantic more into helpers - allow lazy scopes iteration - simplify reporting code in tower resolver - fix some inconsistencies and wrong lookups - remove redundant lookup recordings - remove lookup scopes for non-star imports The commit is a refactoring and doesn't change the behaviour of neither IC nor CRI. Changes in the lookups are mostly due to the previous obviously wrong lookups (see changed test data).
This commit is contained in:
committed by
Space Team
parent
fe4e0e9c2e
commit
a823bfd600
@@ -7,36 +7,74 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCallInfo
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
abstract class FirLookupTrackerComponent : FirSessionComponent {
|
||||
|
||||
abstract fun recordLookup(name: Name, inScopes: List<String>, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||
abstract fun recordLookup(name: String, inScopes: Iterable<String>, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||
|
||||
abstract fun recordLookup(name: Name, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||
abstract fun recordLookup(name: String, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inType: ConeKotlinType) {
|
||||
val classId = inType.classId
|
||||
if (classId?.isLocal == true) return
|
||||
val scopes = SmartList(inType.renderForDebugging().replace('/', '.'))
|
||||
if (classId != null && classId.shortClassName.asString() == "Companion") {
|
||||
classId.outerClassId?.asString()?.replace('/', '.')?.let {
|
||||
val classId = inType.classId ?: return
|
||||
if (classId.isLocal) return
|
||||
val scopes = SmartList(classId.asFqNameString())
|
||||
if (classId.shortClassName == DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||
classId.outerClassId?.asFqNameString()?.also {
|
||||
scopes.add(it)
|
||||
}
|
||||
}
|
||||
recordLookup(callInfo.name, scopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
recordNameLookup(callInfo.name, scopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inScopes: List<String>) {
|
||||
recordLookup(callInfo.name, inScopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inScopes: Iterable<String>) {
|
||||
recordNameLookup(callInfo.name, inScopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordTypeLookup(typeRef: FirTypeRef, inScopes: List<String>, fileSource: KtSourceElement?) {
|
||||
if (typeRef is FirUserTypeRef) recordLookup(typeRef.qualifier.first().name, inScopes, typeRef.source, fileSource)
|
||||
fun FirLookupTrackerComponent.recordTypeLookup(typeRef: FirTypeRef, inScopes: Iterable<String>, fileSource: KtSourceElement?) {
|
||||
if (typeRef is FirUserTypeRef) recordNameLookup(typeRef.qualifier.first().name, inScopes, typeRef.source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordClassLikeLookup(classId: ClassId, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||
if (!classId.isLocal && classId !in StandardClassIds.allBuiltinTypes) {
|
||||
recordLookup(classId.relativeClassName.asString(), classId.packageFqName.asString(), source, fileSource)
|
||||
if (classId.shortClassName == DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||
recordLookup(
|
||||
classId.outerClassId!!.relativeClassName.asString(),
|
||||
classId.outerClassId!!.packageFqName.asString(),
|
||||
source, fileSource
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordClassMemberLookup(
|
||||
memberName: String, classId: ClassId, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||
) {
|
||||
recordLookup(memberName, classId.asFqNameString(), source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordFqNameLookup(fqName: FqName, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||
recordLookup(fqName.shortName().asString(), fqName.parent().asString(), source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordNameLookup(
|
||||
name: Name, inScopes: Iterable<String>, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||
) {
|
||||
recordLookup(name.asString(), inScopes, source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordNameLookup(name: Name, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||
recordLookup(name.asString(), inScope, source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||
@@ -44,23 +82,26 @@ fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, sou
|
||||
recordTypeResolveAsLookup(typeRef.type, source, fileSource)
|
||||
}
|
||||
|
||||
// TODO: review all places that record resolved type as lookup and consider minimize the number of them; see #KT-66366
|
||||
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(type: ConeKotlinType?, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||
if (type == null) return
|
||||
if (source == null && fileSource == null) return // TODO: investigate all cases
|
||||
if (type is ConeErrorType) return // TODO: investigate whether some cases should be recorded, e.g. unresolved
|
||||
type.classId?.let {
|
||||
if (!it.isLocal && it !in StandardClassIds.allBuiltinTypes) {
|
||||
if (it.shortClassName.asString() != "Companion") {
|
||||
recordLookup(it.shortClassName, it.packageFqName.asString(), source, fileSource)
|
||||
} else {
|
||||
recordLookup(it.outerClassId!!.shortClassName, it.outerClassId!!.packageFqName.asString(), source, fileSource)
|
||||
}
|
||||
}
|
||||
type.classId?.let { classId ->
|
||||
recordClassLikeLookup(classId, source, fileSource)
|
||||
}
|
||||
type.typeArguments.forEach {
|
||||
if (it is ConeKotlinType) recordTypeResolveAsLookup(it, source, fileSource)
|
||||
}
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordCallableCandidateAsLookup(
|
||||
callableSymbol: FirCallableSymbol<*>, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||
) {
|
||||
if (!callableSymbol.callableId.isLocal && callableSymbol !is FirConstructorSymbol) {
|
||||
recordTypeResolveAsLookup(callableSymbol.fir.returnTypeRef, source, fileSource)
|
||||
recordFqNameLookup(callableSymbol.callableId.asSingleFqName(), source, fileSource)
|
||||
}
|
||||
}
|
||||
|
||||
val FirSession.lookupTracker: FirLookupTrackerComponent? by FirSession.nullableSessionComponentAccessor()
|
||||
|
||||
Reference in New Issue
Block a user