WritableScope: got rid of mutability of implicit receiver

This commit is contained in:
Valentin Kipyatkov
2015-06-12 15:36:56 +03:00
parent 32bfd53101
commit b20179af9f
7 changed files with 57 additions and 52 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.descriptors.impl; package org.jetbrains.kotlin.descriptors.impl;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; 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.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes { public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes {
private final ClassKind kind; private final ClassKind kind;
@@ -48,7 +46,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
private final Set<PropertyDescriptor> properties = Sets.newLinkedHashSet(); private final Set<PropertyDescriptor> properties = Sets.newLinkedHashSet();
private final Set<SimpleFunctionDescriptor> functions = Sets.newLinkedHashSet(); private final Set<SimpleFunctionDescriptor> functions = Sets.newLinkedHashSet();
private final WritableScope writableScopeForMemberResolution; private final MutableScopeForMemberResolution mutableScopeForMemberResolution;
private final JetScope scopeForMemberResolution; private final JetScope scopeForMemberResolution;
// This scope contains type parameters but does not contain inner classes // This scope contains type parameters but does not contain inner classes
private final WritableScope scopeForSupertypeResolution; private final WritableScope scopeForSupertypeResolution;
@@ -72,18 +70,17 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; 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)); .changeLockLevel(WritableScope.LockLevel.BOTH));
this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution") this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution")
.changeLockLevel(WritableScope.LockLevel.BOTH); .changeLockLevel(WritableScope.LockLevel.BOTH);
this.writableScopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution") this.mutableScopeForMemberResolution = new MutableScopeForMemberResolution();
.changeLockLevel(WritableScope.LockLevel.BOTH);
if (kind == ClassKind.INTERFACE) { if (kind == ClassKind.INTERFACE) {
setUpScopeForInitializers(this); setUpScopeForInitializers(this);
} }
this.scopeForMemberResolution = new ChainedScope(this, "MemberResolutionWithStatic", writableScopeForMemberResolution, staticScope); this.scopeForMemberResolution = new ChainedScope(this, "MemberResolutionWithStatic", mutableScopeForMemberResolution, staticScope);
} }
@Nullable @Nullable
@@ -227,7 +224,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
for (FunctionDescriptor functionDescriptor : getConstructors()) { for (FunctionDescriptor functionDescriptor : getConstructors()) {
((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
} }
writableScopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); mutableScopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter());
} }
@Override @Override
@@ -281,4 +278,41 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
public String toString() { public String toString() {
return DeclarationDescriptorImpl.toString(this); return DeclarationDescriptorImpl.toString(this);
} }
private class MutableScopeForMemberResolution extends AbstractScopeAdapter {
private ReceiverParameterDescriptor implicitReceiver = null;
private List<ReceiverParameterDescriptor> 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<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
if (implicitReceiversHierarchy != null)
return implicitReceiversHierarchy;
else
return super.getImplicitReceiversHierarchy();
}
}
} }
@@ -80,11 +80,8 @@ public class FunctionDescriptorUtil {
@NotNull FunctionDescriptor descriptor, @NotNull FunctionDescriptor descriptor,
@NotNull RedeclarationHandler redeclarationHandler @NotNull RedeclarationHandler redeclarationHandler
) { ) {
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function inner scope", descriptor);
ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter(); ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
if (receiver != null) { WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function inner scope", receiver, descriptor);
parameterScope.setImplicitReceiver(receiver);
}
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
parameterScope.addClassifierDescriptor(typeParameter); parameterScope.addClassifierDescriptor(typeParameter);
} }
@@ -266,8 +266,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@NotNull @NotNull
private JetScope computeScopeForMemberDeclarationResolution() { private JetScope computeScopeForMemberDeclarationResolution() {
WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, RedeclarationHandler.DO_NOTHING, WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, RedeclarationHandler.DO_NOTHING,
"Scope with 'this' for " + getName(), this); "Scope with 'this' for " + getName(), this.getThisAsReceiverParameter(), this);
thisScope.setImplicitReceiver(this.getThisAsReceiverParameter());
thisScope.changeLockLevel(WritableScope.LockLevel.READING); thisScope.changeLockLevel(WritableScope.LockLevel.READING);
return new ChainedScope( return new ChainedScope(
@@ -81,8 +81,7 @@ public class LazyScriptDescriptor(
override fun getScriptCodeDescriptor() = scriptCodeDescriptor() override fun getScriptCodeDescriptor() = scriptCodeDescriptor()
override fun getScopeForBodyResolution(): JetScope { override fun getScopeForBodyResolution(): JetScope {
val parametersScope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.DO_NOTHING, "Parameters of " + this) val parametersScope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.DO_NOTHING, "Parameters of " + this, implicitReceiver)
parametersScope.setImplicitReceiver(implicitReceiver)
for (valueParameterDescriptor in getScriptCodeDescriptor().getValueParameters()) { for (valueParameterDescriptor in getScriptCodeDescriptor().getValueParameters()) {
parametersScope.addVariableDescriptor(valueParameterDescriptor) parametersScope.addVariableDescriptor(valueParameterDescriptor)
} }
@@ -127,13 +127,11 @@ public final class JetScopeUtils {
WritableScopeImpl result = new WritableScopeImpl( WritableScopeImpl result = new WritableScopeImpl(
outerScope, propertyDescriptor, redeclarationHandler, outerScope, propertyDescriptor, redeclarationHandler,
"Property declaration inner scope", "Property declaration inner scope",
receiver,
addLabelForProperty ? propertyDescriptor : null); addLabelForProperty ? propertyDescriptor : null);
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
result.addClassifierDescriptor(typeParameterDescriptor); result.addClassifierDescriptor(typeParameterDescriptor);
} }
if (receiver != null) {
result.setImplicitReceiver(receiver);
}
result.changeLockLevel(WritableScope.LockLevel.READING); result.changeLockLevel(WritableScope.LockLevel.READING);
return result; return result;
} }
@@ -36,7 +36,5 @@ public trait WritableScope : JetScope {
public fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor) public fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor)
public fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor) public fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor)
public fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor)
} }
@@ -37,24 +37,27 @@ public class WritableScopeImpl @jvmOverloads constructor(
private val ownerDeclarationDescriptor: DeclarationDescriptor, private val ownerDeclarationDescriptor: DeclarationDescriptor,
private val redeclarationHandler: RedeclarationHandler, private val redeclarationHandler: RedeclarationHandler,
private val debugName: String, private val debugName: String,
implicitReceiver: ReceiverParameterDescriptor? = null,
private val labeledDeclaration: DeclarationDescriptor? = null private val labeledDeclaration: DeclarationDescriptor? = null
) : AbstractScopeAdapter(), WritableScope { ) : AbstractScopeAdapter(), WritableScope {
override val workerScope: JetScope = if (outerScope is WritableScope) outerScope.takeSnapshot() else outerScope
private val addedDescriptors = SmartList<DeclarationDescriptor>() private val addedDescriptors = SmartList<DeclarationDescriptor>()
private var functionsByName: MutableMap<Name, IntList>? = null private var functionsByName: MutableMap<Name, IntList>? = null
private var variablesAndClassifiersByName: MutableMap<Name, IntList>? = null private var variablesAndClassifiersByName: MutableMap<Name, IntList>? = null
private var implicitReceiver: ReceiverParameterDescriptor? = null private val implicitReceiverHierarchy = if (implicitReceiver != null)
private var implicitReceiverHierarchy: List<ReceiverParameterDescriptor>? = null listOf(implicitReceiver) + super<AbstractScopeAdapter>.getImplicitReceiversHierarchy()
else
override fun getContainingDeclaration(): DeclarationDescriptor = ownerDeclarationDescriptor super<AbstractScopeAdapter>.getImplicitReceiversHierarchy()
private var lastSnapshot: Snapshot? = null private var lastSnapshot: Snapshot? = null
private var lockLevel: WritableScope.LockLevel = WritableScope.LockLevel.WRITING 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 { override fun changeLockLevel(lockLevel: WritableScope.LockLevel): WritableScope {
if (lockLevel.ordinal() < this.lockLevel.ordinal()) { if (lockLevel.ordinal() < this.lockLevel.ordinal()) {
@@ -170,30 +173,7 @@ public class WritableScopeImpl @jvmOverloads constructor(
?: workerScope.getClassifier(name) ?: workerScope.getClassifier(name)
} }
override fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor) { override fun getImplicitReceiversHierarchy() = implicitReceiverHierarchy
checkMayWrite()
if (this.implicitReceiver != null) {
throw UnsupportedOperationException("Receiver redeclared")
}
this.implicitReceiver = implicitReceiver
}
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> {
checkMayRead()
if (implicitReceiverHierarchy == null) {
implicitReceiverHierarchy = computeImplicitReceiversHierarchy()
}
return implicitReceiverHierarchy!!
}
private fun computeImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> {
return if (implicitReceiver != null)
listOf(implicitReceiver!!) + super<AbstractScopeAdapter>.getImplicitReceiversHierarchy()
else
super<AbstractScopeAdapter>.getImplicitReceiversHierarchy()
}
override fun getOwnDeclaredDescriptors(): Collection<DeclarationDescriptor> = addedDescriptors override fun getOwnDeclaredDescriptors(): Collection<DeclarationDescriptor> = addedDescriptors