提交 e087b080 编写于 作者: A Andrey Breslav

A bug with local variable initializers fixed

上级 b75354f4
......@@ -72,7 +72,6 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
@Override
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
expressionTypes.put(expression, type);
markAsProcessed(expression);
}
@Override
......
......@@ -401,7 +401,7 @@ public class ClassDescriptorResolver {
@NotNull
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
JetType type = getType(scope, property);
JetType type = getType(scope, property, false); // For a local variable the type must not be deferred
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
......@@ -415,7 +415,7 @@ public class ClassDescriptorResolver {
@NotNull
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
JetType type = getType(scope, property);
JetType type = getType(scope, property, true);
boolean isVar = property.isVar();
JetModifierList modifierList = property.getModifierList();
......@@ -436,6 +436,39 @@ public class ClassDescriptorResolver {
return propertyDescriptor;
}
@NotNull
private JetType getType(@NotNull final JetScope scope, @NotNull JetProperty property, boolean allowDeferred) {
// TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
JetType type;
if (propertyTypeRef == null) {
final JetExpression initializer = property.getInitializer();
if (initializer == null) {
trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized");
type = ErrorUtils.createErrorType("No type, no body");
} else {
// TODO : ??? Fix-point here: what if we have something like "val a = foo {a.bar()}"
// TODO : a risk of a memory leak
LazyValue<JetType> lazyValue = new LazyValue<JetType>() {
@Override
protected JetType compute() {
return semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false);
}
};
if (allowDeferred) {
type = new DeferredType(lazyValue);
}
else {
type = lazyValue.get();
}
}
} else {
type = typeResolver.resolveType(scope, propertyTypeRef);
}
return type;
}
@NotNull
private MemberModifiers resolveModifiers(@Nullable JetModifierList modifierList, @NotNull MemberModifiers defaultModifiers) {
if (modifierList == null) return defaultModifiers;
......@@ -515,33 +548,6 @@ public class ClassDescriptorResolver {
return getterDescriptor;
}
@NotNull
private JetType getType(@NotNull final JetScope scope, @NotNull JetProperty property) {
// TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
JetType type;
if (propertyTypeRef == null) {
final JetExpression initializer = property.getInitializer();
if (initializer == null) {
trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized");
type = ErrorUtils.createErrorType("No type, no body");
} else {
// TODO : ??? Fix-point here: what if we have something like "val a = foo {a.bar()}"
// TODO : a risk of a memory leak
type = new DeferredType(new LazyValue<JetType>() {
@Override
protected JetType compute() {
return semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false);
}
});
}
} else {
type = typeResolver.resolveType(scope, propertyTypeRef);
}
return type;
}
@NotNull
public ConstructorDescriptor resolveSecondaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetConstructor constructor) {
return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, constructor.getParameters());
......
......@@ -599,7 +599,6 @@ public class JetTypeInferrer {
}
try {
expression.accept(this);
trace.markAsProcessed(expression);
if (result instanceof DeferredType) {
result = ((DeferredType) result).getActualType();
}
......@@ -615,6 +614,7 @@ public class JetTypeInferrer {
result = null;
}
trace.markAsProcessed(expression);
return result;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册