FIR resolve: use lazy nested classifier scopes for Java classes

It's necessary because JavaSymbolProvider adds nested classifiers lazily.
Commit slows things down due to relatively slow search in symbol providers
This commit is contained in:
Mikhail Glukhikh
2019-11-08 13:23:48 +03:00
parent cc891c46b1
commit bd71d1dc3f
6 changed files with 21 additions and 16 deletions
@@ -57,6 +57,7 @@ class JavaSymbolProvider(
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> = override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> =
emptyList() emptyList()
// NB: looks like it's better not to use this function at all...
override fun getClassDeclaredMemberScope(classId: ClassId): FirScope? { override fun getClassDeclaredMemberScope(classId: ClassId): FirScope? {
val classSymbol = getClassLikeSymbolByFqName(classId) ?: return null val classSymbol = getClassLikeSymbolByFqName(classId) ?: return null
return declaredMemberScope(classSymbol.fir) return declaredMemberScope(classSymbol.fir)
@@ -92,7 +93,7 @@ class JavaSymbolProvider(
visitedSymbols: MutableSet<FirClassLikeSymbol<*>> visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
): JavaClassUseSiteMemberScope { ): JavaClassUseSiteMemberScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) { return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val declaredScope = declaredMemberScope(regularClass) val declaredScope = declaredMemberScope(regularClass, useLazyNestedClassifierScope = regularClass is FirJavaClass)
val superTypeEnhancementScopes = val superTypeEnhancementScopes =
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession) lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNull { useSiteSuperType -> .mapNotNull { useSiteSuperType ->
@@ -19,8 +19,12 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirClassDeclaredMemberScope(klass: FirClass<*>) : FirScope() { class FirClassDeclaredMemberScope(klass: FirClass<*>, useLazyNestedClassifierScope: Boolean = false) : FirScope() {
private val nestedClassifierScope = nestedClassifierScope(klass) private val nestedClassifierScope = if (useLazyNestedClassifierScope) {
nestedClassifierScope(klass.symbol.classId, klass.session)
} else {
nestedClassifierScope(klass)
}
private val callablesIndex: Map<Name, List<FirCallableSymbol<*>>> = run { private val callablesIndex: Map<Name, List<FirCallableSymbol<*>>> = run {
val result = mutableMapOf<Name, MutableList<FirCallableSymbol<*>>>() val result = mutableMapOf<Name, MutableList<FirCallableSymbol<*>>>()
@@ -19,9 +19,9 @@ class FirMemberScopeProvider : FirSessionComponent {
private val nestedClassifierCache = mutableMapOf<FirClass<*>, FirNestedClassifierScope>() private val nestedClassifierCache = mutableMapOf<FirClass<*>, FirNestedClassifierScope>()
private val selfImportingCache = mutableMapOf<FqName, FirSelfImportingScope>() private val selfImportingCache = mutableMapOf<FqName, FirSelfImportingScope>()
fun declaredMemberScope(klass: FirClass<*>): FirClassDeclaredMemberScope { fun declaredMemberScope(klass: FirClass<*>, useLazyNestedClassifierScope: Boolean): FirClassDeclaredMemberScope {
return declaredMemberCache.getOrPut(klass) { return declaredMemberCache.getOrPut(klass) {
FirClassDeclaredMemberScope(klass) FirClassDeclaredMemberScope(klass, useLazyNestedClassifierScope)
} }
} }
@@ -39,11 +39,11 @@ class FirMemberScopeProvider : FirSessionComponent {
} }
} }
fun declaredMemberScope(klass: FirClass<*>): FirClassDeclaredMemberScope { fun declaredMemberScope(klass: FirClass<*>, useLazyNestedClassifierScope: Boolean = false): FirClassDeclaredMemberScope {
return klass return klass
.session .session
.memberScopeProvider .memberScopeProvider
.declaredMemberScope(klass) .declaredMemberScope(klass, useLazyNestedClassifierScope)
} }
fun nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope { fun nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope {
@@ -10,10 +10,10 @@ public abstract class AbstractClass {
class User : AbstractClass() { class User : AbstractClass() {
fun foo() { fun foo() {
val sc = <!UNRESOLVED_REFERENCE!>StaticClass<!>() val sc = StaticClass()
} }
} }
fun test() { fun test() {
AbstractClass.<!UNRESOLVED_REFERENCE!>StaticClass<!>() AbstractClass.StaticClass()
} }
@@ -5,10 +5,10 @@ FILE: User.kt
} }
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
lval sc: <ERROR TYPE REF: Unresolved name: StaticClass> = <Unresolved name: StaticClass>#() lval sc: R|AbstractClass.StaticClass| = R|/AbstractClass.StaticClass.StaticClass|()
} }
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
Q|AbstractClass|.<Unresolved name: StaticClass>#() Q|AbstractClass|.R|/AbstractClass.StaticClass.StaticClass|()
} }
+5 -5
View File
@@ -6,15 +6,15 @@ FILE fqName:<root> fileName:/javaInnerClass.kt
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J' DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test1 modality:FINAL visibility:public superTypes:[<root>.J]' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test1 modality:FINAL visibility:public superTypes:[<root>.J]'
PROPERTY name:test visibility:public modality:FINAL [val] PROPERTY name:test visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test type:IrErrorType visibility:private [final] FIELD PROPERTY_BACKING_FIELD name:test type:<root>.J.JInner visibility:private [final]
EXPRESSION_BODY EXPRESSION_BODY
ERROR_CALL 'Unresolved reference: <Unresolved name: JInner>#' type=IrErrorType CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J.JInner' type=<root>.J.JInner origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> ($this:<root>.Test1) returnType:IrErrorType FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> ($this:<root>.Test1) returnType:<root>.J.JInner
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val] correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Test1 $this: VALUE_PARAMETER name:<this> type:<root>.Test1
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test> (): IrErrorType declared in <root>.Test1' RETURN type=kotlin.Nothing from='public final fun <get-test> (): <root>.J.JInner declared in <root>.Test1'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:IrErrorType visibility:private [final]' type=IrErrorType origin=null GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:<root>.J.JInner visibility:private [final]' type=<root>.J.JInner origin=null
receiver: GET_VAR '<this>: <root>.Test1 declared in <root>.Test1.<get-test>' type=<root>.Test1 origin=null receiver: GET_VAR '<this>: <root>.Test1 declared in <root>.Test1.<get-test>' type=<root>.Test1 origin=null
FUN FAKE_OVERRIDE name:bar visibility:public modality:OPEN <> ($this:<root>.J) returnType:kotlin.Unit [fake_override] FUN FAKE_OVERRIDE name:bar visibility:public modality:OPEN <> ($this:<root>.J) returnType:kotlin.Unit [fake_override]
overridden: overridden: