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/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 669af46b9ae..375f472e527 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,13 @@ 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.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution"); this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler).setDebugName("MemberResolution"); + this.scopeForAnyConstructor = new WritableScopeImpl(scopeForMemberResolution, this, redeclarationHandler).setDebugName("AnyConstrutor"); + this.scopeForPrimaryConstructor = new WritableScopeImpl(scopeForAnyConstructor, this, redeclarationHandler).setDebugName("PrimaryConstructor"); + this.scopesForConstructors = new HashMap(); this.kind = kind; } @@ -100,10 +113,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 +125,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 +133,24 @@ 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?! } @Override @@ -128,6 +159,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme callableMembers.add(propertyDescriptor); scopeForMemberLookup.addVariableDescriptor(propertyDescriptor); scopeForMemberResolution.addVariableDescriptor(propertyDescriptor); + scopeForAnyConstructor.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); } @Override @@ -257,6 +289,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 +386,5 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme } return implicitReceiver; } + } 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/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index dd45fdd7af9..c759c83f741 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,35 @@ 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); + 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 +466,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..0b70a64d8c1 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; @@ -470,16 +472,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 +486,26 @@ 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); + } + 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 +514,48 @@ 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); + 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 +747,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 +762,7 @@ public class DescriptorResolver { getterDescriptor = new PropertyGetterDescriptor( propertyDescriptor, Collections.emptyList(), propertyDescriptor.getModality(), propertyDescriptor.getVisibility(), - propertyDescriptor.getOutType(), false, true); + false, true); return getterDescriptor; } @@ -807,12 +831,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/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 61d117433f4..9990c09921a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -147,7 +147,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); } 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 +}