FIR: Implement lookup tracking
This commit is contained in:
@@ -33,6 +33,8 @@ data class BuildLogFinder(
|
||||
private const val GRADLE_LOG = "gradle-build.log"
|
||||
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
|
||||
const val JS_JPS_LOG = "js-jps-build.log"
|
||||
private const val FIR_LOG = "fir-build.log"
|
||||
private const val GRADLE_FIR_LOG = "gradle-fir-build.log"
|
||||
private const val SIMPLE_LOG = "build.log"
|
||||
|
||||
fun isJpsLogFile(file: File): Boolean =
|
||||
@@ -46,10 +48,11 @@ data class BuildLogFinder(
|
||||
isScopeExpansionEnabled && SCOPE_EXPANDING_LOG in files -> SCOPE_EXPANDING_LOG
|
||||
isKlibEnabled && KLIB_LOG in files -> KLIB_LOG
|
||||
isJsEnabled && JS_LOG in files -> JS_LOG
|
||||
isGradleEnabled && isFirEnabled && GRADLE_FIR_LOG in files -> GRADLE_FIR_LOG
|
||||
isFirEnabled && FIR_LOG in files -> FIR_LOG
|
||||
isGradleEnabled && GRADLE_LOG in files -> GRADLE_LOG
|
||||
isJsEnabled && JS_JPS_LOG in files -> JS_JPS_LOG
|
||||
isDataContainerBuildLogEnabled && DATA_CONTAINER_LOG in files -> DATA_CONTAINER_LOG
|
||||
isFirEnabled && FIR_LOG in files -> FIR_LOG
|
||||
SIMPLE_LOG in files -> SIMPLE_LOG
|
||||
else -> null
|
||||
}
|
||||
|
||||
+1
-3
@@ -333,6 +333,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
||||
environment::createPackagePartProvider
|
||||
) {
|
||||
if (extendedAnalysisMode) {
|
||||
@@ -350,9 +351,6 @@ object KotlinToJVMBytecodeCompiler {
|
||||
)
|
||||
performanceManager?.notifyAnalysisFinished()
|
||||
|
||||
// TODO: maybe we should not do it in presence of errors, but tests at the moment expect lookups to be reported
|
||||
session.firLookupTracker?.flushLookups()
|
||||
|
||||
if (syntaxErrors || firDiagnostics.any { it.severity == Severity.ERROR }) {
|
||||
return false
|
||||
}
|
||||
|
||||
+18
-7
@@ -11,9 +11,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.lookupTracker
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
|
||||
object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
@@ -21,7 +20,7 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
val inspector = FirDeclarationInspector()
|
||||
|
||||
when (declaration) {
|
||||
is FirFile -> checkFile(declaration, inspector)
|
||||
is FirFile -> checkFile(declaration, inspector, context)
|
||||
is FirRegularClass -> checkRegularClass(declaration, inspector)
|
||||
else -> return
|
||||
}
|
||||
@@ -47,9 +46,21 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFile(declaration: FirFile, inspector: FirDeclarationInspector) {
|
||||
for (it in declaration.declarations) {
|
||||
inspector.collect(it)
|
||||
private fun checkFile(file: FirFile, inspector: FirDeclarationInspector, context: CheckerContext) {
|
||||
val lookupTracker = context.session.lookupTracker
|
||||
for (topLevelDeclaration in file.declarations) {
|
||||
inspector.collect(topLevelDeclaration)
|
||||
if (lookupTracker != null) {
|
||||
when (topLevelDeclaration) {
|
||||
is FirSimpleFunction -> topLevelDeclaration.name
|
||||
is FirVariable<*> -> topLevelDeclaration.name
|
||||
is FirRegularClass -> topLevelDeclaration.name
|
||||
is FirTypeAlias -> topLevelDeclaration.name
|
||||
else -> null
|
||||
}?.let {
|
||||
lookupTracker.recordLookup(it, file.packageFqName.asString(), topLevelDeclaration.source, file.source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.getLineAndColumnInPsiFile
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class IncrementalPassThroughLookupTrackerComponent(
|
||||
private val lookupTracker: LookupTracker,
|
||||
private val sourceToFilePath: (FirSourceElement) -> String
|
||||
) : FirLookupTrackerComponent() {
|
||||
|
||||
private val requiresPosition = lookupTracker.requiresPosition
|
||||
private val sourceToFilePathsCache = ConcurrentHashMap<FirSourceElement, String>()
|
||||
|
||||
override fun recordLookup(name: Name, inScopes: List<String>, source: FirSourceElement?, fileSource: FirSourceElement?) {
|
||||
val definedSource = fileSource ?: source ?: throw AssertionError("Cannot record lookup for \"$name\" without a source")
|
||||
val path = sourceToFilePathsCache.getOrPut(definedSource) {
|
||||
sourceToFilePath(definedSource)
|
||||
}
|
||||
val position = if (requiresPosition && source != null && source is FirPsiSourceElement<*>) {
|
||||
getLineAndColumnInPsiFile(source.psi.containingFile, source.psi.textRange).let { Position(it.line, it.column) }
|
||||
} else Position.NO_POSITION
|
||||
|
||||
for (scope in inScopes) {
|
||||
lookupTracker.record(path, position, scope, ScopeKind.PACKAGE, name.asString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun recordLookup(name: Name, inScope: String, source: FirSourceElement?, fileSource: FirSourceElement?) {
|
||||
recordLookup(name, SmartList(inScope), source, fileSource)
|
||||
}
|
||||
}
|
||||
+13
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.session
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirTypeResolverImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedClassIndex
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
|
||||
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
|
||||
// -------------------------- Required components --------------------------
|
||||
|
||||
@@ -55,10 +57,20 @@ fun FirSession.registerThreadUnsafeCaches() {
|
||||
* Resolve components which are same on all platforms
|
||||
*/
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirSession.registerResolveComponents() {
|
||||
fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null) {
|
||||
register(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
||||
register(FirTypeResolver::class, FirTypeResolverImpl(this))
|
||||
register(CheckersComponent::class, CheckersComponent())
|
||||
if (lookupTracker != null) {
|
||||
val firFileToPath: (FirSourceElement) -> String = {
|
||||
val psiSource = (it as? FirPsiSourceElement<*>) ?: TODO("Not implemented for non-FirPsiSourceElement")
|
||||
((psiSource.psi as? PsiFile) ?: psiSource.psi.containingFile).virtualFile.path
|
||||
}
|
||||
register(
|
||||
FirLookupTrackerComponent::class,
|
||||
IncrementalPassThroughLookupTrackerComponent(lookupTracker, firFileToPath)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.*
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
@@ -68,12 +69,13 @@ object FirSessionFactory {
|
||||
project: Project,
|
||||
dependenciesProvider: FirSymbolProvider? = null,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
lookupTracker: LookupTracker? = null,
|
||||
init: FirSessionConfigurator.() -> Unit = {}
|
||||
): FirJavaModuleBasedSession {
|
||||
return FirJavaModuleBasedSession(moduleInfo, sessionProvider).apply {
|
||||
registerThreadUnsafeCaches()
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
registerResolveComponents()
|
||||
registerResolveComponents(lookupTracker)
|
||||
registerJavaSpecificResolveComponents()
|
||||
|
||||
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -24,6 +25,7 @@ fun createSessionWithDependencies(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||
): FirSession {
|
||||
@@ -33,6 +35,7 @@ fun createSessionWithDependencies(
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker,
|
||||
packagePartProvider,
|
||||
sessionConfigurator
|
||||
) {
|
||||
@@ -46,6 +49,7 @@ fun createSessionWithDependencies(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||
): FirSession {
|
||||
@@ -55,6 +59,7 @@ fun createSessionWithDependencies(
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker,
|
||||
packagePartProvider,
|
||||
sessionConfigurator
|
||||
) {
|
||||
@@ -68,6 +73,7 @@ private inline fun createSessionWithDependencies(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||
moduleInfoProvider: (dependencies: List<ModuleInfo>) -> ModuleInfo,
|
||||
@@ -84,6 +90,7 @@ private inline fun createSessionWithDependencies(
|
||||
sourceScope,
|
||||
project,
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
lookupTracker = lookupTracker,
|
||||
init = sessionConfigurator
|
||||
)
|
||||
}
|
||||
|
||||
@@ -702,6 +702,7 @@ private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstEx
|
||||
type = kind.expectedConeType(session)
|
||||
}
|
||||
replaceTypeRef(typeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(typeRef, source, null)
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.fir.java.enhancement
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilder
|
||||
@@ -19,11 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.initialSignatureAttr
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -85,7 +82,10 @@ class FirSignatureEnhancement(
|
||||
)
|
||||
|
||||
val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, predefinedInfo)
|
||||
return firElement.symbol.apply { this.fir.replaceReturnTypeRef(newReturnTypeRef) }
|
||||
return firElement.symbol.apply {
|
||||
this.fir.replaceReturnTypeRef(newReturnTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, this.fir.source, null)
|
||||
}
|
||||
}
|
||||
is FirField -> {
|
||||
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
|
||||
|
||||
+3
@@ -104,4 +104,7 @@ class JavaClassStaticUseSiteScope internal constructor(
|
||||
override fun mayContainName(name: Name): Boolean {
|
||||
return declaredMemberScope.mayContainName(name) || superTypesScopes.any { it.mayContainName(name) }
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String>
|
||||
get() = declaredMemberScope.scopeOwnerLookupNames
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@ class FirCallResolver(
|
||||
val typeArguments = (qualifiedAccess as? FirFunctionCall)?.typeArguments.orEmpty()
|
||||
|
||||
val info = CallInfo(
|
||||
qualifiedAccess,
|
||||
if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
||||
name,
|
||||
explicitReceiver,
|
||||
@@ -304,6 +305,7 @@ class FirCallResolver(
|
||||
}
|
||||
|
||||
val callInfo = CallInfo(
|
||||
delegatedConstructorCall,
|
||||
CallKind.DelegatingConstructorCall,
|
||||
name,
|
||||
explicitReceiver = null,
|
||||
@@ -352,6 +354,7 @@ class FirCallResolver(
|
||||
annotationCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||
|
||||
val callInfo = CallInfo(
|
||||
annotationCall,
|
||||
CallKind.Function,
|
||||
name = reference.name,
|
||||
explicitReceiver = null,
|
||||
@@ -462,6 +465,7 @@ class FirCallResolver(
|
||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
||||
): CallInfo {
|
||||
return CallInfo(
|
||||
callableReferenceAccess,
|
||||
CallKind.CallableReference,
|
||||
callableReferenceAccess.calleeReference.name,
|
||||
callableReferenceAccess.explicitReceiver,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.CallInfo
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
abstract class FirLookupTrackerComponent : FirSessionComponent {
|
||||
|
||||
abstract fun recordLookup(name: Name, inScopes: List<String>, source: FirSourceElement?, fileSource: FirSourceElement?)
|
||||
|
||||
abstract fun recordLookup(name: Name, inScope: String, source: FirSourceElement?, fileSource: FirSourceElement?)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: CallInfo, inType: ConeKotlinType) {
|
||||
if (inType.classId?.isLocal == true) return
|
||||
val scopes = SmartList(inType.render().replace('/', '.'))
|
||||
if (inType.classId?.shortClassName?.asString() == "Companion") {
|
||||
scopes.add(inType.classId!!.outerClassId!!.asString().replace('/', '.'))
|
||||
}
|
||||
recordLookup(callInfo.name, scopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: CallInfo, inScopes: List<String>) {
|
||||
recordLookup(callInfo.name, inScopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordTypeLookup(typeRef: FirTypeRef, inScopes: List<String>, fileSource: FirSourceElement?) {
|
||||
if (typeRef is FirUserTypeRef) recordLookup(typeRef.qualifier.first().name, inScopes, typeRef.source, fileSource)
|
||||
}
|
||||
|
||||
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, source: FirSourceElement?, fileSource: FirSourceElement?) {
|
||||
if (typeRef !is FirResolvedTypeRef) return // TODO: check if this is the correct behavior
|
||||
if (source == null && fileSource == null) return // TODO: investigate all cases
|
||||
|
||||
fun recordIfValid(type: ConeKotlinType) {
|
||||
if (type is ConeKotlinErrorType) return // TODO: investigate whether some cases should be recorded, e.g. unresolved
|
||||
type.classId?.let {
|
||||
if (!it.isLocal) {
|
||||
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.typeArguments.forEach {
|
||||
if (it is ConeKotlinType) recordIfValid(it)
|
||||
}
|
||||
}
|
||||
|
||||
recordIfValid(typeRef.type)
|
||||
}
|
||||
|
||||
|
||||
val FirSession.lookupTracker: FirLookupTrackerComponent? by FirSession.nullableSessionComponentAccessor()
|
||||
@@ -298,7 +298,9 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(nullableReceiver
|
||||
|
||||
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
||||
|
||||
replaceTypeRef(typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull()))
|
||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull())
|
||||
replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||
}
|
||||
|
||||
fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
||||
@@ -315,7 +317,9 @@ fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
||||
else
|
||||
typeAfterNullCheck
|
||||
|
||||
replaceTypeRef(typeRef.resolvedTypeFromPrototype(resultingType))
|
||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(resultingType)
|
||||
replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||
}
|
||||
|
||||
private fun FirQualifiedAccess.expressionTypeOrUnitForAssignment(): ConeKotlinType? {
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.lookupTracker
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
||||
@@ -29,6 +31,8 @@ import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
||||
|
||||
fun Candidate.resolveArgumentExpression(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirExpression,
|
||||
@@ -391,6 +395,7 @@ private fun checkApplicabilityForArgumentType(
|
||||
}
|
||||
|
||||
internal fun Candidate.resolveArgument(
|
||||
callInfo: CallInfo,
|
||||
argument: FirExpression,
|
||||
parameter: FirValueParameter?,
|
||||
isReceiver: Boolean,
|
||||
@@ -399,7 +404,8 @@ internal fun Candidate.resolveArgument(
|
||||
) {
|
||||
argument.resultType.ensureResolvedTypeDeclaration(context.session)
|
||||
|
||||
val expectedType = prepareExpectedType(context.session, context.bodyResolveComponents.scopeSession, argument, parameter, context)
|
||||
val expectedType =
|
||||
prepareExpectedType(context.session, context.bodyResolveComponents.scopeSession, callInfo, argument, parameter, context)
|
||||
resolveArgumentExpression(
|
||||
this.system.getBuilder(),
|
||||
argument,
|
||||
@@ -415,13 +421,33 @@ internal fun Candidate.resolveArgument(
|
||||
private fun Candidate.prepareExpectedType(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
callInfo: CallInfo,
|
||||
argument: FirExpression,
|
||||
parameter: FirValueParameter?,
|
||||
context: ResolutionContext
|
||||
): ConeKotlinType? {
|
||||
if (parameter == null) return null
|
||||
val basicExpectedType = argument.getExpectedTypeForSAMConversion(parameter/*, LanguageVersionSettings*/)
|
||||
val expectedType = getExpectedTypeWithSAMConversion(session, scopeSession, argument, basicExpectedType, context) ?: basicExpectedType
|
||||
|
||||
val expectedType =
|
||||
getExpectedTypeWithSAMConversion(session, scopeSession, argument, basicExpectedType, context)?.also {
|
||||
session.lookupTracker?.let { lookupTracker ->
|
||||
parameter.returnTypeRef.coneType.lowerBoundIfFlexible().classId?.takeIf { !it.isLocal }?.let { classId ->
|
||||
lookupTracker.recordLookup(
|
||||
SAM_LOOKUP_NAME,
|
||||
classId.asString(),
|
||||
callInfo.callSite.source,
|
||||
callInfo.containingFile.source
|
||||
)
|
||||
lookupTracker.recordLookup(
|
||||
classId.shortClassName,
|
||||
classId.packageFqName.asString(),
|
||||
callInfo.callSite.source,
|
||||
callInfo.containingFile.source
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: basicExpectedType
|
||||
return this.substitutor.substituteOrSelf(expectedType)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
|
||||
data class CallInfo(
|
||||
val callSite: FirElement,
|
||||
val callKind: CallKind,
|
||||
val name: Name,
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ internal object CheckArguments : CheckerStage() {
|
||||
for (argument in callInfo.arguments) {
|
||||
val parameter = argumentMapping[argument]
|
||||
candidate.resolveArgument(
|
||||
callInfo,
|
||||
argument,
|
||||
parameter,
|
||||
isReceiver = false,
|
||||
|
||||
-1
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
+5
-5
@@ -44,18 +44,18 @@ internal class TowerLevelHandler {
|
||||
|
||||
when (info.callKind) {
|
||||
CallKind.VariableAccess -> {
|
||||
processResult += towerLevel.processPropertiesByName(info.name, processor)
|
||||
processResult += towerLevel.processPropertiesByName(info, processor)
|
||||
|
||||
if (!collector.isSuccess() && towerLevel is ScopeTowerLevel && towerLevel.extensionReceiver == null) {
|
||||
processResult += towerLevel.processObjectsByName(info.name, processor)
|
||||
processResult += towerLevel.processObjectsByName(info, processor)
|
||||
}
|
||||
}
|
||||
CallKind.Function -> {
|
||||
processResult += towerLevel.processFunctionsByName(info.name, processor)
|
||||
processResult += towerLevel.processFunctionsByName(info, processor)
|
||||
}
|
||||
CallKind.CallableReference -> {
|
||||
processResult += towerLevel.processFunctionsByName(info.name, processor)
|
||||
processResult += towerLevel.processPropertiesByName(info.name, processor)
|
||||
processResult += towerLevel.processFunctionsByName(info, processor)
|
||||
processResult += towerLevel.processPropertiesByName(info, processor)
|
||||
}
|
||||
else -> {
|
||||
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||
|
||||
+63
-35
@@ -5,29 +5,23 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
||||
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.constructClassType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
enum class ProcessResult {
|
||||
FOUND, SCOPE_EMPTY;
|
||||
@@ -46,11 +40,11 @@ abstract class TowerScopeLevel {
|
||||
object Objects : Token<AbstractFirBasedSymbol<*>>()
|
||||
}
|
||||
|
||||
abstract fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>): ProcessResult
|
||||
abstract fun processFunctionsByName(info: CallInfo, processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>): ProcessResult
|
||||
|
||||
abstract fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>): ProcessResult
|
||||
abstract fun processPropertiesByName(info: CallInfo, processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>): ProcessResult
|
||||
|
||||
abstract fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>): ProcessResult
|
||||
abstract fun processObjectsByName(info: CallInfo, processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>): ProcessResult
|
||||
|
||||
interface TowerScopeLevelProcessor<in T : AbstractFirBasedSymbol<*>> {
|
||||
fun consumeCandidate(
|
||||
@@ -131,41 +125,50 @@ class MemberScopeTowerLevel(
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
||||
): ProcessResult {
|
||||
val isInvoke = name == OperatorNameConventions.INVOKE
|
||||
val isInvoke = info.name == OperatorNameConventions.INVOKE
|
||||
if (implicitExtensionInvokeMode && !isInvoke) {
|
||||
return ProcessResult.FOUND
|
||||
}
|
||||
val lookupTracker = session.lookupTracker
|
||||
return processMembers(processor) { consumer ->
|
||||
this.processFunctionsAndConstructorsByName(
|
||||
name, session, bodyResolveComponents,
|
||||
includeInnerConstructors = true,
|
||||
processor = {
|
||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
consumer(it as FirFunctionSymbol<*>)
|
||||
}
|
||||
)
|
||||
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
||||
this.processFunctionsAndConstructorsByName(
|
||||
info.name, session, bodyResolveComponents,
|
||||
includeInnerConstructors = true,
|
||||
processor = {
|
||||
lookupCtx.recordCallableMemberLookup(it)
|
||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
consumer(it as FirFunctionSymbol<*>)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
||||
): ProcessResult {
|
||||
val lookupTracker = session.lookupTracker
|
||||
return processMembers(processor) { consumer ->
|
||||
this.processPropertiesByName(name) {
|
||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
consumer(it)
|
||||
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
||||
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
||||
this.processPropertiesByName(info.name) {
|
||||
lookupCtx.recordCallableMemberLookup(it)
|
||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
consumer(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processObjectsByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||
): ProcessResult {
|
||||
return ProcessResult.FOUND
|
||||
@@ -176,6 +179,28 @@ class MemberScopeTowerLevel(
|
||||
session, bodyResolveComponents, receiverValue, extensionReceiver, implicitExtensionInvokeMode, scopeSession
|
||||
)
|
||||
}
|
||||
|
||||
private inline fun withMemberCallLookup(
|
||||
lookupTracker: FirLookupTrackerComponent?,
|
||||
info: CallInfo,
|
||||
body: (Triple<FirLookupTrackerComponent?, SmartList<String>, CallInfo>) -> Unit
|
||||
) {
|
||||
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
||||
val lookupScopes = SmartList<String>()
|
||||
body(Triple(lookupTracker, lookupScopes, info))
|
||||
if (lookupScopes.isNotEmpty()) {
|
||||
lookupTracker?.recordCallLookup(info, lookupScopes)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Triple<FirLookupTrackerComponent?, SmartList<String>, CallInfo>.recordCallableMemberLookup(callable: FirCallableSymbol<*>) {
|
||||
first?.run {
|
||||
recordTypeResolveAsLookup(callable.fir.returnTypeRef, third.callSite.source, third.containingFile.source)
|
||||
callable.callableId.className?.let { lookupScope ->
|
||||
second.add(lookupScope.asString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is more like "scope-based tower level"
|
||||
@@ -269,12 +294,13 @@ class ScopeTowerLevel(
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
||||
): ProcessResult {
|
||||
var empty = true
|
||||
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||
scope.processFunctionsAndConstructorsByName(
|
||||
name,
|
||||
info.name,
|
||||
session,
|
||||
bodyResolveComponents,
|
||||
includeInnerConstructors = includeInnerConstructors
|
||||
@@ -286,11 +312,12 @@ class ScopeTowerLevel(
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
||||
): ProcessResult {
|
||||
var empty = true
|
||||
scope.processPropertiesByName(name) { candidate ->
|
||||
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||
scope.processPropertiesByName(info.name) { candidate ->
|
||||
empty = false
|
||||
consumeCallableCandidate(candidate, processor)
|
||||
}
|
||||
@@ -298,11 +325,12 @@ class ScopeTowerLevel(
|
||||
}
|
||||
|
||||
override fun processObjectsByName(
|
||||
name: Name,
|
||||
info: CallInfo,
|
||||
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||
): ProcessResult {
|
||||
var empty = true
|
||||
scope.processClassifiersByName(name) {
|
||||
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||
scope.processClassifiersByName(info.name) {
|
||||
empty = false
|
||||
processor.consumeCandidate(
|
||||
it, dispatchReceiverValue = null,
|
||||
|
||||
+13
-8
@@ -5,14 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.inference
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.fakeElement
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
@@ -26,7 +25,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBod
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -62,7 +60,9 @@ class FirCallCompleter(
|
||||
val initialType = components.initialTypeOfCandidate(candidate, call)
|
||||
|
||||
if (call is FirExpression) {
|
||||
call.resultType = typeRef.resolvedTypeFromPrototype(initialType)
|
||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(initialType)
|
||||
call.resultType = resolvedTypeRef
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, call.source, null)
|
||||
}
|
||||
|
||||
if (expectedTypeRef is FirResolvedTypeRef) {
|
||||
@@ -208,14 +208,19 @@ class FirCallCompleter(
|
||||
}
|
||||
)
|
||||
|
||||
val lookupTracker = session.lookupTracker
|
||||
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
||||
parameter.replaceReturnTypeRef(
|
||||
parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
||||
)
|
||||
val newReturnTypeRef = parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
||||
parameter.replaceReturnTypeRef(newReturnTypeRef)
|
||||
lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, parameter.source, null)
|
||||
}
|
||||
|
||||
lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam))
|
||||
lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: components.noExpectedType)
|
||||
lambdaArgument.replaceReturnTypeRef(
|
||||
expectedReturnTypeRef?.also {
|
||||
lookupTracker?.recordTypeResolveAsLookup(it, lambdaArgument.source, null)
|
||||
} ?: components.noExpectedType
|
||||
)
|
||||
|
||||
val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
+5
-1
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
||||
import org.jetbrains.kotlin.fir.FirCallResolver
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.lookupTracker
|
||||
import org.jetbrains.kotlin.fir.recordTypeResolveAsLookup
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||
@@ -93,7 +95,9 @@ class PostponedArgumentsAnalyzer(
|
||||
namedReference
|
||||
).apply {
|
||||
if (resultingCandidate != null) {
|
||||
replaceTypeRef(buildResolvedTypeRef { type = resultingCandidate.resultingTypeForCallableReference!! })
|
||||
val resolvedTypeRef = buildResolvedTypeRef { type = resultingCandidate.resultingTypeForCallableReference!! }
|
||||
replaceTypeRef(resolvedTypeRef)
|
||||
resolutionContext.session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-10
@@ -113,6 +113,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
if (declaration !is FirErrorFunction) {
|
||||
result.replaceTypeArguments(typeArguments)
|
||||
}
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(typeRef, qualifiedAccessExpression.source, null)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -135,6 +136,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
val resultType = typeRef.substituteTypeRef(subCandidate)
|
||||
resultType.ensureResolvedTypeDeclaration(session)
|
||||
result.replaceTypeRef(resultType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, null)
|
||||
|
||||
if (mode == Mode.DelegatedPropertyCompletion) {
|
||||
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
||||
@@ -179,6 +181,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
}
|
||||
|
||||
result.replaceTypeRef(resultType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null)
|
||||
|
||||
if (mode == Mode.DelegatedPropertyCompletion) {
|
||||
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
||||
@@ -249,6 +252,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
): D {
|
||||
val resultTypeRef = typeRef.substituteTypeRef(calleeReference.candidate)
|
||||
replaceTypeRef(resultTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultTypeRef, source, null)
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -297,6 +301,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
val resultType = typeRef.withReplacedConeType(finalType)
|
||||
callableReferenceAccess.replaceTypeRef(resultType)
|
||||
callableReferenceAccess.replaceTypeArguments(typeArguments)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, typeRef.source ?: callableReferenceAccess.source, null)
|
||||
|
||||
return callableReferenceAccess.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
@@ -338,9 +343,9 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val originalType = qualifiedAccessExpression.typeRef.coneType
|
||||
val substitutedReceiverType = finalSubstitutor.substituteOrNull(originalType) ?: return qualifiedAccessExpression.compose()
|
||||
qualifiedAccessExpression.replaceTypeRef(
|
||||
qualifiedAccessExpression.typeRef.resolvedTypeFromPrototype(substitutedReceiverType)
|
||||
)
|
||||
val resolvedTypeRef = qualifiedAccessExpression.typeRef.resolvedTypeFromPrototype(substitutedReceiverType)
|
||||
qualifiedAccessExpression.replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, qualifiedAccessExpression.source, null)
|
||||
return qualifiedAccessExpression.compose()
|
||||
}
|
||||
}
|
||||
@@ -500,9 +505,9 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
}
|
||||
|
||||
if (needUpdateLambdaType) {
|
||||
anonymousFunction.replaceTypeRef(
|
||||
anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
)
|
||||
val resolvedTypeRef = anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
anonymousFunction.replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null)
|
||||
}
|
||||
|
||||
val result = transformElement(anonymousFunction, null)
|
||||
@@ -519,10 +524,14 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
(returnExpressionsOfAnonymousFunction.lastOrNull() as? FirExpression)
|
||||
?.typeRef?.coneTypeSafe<ConeKotlinType>()
|
||||
|
||||
resultFunction.replaceReturnTypeRef(resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType))
|
||||
resultFunction.replaceTypeRef(
|
||||
resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
)
|
||||
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
|
||||
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
|
||||
val resolvedTypeRef = resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
resultFunction.replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.let {
|
||||
it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, null)
|
||||
it.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -576,6 +585,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)))
|
||||
}
|
||||
block.replaceTypeRef(resultType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, null)
|
||||
}
|
||||
transformElement(block, data)
|
||||
if (block.resultType is FirErrorTypeRef) {
|
||||
|
||||
+16
-2
@@ -11,8 +11,9 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirImport
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.lookupTracker
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
@@ -36,10 +37,20 @@ open class FirImportResolveTransformer protected constructor(
|
||||
|
||||
private val symbolProvider: FirSymbolProvider = session.symbolProvider
|
||||
|
||||
private var currentFile: FirFile? = null
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||
checkSessionConsistency(file)
|
||||
file.replaceResolvePhase(transformerPhase)
|
||||
return file.also { it.transformChildren(this, null) }.compose()
|
||||
return file.also {
|
||||
val prevValue = currentFile
|
||||
currentFile = file
|
||||
try {
|
||||
it.transformChildren(this, null)
|
||||
} finally {
|
||||
currentFile = prevValue
|
||||
}
|
||||
}.compose()
|
||||
}
|
||||
|
||||
override fun transformImport(import: FirImport, data: Nothing?): CompositeTransformResult<FirImport> {
|
||||
@@ -52,6 +63,9 @@ open class FirImportResolveTransformer protected constructor(
|
||||
}
|
||||
|
||||
val parentFqName = fqName.parent()
|
||||
currentFile?.let {
|
||||
session.lookupTracker?.recordLookup(fqName.shortName(), parentFqName.asString(), import.source, it.source)
|
||||
}
|
||||
return transformImportForFqName(parentFqName, import)
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
|
||||
@@ -38,16 +39,35 @@ class FirSpecificTypeResolverTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
@JvmField
|
||||
var currentFile: FirFile? = null
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <R> withFile(file: FirFile?, block: FirSpecificTypeResolverTransformer.() -> R): R {
|
||||
val oldValue = currentFile
|
||||
currentFile = file
|
||||
return try {
|
||||
block()
|
||||
} finally {
|
||||
currentFile = oldValue
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
override fun transformTypeRef(typeRef: FirTypeRef, data: FirScope): CompositeTransformResult<FirResolvedTypeRef> {
|
||||
session.lookupTracker?.recordTypeLookup(typeRef, data.scopeOwnerLookupNames, currentFile?.source)
|
||||
typeRef.transformChildren(this, data)
|
||||
return transformType(typeRef, typeResolver.resolveType(typeRef, data, areBareTypesAllowed))
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
override fun transformFunctionTypeRef(
|
||||
functionTypeRef: FirFunctionTypeRef,
|
||||
data: FirScope
|
||||
): CompositeTransformResult<FirResolvedTypeRef> {
|
||||
functionTypeRef.transformChildren(this, data)
|
||||
session.lookupTracker?.recordTypeLookup(functionTypeRef, data.scopeOwnerLookupNames, currentFile?.source)
|
||||
val resolvedType = typeResolver.resolveType(functionTypeRef, data, areBareTypesAllowed).takeIfAcceptable()
|
||||
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
|
||||
buildResolvedTypeRef {
|
||||
|
||||
+10
-3
@@ -8,16 +8,15 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||
import org.jetbrains.kotlin.fir.extensions.supertypeGenerators
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
||||
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
|
||||
@@ -284,6 +283,14 @@ private class FirSupertypeResolverVisitor(
|
||||
supertypeRefs: List<FirTypeRef>
|
||||
): List<FirTypeRef> {
|
||||
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scope ->
|
||||
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
||||
session.lookupTracker?.let {
|
||||
val fileSource = session.firProvider.getFirClassifierContainerFile(classLikeDeclaration.symbol).source
|
||||
for (supertypeRef in supertypeRefs) {
|
||||
it.recordTypeLookup(supertypeRef, scope.scopeOwnerLookupNames, fileSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
This list is backed by mutable list and during iterating on it we can resolve supertypes of that class via IDE light classes
|
||||
as IJ Java resolve may resolve a lot of stuff by light classes
|
||||
|
||||
+9
-2
@@ -62,6 +62,7 @@ class FirSyntheticCallGenerator(
|
||||
arguments += whenExpression.branches.map { it.result }
|
||||
}
|
||||
val reference = generateCalleeReferenceWithCandidate(
|
||||
whenExpression,
|
||||
whenSelectFunction,
|
||||
argumentList,
|
||||
SyntheticCallableId.WHEN.callableName,
|
||||
@@ -85,6 +86,7 @@ class FirSyntheticCallGenerator(
|
||||
}
|
||||
|
||||
val reference = generateCalleeReferenceWithCandidate(
|
||||
tryExpression,
|
||||
trySelectFunction,
|
||||
argumentList,
|
||||
SyntheticCallableId.TRY.callableName,
|
||||
@@ -99,6 +101,7 @@ class FirSyntheticCallGenerator(
|
||||
if (stubReference !is FirStubReference) return null
|
||||
|
||||
val reference = generateCalleeReferenceWithCandidate(
|
||||
checkNotNullCall,
|
||||
checkNotNullFunction,
|
||||
checkNotNullCall.argumentList,
|
||||
SyntheticCallableId.CHECK_NOT_NULL.callableName,
|
||||
@@ -116,6 +119,7 @@ class FirSyntheticCallGenerator(
|
||||
arguments += elvisExpression.rhs
|
||||
}
|
||||
val reference = generateCalleeReferenceWithCandidate(
|
||||
elvisExpression,
|
||||
elvisFunction,
|
||||
argumentList,
|
||||
SyntheticCallableId.ELVIS_NOT_NULL.callableName,
|
||||
@@ -134,6 +138,7 @@ class FirSyntheticCallGenerator(
|
||||
|
||||
val reference =
|
||||
generateCalleeReferenceWithCandidate(
|
||||
callableReferenceAccess,
|
||||
idFunction,
|
||||
argumentList,
|
||||
SyntheticCallableId.ID.callableName,
|
||||
@@ -156,13 +161,14 @@ class FirSyntheticCallGenerator(
|
||||
}
|
||||
|
||||
private fun generateCalleeReferenceWithCandidate(
|
||||
callSite: FirExpression,
|
||||
function: FirSimpleFunction,
|
||||
argumentList: FirArgumentList,
|
||||
name: Name,
|
||||
callKind: CallKind = CallKind.SyntheticSelect,
|
||||
context: ResolutionContext
|
||||
): FirNamedReferenceWithCandidate? {
|
||||
val callInfo = generateCallInfo(name, argumentList, callKind)
|
||||
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
|
||||
val candidate = generateCandidate(callInfo, function, context)
|
||||
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
||||
if (applicability <= CandidateApplicability.INAPPLICABLE) {
|
||||
@@ -182,7 +188,8 @@ class FirSyntheticCallGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateCallInfo(name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
|
||||
private fun generateCallInfo(callSite: FirExpression, name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
|
||||
callSite = callSite,
|
||||
callKind = callKind,
|
||||
name = name,
|
||||
explicitReceiver = null,
|
||||
|
||||
+3
-1
@@ -50,9 +50,11 @@ class FirTypeResolveTransformer(
|
||||
}
|
||||
|
||||
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(session)
|
||||
private var currentFile: FirFile? = null
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||
checkSessionConsistency(file)
|
||||
currentFile = file
|
||||
return withScopeCleanup {
|
||||
scopes.addAll(createImportingScopes(file, session, scopeSession))
|
||||
super.transformFile(file, data)
|
||||
@@ -169,7 +171,7 @@ class FirTypeResolveTransformer(
|
||||
}
|
||||
|
||||
override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): CompositeTransformResult<FirResolvedTypeRef> {
|
||||
return typeRef.transform(typeResolverTransformer, towerScope)
|
||||
return typeResolverTransformer.withFile(currentFile) { typeRef.transform(typeResolverTransformer, towerScope) }
|
||||
}
|
||||
|
||||
override fun transformValueParameter(valueParameter: FirValueParameter, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
|
||||
+3
-1
@@ -66,7 +66,9 @@ open class FirBodyResolveTransformer(
|
||||
if (typeRef is FirResolvedTypeRef) {
|
||||
return typeRef.compose()
|
||||
}
|
||||
return typeResolverTransformer.transformTypeRef(typeRef, FirCompositeScope(components.createCurrentScopeList()))
|
||||
return typeResolverTransformer.withFile(context.file) {
|
||||
transformTypeRef(typeRef, FirCompositeScope(components.createCurrentScopeList()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: ResolutionMode): CompositeTransformResult<FirTypeRef> {
|
||||
|
||||
+10
-2
@@ -201,6 +201,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}.toTypedArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}.also {
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(it, propertyReferenceAccess.source ?: source, null)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -716,11 +718,17 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
returnStatements.mapNotNull { (it as? FirExpression)?.resultType?.coneType }
|
||||
) ?: session.builtinTypes.unitType.type
|
||||
}
|
||||
lambda.replaceReturnTypeRef(lambda.returnTypeRef.resolvedTypeFromPrototype(returnType))
|
||||
lambda.replaceReturnTypeRef(
|
||||
lambda.returnTypeRef.resolvedTypeFromPrototype(returnType).also {
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(it, lambda.source, null)
|
||||
}
|
||||
)
|
||||
lambda.replaceTypeRef(
|
||||
lambda.constructFunctionalTypeRef(
|
||||
isSuspend = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.isSuspendFunctionType(session) == true
|
||||
)
|
||||
).also {
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(it, lambda.source, null)
|
||||
}
|
||||
)
|
||||
lambda.addReturn().compose()
|
||||
}
|
||||
|
||||
+5
-1
@@ -718,7 +718,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
}
|
||||
val typeRef = symbol?.constructType(typeArguments, isNullable = false)
|
||||
if (typeRef != null) {
|
||||
lhs.replaceTypeRef(buildResolvedTypeRef { type = typeRef })
|
||||
lhs.replaceTypeRef(
|
||||
buildResolvedTypeRef { type = typeRef }.also {
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(it, getClassCall.source, null)
|
||||
}
|
||||
)
|
||||
typeRef
|
||||
} else {
|
||||
lhs.resultType.coneType
|
||||
|
||||
+6
-1
@@ -219,13 +219,18 @@ private class ReturnTypeCalculatorWithJump(
|
||||
if (declaration.isIntersectionOverride) {
|
||||
val result = tryCalculateReturnType(declaration.symbol.baseForIntersectionOverride!!.fir)
|
||||
declaration.replaceReturnTypeRef(result)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(result, declaration.source, null)
|
||||
return result
|
||||
}
|
||||
|
||||
runIf(declaration.isSubstitutionOverride) {
|
||||
val overriddenDeclaration = declaration.originalForSubstitutionOverride ?: return@runIf
|
||||
tryCalculateReturnType(overriddenDeclaration)
|
||||
return FakeOverrideTypeCalculator.Forced.computeReturnType(declaration)
|
||||
val result = FakeOverrideTypeCalculator.Forced.computeReturnType(declaration)
|
||||
(declaration.returnTypeRef as? FirResolvedTypeRef)?.let {
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(it, declaration.source, null)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
return when (val status = implicitBodyResolveComputationSession.getStatus(declaration.symbol)) {
|
||||
|
||||
+4
@@ -19,4 +19,8 @@ class FirExplicitSimpleImportingScope(
|
||||
imports.filterIsInstance<FirResolvedImport>()
|
||||
.filter { !it.isAllUnder && it.importedName != null }
|
||||
.groupBy { it.aliasName ?: it.importedName!! }
|
||||
|
||||
override val scopeOwnerLookupNames: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
simpleImports.values.flatMapTo(LinkedHashSet()) { it.map { it.packageFqName.asString() } }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -17,4 +17,8 @@ class FirExplicitStarImportingScope(
|
||||
filter: FirImportingScopeFilter
|
||||
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
|
||||
override val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder }
|
||||
|
||||
override val scopeOwnerLookupNames: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
starImports.mapTo(LinkedHashSet()) { it.packageFqName.asString() }.toList()
|
||||
}
|
||||
}
|
||||
+3
@@ -43,6 +43,9 @@ private class FirNestedClassifierScopeWithSubstitution(
|
||||
|
||||
override fun getCallableNames(): Set<Name> = scope.getContainingCallableNamesIfPresent()
|
||||
override fun getClassifierNames(): Set<Name> = scope.getContainingClassifierNamesIfPresent()
|
||||
|
||||
override val scopeOwnerLookupNames: List<String>
|
||||
get() = scope.scopeOwnerLookupNames
|
||||
}
|
||||
|
||||
fun FirScope.wrapNestedClassifierScopeWithSubstitutionForSuperType(
|
||||
|
||||
@@ -18,4 +18,7 @@ class FirOnlyCallablesScope(val delegate: FirScope) : FirScope() {
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
return delegate.processPropertiesByName(name, processor)
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String>
|
||||
get() = delegate.scopeOwnerLookupNames
|
||||
}
|
||||
+7
-1
@@ -10,10 +10,14 @@ import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() {
|
||||
private val symbolProvider = session.symbolProvider
|
||||
@@ -56,4 +60,6 @@ class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirSc
|
||||
processor(symbol)
|
||||
}
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String> = SmartList(fqName.asString())
|
||||
}
|
||||
|
||||
+3
@@ -80,4 +80,7 @@ class FirScopeWithFakeOverrideTypeCalculator(
|
||||
fakeOverrideTypeCalculator.computeReturnType(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String>
|
||||
get() = delegate.scopeOwnerLookupNames
|
||||
}
|
||||
|
||||
@@ -52,4 +52,8 @@ class FirCompositeScope(val scopes: Iterable<FirScope>) : FirScope(), FirContain
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
return scopes.flatMapTo(hashSetOf()) { it.getContainingClassifierNamesIfPresent() }
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
scopes.flatMap { it.scopeOwnerLookupNames }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ abstract class FirScope {
|
||||
}
|
||||
|
||||
open fun mayContainName(name: Name) = true
|
||||
|
||||
open val scopeOwnerLookupNames: List<String> get() = emptyList()
|
||||
}
|
||||
|
||||
fun FirScope.getSingleClassifier(name: Name): FirClassifierSymbol<*>? = mutableListOf<FirClassifierSymbol<*>>().apply {
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -17,13 +18,15 @@ fun createSessionForTests(
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope),
|
||||
moduleName: String = "TestModule",
|
||||
friendPaths: List<String> = emptyList()
|
||||
friendPaths: List<String> = emptyList(),
|
||||
lookupTracker: LookupTracker? = null
|
||||
): FirSession = createSessionForTests(
|
||||
environment.project,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
moduleName,
|
||||
friendPaths,
|
||||
lookupTracker,
|
||||
environment::createPackagePartProvider
|
||||
)
|
||||
|
||||
@@ -33,6 +36,7 @@ fun createSessionForTests(
|
||||
librariesScope: GlobalSearchScope,
|
||||
moduleName: String = "TestModule",
|
||||
friendPaths: List<String> = emptyList(),
|
||||
lookupTracker: LookupTracker? = null,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
|
||||
): FirSession {
|
||||
return createSessionWithDependencies(
|
||||
@@ -43,6 +47,7 @@ fun createSessionForTests(
|
||||
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker,
|
||||
packagePartProvider
|
||||
)
|
||||
}
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ abstract class AbstractCandidateInfoProvider(
|
||||
) : CandidateInfoProvider {
|
||||
override fun callInfo(): CallInfo = with(resolutionParameters) {
|
||||
CallInfo(
|
||||
firFile, // TODO: consider passing more precise info here, if needed
|
||||
callKind = callKind(),
|
||||
name = callableSymbol.callableId.callableName,
|
||||
explicitReceiver = explicitReceiver,
|
||||
|
||||
Reference in New Issue
Block a user