From b20179af9f30d96c98e0a696d8e336b68a5babda Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 12 Jun 2015 15:36:56 +0300 Subject: [PATCH] WritableScope: got rid of mutability of implicit receiver --- .../impl/MutableClassDescriptor.java | 54 +++++++++++++++---- .../resolve/FunctionDescriptorUtil.java | 5 +- .../lazy/descriptors/LazyClassDescriptor.java | 3 +- .../lazy/descriptors/LazyScriptDescriptor.kt | 3 +- .../kotlin/resolve/scopes/JetScopeUtils.java | 4 +- .../kotlin/resolve/scopes/WritableScope.kt | 2 - .../resolve/scopes/WritableScopeImpl.kt | 38 ++++--------- 7 files changed, 57 insertions(+), 52 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java index 445b2fcaa7e..392af8fdecf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.descriptors.impl; import com.google.common.collect.Sets; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; @@ -26,10 +27,7 @@ import org.jetbrains.kotlin.resolve.scopes.*; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.types.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes { private final ClassKind kind; @@ -48,7 +46,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class private final Set properties = Sets.newLinkedHashSet(); private final Set functions = Sets.newLinkedHashSet(); - private final WritableScope writableScopeForMemberResolution; + private final MutableScopeForMemberResolution mutableScopeForMemberResolution; private final JetScope scopeForMemberResolution; // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; @@ -72,18 +70,17 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; - setScopeForMemberLookup(new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, redeclarationHandler, "MemberLookup", this) + setScopeForMemberLookup(new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, redeclarationHandler, "MemberLookup", null, this) .changeLockLevel(WritableScope.LockLevel.BOTH)); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution") .changeLockLevel(WritableScope.LockLevel.BOTH); - this.writableScopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution") - .changeLockLevel(WritableScope.LockLevel.BOTH); + this.mutableScopeForMemberResolution = new MutableScopeForMemberResolution(); if (kind == ClassKind.INTERFACE) { setUpScopeForInitializers(this); } - this.scopeForMemberResolution = new ChainedScope(this, "MemberResolutionWithStatic", writableScopeForMemberResolution, staticScope); + this.scopeForMemberResolution = new ChainedScope(this, "MemberResolutionWithStatic", mutableScopeForMemberResolution, staticScope); } @Nullable @@ -227,7 +224,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class for (FunctionDescriptor functionDescriptor : getConstructors()) { ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); } - writableScopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); + mutableScopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); } @Override @@ -281,4 +278,41 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class public String toString() { return DeclarationDescriptorImpl.toString(this); } + + private class MutableScopeForMemberResolution extends AbstractScopeAdapter { + private ReceiverParameterDescriptor implicitReceiver = null; + private List implicitReceiversHierarchy = null; + + @NotNull + @Override + protected JetScope getWorkerScope() { + return scopeForSupertypeResolution; + } + + @NotNull + @Override + public DeclarationDescriptor getContainingDeclaration() { + return MutableClassDescriptor.this; + } + + public void setImplicitReceiver(@NotNull ReceiverParameterDescriptor implicitReceiver) { + if (this.implicitReceiver != null) { + throw new UnsupportedOperationException("Receiver redeclared"); + } + if (this.implicitReceiversHierarchy != null) { + throw new UnsupportedOperationException("Receiver hierarchy already computed"); + } + this.implicitReceiver = implicitReceiver; + this.implicitReceiversHierarchy = KotlinPackage.plus(Collections.singletonList(implicitReceiver), super.getImplicitReceiversHierarchy()); + } + + @NotNull + @Override + public List getImplicitReceiversHierarchy() { + if (implicitReceiversHierarchy != null) + return implicitReceiversHierarchy; + else + return super.getImplicitReceiversHierarchy(); + } + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java index 7835d397cc3..bf47571826b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java @@ -80,11 +80,8 @@ public class FunctionDescriptorUtil { @NotNull FunctionDescriptor descriptor, @NotNull RedeclarationHandler redeclarationHandler ) { - WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function inner scope", descriptor); ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter(); - if (receiver != null) { - parameterScope.setImplicitReceiver(receiver); - } + WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function inner scope", receiver, descriptor); for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { parameterScope.addClassifierDescriptor(typeParameter); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 946d47867b7..e9a997ae7c0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -266,8 +266,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @NotNull private JetScope computeScopeForMemberDeclarationResolution() { WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, RedeclarationHandler.DO_NOTHING, - "Scope with 'this' for " + getName(), this); - thisScope.setImplicitReceiver(this.getThisAsReceiverParameter()); + "Scope with 'this' for " + getName(), this.getThisAsReceiverParameter(), this); thisScope.changeLockLevel(WritableScope.LockLevel.READING); return new ChainedScope( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt index ee479f4de26..00003d043a9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt @@ -81,8 +81,7 @@ public class LazyScriptDescriptor( override fun getScriptCodeDescriptor() = scriptCodeDescriptor() override fun getScopeForBodyResolution(): JetScope { - val parametersScope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.DO_NOTHING, "Parameters of " + this) - parametersScope.setImplicitReceiver(implicitReceiver) + val parametersScope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.DO_NOTHING, "Parameters of " + this, implicitReceiver) for (valueParameterDescriptor in getScriptCodeDescriptor().getValueParameters()) { parametersScope.addVariableDescriptor(valueParameterDescriptor) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java index 612b28faede..cec5e0df1b2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java @@ -127,13 +127,11 @@ public final class JetScopeUtils { WritableScopeImpl result = new WritableScopeImpl( outerScope, propertyDescriptor, redeclarationHandler, "Property declaration inner scope", + receiver, addLabelForProperty ? propertyDescriptor : null); for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { result.addClassifierDescriptor(typeParameterDescriptor); } - if (receiver != null) { - result.setImplicitReceiver(receiver); - } result.changeLockLevel(WritableScope.LockLevel.READING); return result; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt index d33def2c732..69225fe4c70 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt @@ -36,7 +36,5 @@ public trait WritableScope : JetScope { public fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor) public fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor) - - public fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt index 1550feb62b9..c7f37b9726f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt @@ -37,24 +37,27 @@ public class WritableScopeImpl @jvmOverloads constructor( private val ownerDeclarationDescriptor: DeclarationDescriptor, private val redeclarationHandler: RedeclarationHandler, private val debugName: String, + implicitReceiver: ReceiverParameterDescriptor? = null, private val labeledDeclaration: DeclarationDescriptor? = null ) : AbstractScopeAdapter(), WritableScope { + override val workerScope: JetScope = if (outerScope is WritableScope) outerScope.takeSnapshot() else outerScope + private val addedDescriptors = SmartList() private var functionsByName: MutableMap? = null private var variablesAndClassifiersByName: MutableMap? = null - private var implicitReceiver: ReceiverParameterDescriptor? = null - private var implicitReceiverHierarchy: List? = null - - override fun getContainingDeclaration(): DeclarationDescriptor = ownerDeclarationDescriptor + private val implicitReceiverHierarchy = if (implicitReceiver != null) + listOf(implicitReceiver) + super.getImplicitReceiversHierarchy() + else + super.getImplicitReceiversHierarchy() private var lastSnapshot: Snapshot? = null private var lockLevel: WritableScope.LockLevel = WritableScope.LockLevel.WRITING - override val workerScope: JetScope = if (outerScope is WritableScope) outerScope.takeSnapshot() else outerScope + override fun getContainingDeclaration() = ownerDeclarationDescriptor override fun changeLockLevel(lockLevel: WritableScope.LockLevel): WritableScope { if (lockLevel.ordinal() < this.lockLevel.ordinal()) { @@ -170,30 +173,7 @@ public class WritableScopeImpl @jvmOverloads constructor( ?: workerScope.getClassifier(name) } - override fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor) { - checkMayWrite() - - if (this.implicitReceiver != null) { - throw UnsupportedOperationException("Receiver redeclared") - } - this.implicitReceiver = implicitReceiver - } - - override fun getImplicitReceiversHierarchy(): List { - checkMayRead() - - if (implicitReceiverHierarchy == null) { - implicitReceiverHierarchy = computeImplicitReceiversHierarchy() - } - return implicitReceiverHierarchy!! - } - - private fun computeImplicitReceiversHierarchy(): List { - return if (implicitReceiver != null) - listOf(implicitReceiver!!) + super.getImplicitReceiversHierarchy() - else - super.getImplicitReceiversHierarchy() - } + override fun getImplicitReceiversHierarchy() = implicitReceiverHierarchy override fun getOwnDeclaredDescriptors(): Collection = addedDescriptors