提交 7a8ea7fd 编写于 作者: A Andrey Breslav

JET-65 Identifier in initializer block resolves to constructor parameter instead of property

+
Scopes for secondary constructors fixed
上级 82693678
......@@ -37,7 +37,6 @@ public class TopDownAnalyzer {
private final JetSemanticServices semanticServices;
private final ClassDescriptorResolver classDescriptorResolver;
private final BindingTraceContext trace;
private boolean readyToProcessExpressions = false;
private final BindingTraceAdapter traceForConstructors;
private final BindingTraceAdapter traceForMembers;
......@@ -93,7 +92,6 @@ public class TopDownAnalyzer {
resolveFunctionAndPropertyHeaders(declarations); // Constructor headers are resolved as well
readyToProcessExpressions = true;
resolveBehaviorDeclarationBodies();
}
......@@ -397,7 +395,7 @@ public class TopDownAnalyzer {
final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor();
final JetScope scopeForConstructor = primaryConstructor == null
? null
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution());
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
final JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
......@@ -472,7 +470,7 @@ public class TopDownAnalyzer {
if (jetClass.hasPrimaryConstructor()) {
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
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
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
......@@ -491,17 +489,14 @@ public class TopDownAnalyzer {
JetDeclaration declaration = entry.getKey();
ConstructorDescriptor descriptor = entry.getValue();
JetScope declaringScope = declaringScopes.get(declaration);
assert declaringScope != null;
resolveSecondaryConstructorBody((JetConstructor) declaration, descriptor, declaringScope);
resolveSecondaryConstructorBody((JetConstructor) declaration, descriptor, ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getScopeForMemberResolution());
assert descriptor.getUnsubstitutedReturnType() != null;
}
}
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);
......@@ -529,7 +524,7 @@ public class TopDownAnalyzer {
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
// TODO : check that there's no recursion in this() calls
// TODO : check: if a this() call is present, no other initializers are allowed
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
typeInferrerForInitializers.checkClassConstructorCall(
functionInnerScope,
call.getThisReference(),
......@@ -570,12 +565,24 @@ public class TopDownAnalyzer {
}
@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());
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
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() {
......@@ -599,7 +606,7 @@ public class TopDownAnalyzer {
trace.getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present");
}
else {
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution());
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
resolvePropertyInitializer(property, propertyDescriptor, initializer, scope);
}
}
......@@ -727,8 +734,6 @@ public class TopDownAnalyzer {
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
assert readyToProcessExpressions : "Must be ready collecting types";
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
List<JetElement> unreachableElements = new ArrayList<JetElement>();
......
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
}
}
class A(~a~val a : Int) {
this() {`$a`a}
~b~val b = `a`a
~b~val b = `$a`a
~f~fun f() = `$a`a
}
......@@ -10,3 +10,20 @@ fun test() {
a.`b`b`: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
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册