diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/Collections.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/Collections.kt new file mode 100644 index 00000000000..e37ff3ce89e --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/Collections.kt @@ -0,0 +1,15 @@ +/* + * 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 + +private open class FrozenReversedListReadOnly( + private val delegate: List +) : AbstractList() { + override val size: Int = delegate.size + override fun get(index: Int): T = delegate[size - 1 - index] +} + +fun List.asReversedFrozen(): List = FrozenReversedListReadOnly(this) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt index c669b16109d..09a114610c2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt @@ -39,6 +39,7 @@ interface BodyResolveComponents : SessionHolder { val containingDeclarations: List val fileImportsScope: List val towerDataElements: List + val towerDataContext: FirTowerDataContext val localScopes: FirLocalScopes val towerDataContextForAnonymousFunctions: TowerDataContextForAnonymousFunctions val noExpectedType: FirTypeRef @@ -68,12 +69,14 @@ class FirTowerDataContext private constructor( // i.e. implicitReceiverStack == towerDataElements.mapNotNull { it.receiver } // i.e. localScopes == towerDataElements.mapNotNull { it.scope?.takeIf { it.isLocal } } val implicitReceiverStack: PersistentImplicitReceiverStack, - val localScopes: FirLocalScopes + val localScopes: FirLocalScopes, + val nonLocalTowerDataElements: PersistentList ) { constructor() : this( persistentListOf(), PersistentImplicitReceiverStack(), + persistentListOf(), persistentListOf() ) @@ -84,7 +87,8 @@ class FirTowerDataContext private constructor( return FirTowerDataContext( towerDataElements.set(indexOfLastLocalScope, newLastScope.asTowerDataElement(isLocal = true)), implicitReceiverStack, - localScopes.set(localScopes.lastIndex, newLastScope) + localScopes.set(localScopes.lastIndex, newLastScope), + nonLocalTowerDataElements ) } @@ -92,7 +96,8 @@ class FirTowerDataContext private constructor( return FirTowerDataContext( towerDataElements.addAll(newElements), implicitReceiverStack.addAll(newElements.mapNotNull { it.implicitReceiver }), - localScopes + localScopes, + nonLocalTowerDataElements.addAll(newElements) ) } @@ -100,15 +105,18 @@ class FirTowerDataContext private constructor( return FirTowerDataContext( towerDataElements.add(localScope.asTowerDataElement(isLocal = true)), implicitReceiverStack, - localScopes.add(localScope) + localScopes.add(localScope), + nonLocalTowerDataElements ) } fun addReceiver(name: Name?, implicitReceiverValue: ImplicitReceiverValue<*>): FirTowerDataContext { + val element = implicitReceiverValue.asTowerDataElement() return FirTowerDataContext( - towerDataElements.add(implicitReceiverValue.asTowerDataElement()), + towerDataElements.add(element), implicitReceiverStack.add(name, implicitReceiverValue), - localScopes + localScopes, + nonLocalTowerDataElements.add(element) ) } @@ -118,10 +126,12 @@ class FirTowerDataContext private constructor( } private fun addNonLocalScope(scope: FirScope): FirTowerDataContext { + val element = scope.asTowerDataElement(isLocal = false) return FirTowerDataContext( - towerDataElements.add(scope.asTowerDataElement(isLocal = false)), + towerDataElements.add(element), implicitReceiverStack, - localScopes + localScopes, + nonLocalTowerDataElements.add(element) ) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt index 167ea5509f1..751943d6033 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.asReversedFrozen import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression @@ -43,16 +44,12 @@ class FirTowerResolverSession internal constructor( private val session: FirSession get() = components.session - private val reversedTowerDataElements = components.towerDataElements.asReversed() + private val localScopes: List = components.localScopes.asReversedFrozen() - private val localScopes: List = reversedTowerDataElements.mapNotNull { lexical -> - lexical.scope?.takeIf { lexical.isLocal } - } - - private val nonLocalLexical = reversedTowerDataElements.filter { !it.isLocal } + private val nonLocalTowerDataElements = components.towerDataContext.nonLocalTowerDataElements.asReversedFrozen() private val implicitReceivers: List by lazy(LazyThreadSafetyMode.NONE) { - reversedTowerDataElements.withIndex().mapNotNull { (index, element) -> + nonLocalTowerDataElements.withIndex().mapNotNull { (index, element) -> element.implicitReceiver?.let { ImplicitReceiver(it, index) } } } @@ -404,7 +401,7 @@ class FirTowerResolverSession internal constructor( onLocalScope(index, localScope) } - for ((depth, lexical) in nonLocalLexical.withIndex()) { + for ((depth, lexical) in nonLocalTowerDataElements.withIndex()) { if (!lexical.isLocal && lexical.scope != null) { onNonLocalScope(depth, lexical.scope) } 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 c436125549d..259f64c2e06 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 @@ -245,6 +245,9 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val fileImportsScope: List get() = context.fileImportsScope override val towerDataElements: List get() = context.towerDataContext.towerDataElements override val localScopes: FirLocalScopes get() = context.towerDataContext.localScopes + + override val towerDataContext: FirTowerDataContext get() = context.towerDataContext + override val file: FirFile get() = context.file override val implicitReceiverStack: ImplicitReceiverStack get() = context.implicitReceiverStack override val containingDeclarations: List get() = context.containers