K2: unify all importing data logic inside FirAbstractImportingScope

This commit is contained in:
Mikhail Glukhikh
2022-11-09 10:52:49 +01:00
committed by Space Team
parent e46978f7b3
commit 08d351db57
4 changed files with 83 additions and 106 deletions
@@ -7,14 +7,18 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildPropertyCopy
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
abstract class FirAbstractImportingScope(
@@ -30,9 +34,7 @@ abstract class FirAbstractImportingScope(
private fun FirClassSymbol<*>.getStaticsScope(): FirContainingNamesAwareScope? =
if (fir.classKind == ClassKind.OBJECT) {
FirObjectImportedCallableScope(
classId, fir.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
)
unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
} else {
fir.scopeProvider.getStaticScope(fir, session, scopeSession)
}
@@ -42,7 +44,7 @@ abstract class FirAbstractImportingScope(
protected abstract fun isExcluded(import: FirResolvedImport, name: Name): Boolean
protected fun processImportsByName(
protected fun processClassifiersFromImportsByName(
name: Name?,
imports: List<FirResolvedImport>,
processor: (FirClassLikeSymbol<*>) -> Unit
@@ -57,47 +59,96 @@ abstract class FirAbstractImportingScope(
}
}
protected fun processFunctionsByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirNamedFunctionSymbol) -> Unit) {
private inline fun <D : FirCallableDeclaration, S : FirCallableSymbol<D>> processCallablesFromImportsByName(
name: Name?,
imports: List<FirResolvedImport>,
crossinline processor: (S) -> Unit,
crossinline buildImportedCopy: S.(ClassId) -> S,
processCallablesByName: FirContainingNamesAwareScope.(Name, (S) -> Unit) -> Unit,
getTopLevelCallableSymbols: (FqName, Name) -> List<S>
) {
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
if (isExcluded(import, importedName)) continue
val parentClassId = import.resolvedParentClassId
val staticsScope = parentClassId?.let { getStaticsScope(it) }
if (staticsScope != null) {
staticsScope.processFunctionsByName(importedName) {
if (it.isStatic) processor(it.fir.buildImportedCopy(parentClassId).symbol)
else processor(it)
if (parentClassId != null) {
val staticsScopeOwnerSymbol = provider.getClassLikeSymbolByClassId(parentClassId)?.fullyExpandedSymbol
val staticsScope = staticsScopeOwnerSymbol?.getStaticsScope()
if (staticsScope != null) {
staticsScope.processCallablesByName(importedName) {
if (it.isStatic || staticsScopeOwnerSymbol.classKind == ClassKind.OBJECT) {
processor(it.buildImportedCopy(parentClassId))
} else {
processor(it)
}
}
continue
}
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, importedName)) {
}
if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in getTopLevelCallableSymbols(import.packageFqName, importedName)) {
processor(symbol)
}
}
}
}
protected fun processPropertiesByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirVariableSymbol<*>) -> Unit) {
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
if (isExcluded(import, importedName)) continue
val parentClassId = import.resolvedParentClassId
val staticsScope = parentClassId?.let { getStaticsScope(it) }
protected fun processFunctionsByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirNamedFunctionSymbol) -> Unit) {
processCallablesFromImportsByName(
name,
imports,
processor,
{ classId -> fir.buildImportedCopy(classId).symbol },
FirContainingNamesAwareScope::processFunctionsByName,
provider::getTopLevelFunctionSymbols
)
}
if (staticsScope != null) {
staticsScope.processPropertiesByName(importedName) {
protected fun processPropertiesByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirVariableSymbol<*>) -> Unit) {
processCallablesFromImportsByName(
name,
imports,
processor,
{ classId -> fir.buildImportedCopy(classId).symbol },
{ importedName, importedProcessor ->
processPropertiesByName(importedName) {
if (it is FirPropertySymbol) {
if (it.isStatic) processor(it.fir.buildImportedCopy(parentClassId).symbol)
else processor(it)
importedProcessor(it)
} else {
processor(it)
}
}
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, importedName)) {
processor(symbol)
}
}
}
},
provider::getTopLevelPropertySymbols
)
}
}
internal fun FirSimpleFunction.buildImportedCopy(importedClassId: ClassId): FirSimpleFunction {
return buildSimpleFunctionCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirNamedFunctionSymbol(CallableId(importedClassId, name))
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
internal fun FirProperty.buildImportedCopy(importedClassId: ClassId): FirProperty {
return buildPropertyCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirPropertySymbol(CallableId(importedClassId, name))
this.delegateFieldSymbol = null
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
private object ImportedFromObjectOrStaticClassIdKey : FirDeclarationDataKey()
class ImportedFromObjectOrStaticData<D : FirCallableDeclaration>(
val objectClassId: ClassId,
val original: D,
)
var <D : FirCallableDeclaration> D.importedFromObjectOrStaticData: ImportedFromObjectOrStaticData<D>?
by FirDeclarationDataRegistry.data(ImportedFromObjectOrStaticClassIdKey)
@@ -26,7 +26,7 @@ abstract class FirAbstractSimpleImportingScope(
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
val imports = simpleImports[name] ?: return
processImportsByName(name = null, imports) { symbol ->
processClassifiersFromImportsByName(name = null, imports) { symbol ->
processor(symbol, ConeSubstitutor.Empty)
}
}
@@ -39,7 +39,7 @@ abstract class FirAbstractStarImportingScope(
return
}
var foundAny = false
processImportsByName(name, starImports) { symbol ->
processClassifiersFromImportsByName(name, starImports) { symbol ->
foundAny = true
processor(symbol, ConeSubstitutor.Empty)
}
@@ -1,74 +0,0 @@
/*
* Copyright 2010-2021 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.scopes.impl
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildPropertyCopy
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
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.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
class FirObjectImportedCallableScope(
private val importedClassId: ClassId,
private val objectUseSiteScope: FirTypeScope
) : FirContainingNamesAwareScope() {
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
objectUseSiteScope.processFunctionsByName(name) wrapper@{ symbol ->
val syntheticFunction = symbol.fir.buildImportedCopy(importedClassId)
processor(syntheticFunction.symbol)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
objectUseSiteScope.processPropertiesByName(name) wrapper@{ symbol ->
if (symbol !is FirPropertySymbol) {
processor(symbol)
return@wrapper
}
val syntheticProperty = symbol.fir.buildImportedCopy(importedClassId)
processor(syntheticProperty.symbol)
}
}
override fun getCallableNames(): Set<Name> = objectUseSiteScope.getCallableNames()
override fun getClassifierNames(): Set<Name> = emptySet()
}
internal fun FirSimpleFunction.buildImportedCopy(importedClassId: ClassId): FirSimpleFunction {
return buildSimpleFunctionCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirNamedFunctionSymbol(CallableId(importedClassId, name))
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
internal fun FirProperty.buildImportedCopy(importedClassId: ClassId): FirProperty {
return buildPropertyCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirPropertySymbol(CallableId(importedClassId, name))
this.delegateFieldSymbol = null
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
private object ImportedFromObjectOrStaticClassIdKey : FirDeclarationDataKey()
class ImportedFromObjectOrStaticData<D : FirCallableDeclaration>(
val objectClassId: ClassId,
val original: D,
)
var <D : FirCallableDeclaration> D.importedFromObjectOrStaticData: ImportedFromObjectOrStaticData<D>?
by FirDeclarationDataRegistry.data(ImportedFromObjectOrStaticClassIdKey)