diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index a1135e9c65c..11c1bf1c810 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -220,26 +220,29 @@ public abstract class CodegenContext { else if(descriptor instanceof PropertyDescriptor) { PropertyDescriptor pd = (PropertyDescriptor) descriptor; PropertyDescriptor myAccessor = new PropertyDescriptor(contextType, - Collections.emptyList(), - pd.getModality(), - pd.getVisibility(), - pd.isVar(), - pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null, - pd.getExpectedThisObject(), - pd.getName() + "$bridge$" + accessors.size(), - pd.getInType(), - pd.getOutType()); + Collections.emptyList(), + pd.getModality(), + pd.getVisibility(), + pd.isVar(), + pd.getExpectedThisObject(), + pd.getName() + "$bridge$" + accessors.size() + ); + JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null; + myAccessor.setType(pd.getInType(), pd.getOutType(), Collections.emptyList(), receiverType); + PropertyGetterDescriptor pgd = new PropertyGetterDescriptor( myAccessor, Collections.emptyList(), myAccessor.getModality(), myAccessor.getVisibility(), - myAccessor.getOutType(), false, false); + false, false); + pgd.initialize(myAccessor.getOutType()); + PropertySetterDescriptor psd = new PropertySetterDescriptor( myAccessor.getModality(), myAccessor.getVisibility(), myAccessor, Collections.emptyList(), false, false); - myAccessor.initialize(Collections.emptyList(), pgd, psd); + myAccessor.initialize(pgd, psd); accessor = myAccessor; } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java index e4bc91d4854..8208b807e8f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java @@ -80,6 +80,7 @@ public class FunctionDescriptorUtil { parameterScope.addVariableDescriptor(valueParameterDescriptor); } parameterScope.addLabeledDeclaration(descriptor); + parameterScope.changeLockLevel(WritableScope.LockLevel.READING); return parameterScope; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 669af46b9ae..19ff65681ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -5,10 +5,13 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; @@ -34,10 +37,16 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme private Modality modality; private Visibility visibility; private TypeConstructor typeConstructor; + private final RedeclarationHandler redeclarationHandler; private final WritableScope scopeForMemberResolution; private final WritableScope scopeForMemberLookup; // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; + private final WritableScope scopeForAnyConstructor; + private final Map scopesForConstructors; + // for primary constructor and property initializers + private final WritableScope scopeForPrimaryConstructor; + private MutableClassDescriptor classObjectDescriptor; private JetType classObjectType; private JetType defaultType; @@ -48,9 +57,18 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { super(containingDeclaration); TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); + this.redeclarationHandler = redeclarationHandler; this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup"); + this.scopeForMemberLookup.changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution"); + this.scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler).setDebugName("MemberResolution"); + this.scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.BOTH); + this.scopeForAnyConstructor = new WritableScopeImpl(scopeForMemberResolution, this, redeclarationHandler).setDebugName("AnyConstrutor"); + this.scopeForAnyConstructor.changeLockLevel(WritableScope.LockLevel.BOTH); + this.scopeForPrimaryConstructor = new WritableScopeImpl(scopeForAnyConstructor, this, redeclarationHandler).setDebugName("PrimaryConstructor"); + this.scopeForPrimaryConstructor.changeLockLevel(WritableScope.LockLevel.BOTH); + this.scopesForConstructors = new HashMap(); this.kind = kind; } @@ -100,10 +118,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return classObjectDescriptor; } - public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { + public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; this.primaryConstructor = constructorDescriptor; - addConstructor(constructorDescriptor); + addConstructor(constructorDescriptor, trace); } @Override @@ -112,7 +130,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return primaryConstructor; } - public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { assert constructorDescriptor.getContainingDeclaration() == this; // assert constructorDescriptor.getTypeParameters().size() == getTypeConstructor().getValueParameters().size(); constructors.add(constructorDescriptor); @@ -120,6 +138,26 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme // constructorDescriptor.getTypeParameters().addAll(typeParameters); ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); } + + WritableScope scope = constructorDescriptor.isPrimary() ? + scopeForPrimaryConstructor : + new WritableScopeImpl(scopeForAnyConstructor, this, redeclarationHandler).setDebugName("SecondaryConstructor"); + + WritableScope old = scopesForConstructors.put(constructorDescriptor, scope); + if (old != null) { + throw new IllegalStateException(); + } + + for (ValueParameterDescriptor valueParameterDescriptor : constructorDescriptor.getValueParameters()) { + JetParameter parameter = (JetParameter) trace.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor); + if (parameter.getValOrVarNode() == null || !constructorDescriptor.isPrimary()) { + scope.addVariableDescriptor(valueParameterDescriptor); + } + } + + scope.addLabeledDeclaration(constructorDescriptor); // TODO : Labels for constructors?! + + scope.changeLockLevel(WritableScope.LockLevel.READING); } @Override @@ -128,6 +166,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme callableMembers.add(propertyDescriptor); scopeForMemberLookup.addVariableDescriptor(propertyDescriptor); scopeForMemberResolution.addVariableDescriptor(propertyDescriptor); + scopeForAnyConstructor.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); } @Override @@ -180,6 +219,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme this.typeParameters.add(typeParameterDescriptor); scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); } + scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -257,6 +297,16 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public JetScope getScopeForMemberResolution() { return scopeForMemberResolution; } + + @NotNull + public JetScope getScopeForConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { + return scopesForConstructors.get(constructorDescriptor); + } + + @NotNull + public JetScope getScopeForPropertyIntiailizer() { + return scopeForPrimaryConstructor; + } @NotNull @Override @@ -344,4 +394,20 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme } return implicitReceiver; } + + public void lockScopes() { + scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); + scopeForMemberLookup.changeLockLevel(WritableScope.LockLevel.READING); + scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); + scopeForAnyConstructor.changeLockLevel(WritableScope.LockLevel.READING); + scopeForPrimaryConstructor.changeLockLevel(WritableScope.LockLevel.READING); + for (WritableScope scope : scopesForConstructors.values()) { + scope.changeLockLevel(WritableScope.LockLevel.READING); + } + + if (classObjectDescriptor != null) { + classObjectDescriptor.lockScopes(); + } + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java index 27768fa2b22..30f49dbfd31 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.Variance; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -24,12 +25,13 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab private final Modality modality; private final Visibility visibility; private final boolean isVar; - private final ReceiverDescriptor receiver; private final ReceiverDescriptor expectedThisObject; private final Set overriddenProperties = Sets.newLinkedHashSet(); private final Set overridingProperties = Sets.newLinkedHashSet(); - private final List typeParemeters = Lists.newArrayListWithCapacity(0); private final PropertyDescriptor original; + + private ReceiverDescriptor receiver; + private List typeParemeters; private PropertyGetterDescriptor getter; private PropertySetterDescriptor setter; @@ -40,22 +42,28 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab @NotNull Modality modality, @NotNull Visibility visibility, boolean isVar, - @Nullable JetType receiverType, @NotNull ReceiverDescriptor expectedThisObject, - @NotNull String name, - @Nullable JetType inType, - @NotNull JetType outType) { - super(containingDeclaration, annotations, name, inType, outType); - assert !isVar || inType != null; + @NotNull String name) { + super(containingDeclaration, annotations, name); // assert outType != null; this.isVar = isVar; this.modality = modality; this.visibility = visibility; - this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType); this.expectedThisObject = expectedThisObject; this.original = original == null ? this : original.getOriginal(); } + public PropertyDescriptor( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull List annotations, + @NotNull Modality modality, + @NotNull Visibility visibility, + boolean isVar, + @NotNull ReceiverDescriptor expectedThisObject, + @NotNull String name) { + this(null, containingDeclaration, annotations, modality, visibility, isVar, expectedThisObject, name); + } + public PropertyDescriptor( @NotNull DeclarationDescriptor containingDeclaration, @NotNull List annotations, @@ -66,8 +74,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab @NotNull ReceiverDescriptor expectedThisObject, @NotNull String name, @Nullable JetType inType, - @NotNull JetType outType) { - this(null, containingDeclaration, annotations, modality, visibility, isVar, receiverType, expectedThisObject, name, inType, outType); + @NotNull JetType outType + ) + { + this(containingDeclaration, annotations, modality, visibility, isVar, expectedThisObject, name); + setType(inType, outType, Collections.emptyList(), receiverType); } private PropertyDescriptor( @@ -75,7 +86,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab @Nullable JetType receiverType, @NotNull ReceiverDescriptor expectedThisObject, @Nullable JetType inType, - @NotNull JetType outType) { + @NotNull JetType outType + ) + { this( original, original.getContainingDeclaration(), @@ -83,15 +96,38 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab original.getModality(), original.getVisibility(), original.isVar, - receiverType, expectedThisObject, - original.getName(), - inType, - outType); + original.getName() + ); + setType(inType, outType, Collections.emptyList(), receiverType); } - public void initialize(@NotNull List typeParameters, @Nullable PropertyGetterDescriptor getter, @Nullable PropertySetterDescriptor setter) { - this.typeParemeters.addAll(typeParameters); + public void setType(@Nullable JetType inType, @NotNull JetType outType, + @NotNull List typeParameters, + @Nullable JetType receiverType + ) + { + ReceiverDescriptor receiver = receiverType == null + ? ReceiverDescriptor.NO_RECEIVER + : new ExtensionReceiver(this, receiverType); + setType(inType, outType, typeParameters, receiver); + } + + public void setType(@Nullable JetType inType, @NotNull JetType outType, + @NotNull List typeParameters, @NotNull ReceiverDescriptor receiver) + { + assert !isVar || inType != null; + setInType(inType); + setOutType(outType); + + this.typeParemeters = typeParameters; + + this.receiver = receiver; + } + + public void initialize( + @Nullable PropertyGetterDescriptor getter, @Nullable PropertySetterDescriptor setter) + { this.getter = getter; this.setter = setter; } @@ -209,20 +245,24 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab newOwner, Lists.newArrayList(getAnnotations()), DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, - receiver.exists() ? receiver.getType() : null, expectedThisObject, - getName(), getInType(), getOutType()); + getName()); + + propertyDescriptor.setType(getInType(), getOutType(), DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), receiver.exists() ? receiver.getType() : null); + PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor( propertyDescriptor, Lists.newArrayList(getter.getAnnotations()), DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(), - getter.getReturnType(), getter.hasBody(), getter.isDefault()); + if (newGetter != null) { + newGetter.initialize(getter.getReturnType()); + } PropertySetterDescriptor newSetter = setter == null ? null : new PropertySetterDescriptor( DescriptorUtils.convertModality(setter.getModality(), makeNonAbstract), setter.getVisibility(), propertyDescriptor, Lists.newArrayList(setter.getAnnotations()), setter.hasBody(), setter.isDefault()); - propertyDescriptor.initialize(DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), newGetter, newSetter); + propertyDescriptor.initialize(newGetter, newSetter); return propertyDescriptor; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java index 095254c7f3d..2574235361c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java @@ -17,9 +17,14 @@ import java.util.Set; public class PropertyGetterDescriptor extends PropertyAccessorDescriptor { private JetType returnType; - public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, @NotNull Modality modality, @NotNull Visibility visibility, @Nullable JetType returnType, boolean hasBody, boolean isDefault) { + public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, + @NotNull Modality modality, @NotNull Visibility visibility, boolean hasBody, boolean isDefault) + { super(modality, visibility, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault); - this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType; + } + + public void initialize(JetType returnType) { + this.returnType = returnType == null ? getCorrespondingProperty().getOutType() : returnType; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java index 7319cb5ce3b..f0590c49604 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java @@ -17,7 +17,10 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor { private MutableValueParameterDescriptor parameter; - public PropertySetterDescriptor(@NotNull Modality modality, @NotNull Visibility visibility, @NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, boolean hasBody, boolean isDefault) { + public PropertySetterDescriptor(@NotNull Modality modality, @NotNull Visibility visibility, + @NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, + boolean hasBody, boolean isDefault) + { super(modality, visibility, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java index 9ff1027e6c6..a8038dd3bba 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java @@ -30,6 +30,15 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i this.outType = outType; } + protected VariableDescriptorImpl( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull List annotations, + @NotNull String name + ) + { + super(containingDeclaration, annotations, name); + } + @Override public JetType getOutType() { return outType; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index da5cb3020b5..13cb17841bc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -96,6 +96,7 @@ public class AnalyzingUtils { final WritableScope scope = new WritableScopeImpl(JetScope.EMPTY, owner, new TraceBasedRedeclarationHandler(bindingTraceContext)).setDebugName("Root scope in analyzeNamespace"); importingStrategy.addImports(project, semanticServices, bindingTraceContext, scope); scope.importScope(libraryScope); + scope.changeLockLevel(WritableScope.LockLevel.BOTH); TopDownAnalyzer.process(semanticServices, bindingTraceContext, scope, new NamespaceLike.Adapter(owner) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index dd45fdd7af9..d6c8a64c8df 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -100,7 +100,7 @@ public class BodyResolver { final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor(); final JetScope scopeForConstructor = primaryConstructor == null ? null - : getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true); + : getInnerScopeForConstructor(primaryConstructor); final ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); // TODO : flow final Map supertypes = Maps.newLinkedHashMap(); @@ -267,7 +267,7 @@ public class BodyResolver { if (jetClassOrObject.hasPrimaryConstructor()) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); assert primaryConstructor != null; - final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true); + final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor); ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); for (JetClassInitializer anonymousInitializer : anonymousInitializers) { typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE); @@ -293,7 +293,7 @@ public class BodyResolver { private void resolveSecondaryConstructorBody(JetSecondaryConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) { if (!context.completeAnalysisNeeded(declaration)) return; - final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false); + final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor); final CallResolver callResolver = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY); // TODO: dataFlowInfo @@ -366,24 +366,9 @@ public class BodyResolver { } @NotNull - private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) { - WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Inner scope for constructor"); - for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) { - constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); - } - -// constructorScope.setImplicitReceiver(new ClassReceiver(descriptor.getContainingDeclaration())); - - for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) { - JetParameter parameter = (JetParameter) context.getTrace().getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor); - if (parameter.getValOrVarNode() == null || !primary) { - constructorScope.addVariableDescriptor(valueParameterDescriptor); - } - } - - constructorScope.addLabeledDeclaration(descriptor); // TODO : Labels for constructors?! - - return constructorScope; + private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor) { + MutableClassDescriptor mutableClassDescriptor = (MutableClassDescriptor) descriptor.getContainingDeclaration(); + return mutableClassDescriptor.getScopeForConstructor(descriptor); } private void resolvePropertyDeclarationBodies() { @@ -399,18 +384,16 @@ public class BodyResolver { final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property); assert propertyDescriptor != null; - JetScope declaringScope = this.context.getDeclaringScopes().get(property); - JetExpression initializer = property.getInitializer(); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { - JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true); - resolvePropertyInitializer(property, propertyDescriptor, initializer, scope); + JetScope declaringScopeForPropertyInitializer = this.context.getDeclaringScopes().get(property); + resolvePropertyInitializer(property, propertyDescriptor, initializer, declaringScopeForPropertyInitializer); } } - resolvePropertyAccessors(property, propertyDescriptor, declaringScope); + resolvePropertyAccessors(property, propertyDescriptor); processed.add(property); } } @@ -429,37 +412,36 @@ public class BodyResolver { resolvePropertyInitializer(property, propertyDescriptor, initializer, declaringScope); } - resolvePropertyAccessors(property, propertyDescriptor, declaringScope); + resolvePropertyAccessors(property, propertyDescriptor); } } + + private JetScope makeScopeForPropertyAccessor(@NotNull JetPropertyAccessor accessor, PropertyDescriptor propertyDescriptor) { + JetScope declaringScope = context.getDeclaringScopes().get(accessor); - private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) { - WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Property declaration inner scope"); - for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) { - result.addTypeParameterDescriptor(typeParameterDescriptor); - } - ReceiverDescriptor receiver = propertyDescriptor.getReceiverParameter(); - if (receiver.exists()) { - result.setImplicitReceiver(receiver); - } - return result; - } - - private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) { - ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); - - WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Accessor scope"); + JetScope propertyDeclarationInnerScope = context.getDescriptorResolver().getPropertyDeclarationInnerScope( + declaringScope, propertyDescriptor, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter()); + WritableScope accessorScope = new WritableScopeImpl(propertyDeclarationInnerScope, declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Accessor scope"); accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); + accessorScope.changeLockLevel(WritableScope.LockLevel.READING); + + return accessorScope; + } + + private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) { + ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); JetPropertyAccessor getter = property.getGetter(); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); if (getter != null && getterDescriptor != null) { + JetScope accessorScope = makeScopeForPropertyAccessor(getter, propertyDescriptor); resolveFunctionBody(fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope); } JetPropertyAccessor setter = property.getSetter(); PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); if (setter != null && setterDescriptor != null) { + JetScope accessorScope = makeScopeForPropertyAccessor(setter, propertyDescriptor); resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope); } } @@ -485,7 +467,7 @@ public class BodyResolver { //JetFlowInformationProvider flowInformationProvider = context.getDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); JetType expectedTypeForInitializer = property.getPropertyTypeRef() != null ? propertyDescriptor.getOutType() : NO_EXPECTED_TYPE; - JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, expectedTypeForInitializer); + JetType type = typeInferrer.getType(context.getDescriptorResolver().getPropertyDeclarationInnerScope(scope, propertyDescriptor, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter()), initializer, expectedTypeForInitializer); // // JetType expectedType = propertyDescriptor.getInType(); // if (expectedType == null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index 8c645412d1f..66de67baa15 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -67,13 +67,15 @@ public class DeclarationResolver { WritableScope namespaceScope = entry.getValue(); NamespaceLike namespaceDescriptor = context.getNamespaceDescriptors().get(namespace); - resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor); + resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceScope, namespaceScope, namespaceDescriptor); } for (Map.Entry entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); - resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor); + resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), + classDescriptor.getScopeForPropertyIntiailizer(), classDescriptor.getScopeForMemberResolution(), + classDescriptor); // processPrimaryConstructor(classDescriptor, jetClass); // for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) { // processSecondaryConstructor(classDescriptor, jetConstructor); @@ -83,29 +85,41 @@ public class DeclarationResolver { JetObjectDeclaration object = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); - resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor); + resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(), + classDescriptor.getScopeForPropertyIntiailizer(), classDescriptor.getScopeForMemberResolution(), + classDescriptor); } // TODO : Extensions } - private void resolveFunctionAndPropertyHeaders(@NotNull List declarations, final @NotNull JetScope scope, final @NotNull NamespaceLike namespaceLike) { + private void resolveFunctionAndPropertyHeaders(@NotNull List declarations, + final @NotNull JetScope scopeForFunctions, + final @NotNull JetScope scopeForPropertyInitializers, final @NotNull JetScope scopeForPropertyAccessors, + final @NotNull NamespaceLike namespaceLike) + { for (JetDeclaration declaration : declarations) { declaration.accept(new JetVisitorVoid() { @Override public void visitNamedFunction(JetNamedFunction function) { - FunctionDescriptorImpl functionDescriptor = context.getDescriptorResolver().resolveFunctionDescriptor(namespaceLike, scope, function); + FunctionDescriptorImpl functionDescriptor = context.getDescriptorResolver().resolveFunctionDescriptor(namespaceLike, scopeForFunctions, function); namespaceLike.addFunctionDescriptor(functionDescriptor); context.getFunctions().put(function, functionDescriptor); - context.getDeclaringScopes().put(function, scope); + context.getDeclaringScopes().put(function, scopeForFunctions); } @Override public void visitProperty(JetProperty property) { - PropertyDescriptor propertyDescriptor = context.getDescriptorResolver().resolvePropertyDescriptor(namespaceLike, scope, property); + PropertyDescriptor propertyDescriptor = context.getDescriptorResolver().resolvePropertyDescriptor(namespaceLike, scopeForPropertyInitializers, property); namespaceLike.addPropertyDescriptor(propertyDescriptor); context.getProperties().put(property, propertyDescriptor); - context.getDeclaringScopes().put(property, scope); + context.getDeclaringScopes().put(property, scopeForPropertyInitializers); + if (property.getGetter() != null) { + context.getDeclaringScopes().put(property.getGetter(), scopeForPropertyAccessors); + } + if (property.getSetter() != null) { + context.getDeclaringScopes().put(property.getSetter(), scopeForPropertyAccessors); + } } @Override @@ -150,7 +164,7 @@ public class DeclarationResolver { } } if (constructorDescriptor != null) { - classDescriptor.setPrimaryConstructor(constructorDescriptor); + classDescriptor.setPrimaryConstructor(constructorDescriptor, context.getTrace()); } } @@ -163,7 +177,7 @@ public class DeclarationResolver { classDescriptor.getScopeForMemberResolution(), classDescriptor, constructor); - classDescriptor.addConstructor(constructorDescriptor); + classDescriptor.addConstructor(constructorDescriptor, context.getTrace()); context.getConstructors().put(constructor, constructorDescriptor); context.getDeclaringScopes().put(constructor, classDescriptor.getScopeForMemberLookup()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 8be709898fd..87b1f0a72b2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -15,6 +15,8 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.util.lazy.LazyValue; @@ -146,6 +148,7 @@ public class DescriptorResolver { innerScope.addLabeledDeclaration(functionDescriptor); List typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters()); + innerScope.changeLockLevel(WritableScope.LockLevel.BOTH); resolveGenericBounds(function, innerScope, typeParameterDescriptors); JetType receiverType = null; @@ -160,6 +163,8 @@ public class DescriptorResolver { List valueParameterDescriptors = resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters()); + innerScope.changeLockLevel(WritableScope.LockLevel.READING); + JetTypeReference returnTypeRef = function.getReturnTypeRef(); JetType returnType; if (returnTypeRef != null) { @@ -470,16 +475,12 @@ public class DescriptorResolver { Modality.FINAL, resolveVisibilityFromModifiers(objectDeclaration.getModifierList()), false, - null, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), - JetPsiUtil.safeName(objectDeclaration.getName()), - null, - classDescriptor.getDefaultType()); + JetPsiUtil.safeName(objectDeclaration.getName()) + ); - propertyDescriptor.initialize( - Collections.emptyList(), - null, // TODO : is it really OK? - null); + propertyDescriptor.setType(null, classDescriptor.getDefaultType(), Collections.emptyList(), ReceiverDescriptor.NO_RECEIVER); + propertyDescriptor.initialize(null, null); JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration(); if (nameAsDeclaration != null) { @@ -488,33 +489,27 @@ public class DescriptorResolver { return propertyDescriptor; } + public JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, + @NotNull PropertyDescriptor propertyDescriptor, List typeParameters, + ReceiverDescriptor receiver) + { + WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Property declaration inner scope"); + for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { + result.addTypeParameterDescriptor(typeParameterDescriptor); + } + if (receiver.exists()) { + result.setImplicitReceiver(receiver); + } + result.changeLockLevel(WritableScope.LockLevel.READING); + return result; + } + @NotNull public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) { - JetScope scopeWithTypeParameters; - List typeParameterDescriptors; - List typeParameters = property.getTypeParameters(); - if (typeParameters.isEmpty()) { - scopeWithTypeParameters = scope; - typeParameterDescriptors = Collections.emptyList(); - } - else { - WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with type parameters of a property"); - typeParameterDescriptors = resolveTypeParameters(containingDeclaration, writableScope, typeParameters); - resolveGenericBounds(property, writableScope, typeParameterDescriptors); - scopeWithTypeParameters = writableScope; - } - - JetType receiverType = null; - JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); - if (receiverTypeRef != null) { - receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef); - } JetModifierList modifierList = property.getModifierList(); boolean isVar = property.isVar(); - JetType type = getVariableType(scopeWithTypeParameters, property, true); - boolean hasBody = hasBody(property); Modality defaultModality = getDefaultModality(containingDeclaration, hasBody); PropertyDescriptor propertyDescriptor = new PropertyDescriptor( @@ -523,16 +518,49 @@ public class DescriptorResolver { resolveModalityFromModifiers(property.getModifierList(), defaultModality), resolveVisibilityFromModifiers(property.getModifierList()), isVar, - receiverType, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), - JetPsiUtil.safeName(property.getName()), - isVar ? type : null, - type); + JetPsiUtil.safeName(property.getName()) + ); - propertyDescriptor.initialize( - typeParameterDescriptors, - resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor), - resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor)); + List typeParameterDescriptors; + JetScope scopeWithTypeParameters; + JetType receiverType = null; + + { + List typeParameters = property.getTypeParameters(); + if (typeParameters.isEmpty()) { + scopeWithTypeParameters = scope; + typeParameterDescriptors = Collections.emptyList(); + } + else { + WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with type parameters of a property"); + typeParameterDescriptors = resolveTypeParameters(containingDeclaration, writableScope, typeParameters); + writableScope.changeLockLevel(WritableScope.LockLevel.READING); + resolveGenericBounds(property, writableScope, typeParameterDescriptors); + scopeWithTypeParameters = writableScope; + } + + JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); + if (receiverTypeRef != null) { + receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef); + } + } + + ReceiverDescriptor receiverDescriptor = receiverType == null + ? ReceiverDescriptor.NO_RECEIVER + : new ExtensionReceiver(propertyDescriptor, receiverType); + + JetScope scope2 = getPropertyDeclarationInnerScope(scope, propertyDescriptor, typeParameterDescriptors, receiverDescriptor); + + JetType type = getVariableType(scope2, property, true); + + JetType inType = isVar ? type : null; + propertyDescriptor.setType(inType, type, typeParameterDescriptors, receiverDescriptor); + + PropertyGetterDescriptor getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor); + PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor); + + propertyDescriptor.initialize(getter, setter); trace.record(BindingContext.VARIABLE, property, propertyDescriptor); return propertyDescriptor; @@ -724,7 +752,8 @@ public class DescriptorResolver { getterDescriptor = new PropertyGetterDescriptor( propertyDescriptor, annotations, resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()), resolveVisibilityFromModifiers(getter.getModifierList(), propertyDescriptor.getVisibility()), - returnType, getter.getBodyExpression() != null, false); + getter.getBodyExpression() != null, false); + getterDescriptor.initialize(returnType); trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor); } else { @@ -738,7 +767,7 @@ public class DescriptorResolver { getterDescriptor = new PropertyGetterDescriptor( propertyDescriptor, Collections.emptyList(), propertyDescriptor.getModality(), propertyDescriptor.getVisibility(), - propertyDescriptor.getOutType(), false, true); + false, true); return getterDescriptor; } @@ -761,11 +790,13 @@ public class DescriptorResolver { isPrimary ); trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor); + WritableScopeImpl parameterScope = new WritableScopeImpl(scope, classDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with value parameters of a constructor"); + parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH); return constructorDescriptor.initialize( typeParameters, resolveValueParameters( constructorDescriptor, - new WritableScopeImpl(scope, classDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with value parameters of a constructor"), + parameterScope, valueParameters), Modality.FINAL, resolveVisibilityFromModifiers(modifierList)); @@ -807,12 +838,17 @@ public class DescriptorResolver { resolveModalityFromModifiers(parameter.getModifierList(), Modality.FINAL), resolveVisibilityFromModifiers(parameter.getModifierList()), isMutable, - null, DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), - name == null ? "" : name, - isMutable ? type : null, - type); - propertyDescriptor.initialize(Collections.emptyList(), createDefaultGetter(propertyDescriptor), createDefaultSetter(propertyDescriptor)); + name == null ? "" : name + ); + PropertyGetterDescriptor getter = createDefaultGetter(propertyDescriptor); + PropertySetterDescriptor setter = createDefaultSetter(propertyDescriptor); + + JetType inType = isMutable ? type : null; + propertyDescriptor.setType(inType, type, Collections.emptyList(), ReceiverDescriptor.NO_RECEIVER); + propertyDescriptor.initialize(getter, setter); + getter.initialize(propertyDescriptor.getOutType()); + trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor); return propertyDescriptor; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index e6a9f31e64d..5e311a37bd8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -60,6 +60,7 @@ public class TopDownAnalyzer { new TypeHierarchyResolver(context).process(outerScope, owner, declarations); new DeclarationResolver(context).process(); new DelegationResolver(context).process(); + lockScopes(context); new OverrideResolver(context).process(); new OverloadResolver(context).process(); if (!context.analyzingBootstrapLibrary()) { @@ -72,6 +73,18 @@ public class TopDownAnalyzer { context.printDebugOutput(System.out); } + private static void lockScopes(TopDownAnalysisContext context) { + for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) { + mutableClassDescriptor.lockScopes(); + } + for (MutableClassDescriptor mutableClassDescriptor : context.getObjects().values()) { + mutableClassDescriptor.lockScopes(); + } + for (WritableScope namespaceScope : context.getNamespaceScopes().values()) { + namespaceScope.changeLockLevel(WritableScope.LockLevel.READING); + } + } + public static void processStandardLibraryNamespace( @NotNull JetSemanticServices semanticServices, @NotNull BindingTrace trace, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 61d117433f4..49fb12d2294 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -73,6 +73,7 @@ public class TypeHierarchyResolver { context.getNamespaceDescriptors().put(namespace, namespaceDescriptor); WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); + namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH); context.getNamespaceScopes().put(namespace, namespaceScope); context.getDeclaringScopes().put(namespace, outerScope); @@ -147,7 +148,7 @@ public class TypeHierarchyResolver { constructorDescriptor.initialize(Collections.emptyList(), Collections.emptyList(), Modality.FINAL, Visibility.INTERNAL);//TODO check set mutableClassDescriptor.getVisibility() // TODO : make the constructor private? - mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor); + mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, context.getTrace()); if (object != null) { context.getTrace().record(CONSTRUCTOR, object, constructorDescriptor); } @@ -210,7 +211,9 @@ public class TypeHierarchyResolver { Collections.emptyList(), // TODO: annotations name ); - namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope")); + WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope"); + scope.changeLockLevel(WritableScope.LockLevel.BOTH); + namespaceDescriptor.initialize(scope); owner.addNamespace(namespaceDescriptor); if (namespace != null) { context.getTrace().record(BindingContext.NAMESPACE, namespace, namespaceDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java index f56816079fb..4716d808cc0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java @@ -9,6 +9,14 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; * @author abreslav */ public interface WritableScope extends JetScope { + enum LockLevel { + WRITING, + BOTH, + READING, + } + + void changeLockLevel(LockLevel lockLevel); + void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor); void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index ed1febfd63a..bacaa26ea9e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -55,17 +55,22 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void importScope(@NotNull JetScope imported) { + checkMayWrite(); super.importScope(imported); } @Override public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) { + checkMayWrite(); + allDescriptors.add(classifierDescriptor); super.importClassifierAlias(importedClassifierName, classifierDescriptor); } @Override public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + allDescriptors.add(namespaceDescriptor); super.importNamespaceAlias(aliasName, namespaceDescriptor); } @@ -73,6 +78,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @NotNull @Override public Collection getAllDescriptors() { + checkMayRead(); + if (!allDescriptorsDone) { allDescriptorsDone = true; allDescriptors.addAll(getWorkerScope().getAllDescriptors()); @@ -94,6 +101,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @NotNull @Override public Collection getDeclarationsByLabel(@NotNull String labelName) { + checkMayRead(); + Collection superResult = super.getDeclarationsByLabel(labelName); Map> labelsToDescriptors = getLabelsToDescriptors(); List declarationDescriptors = labelsToDescriptors.get(labelName); @@ -108,6 +117,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) { + checkMayWrite(); + Map> labelsToDescriptors = getLabelsToDescriptors(); String name = descriptor.getName(); assert name != null; @@ -137,6 +148,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) { + checkMayWrite(); + Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor existingDescriptor = variableClassOrNamespaceDescriptors.get(variableDescriptor.getName()); if (existingDescriptor != null) { @@ -149,6 +162,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public VariableDescriptor getVariable(@NotNull String name) { + checkMayRead(); + Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor descriptor = variableClassOrNamespaceDescriptors.get(name); if (descriptor instanceof VariableDescriptor) { @@ -172,6 +187,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { + checkMayWrite(); + getFunctionGroups().put(functionDescriptor.getName(), functionDescriptor); allDescriptors.add(functionDescriptor); } @@ -179,6 +196,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override @NotNull public Set getFunctions(@NotNull String name) { + checkMayRead(); + Set result = Sets.newLinkedHashSet(getFunctionGroups().get(name)); result.addAll(getWorkerScope().getFunctions(name)); @@ -190,17 +209,23 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) { + checkMayWrite(); + String name = typeParameterDescriptor.getName(); addClassifierAlias(name, typeParameterDescriptor); } @Override public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) { + checkMayWrite(); + addClassifierAlias(classDescriptor.getName(), classDescriptor); } @Override public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) { + checkMayWrite(); + checkForRedeclaration(name, classifierDescriptor); getVariableClassOrNamespaceDescriptors().put(name, classifierDescriptor); allDescriptors.add(classifierDescriptor); @@ -208,6 +233,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + checkForRedeclaration(name, namespaceDescriptor); getNamespaceAliases().put(name, namespaceDescriptor); allDescriptors.add(namespaceDescriptor); @@ -222,6 +249,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public ClassifierDescriptor getClassifier(@NotNull String name) { + checkMayRead(); + Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor descriptor = variableClassOrNamespaceDescriptors.get(name); if (descriptor instanceof ClassifierDescriptor) return (ClassifierDescriptor) descriptor; @@ -234,6 +263,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor oldValue = variableClassOrNamespaceDescriptors.put(namespaceDescriptor.getName(), namespaceDescriptor); if (oldValue != null) { @@ -244,6 +275,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public NamespaceDescriptor getDeclaredNamespace(@NotNull String name) { + checkMayRead(); + Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor namespaceDescriptor = variableClassOrNamespaceDescriptors.get(name); if (namespaceDescriptor instanceof NamespaceDescriptor) return (NamespaceDescriptor) namespaceDescriptor; @@ -252,6 +285,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public NamespaceDescriptor getNamespace(@NotNull String name) { + checkMayRead(); + NamespaceDescriptor declaredNamespace = getDeclaredNamespace(name); if (declaredNamespace != null) return declaredNamespace; @@ -266,6 +301,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @NotNull @Override public ReceiverDescriptor getImplicitReceiver() { + checkMayRead(); + if (implicitReceiver == null) { return super.getImplicitReceiver(); } @@ -274,6 +311,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) { + checkMayWrite(); + if (this.implicitReceiver != null) { throw new UnsupportedOperationException("Receiver redeclared"); } @@ -282,6 +321,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void getImplicitReceiversHierarchy(@NotNull List result) { + checkMayRead(); + if (implicitReceiver != null && implicitReceiver.exists()) { result.add(implicitReceiver); } @@ -299,6 +340,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor) { + checkMayWrite(); + if (!fieldName.startsWith("$")) { throw new IllegalStateException(); } @@ -308,6 +351,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) { + checkMayRead(); + if (!fieldName.startsWith("$")) { throw new IllegalStateException(); } @@ -318,6 +363,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { } public List getDeclaredVariables() { + checkMayRead(); + List result = Lists.newArrayList(); for (DeclarationDescriptor descriptor : getVariableClassOrNamespaceDescriptors().values()) { if (descriptor instanceof VariableDescriptor) { @@ -334,6 +381,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public WritableScopeImpl setDebugName(@NotNull String debugName) { + checkMayWrite(); + super.setDebugName(debugName); return this; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index 97cdb1df602..ecca869bd2c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -31,7 +31,36 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement this.redeclarationHandler = redeclarationHandler; } + + + private LockLevel lockLevel = LockLevel.WRITING; + + @Override + public void changeLockLevel(LockLevel lockLevel) { + if (lockLevel.ordinal() < this.lockLevel.ordinal()) { + throw new IllegalStateException("cannot lower lock level from " + this.lockLevel + " to " + lockLevel); + } + this.lockLevel = lockLevel; + } + + protected void checkMayRead() { + if (lockLevel != LockLevel.READING && lockLevel != LockLevel.BOTH) { + throw new IllegalStateException("cannot read with lock level " + lockLevel); + } + } + + protected void checkMayWrite() { + if (lockLevel != LockLevel.WRITING && lockLevel != LockLevel.BOTH) { + throw new IllegalStateException("cannot write with lock level " + lockLevel); + } + } + + + + public WritableScopeWithImports setDebugName(@NotNull String debugName) { + checkMayWrite(); + assert this.debugName == null : this.debugName; this.debugName = debugName; return this; @@ -47,12 +76,16 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Override public void importScope(@NotNull JetScope imported) { + checkMayWrite(); + getImports().add(0, imported); currentIndividualImportScope = null; } @Override public void getImplicitReceiversHierarchy(@NotNull List result) { + checkMayRead(); + super.getImplicitReceiversHierarchy(result); // Imported scopes come with their receivers // Example: class member resolution scope imports a scope of it's class object @@ -67,6 +100,8 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Override public VariableDescriptor getVariable(@NotNull String name) { + checkMayRead(); + // Meaningful lookup goes here for (JetScope imported : getImports()) { VariableDescriptor importedDescriptor = imported.getVariable(name); @@ -80,6 +115,8 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @NotNull @Override public Set getFunctions(@NotNull String name) { + checkMayRead(); + if (getImports().isEmpty()) { return Collections.emptySet(); } @@ -92,6 +129,8 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Override public ClassifierDescriptor getClassifier(@NotNull String name) { + checkMayRead(); + for (JetScope imported : getImports()) { ClassifierDescriptor importedClassifier = imported.getClassifier(name); if (importedClassifier != null) { @@ -103,6 +142,8 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Override public NamespaceDescriptor getNamespace(@NotNull String name) { + checkMayRead(); + for (JetScope imported : getImports()) { NamespaceDescriptor importedDescriptor = imported.getNamespace(name); if (importedDescriptor != null) { @@ -115,6 +156,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement private WritableScope getCurrentIndividualImportScope() { if (currentIndividualImportScope == null) { WritableScopeImpl writableScope = new WritableScopeImpl(EMPTY, getContainingDeclaration(), RedeclarationHandler.DO_NOTHING).setDebugName("Individual import scope"); + writableScope.changeLockLevel(LockLevel.BOTH); importScope(writableScope); currentIndividualImportScope = writableScope; } @@ -123,12 +165,16 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Override public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) { + checkMayWrite(); + getCurrentIndividualImportScope().addClassifierAlias(importedClassifierName, classifierDescriptor); } @Override public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + getCurrentIndividualImportScope().addNamespaceAlias(aliasName, namespaceDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index 9c3a2abc7e6..c00a3e04547 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -25,30 +25,40 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @Nullable public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) { + checkMayRead(); + return writableWorker.getPropertyByFieldReference(fieldName); } @Override @NotNull public Collection getDeclarationsByLabel(String labelName) { + checkMayRead(); + return writableWorker.getDeclarationsByLabel(labelName); } @Override @NotNull public DeclarationDescriptor getContainingDeclaration() { + checkMayRead(); + return writableWorker.getContainingDeclaration(); } @Override @NotNull public ReceiverDescriptor getImplicitReceiver() { + checkMayRead(); + return writableWorker.getImplicitReceiver(); } @Override @NotNull public Set getFunctions(@NotNull String name) { + checkMayRead(); + Set result = Sets.newLinkedHashSet(); result.addAll(writableWorker.getFunctions(name)); @@ -63,6 +73,8 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @Nullable public VariableDescriptor getVariable(@NotNull String name) { + checkMayRead(); + VariableDescriptor variable = writableWorker.getVariable(name); if (variable != null) return variable; @@ -75,6 +87,8 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @Nullable public NamespaceDescriptor getNamespace(@NotNull String name) { + checkMayRead(); + NamespaceDescriptor namespace = writableWorker.getNamespace(name); if (namespace != null) return namespace; @@ -87,6 +101,8 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @Nullable public ClassifierDescriptor getClassifier(@NotNull String name) { + checkMayRead(); + ClassifierDescriptor classifier = writableWorker.getClassifier(name); if (classifier != null) return classifier; @@ -98,68 +114,94 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) { + checkMayWrite(); + writableWorker.addLabeledDeclaration(descriptor); // TODO : review } @Override public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) { + checkMayWrite(); + writableWorker.addVariableDescriptor(variableDescriptor); } @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { + checkMayWrite(); + writableWorker.addFunctionDescriptor(functionDescriptor); } @Override public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) { + checkMayWrite(); + writableWorker.addTypeParameterDescriptor(typeParameterDescriptor); } @Override public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) { + checkMayWrite(); + writableWorker.addClassifierDescriptor(classDescriptor); } @Override public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) { + checkMayWrite(); + writableWorker.addClassifierAlias(name, classifierDescriptor); } @Override public void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + writableWorker.addNamespaceAlias(name, namespaceDescriptor); } @Override public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + checkMayWrite(); + writableWorker.addNamespace(namespaceDescriptor); } @Override @Nullable public NamespaceDescriptor getDeclaredNamespace(@NotNull String name) { + checkMayRead(); + return writableWorker.getDeclaredNamespace(name); } @Override public void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor) { + checkMayWrite(); + writableWorker.addPropertyDescriptorByFieldName(fieldName, propertyDescriptor); } @Override public void importScope(@NotNull JetScope imported) { + checkMayWrite(); + super.importScope(imported); // } @Override public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) { + checkMayWrite(); + writableWorker.setImplicitReceiver(implicitReceiver); } @NotNull @Override public Collection getAllDescriptors() { + checkMayRead(); + if (allDescriptors == null) { allDescriptors = Lists.newArrayList(); allDescriptors.addAll(writableWorker.getAllDescriptors()); @@ -170,6 +212,8 @@ public class WriteThroughScope extends WritableScopeWithImports { @NotNull public JetScope getOuterScope() { + checkMayRead(); + return getWorkerScope(); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 55908afd1b6..a6e120b1e8d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -194,6 +194,8 @@ public class JetStandardClasses { static { WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.DO_NOTHING).setDebugName("JetStandardClasses.STANDARD_CLASSES"); + writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); + STANDARD_CLASSES = writableScope; writableScope.addClassifierAlias("Unit", getTuple(0)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index c095764a3ab..0b99cbe5f69 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.plugin.JetFileType; @@ -133,6 +134,7 @@ public class JetStandardLibrary { JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this); BindingTraceContext bindingTraceContext = new BindingTraceContext(); WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope"); + writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); // this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations()); // bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations()); TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java index db493f27c06..a6be38a744c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -140,6 +140,7 @@ public class ExpressionTypingServices { DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration(); WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, new TraceBasedRedeclarationHandler(context.trace)).setDebugName("getBlockReturnedType"); + scope.changeLockLevel(WritableScope.LockLevel.BOTH); return getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index f9cdac37fcb..368b8e912b3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.types.JetStandardClasses; @@ -42,7 +43,9 @@ public class ExpressionTypingUtils { @NotNull public static WritableScopeImpl newWritableScopeImpl(ExpressionTypingContext context) { - return new WritableScopeImpl(context.scope, context.scope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.trace)); + WritableScopeImpl scope = new WritableScopeImpl(context.scope, context.scope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.trace)); + scope.changeLockLevel(WritableScope.LockLevel.BOTH); + return scope; } public static boolean isBoolean(@NotNull JetSemanticServices semanticServices, @NotNull JetType type) { diff --git a/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet b/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet index 593d34b02c4..a3dcf7c81cf 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet @@ -243,7 +243,7 @@ class Outer() { } class ForwardAccessToBackingField() { //kt-147 - val a = $a // error + val a = $a // error val b = $c // error val c = 1 } @@ -349,4 +349,4 @@ fun test(m : M) { fun test1(m : M) { m.x++ m.y-- -} \ No newline at end of file +} diff --git a/compiler/testData/checkerWithErrorTypes/quick/backingField/CyclicReferenceInitializer.jet b/compiler/testData/checkerWithErrorTypes/quick/backingField/CyclicReferenceInitializer.jet index 9970bbe43b7..088063e7df9 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/backingField/CyclicReferenceInitializer.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/backingField/CyclicReferenceInitializer.jet @@ -1,3 +1,3 @@ class Cyclic() { - val a = $a + val a = $a } diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt421Scopes.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt421Scopes.jet new file mode 100644 index 00000000000..1e7138507ad --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt421Scopes.jet @@ -0,0 +1,8 @@ +// http://youtrack.jetbrains.net/issue/KT-421 +// KT-421 Strange 'unresolved' bug with backing fields + +class A() { + val c = 1 + val a = b + val b = $c // '$c' is unresolved +} diff --git a/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java b/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java index fb9556a89c3..ea1f05d8935 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java @@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.types.JetStandardLibrary; @@ -49,6 +50,7 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture { WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING); assert classDescriptor instanceof ClassifierDescriptor; scope.addClassifierDescriptor((ClassifierDescriptor) classDescriptor); + scope.changeLockLevel(WritableScope.LockLevel.READING); return scope; } diff --git a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 1ead89fcde2..e765cef474a 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -545,6 +545,7 @@ public class JetTypeCheckerTest extends JetLiteFixture { JavaSemanticServices javaSemanticServices = new JavaSemanticServices(getProject(), semanticServices, JetTestUtils.DUMMY_TRACE); writableScope.importScope(new JavaPackageScope("", null, javaSemanticServices)); writableScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices)); + writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); return writableScope; } @@ -641,6 +642,7 @@ public class JetTypeCheckerTest extends JetLiteFixture { trace.record(BindingContext.CLASS, classElement, classDescriptor); final WritableScope parameterScope = new WritableScopeImpl(scope, classDescriptor, new TraceBasedRedeclarationHandler(trace)); + parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH); // This call has side-effects on the parameterScope (fills it in) List typeParameters @@ -660,6 +662,7 @@ public class JetTypeCheckerTest extends JetLiteFixture { boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); final WritableScope memberDeclarations = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, new TraceBasedRedeclarationHandler(trace)); + memberDeclarations.changeLockLevel(WritableScope.LockLevel.BOTH); List declarations = classElement.getDeclarations(); for (JetDeclaration declaration : declarations) {