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 GRADLE_LOG = "gradle-build.log"
|
||||||
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
|
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
|
||||||
const val JS_JPS_LOG = "js-jps-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"
|
private const val SIMPLE_LOG = "build.log"
|
||||||
|
|
||||||
fun isJpsLogFile(file: File): Boolean =
|
fun isJpsLogFile(file: File): Boolean =
|
||||||
@@ -46,10 +48,11 @@ data class BuildLogFinder(
|
|||||||
isScopeExpansionEnabled && SCOPE_EXPANDING_LOG in files -> SCOPE_EXPANDING_LOG
|
isScopeExpansionEnabled && SCOPE_EXPANDING_LOG in files -> SCOPE_EXPANDING_LOG
|
||||||
isKlibEnabled && KLIB_LOG in files -> KLIB_LOG
|
isKlibEnabled && KLIB_LOG in files -> KLIB_LOG
|
||||||
isJsEnabled && JS_LOG in files -> JS_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
|
isGradleEnabled && GRADLE_LOG in files -> GRADLE_LOG
|
||||||
isJsEnabled && JS_JPS_LOG in files -> JS_JPS_LOG
|
isJsEnabled && JS_JPS_LOG in files -> JS_JPS_LOG
|
||||||
isDataContainerBuildLogEnabled && DATA_CONTAINER_LOG in files -> DATA_CONTAINER_LOG
|
isDataContainerBuildLogEnabled && DATA_CONTAINER_LOG in files -> DATA_CONTAINER_LOG
|
||||||
isFirEnabled && FIR_LOG in files -> FIR_LOG
|
|
||||||
SIMPLE_LOG in files -> SIMPLE_LOG
|
SIMPLE_LOG in files -> SIMPLE_LOG
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -333,6 +333,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
sourceScope,
|
sourceScope,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
|
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
||||||
environment::createPackagePartProvider
|
environment::createPackagePartProvider
|
||||||
) {
|
) {
|
||||||
if (extendedAnalysisMode) {
|
if (extendedAnalysisMode) {
|
||||||
@@ -350,9 +351,6 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
)
|
)
|
||||||
performanceManager?.notifyAnalysisFinished()
|
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 }) {
|
if (syntaxErrors || firDiagnostics.any { it.severity == Severity.ERROR }) {
|
||||||
return false
|
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.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.lookupTracker
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
|
|
||||||
object FirConflictsChecker : FirBasicDeclarationChecker() {
|
object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||||
@@ -21,7 +20,7 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
|||||||
val inspector = FirDeclarationInspector()
|
val inspector = FirDeclarationInspector()
|
||||||
|
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirFile -> checkFile(declaration, inspector)
|
is FirFile -> checkFile(declaration, inspector, context)
|
||||||
is FirRegularClass -> checkRegularClass(declaration, inspector)
|
is FirRegularClass -> checkRegularClass(declaration, inspector)
|
||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
@@ -47,9 +46,21 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFile(declaration: FirFile, inspector: FirDeclarationInspector) {
|
private fun checkFile(file: FirFile, inspector: FirDeclarationInspector, context: CheckerContext) {
|
||||||
for (it in declaration.declarations) {
|
val lookupTracker = context.session.lookupTracker
|
||||||
inspector.collect(it)
|
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
|
package org.jetbrains.kotlin.fir.session
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
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.resolve.transformers.plugin.GeneratedClassIndex
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
|
||||||
// -------------------------- Required components --------------------------
|
// -------------------------- Required components --------------------------
|
||||||
|
|
||||||
@@ -55,10 +57,20 @@ fun FirSession.registerThreadUnsafeCaches() {
|
|||||||
* Resolve components which are same on all platforms
|
* Resolve components which are same on all platforms
|
||||||
*/
|
*/
|
||||||
@OptIn(SessionConfiguration::class)
|
@OptIn(SessionConfiguration::class)
|
||||||
fun FirSession.registerResolveComponents() {
|
fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null) {
|
||||||
register(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
register(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
||||||
register(FirTypeResolver::class, FirTypeResolverImpl(this))
|
register(FirTypeResolver::class, FirTypeResolverImpl(this))
|
||||||
register(CheckersComponent::class, CheckersComponent())
|
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.providers.impl.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||||
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
|
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.java.JavaClassFinderImpl
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||||
@@ -68,12 +69,13 @@ object FirSessionFactory {
|
|||||||
project: Project,
|
project: Project,
|
||||||
dependenciesProvider: FirSymbolProvider? = null,
|
dependenciesProvider: FirSymbolProvider? = null,
|
||||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||||
|
lookupTracker: LookupTracker? = null,
|
||||||
init: FirSessionConfigurator.() -> Unit = {}
|
init: FirSessionConfigurator.() -> Unit = {}
|
||||||
): FirJavaModuleBasedSession {
|
): FirJavaModuleBasedSession {
|
||||||
return FirJavaModuleBasedSession(moduleInfo, sessionProvider).apply {
|
return FirJavaModuleBasedSession(moduleInfo, sessionProvider).apply {
|
||||||
registerThreadUnsafeCaches()
|
registerThreadUnsafeCaches()
|
||||||
registerCommonComponents(languageVersionSettings)
|
registerCommonComponents(languageVersionSettings)
|
||||||
registerResolveComponents()
|
registerResolveComponents(lookupTracker)
|
||||||
registerJavaSpecificResolveComponents()
|
registerJavaSpecificResolveComponents()
|
||||||
|
|
||||||
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
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.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
|
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
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.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.modules.Module
|
import org.jetbrains.kotlin.modules.Module
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -24,6 +25,7 @@ fun createSessionWithDependencies(
|
|||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
sourceScope: GlobalSearchScope,
|
sourceScope: GlobalSearchScope,
|
||||||
librariesScope: GlobalSearchScope,
|
librariesScope: GlobalSearchScope,
|
||||||
|
lookupTracker: LookupTracker?,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||||
): FirSession {
|
): FirSession {
|
||||||
@@ -33,6 +35,7 @@ fun createSessionWithDependencies(
|
|||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
sourceScope,
|
sourceScope,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
|
lookupTracker,
|
||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
sessionConfigurator
|
sessionConfigurator
|
||||||
) {
|
) {
|
||||||
@@ -46,6 +49,7 @@ fun createSessionWithDependencies(
|
|||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
sourceScope: GlobalSearchScope,
|
sourceScope: GlobalSearchScope,
|
||||||
librariesScope: GlobalSearchScope,
|
librariesScope: GlobalSearchScope,
|
||||||
|
lookupTracker: LookupTracker?,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||||
): FirSession {
|
): FirSession {
|
||||||
@@ -55,6 +59,7 @@ fun createSessionWithDependencies(
|
|||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
sourceScope,
|
sourceScope,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
|
lookupTracker,
|
||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
sessionConfigurator
|
sessionConfigurator
|
||||||
) {
|
) {
|
||||||
@@ -68,6 +73,7 @@ private inline fun createSessionWithDependencies(
|
|||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
sourceScope: GlobalSearchScope,
|
sourceScope: GlobalSearchScope,
|
||||||
librariesScope: GlobalSearchScope,
|
librariesScope: GlobalSearchScope,
|
||||||
|
lookupTracker: LookupTracker?,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||||
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||||
moduleInfoProvider: (dependencies: List<ModuleInfo>) -> ModuleInfo,
|
moduleInfoProvider: (dependencies: List<ModuleInfo>) -> ModuleInfo,
|
||||||
@@ -84,6 +90,7 @@ private inline fun createSessionWithDependencies(
|
|||||||
sourceScope,
|
sourceScope,
|
||||||
project,
|
project,
|
||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings = languageVersionSettings,
|
||||||
|
lookupTracker = lookupTracker,
|
||||||
init = sessionConfigurator
|
init = sessionConfigurator
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -702,6 +702,7 @@ private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstEx
|
|||||||
type = kind.expectedConeType(session)
|
type = kind.expectedConeType(session)
|
||||||
}
|
}
|
||||||
replaceTypeRef(typeRef)
|
replaceTypeRef(typeRef)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(typeRef, source, null)
|
||||||
return this
|
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.builtins.jvm.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilder
|
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.impl.FirResolvedDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
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.JavaTypeParameterStack
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
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.fir.scopes.jvm.computeJvmDescriptor
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -85,7 +82,10 @@ class FirSignatureEnhancement(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, predefinedInfo)
|
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 -> {
|
is FirField -> {
|
||||||
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
|
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
|
||||||
|
|||||||
+3
@@ -104,4 +104,7 @@ class JavaClassStaticUseSiteScope internal constructor(
|
|||||||
override fun mayContainName(name: Name): Boolean {
|
override fun mayContainName(name: Name): Boolean {
|
||||||
return declaredMemberScope.mayContainName(name) || superTypesScopes.any { it.mayContainName(name) }
|
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 typeArguments = (qualifiedAccess as? FirFunctionCall)?.typeArguments.orEmpty()
|
||||||
|
|
||||||
val info = CallInfo(
|
val info = CallInfo(
|
||||||
|
qualifiedAccess,
|
||||||
if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
||||||
name,
|
name,
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
@@ -304,6 +305,7 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val callInfo = CallInfo(
|
val callInfo = CallInfo(
|
||||||
|
delegatedConstructorCall,
|
||||||
CallKind.DelegatingConstructorCall,
|
CallKind.DelegatingConstructorCall,
|
||||||
name,
|
name,
|
||||||
explicitReceiver = null,
|
explicitReceiver = null,
|
||||||
@@ -352,6 +354,7 @@ class FirCallResolver(
|
|||||||
annotationCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
annotationCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||||
|
|
||||||
val callInfo = CallInfo(
|
val callInfo = CallInfo(
|
||||||
|
annotationCall,
|
||||||
CallKind.Function,
|
CallKind.Function,
|
||||||
name = reference.name,
|
name = reference.name,
|
||||||
explicitReceiver = null,
|
explicitReceiver = null,
|
||||||
@@ -462,6 +465,7 @@ class FirCallResolver(
|
|||||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
||||||
): CallInfo {
|
): CallInfo {
|
||||||
return CallInfo(
|
return CallInfo(
|
||||||
|
callableReferenceAccess,
|
||||||
CallKind.CallableReference,
|
CallKind.CallableReference,
|
||||||
callableReferenceAccess.calleeReference.name,
|
callableReferenceAccess.calleeReference.name,
|
||||||
callableReferenceAccess.explicitReceiver,
|
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
|
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(
|
fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
||||||
@@ -315,7 +317,9 @@ fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
|||||||
else
|
else
|
||||||
typeAfterNullCheck
|
typeAfterNullCheck
|
||||||
|
|
||||||
replaceTypeRef(typeRef.resolvedTypeFromPrototype(resultingType))
|
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(resultingType)
|
||||||
|
replaceTypeRef(resolvedTypeRef)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.expressionTypeOrUnitForAssignment(): ConeKotlinType? {
|
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.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.lookupTracker
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
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.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
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.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
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.types.model.TypeSystemCommonSuperTypesContext
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
|
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
||||||
|
|
||||||
fun Candidate.resolveArgumentExpression(
|
fun Candidate.resolveArgumentExpression(
|
||||||
csBuilder: ConstraintSystemBuilder,
|
csBuilder: ConstraintSystemBuilder,
|
||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
@@ -391,6 +395,7 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun Candidate.resolveArgument(
|
internal fun Candidate.resolveArgument(
|
||||||
|
callInfo: CallInfo,
|
||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
parameter: FirValueParameter?,
|
parameter: FirValueParameter?,
|
||||||
isReceiver: Boolean,
|
isReceiver: Boolean,
|
||||||
@@ -399,7 +404,8 @@ internal fun Candidate.resolveArgument(
|
|||||||
) {
|
) {
|
||||||
argument.resultType.ensureResolvedTypeDeclaration(context.session)
|
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(
|
resolveArgumentExpression(
|
||||||
this.system.getBuilder(),
|
this.system.getBuilder(),
|
||||||
argument,
|
argument,
|
||||||
@@ -415,13 +421,33 @@ internal fun Candidate.resolveArgument(
|
|||||||
private fun Candidate.prepareExpectedType(
|
private fun Candidate.prepareExpectedType(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
|
callInfo: CallInfo,
|
||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
parameter: FirValueParameter?,
|
parameter: FirValueParameter?,
|
||||||
context: ResolutionContext
|
context: ResolutionContext
|
||||||
): ConeKotlinType? {
|
): ConeKotlinType? {
|
||||||
if (parameter == null) return null
|
if (parameter == null) return null
|
||||||
val basicExpectedType = argument.getExpectedTypeForSAMConversion(parameter/*, LanguageVersionSettings*/)
|
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)
|
return this.substitutor.substituteOrSelf(expectedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
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
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
|
|
||||||
data class CallInfo(
|
data class CallInfo(
|
||||||
|
val callSite: FirElement,
|
||||||
val callKind: CallKind,
|
val callKind: CallKind,
|
||||||
val name: Name,
|
val name: Name,
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ internal object CheckArguments : CheckerStage() {
|
|||||||
for (argument in callInfo.arguments) {
|
for (argument in callInfo.arguments) {
|
||||||
val parameter = argumentMapping[argument]
|
val parameter = argumentMapping[argument]
|
||||||
candidate.resolveArgument(
|
candidate.resolveArgument(
|
||||||
|
callInfo,
|
||||||
argument,
|
argument,
|
||||||
parameter,
|
parameter,
|
||||||
isReceiver = false,
|
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.FirTowerDataContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
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.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|||||||
+5
-5
@@ -44,18 +44,18 @@ internal class TowerLevelHandler {
|
|||||||
|
|
||||||
when (info.callKind) {
|
when (info.callKind) {
|
||||||
CallKind.VariableAccess -> {
|
CallKind.VariableAccess -> {
|
||||||
processResult += towerLevel.processPropertiesByName(info.name, processor)
|
processResult += towerLevel.processPropertiesByName(info, processor)
|
||||||
|
|
||||||
if (!collector.isSuccess() && towerLevel is ScopeTowerLevel && towerLevel.extensionReceiver == null) {
|
if (!collector.isSuccess() && towerLevel is ScopeTowerLevel && towerLevel.extensionReceiver == null) {
|
||||||
processResult += towerLevel.processObjectsByName(info.name, processor)
|
processResult += towerLevel.processObjectsByName(info, processor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind.Function -> {
|
CallKind.Function -> {
|
||||||
processResult += towerLevel.processFunctionsByName(info.name, processor)
|
processResult += towerLevel.processFunctionsByName(info, processor)
|
||||||
}
|
}
|
||||||
CallKind.CallableReference -> {
|
CallKind.CallableReference -> {
|
||||||
processResult += towerLevel.processFunctionsByName(info.name, processor)
|
processResult += towerLevel.processFunctionsByName(info, processor)
|
||||||
processResult += towerLevel.processPropertiesByName(info.name, processor)
|
processResult += towerLevel.processPropertiesByName(info, processor)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||||
|
|||||||
+63
-35
@@ -5,29 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
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.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
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.expressions.builder.buildResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
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.FirDefaultStarImportingScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
||||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
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.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
enum class ProcessResult {
|
enum class ProcessResult {
|
||||||
FOUND, SCOPE_EMPTY;
|
FOUND, SCOPE_EMPTY;
|
||||||
@@ -46,11 +40,11 @@ abstract class TowerScopeLevel {
|
|||||||
object Objects : Token<AbstractFirBasedSymbol<*>>()
|
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<*>> {
|
interface TowerScopeLevelProcessor<in T : AbstractFirBasedSymbol<*>> {
|
||||||
fun consumeCandidate(
|
fun consumeCandidate(
|
||||||
@@ -131,41 +125,50 @@ class MemberScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processFunctionsByName(
|
override fun processFunctionsByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
val isInvoke = name == OperatorNameConventions.INVOKE
|
val isInvoke = info.name == OperatorNameConventions.INVOKE
|
||||||
if (implicitExtensionInvokeMode && !isInvoke) {
|
if (implicitExtensionInvokeMode && !isInvoke) {
|
||||||
return ProcessResult.FOUND
|
return ProcessResult.FOUND
|
||||||
}
|
}
|
||||||
|
val lookupTracker = session.lookupTracker
|
||||||
return processMembers(processor) { consumer ->
|
return processMembers(processor) { consumer ->
|
||||||
this.processFunctionsAndConstructorsByName(
|
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
||||||
name, session, bodyResolveComponents,
|
this.processFunctionsAndConstructorsByName(
|
||||||
includeInnerConstructors = true,
|
info.name, session, bodyResolveComponents,
|
||||||
processor = {
|
includeInnerConstructors = true,
|
||||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
processor = {
|
||||||
@Suppress("UNCHECKED_CAST")
|
lookupCtx.recordCallableMemberLookup(it)
|
||||||
consumer(it as FirFunctionSymbol<*>)
|
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||||
}
|
@Suppress("UNCHECKED_CAST")
|
||||||
)
|
consumer(it as FirFunctionSymbol<*>)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(
|
override fun processPropertiesByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
|
val lookupTracker = session.lookupTracker
|
||||||
return processMembers(processor) { consumer ->
|
return processMembers(processor) { consumer ->
|
||||||
this.processPropertiesByName(name) {
|
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
||||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
||||||
@Suppress("UNCHECKED_CAST")
|
this.processPropertiesByName(info.name) {
|
||||||
consumer(it)
|
lookupCtx.recordCallableMemberLookup(it)
|
||||||
|
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
consumer(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processObjectsByName(
|
override fun processObjectsByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
return ProcessResult.FOUND
|
return ProcessResult.FOUND
|
||||||
@@ -176,6 +179,28 @@ class MemberScopeTowerLevel(
|
|||||||
session, bodyResolveComponents, receiverValue, extensionReceiver, implicitExtensionInvokeMode, scopeSession
|
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"
|
// This is more like "scope-based tower level"
|
||||||
@@ -269,12 +294,13 @@ class ScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processFunctionsByName(
|
override fun processFunctionsByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
var empty = true
|
var empty = true
|
||||||
|
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||||
scope.processFunctionsAndConstructorsByName(
|
scope.processFunctionsAndConstructorsByName(
|
||||||
name,
|
info.name,
|
||||||
session,
|
session,
|
||||||
bodyResolveComponents,
|
bodyResolveComponents,
|
||||||
includeInnerConstructors = includeInnerConstructors
|
includeInnerConstructors = includeInnerConstructors
|
||||||
@@ -286,11 +312,12 @@ class ScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(
|
override fun processPropertiesByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
var empty = true
|
var empty = true
|
||||||
scope.processPropertiesByName(name) { candidate ->
|
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||||
|
scope.processPropertiesByName(info.name) { candidate ->
|
||||||
empty = false
|
empty = false
|
||||||
consumeCallableCandidate(candidate, processor)
|
consumeCallableCandidate(candidate, processor)
|
||||||
}
|
}
|
||||||
@@ -298,11 +325,12 @@ class ScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processObjectsByName(
|
override fun processObjectsByName(
|
||||||
name: Name,
|
info: CallInfo,
|
||||||
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
var empty = true
|
var empty = true
|
||||||
scope.processClassifiersByName(name) {
|
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||||
|
scope.processClassifiersByName(info.name) {
|
||||||
empty = false
|
empty = false
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
it, dispatchReceiverValue = null,
|
it, dispatchReceiverValue = null,
|
||||||
|
|||||||
+13
-8
@@ -5,14 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.inference
|
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.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
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.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
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.FirBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
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.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
@@ -62,7 +60,9 @@ class FirCallCompleter(
|
|||||||
val initialType = components.initialTypeOfCandidate(candidate, call)
|
val initialType = components.initialTypeOfCandidate(candidate, call)
|
||||||
|
|
||||||
if (call is FirExpression) {
|
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) {
|
if (expectedTypeRef is FirResolvedTypeRef) {
|
||||||
@@ -208,14 +208,19 @@ class FirCallCompleter(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val lookupTracker = session.lookupTracker
|
||||||
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
||||||
parameter.replaceReturnTypeRef(
|
val newReturnTypeRef = parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
||||||
parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
parameter.replaceReturnTypeRef(newReturnTypeRef)
|
||||||
)
|
lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, parameter.source, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam))
|
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()) {
|
val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@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.FirCallResolver
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
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.references.builder.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||||
@@ -93,7 +95,9 @@ class PostponedArgumentsAnalyzer(
|
|||||||
namedReference
|
namedReference
|
||||||
).apply {
|
).apply {
|
||||||
if (resultingCandidate != null) {
|
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) {
|
if (declaration !is FirErrorFunction) {
|
||||||
result.replaceTypeArguments(typeArguments)
|
result.replaceTypeArguments(typeArguments)
|
||||||
}
|
}
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(typeRef, qualifiedAccessExpression.source, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +136,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val resultType = typeRef.substituteTypeRef(subCandidate)
|
val resultType = typeRef.substituteTypeRef(subCandidate)
|
||||||
resultType.ensureResolvedTypeDeclaration(session)
|
resultType.ensureResolvedTypeDeclaration(session)
|
||||||
result.replaceTypeRef(resultType)
|
result.replaceTypeRef(resultType)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, null)
|
||||||
|
|
||||||
if (mode == Mode.DelegatedPropertyCompletion) {
|
if (mode == Mode.DelegatedPropertyCompletion) {
|
||||||
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
||||||
@@ -179,6 +181,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.replaceTypeRef(resultType)
|
result.replaceTypeRef(resultType)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null)
|
||||||
|
|
||||||
if (mode == Mode.DelegatedPropertyCompletion) {
|
if (mode == Mode.DelegatedPropertyCompletion) {
|
||||||
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
subCandidate.symbol.fir.transformSingle(declarationWriter, null)
|
||||||
@@ -249,6 +252,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
): D {
|
): D {
|
||||||
val resultTypeRef = typeRef.substituteTypeRef(calleeReference.candidate)
|
val resultTypeRef = typeRef.substituteTypeRef(calleeReference.candidate)
|
||||||
replaceTypeRef(resultTypeRef)
|
replaceTypeRef(resultTypeRef)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultTypeRef, source, null)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,6 +301,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val resultType = typeRef.withReplacedConeType(finalType)
|
val resultType = typeRef.withReplacedConeType(finalType)
|
||||||
callableReferenceAccess.replaceTypeRef(resultType)
|
callableReferenceAccess.replaceTypeRef(resultType)
|
||||||
callableReferenceAccess.replaceTypeArguments(typeArguments)
|
callableReferenceAccess.replaceTypeArguments(typeArguments)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, typeRef.source ?: callableReferenceAccess.source, null)
|
||||||
|
|
||||||
return callableReferenceAccess.transformCalleeReference(
|
return callableReferenceAccess.transformCalleeReference(
|
||||||
StoreCalleeReference,
|
StoreCalleeReference,
|
||||||
@@ -338,9 +343,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
val originalType = qualifiedAccessExpression.typeRef.coneType
|
val originalType = qualifiedAccessExpression.typeRef.coneType
|
||||||
val substitutedReceiverType = finalSubstitutor.substituteOrNull(originalType) ?: return qualifiedAccessExpression.compose()
|
val substitutedReceiverType = finalSubstitutor.substituteOrNull(originalType) ?: return qualifiedAccessExpression.compose()
|
||||||
qualifiedAccessExpression.replaceTypeRef(
|
val resolvedTypeRef = qualifiedAccessExpression.typeRef.resolvedTypeFromPrototype(substitutedReceiverType)
|
||||||
qualifiedAccessExpression.typeRef.resolvedTypeFromPrototype(substitutedReceiverType)
|
qualifiedAccessExpression.replaceTypeRef(resolvedTypeRef)
|
||||||
)
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, qualifiedAccessExpression.source, null)
|
||||||
return qualifiedAccessExpression.compose()
|
return qualifiedAccessExpression.compose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -500,9 +505,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needUpdateLambdaType) {
|
if (needUpdateLambdaType) {
|
||||||
anonymousFunction.replaceTypeRef(
|
val resolvedTypeRef = anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||||
anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
anonymousFunction.replaceTypeRef(resolvedTypeRef)
|
||||||
)
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = transformElement(anonymousFunction, null)
|
val result = transformElement(anonymousFunction, null)
|
||||||
@@ -519,10 +524,14 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
(returnExpressionsOfAnonymousFunction.lastOrNull() as? FirExpression)
|
(returnExpressionsOfAnonymousFunction.lastOrNull() as? FirExpression)
|
||||||
?.typeRef?.coneTypeSafe<ConeKotlinType>()
|
?.typeRef?.coneTypeSafe<ConeKotlinType>()
|
||||||
|
|
||||||
resultFunction.replaceReturnTypeRef(resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType))
|
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
|
||||||
resultFunction.replaceTypeRef(
|
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
|
||||||
resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
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
|
return result
|
||||||
@@ -576,6 +585,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)))
|
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)))
|
||||||
}
|
}
|
||||||
block.replaceTypeRef(resultType)
|
block.replaceTypeRef(resultType)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, null)
|
||||||
}
|
}
|
||||||
transformElement(block, data)
|
transformElement(block, data)
|
||||||
if (block.resultType is FirErrorTypeRef) {
|
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.FirImport
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
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.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
@@ -36,10 +37,20 @@ open class FirImportResolveTransformer protected constructor(
|
|||||||
|
|
||||||
private val symbolProvider: FirSymbolProvider = session.symbolProvider
|
private val symbolProvider: FirSymbolProvider = session.symbolProvider
|
||||||
|
|
||||||
|
private var currentFile: FirFile? = null
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
checkSessionConsistency(file)
|
checkSessionConsistency(file)
|
||||||
file.replaceResolvePhase(transformerPhase)
|
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> {
|
override fun transformImport(import: FirImport, data: Nothing?): CompositeTransformResult<FirImport> {
|
||||||
@@ -52,6 +63,9 @@ open class FirImportResolveTransformer protected constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val parentFqName = fqName.parent()
|
val parentFqName = fqName.parent()
|
||||||
|
currentFile?.let {
|
||||||
|
session.lookupTracker?.recordLookup(fqName.shortName(), parentFqName.asString(), import.source, it.source)
|
||||||
|
}
|
||||||
return transformImportForFqName(parentFqName, import)
|
return transformImportForFqName(parentFqName, import)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
|
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> {
|
override fun transformTypeRef(typeRef: FirTypeRef, data: FirScope): CompositeTransformResult<FirResolvedTypeRef> {
|
||||||
|
session.lookupTracker?.recordTypeLookup(typeRef, data.scopeOwnerLookupNames, currentFile?.source)
|
||||||
typeRef.transformChildren(this, data)
|
typeRef.transformChildren(this, data)
|
||||||
return transformType(typeRef, typeResolver.resolveType(typeRef, data, areBareTypesAllowed))
|
return transformType(typeRef, typeResolver.resolveType(typeRef, data, areBareTypesAllowed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(PrivateForInline::class)
|
||||||
override fun transformFunctionTypeRef(
|
override fun transformFunctionTypeRef(
|
||||||
functionTypeRef: FirFunctionTypeRef,
|
functionTypeRef: FirFunctionTypeRef,
|
||||||
data: FirScope
|
data: FirScope
|
||||||
): CompositeTransformResult<FirResolvedTypeRef> {
|
): CompositeTransformResult<FirResolvedTypeRef> {
|
||||||
functionTypeRef.transformChildren(this, data)
|
functionTypeRef.transformChildren(this, data)
|
||||||
|
session.lookupTracker?.recordTypeLookup(functionTypeRef, data.scopeOwnerLookupNames, currentFile?.source)
|
||||||
val resolvedType = typeResolver.resolveType(functionTypeRef, data, areBareTypesAllowed).takeIfAcceptable()
|
val resolvedType = typeResolver.resolveType(functionTypeRef, data, areBareTypesAllowed).takeIfAcceptable()
|
||||||
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
|
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
|
||||||
buildResolvedTypeRef {
|
buildResolvedTypeRef {
|
||||||
|
|||||||
+10
-3
@@ -8,16 +8,15 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
|||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.supertypeGenerators
|
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.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
|
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
|
||||||
@@ -284,6 +283,14 @@ private class FirSupertypeResolverVisitor(
|
|||||||
supertypeRefs: List<FirTypeRef>
|
supertypeRefs: List<FirTypeRef>
|
||||||
): List<FirTypeRef> {
|
): List<FirTypeRef> {
|
||||||
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scope ->
|
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
|
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
|
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 }
|
arguments += whenExpression.branches.map { it.result }
|
||||||
}
|
}
|
||||||
val reference = generateCalleeReferenceWithCandidate(
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
whenExpression,
|
||||||
whenSelectFunction,
|
whenSelectFunction,
|
||||||
argumentList,
|
argumentList,
|
||||||
SyntheticCallableId.WHEN.callableName,
|
SyntheticCallableId.WHEN.callableName,
|
||||||
@@ -85,6 +86,7 @@ class FirSyntheticCallGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val reference = generateCalleeReferenceWithCandidate(
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
tryExpression,
|
||||||
trySelectFunction,
|
trySelectFunction,
|
||||||
argumentList,
|
argumentList,
|
||||||
SyntheticCallableId.TRY.callableName,
|
SyntheticCallableId.TRY.callableName,
|
||||||
@@ -99,6 +101,7 @@ class FirSyntheticCallGenerator(
|
|||||||
if (stubReference !is FirStubReference) return null
|
if (stubReference !is FirStubReference) return null
|
||||||
|
|
||||||
val reference = generateCalleeReferenceWithCandidate(
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
checkNotNullCall,
|
||||||
checkNotNullFunction,
|
checkNotNullFunction,
|
||||||
checkNotNullCall.argumentList,
|
checkNotNullCall.argumentList,
|
||||||
SyntheticCallableId.CHECK_NOT_NULL.callableName,
|
SyntheticCallableId.CHECK_NOT_NULL.callableName,
|
||||||
@@ -116,6 +119,7 @@ class FirSyntheticCallGenerator(
|
|||||||
arguments += elvisExpression.rhs
|
arguments += elvisExpression.rhs
|
||||||
}
|
}
|
||||||
val reference = generateCalleeReferenceWithCandidate(
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
elvisExpression,
|
||||||
elvisFunction,
|
elvisFunction,
|
||||||
argumentList,
|
argumentList,
|
||||||
SyntheticCallableId.ELVIS_NOT_NULL.callableName,
|
SyntheticCallableId.ELVIS_NOT_NULL.callableName,
|
||||||
@@ -134,6 +138,7 @@ class FirSyntheticCallGenerator(
|
|||||||
|
|
||||||
val reference =
|
val reference =
|
||||||
generateCalleeReferenceWithCandidate(
|
generateCalleeReferenceWithCandidate(
|
||||||
|
callableReferenceAccess,
|
||||||
idFunction,
|
idFunction,
|
||||||
argumentList,
|
argumentList,
|
||||||
SyntheticCallableId.ID.callableName,
|
SyntheticCallableId.ID.callableName,
|
||||||
@@ -156,13 +161,14 @@ class FirSyntheticCallGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCalleeReferenceWithCandidate(
|
private fun generateCalleeReferenceWithCandidate(
|
||||||
|
callSite: FirExpression,
|
||||||
function: FirSimpleFunction,
|
function: FirSimpleFunction,
|
||||||
argumentList: FirArgumentList,
|
argumentList: FirArgumentList,
|
||||||
name: Name,
|
name: Name,
|
||||||
callKind: CallKind = CallKind.SyntheticSelect,
|
callKind: CallKind = CallKind.SyntheticSelect,
|
||||||
context: ResolutionContext
|
context: ResolutionContext
|
||||||
): FirNamedReferenceWithCandidate? {
|
): FirNamedReferenceWithCandidate? {
|
||||||
val callInfo = generateCallInfo(name, argumentList, callKind)
|
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
|
||||||
val candidate = generateCandidate(callInfo, function, context)
|
val candidate = generateCandidate(callInfo, function, context)
|
||||||
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
||||||
if (applicability <= CandidateApplicability.INAPPLICABLE) {
|
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,
|
callKind = callKind,
|
||||||
name = name,
|
name = name,
|
||||||
explicitReceiver = null,
|
explicitReceiver = null,
|
||||||
|
|||||||
+3
-1
@@ -50,9 +50,11 @@ class FirTypeResolveTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(session)
|
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(session)
|
||||||
|
private var currentFile: FirFile? = null
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
checkSessionConsistency(file)
|
checkSessionConsistency(file)
|
||||||
|
currentFile = file
|
||||||
return withScopeCleanup {
|
return withScopeCleanup {
|
||||||
scopes.addAll(createImportingScopes(file, session, scopeSession))
|
scopes.addAll(createImportingScopes(file, session, scopeSession))
|
||||||
super.transformFile(file, data)
|
super.transformFile(file, data)
|
||||||
@@ -169,7 +171,7 @@ class FirTypeResolveTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): CompositeTransformResult<FirResolvedTypeRef> {
|
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> {
|
override fun transformValueParameter(valueParameter: FirValueParameter, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||||
|
|||||||
+3
-1
@@ -66,7 +66,9 @@ open class FirBodyResolveTransformer(
|
|||||||
if (typeRef is FirResolvedTypeRef) {
|
if (typeRef is FirResolvedTypeRef) {
|
||||||
return typeRef.compose()
|
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> {
|
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: ResolutionMode): CompositeTransformResult<FirTypeRef> {
|
||||||
|
|||||||
+10
-2
@@ -201,6 +201,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}.toTypedArray(),
|
}.toTypedArray(),
|
||||||
isNullable = false
|
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 }
|
returnStatements.mapNotNull { (it as? FirExpression)?.resultType?.coneType }
|
||||||
) ?: session.builtinTypes.unitType.type
|
) ?: 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.replaceTypeRef(
|
||||||
lambda.constructFunctionalTypeRef(
|
lambda.constructFunctionalTypeRef(
|
||||||
isSuspend = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.isSuspendFunctionType(session) == true
|
isSuspend = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.isSuspendFunctionType(session) == true
|
||||||
)
|
).also {
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(it, lambda.source, null)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
lambda.addReturn().compose()
|
lambda.addReturn().compose()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -718,7 +718,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
}
|
}
|
||||||
val typeRef = symbol?.constructType(typeArguments, isNullable = false)
|
val typeRef = symbol?.constructType(typeArguments, isNullable = false)
|
||||||
if (typeRef != null) {
|
if (typeRef != null) {
|
||||||
lhs.replaceTypeRef(buildResolvedTypeRef { type = typeRef })
|
lhs.replaceTypeRef(
|
||||||
|
buildResolvedTypeRef { type = typeRef }.also {
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(it, getClassCall.source, null)
|
||||||
|
}
|
||||||
|
)
|
||||||
typeRef
|
typeRef
|
||||||
} else {
|
} else {
|
||||||
lhs.resultType.coneType
|
lhs.resultType.coneType
|
||||||
|
|||||||
+6
-1
@@ -219,13 +219,18 @@ private class ReturnTypeCalculatorWithJump(
|
|||||||
if (declaration.isIntersectionOverride) {
|
if (declaration.isIntersectionOverride) {
|
||||||
val result = tryCalculateReturnType(declaration.symbol.baseForIntersectionOverride!!.fir)
|
val result = tryCalculateReturnType(declaration.symbol.baseForIntersectionOverride!!.fir)
|
||||||
declaration.replaceReturnTypeRef(result)
|
declaration.replaceReturnTypeRef(result)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(result, declaration.source, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
runIf(declaration.isSubstitutionOverride) {
|
runIf(declaration.isSubstitutionOverride) {
|
||||||
val overriddenDeclaration = declaration.originalForSubstitutionOverride ?: return@runIf
|
val overriddenDeclaration = declaration.originalForSubstitutionOverride ?: return@runIf
|
||||||
tryCalculateReturnType(overriddenDeclaration)
|
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)) {
|
return when (val status = implicitBodyResolveComputationSession.getStatus(declaration.symbol)) {
|
||||||
|
|||||||
+4
@@ -19,4 +19,8 @@ class FirExplicitSimpleImportingScope(
|
|||||||
imports.filterIsInstance<FirResolvedImport>()
|
imports.filterIsInstance<FirResolvedImport>()
|
||||||
.filter { !it.isAllUnder && it.importedName != null }
|
.filter { !it.isAllUnder && it.importedName != null }
|
||||||
.groupBy { it.aliasName ?: it.importedName!! }
|
.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
|
filter: FirImportingScopeFilter
|
||||||
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
|
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
|
||||||
override val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder }
|
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 getCallableNames(): Set<Name> = scope.getContainingCallableNamesIfPresent()
|
||||||
override fun getClassifierNames(): Set<Name> = scope.getContainingClassifierNamesIfPresent()
|
override fun getClassifierNames(): Set<Name> = scope.getContainingClassifierNamesIfPresent()
|
||||||
|
|
||||||
|
override val scopeOwnerLookupNames: List<String>
|
||||||
|
get() = scope.scopeOwnerLookupNames
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirScope.wrapNestedClassifierScopeWithSubstitutionForSuperType(
|
fun FirScope.wrapNestedClassifierScopeWithSubstitutionForSuperType(
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ class FirOnlyCallablesScope(val delegate: FirScope) : FirScope() {
|
|||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
return delegate.processPropertiesByName(name, processor)
|
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.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() {
|
class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() {
|
||||||
private val symbolProvider = session.symbolProvider
|
private val symbolProvider = session.symbolProvider
|
||||||
@@ -56,4 +60,6 @@ class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirSc
|
|||||||
processor(symbol)
|
processor(symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val scopeOwnerLookupNames: List<String> = SmartList(fqName.asString())
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -80,4 +80,7 @@ class FirScopeWithFakeOverrideTypeCalculator(
|
|||||||
fakeOverrideTypeCalculator.computeReturnType(declaration)
|
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> {
|
override fun getClassifierNames(): Set<Name> {
|
||||||
return scopes.flatMapTo(hashSetOf()) { it.getContainingClassifierNamesIfPresent() }
|
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 fun mayContainName(name: Name) = true
|
||||||
|
|
||||||
|
open val scopeOwnerLookupNames: List<String> get() = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirScope.getSingleClassifier(name: Name): FirClassifierSymbol<*>? = mutableListOf<FirClassifierSymbol<*>>().apply {
|
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 com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -17,13 +18,15 @@ fun createSessionForTests(
|
|||||||
sourceScope: GlobalSearchScope,
|
sourceScope: GlobalSearchScope,
|
||||||
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope),
|
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope),
|
||||||
moduleName: String = "TestModule",
|
moduleName: String = "TestModule",
|
||||||
friendPaths: List<String> = emptyList()
|
friendPaths: List<String> = emptyList(),
|
||||||
|
lookupTracker: LookupTracker? = null
|
||||||
): FirSession = createSessionForTests(
|
): FirSession = createSessionForTests(
|
||||||
environment.project,
|
environment.project,
|
||||||
sourceScope,
|
sourceScope,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
moduleName,
|
moduleName,
|
||||||
friendPaths,
|
friendPaths,
|
||||||
|
lookupTracker,
|
||||||
environment::createPackagePartProvider
|
environment::createPackagePartProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,6 +36,7 @@ fun createSessionForTests(
|
|||||||
librariesScope: GlobalSearchScope,
|
librariesScope: GlobalSearchScope,
|
||||||
moduleName: String = "TestModule",
|
moduleName: String = "TestModule",
|
||||||
friendPaths: List<String> = emptyList(),
|
friendPaths: List<String> = emptyList(),
|
||||||
|
lookupTracker: LookupTracker? = null,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
|
||||||
): FirSession {
|
): FirSession {
|
||||||
return createSessionWithDependencies(
|
return createSessionWithDependencies(
|
||||||
@@ -43,6 +47,7 @@ fun createSessionForTests(
|
|||||||
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||||
sourceScope,
|
sourceScope,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
|
lookupTracker,
|
||||||
packagePartProvider
|
packagePartProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -36,6 +36,7 @@ abstract class AbstractCandidateInfoProvider(
|
|||||||
) : CandidateInfoProvider {
|
) : CandidateInfoProvider {
|
||||||
override fun callInfo(): CallInfo = with(resolutionParameters) {
|
override fun callInfo(): CallInfo = with(resolutionParameters) {
|
||||||
CallInfo(
|
CallInfo(
|
||||||
|
firFile, // TODO: consider passing more precise info here, if needed
|
||||||
callKind = callKind(),
|
callKind = callKind(),
|
||||||
name = callableSymbol.callableId.callableName,
|
name = callableSymbol.callableId.callableName,
|
||||||
explicitReceiver = explicitReceiver,
|
explicitReceiver = explicitReceiver,
|
||||||
|
|||||||
Reference in New Issue
Block a user