JET-65 Identifier in initializer block resolves to constructor parameter instead of property
+ Scopes for secondary constructors fixed
This commit is contained in:
@@ -37,7 +37,6 @@ public class TopDownAnalyzer {
|
|||||||
private final JetSemanticServices semanticServices;
|
private final JetSemanticServices semanticServices;
|
||||||
private final ClassDescriptorResolver classDescriptorResolver;
|
private final ClassDescriptorResolver classDescriptorResolver;
|
||||||
private final BindingTraceContext trace;
|
private final BindingTraceContext trace;
|
||||||
private boolean readyToProcessExpressions = false;
|
|
||||||
private final BindingTraceAdapter traceForConstructors;
|
private final BindingTraceAdapter traceForConstructors;
|
||||||
private final BindingTraceAdapter traceForMembers;
|
private final BindingTraceAdapter traceForMembers;
|
||||||
|
|
||||||
@@ -93,7 +92,6 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
resolveFunctionAndPropertyHeaders(declarations); // Constructor headers are resolved as well
|
resolveFunctionAndPropertyHeaders(declarations); // Constructor headers are resolved as well
|
||||||
|
|
||||||
readyToProcessExpressions = true;
|
|
||||||
resolveBehaviorDeclarationBodies();
|
resolveBehaviorDeclarationBodies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +395,7 @@ public class TopDownAnalyzer {
|
|||||||
final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor();
|
final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
final JetScope scopeForConstructor = primaryConstructor == null
|
final JetScope scopeForConstructor = primaryConstructor == null
|
||||||
? null
|
? null
|
||||||
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution());
|
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
|
||||||
final JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
final JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
|
|
||||||
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
||||||
@@ -472,7 +470,7 @@ public class TopDownAnalyzer {
|
|||||||
if (jetClass.hasPrimaryConstructor()) {
|
if (jetClass.hasPrimaryConstructor()) {
|
||||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
assert primaryConstructor != null;
|
assert primaryConstructor != null;
|
||||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution());
|
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
|
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
|
||||||
@@ -491,17 +489,14 @@ public class TopDownAnalyzer {
|
|||||||
JetDeclaration declaration = entry.getKey();
|
JetDeclaration declaration = entry.getKey();
|
||||||
ConstructorDescriptor descriptor = entry.getValue();
|
ConstructorDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
JetScope declaringScope = declaringScopes.get(declaration);
|
resolveSecondaryConstructorBody((JetConstructor) declaration, descriptor, ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getScopeForMemberResolution());
|
||||||
assert declaringScope != null;
|
|
||||||
|
|
||||||
resolveSecondaryConstructorBody((JetConstructor) declaration, descriptor, declaringScope);
|
|
||||||
|
|
||||||
assert descriptor.getUnsubstitutedReturnType() != null;
|
assert descriptor.getUnsubstitutedReturnType() != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
|
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
|
||||||
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope);
|
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
|
||||||
|
|
||||||
final JetTypeInferrer typeInferrerForInitializers = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE);
|
final JetTypeInferrer typeInferrerForInitializers = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE);
|
||||||
|
|
||||||
@@ -529,7 +524,7 @@ public class TopDownAnalyzer {
|
|||||||
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
||||||
// TODO : check that there's no recursion in this() calls
|
// TODO : check that there's no recursion in this() calls
|
||||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||||
typeInferrerForInitializers.checkClassConstructorCall(
|
typeInferrerForInitializers.checkClassConstructorCall(
|
||||||
functionInnerScope,
|
functionInnerScope,
|
||||||
call.getThisReference(),
|
call.getThisReference(),
|
||||||
@@ -570,12 +565,24 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope) {
|
private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) {
|
||||||
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler());
|
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler());
|
||||||
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
|
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
|
||||||
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
||||||
}
|
}
|
||||||
return FunctionDescriptorUtil.getFunctionInnerScope(constructorScope, descriptor, trace);
|
|
||||||
|
constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType());
|
||||||
|
|
||||||
|
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getUnsubstitutedValueParameters()) {
|
||||||
|
JetParameter parameter = (JetParameter) trace.getDeclarationPsiElement(valueParameterDescriptor);
|
||||||
|
if (parameter.getValOrVarNode() == null || !primary) {
|
||||||
|
constructorScope.addVariableDescriptor(valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructorScope.addLabeledDeclaration(descriptor); // TODO : Labels for constructors?!
|
||||||
|
|
||||||
|
return constructorScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolvePropertyDeclarationBodies() {
|
private void resolvePropertyDeclarationBodies() {
|
||||||
@@ -599,7 +606,7 @@ public class TopDownAnalyzer {
|
|||||||
trace.getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present");
|
trace.getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution());
|
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
resolvePropertyInitializer(property, propertyDescriptor, initializer, scope);
|
resolvePropertyInitializer(property, propertyDescriptor, initializer, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -727,8 +734,6 @@ public class TopDownAnalyzer {
|
|||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
|
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
||||||
|
|
||||||
assert readyToProcessExpressions : "Must be ready collecting types";
|
|
||||||
|
|
||||||
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
||||||
|
|
||||||
List<JetElement> unreachableElements = new ArrayList<JetElement>();
|
List<JetElement> unreachableElements = new ArrayList<JetElement>();
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class Foo(var bar : Int, barr : Int, val barrr : Int) {
|
||||||
|
{
|
||||||
|
bar = 1
|
||||||
|
barr = 1
|
||||||
|
barrr = 1
|
||||||
|
1 : Int
|
||||||
|
this : Foo
|
||||||
|
}
|
||||||
|
|
||||||
|
this(val bar : Int) : this(1, 1, 1) {
|
||||||
|
bar = 1
|
||||||
|
this.bar
|
||||||
|
1 : Int
|
||||||
|
val a : Int =1
|
||||||
|
this : Foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
class A(~a~val a : Int) {
|
class A(~a~val a : Int) {
|
||||||
this() {`$a`a}
|
this() {`$a`a}
|
||||||
~b~val b = `a`a
|
~b~val b = `$a`a
|
||||||
~f~fun f() = `$a`a
|
~f~fun f() = `$a`a
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,3 +10,20 @@ fun test() {
|
|||||||
a.`b`b`:std::Int`
|
a.`b`b`:std::Int`
|
||||||
a.`f`f()`:std::Int`
|
a.`f`f()`:std::Int`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Jet65 {
|
||||||
|
|
||||||
|
class Foo(~bar~var bar : Int, ~barr~barr : Int, ~barrr~val barrr : Int) {
|
||||||
|
{
|
||||||
|
`$bar`bar = 1
|
||||||
|
`barr`barr = 1
|
||||||
|
`$barrr`barrr = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
this(~s.bar~val bar : Int) : this(1, 1, 1) {
|
||||||
|
`s.bar`bar = 1
|
||||||
|
this.`$bar`bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user