KT-244 Use dataflow info while resolving variable initializers

This commit is contained in:
svtk
2011-12-14 16:01:23 +04:00
committed by Nikolay Krasko
parent d76310f4d6
commit 09acc4d0da
4 changed files with 48 additions and 10 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
@@ -449,8 +450,8 @@ public class DescriptorResolver {
}
@NotNull
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property) {
JetType type = getVariableType(scope, property, false); // For a local variable the type must not be deferred
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property, DataFlowInfo dataFlowInfo) {
JetType type = getVariableType(scope, property, dataFlowInfo, false); // For a local variable the type must not be deferred
return resolveLocalVariableDescriptorWithType(containingDeclaration, property, type);
}
@@ -548,9 +549,9 @@ public class DescriptorResolver {
? ReceiverDescriptor.NO_RECEIVER
: new ExtensionReceiver(propertyDescriptor, receiverType);
JetScope scope2 = getPropertyDeclarationInnerScope(scope, propertyDescriptor, typeParameterDescriptors, receiverDescriptor);
JetScope propertyScope = getPropertyDeclarationInnerScope(scope, propertyDescriptor, typeParameterDescriptors, receiverDescriptor);
JetType type = getVariableType(scope2, property, true);
JetType type = getVariableType(propertyScope, property, DataFlowInfo.EMPTY, true);
JetType inType = isVar ? type : null;
propertyDescriptor.setType(inType, type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), receiverDescriptor);
@@ -580,7 +581,7 @@ public class DescriptorResolver {
}
@NotNull
private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, boolean allowDeferred) {
private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, @NotNull final DataFlowInfo dataFlowInfo, boolean allowDeferred) {
// TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
@@ -598,8 +599,7 @@ public class DescriptorResolver {
LazyValue<JetType> lazyValue = new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
//JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE);
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo);
}
};
if (allowDeferred) {
@@ -48,7 +48,11 @@ public class ExpressionTypingServices {
@NotNull
public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
JetType type = getType(scope, expression, expectedType);
return safeGetType(scope, expression, expectedType, DataFlowInfo.EMPTY);
}
public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo) {
JetType type = getType(scope, expression, expectedType, dataFlowInfo);
if (type != null) {
return type;
}
@@ -61,7 +65,7 @@ public class ExpressionTypingServices {
}
@Nullable
public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, DataFlowInfo dataFlowInfo) {
public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo) {
ExpressionTypingContext context = ExpressionTypingContext.newContext(
semanticServices,
new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
@@ -85,7 +85,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter));
}
VariableDescriptor propertyDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property);
VariableDescriptor propertyDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property, context.dataFlowInfo);
JetExpression initializer = property.getInitializer();
if (property.getPropertyTypeRef() != null && initializer != null) {
JetType outType = propertyDescriptor.getOutType();
@@ -0,0 +1,34 @@
namespace kt244
//+JDK
// KT-244 Use dataflow info while resolving variable initializers
fun f(s: String?) {
if (s != null) {
s.length //ok
var <!UNUSED_VARIABLE!>i<!> = s.length //error: Only safe calls are allowed on a nullable receiver
System.out?.println(s.length) //error
}
}
// more tests
class A(a: String?) {
val b = if (a != null) a.length else 1
{
if (a != null) {
val c = a.length
}
}
val i : Int
{
if (a is String) {
i = a.length
}
else {
i = 3
}
}
}