A bug with local variable initializers fixed
This commit is contained in:
@@ -72,7 +72,6 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
|||||||
@Override
|
@Override
|
||||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||||
expressionTypes.put(expression, type);
|
expressionTypes.put(expression, type);
|
||||||
markAsProcessed(expression);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
|
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(
|
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
@@ -415,7 +415,7 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
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();
|
boolean isVar = property.isVar();
|
||||||
JetModifierList modifierList = property.getModifierList();
|
JetModifierList modifierList = property.getModifierList();
|
||||||
@@ -436,6 +436,39 @@ public class ClassDescriptorResolver {
|
|||||||
return propertyDescriptor;
|
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
|
@NotNull
|
||||||
private MemberModifiers resolveModifiers(@Nullable JetModifierList modifierList, @NotNull MemberModifiers defaultModifiers) {
|
private MemberModifiers resolveModifiers(@Nullable JetModifierList modifierList, @NotNull MemberModifiers defaultModifiers) {
|
||||||
if (modifierList == null) return defaultModifiers;
|
if (modifierList == null) return defaultModifiers;
|
||||||
@@ -515,33 +548,6 @@ public class ClassDescriptorResolver {
|
|||||||
return getterDescriptor;
|
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
|
@NotNull
|
||||||
public ConstructorDescriptor resolveSecondaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetConstructor constructor) {
|
public ConstructorDescriptor resolveSecondaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetConstructor constructor) {
|
||||||
return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, constructor.getParameters());
|
return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, constructor.getParameters());
|
||||||
|
|||||||
@@ -599,7 +599,6 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
expression.accept(this);
|
expression.accept(this);
|
||||||
trace.markAsProcessed(expression);
|
|
||||||
if (result instanceof DeferredType) {
|
if (result instanceof DeferredType) {
|
||||||
result = ((DeferredType) result).getActualType();
|
result = ((DeferredType) result).getActualType();
|
||||||
}
|
}
|
||||||
@@ -615,6 +614,7 @@ public class JetTypeInferrer {
|
|||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace.markAsProcessed(expression);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user