From 41c81d25a0fffd799aa48731284a439758608b78 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 7 Nov 2019 15:58:58 +0300 Subject: [PATCH] FIR body resolve: use nested classifier scopes only via member scopes --- .../java/scopes/JavaClassEnhancementScope.kt | 4 ++ .../calls/ConeOverloadConflictResolver.kt | 14 ++++++ .../FirAbstractBodyResolveTransformer.kt | 2 +- .../FirDeclarationsResolveTransformer.kt | 8 ---- .../impl/AbstractFirUseSiteMemberScope.kt | 5 ++- .../scopes/impl/FirClassSubstitutionScope.kt | 4 ++ .../fir/scopes/impl/FirSuperTypeScope.kt | 32 +++++++++++++ .../impl/FirTypeResolveScopeForBodyResolve.kt | 9 ++++ .../testData/resolve/companionUsesNested.kt | 18 ++++++++ .../testData/resolve/companionUsesNested.txt | 45 +++++++++++++++++++ .../fir/FirDiagnosticsTestGenerated.java | 5 +++ 11 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 compiler/fir/resolve/testData/resolve/companionUsesNested.kt create mode 100644 compiler/fir/resolve/testData/resolve/companionUsesNested.txt diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index b6bf054714e..76ba4133a53 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -72,6 +72,10 @@ class JavaClassEnhancementScope( return super.processFunctionsByName(name, processor) } + override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> ProcessorAction): ProcessorAction { + return useSiteMemberScope.processClassifiersByName(name, processor) + } + private fun enhance( original: FirCallableSymbol<*>, name: Name diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt index 94db1c14ce4..2c04807b062 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt @@ -53,6 +53,7 @@ class ConeOverloadConflictResolver( is FirSimpleFunction -> createFlatSignature(call, declaration) is FirConstructor -> createFlatSignature(call, declaration) is FirVariable<*> -> createFlatSignature(call, declaration) + is FirClass<*> -> createFlatSignature(call, declaration) else -> error("Not supported: $declaration") } } @@ -112,6 +113,19 @@ class ConeOverloadConflictResolver( ) } + private fun createFlatSignature(call: Candidate, klass: FirClass<*>): FlatSignature { + return FlatSignature( + call, + (klass as? FirRegularClass)?.typeParameters?.map { it.symbol }.orEmpty(), + valueParameterTypes = emptyList(), + hasExtensionReceiver = false, + hasVarargs = false, + numDefaults = 0, + isExpect = (klass as? FirRegularClass)?.isExpect == true, + isSyntheticMember = false + ) + } + private fun createEmptyConstraintSystem(): SimpleConstraintSystem { return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem()) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index 94dc32d021d..7d5ba877cf4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -117,7 +117,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb qualifiedResolver ) val typeResolverTransformer = FirSpecificTypeResolverTransformer( - FirTypeResolveScopeForBodyResolve(topLevelScopes, localScopes), session + FirTypeResolveScopeForBodyResolve(topLevelScopes, implicitReceiverStack, localScopes), session ) val callCompleter: FirCallCompleter = FirCallCompleter(transformer, this) val dataFlowAnalyzer: FirDataFlowAnalyzer = FirDataFlowAnalyzer(this) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 322d717eede..0e55d86e326 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayT import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope -import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirComputingImplicitTypeRef @@ -229,11 +228,6 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) if (regularClass.symbol.classId.isLocal) { prepareLocalClassForBodyResolve(regularClass) } - val companionObject = regularClass.companionObject - if (companionObject != null) { - topLevelScopes += nestedClassifierScope(companionObject) - } - topLevelScopes += nestedClassifierScope(regularClass) val oldConstructorScope = primaryConstructorParametersScope val oldContainingClass = containingClass @@ -258,8 +252,6 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult { prepareLocalClassForBodyResolve(anonymousObject) return withScopeCleanup(topLevelScopes) { - topLevelScopes += nestedClassifierScope(anonymousObject) - val type = anonymousObject.defaultType() anonymousObject.resultType = FirResolvedTypeRefImpl(anonymousObject.source, type) val result = withLabelAndReceiverType(null, anonymousObject, type) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt index ec4a8aab653..191d9deac51 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt @@ -42,6 +42,9 @@ abstract class AbstractFirUseSiteMemberScope( name: Name, processor: (FirClassifierSymbol<*>) -> ProcessorAction ): ProcessorAction { - return declaredMemberScope.processClassifiersByName(name, processor) + if (!declaredMemberScope.processClassifiersByName(name, processor)) { + return ProcessorAction.NEXT + } + return superTypesScope.processClassifiersByName(name, processor) } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 7ee2d839d7e..c90cbed538c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -68,6 +68,10 @@ class FirClassSubstitutionScope( } } + override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> ProcessorAction): ProcessorAction { + return useSiteMemberScope.processClassifiersByName(name, processor) + } + private val typeCalculator by lazy { ReturnTypeCalculatorWithJump(session, scopeSession) } private fun ConeKotlinType.substitute(): ConeKotlinType? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSuperTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSuperTypeScope.kt index 39fa7dad159..0e07485a94e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSuperTypeScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSuperTypeScope.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.name.Name @@ -23,6 +24,8 @@ open class FirSuperTypeScope( private val absentProperties = mutableSetOf() + private val absentClassifiers = mutableSetOf() + override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction { if (name in absentFunctions) { return ProcessorAction.NEXT @@ -80,4 +83,33 @@ open class FirSuperTypeScope( } return super.processPropertiesByName(name, processor) } + + override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> ProcessorAction): ProcessorAction { + if (name in absentClassifiers) { + return ProcessorAction.NEXT + } + val accepted = HashSet>() + val pending = mutableListOf>() + var empty = true + for (scope in scopes) { + if (scope.processClassifiersByName(name) { + empty = false + if (it !in accepted) { + pending += it + processor(it) + } else { + ProcessorAction.NEXT + } + }.stop() + ) { + return ProcessorAction.STOP + } + accepted += pending + pending.clear() + } + if (empty) { + absentClassifiers += name + } + return super.processClassifiersByName(name, processor) + } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt index aabc05644e6..14c9f3bd679 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.fir.scopes.impl +import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack +import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol @@ -12,6 +14,7 @@ import org.jetbrains.kotlin.name.Name class FirTypeResolveScopeForBodyResolve( private val topLevelScopes: List, + private val implicitReceiverStack: ImplicitReceiverStack, private val localScopes: List ) : FirScope() { override fun processClassifiersByName( @@ -23,6 +26,12 @@ class FirTypeResolveScopeForBodyResolve( return ProcessorAction.STOP } } + for (receiverValue in implicitReceiverStack.receiversAsReversed()) { + if (receiverValue is ImplicitExtensionReceiverValue) continue + if (receiverValue.implicitScope?.processClassifiersByName(name, processor) == ProcessorAction.STOP) { + return ProcessorAction.STOP + } + } for (scope in topLevelScopes.asReversed()) { if (!scope.processClassifiersByName(name, processor)) { return ProcessorAction.STOP diff --git a/compiler/fir/resolve/testData/resolve/companionUsesNested.kt b/compiler/fir/resolve/testData/resolve/companionUsesNested.kt new file mode 100644 index 00000000000..af3ba0912f6 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/companionUsesNested.kt @@ -0,0 +1,18 @@ +abstract class Base { + class BaseNested +} + +class Derived : Base() { + class DerivedNested + + companion object { + val b: BaseNested = BaseNested() + + val d: DerivedNested = DerivedNested() + + fun foo() { + val bb: BaseNested = BaseNested() + val dd: DerivedNested = DerivedNested() + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/companionUsesNested.txt b/compiler/fir/resolve/testData/resolve/companionUsesNested.txt new file mode 100644 index 00000000000..0b9d8c54295 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/companionUsesNested.txt @@ -0,0 +1,45 @@ +FILE: companionUsesNested.kt + public abstract class Base : R|kotlin/Any| { + public constructor(): R|Base| { + super() + } + + public final class BaseNested : R|kotlin/Any| { + public constructor(): R|Base.BaseNested| { + super() + } + + } + + } + public final class Derived : R|Base| { + public constructor(): R|Derived| { + super() + } + + public final class DerivedNested : R|kotlin/Any| { + public constructor(): R|Derived.DerivedNested| { + super() + } + + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|Derived.Companion| { + super() + } + + public final val b: R|Base.BaseNested| = R|/Base.BaseNested.BaseNested|() + public get(): R|Base.BaseNested| + + public final val d: R|Derived.DerivedNested| = R|/Derived.DerivedNested.DerivedNested|() + public get(): R|Derived.DerivedNested| + + public final fun foo(): R|kotlin/Unit| { + lval bb: R|Base.BaseNested| = R|/Base.BaseNested.BaseNested|() + lval dd: R|Derived.DerivedNested| = R|/Derived.DerivedNested.DerivedNested|() + } + + } + + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index c1a91aa5aa8..8a1da123510 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -38,6 +38,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/companion.kt"); } + @TestMetadata("companionUsesNested.kt") + public void testCompanionUsesNested() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/companionUsesNested.kt"); + } + @TestMetadata("copy.kt") public void testCopy() throws Exception { runTest("compiler/fir/resolve/testData/resolve/copy.kt");