KT-244 Use dataflow info while resolving variable initializers
This commit is contained in:
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
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.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||||
@@ -449,8 +450,8 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property) {
|
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property, DataFlowInfo dataFlowInfo) {
|
||||||
JetType type = getVariableType(scope, property, false); // For a local variable the type must not be deferred
|
JetType type = getVariableType(scope, property, dataFlowInfo, false); // For a local variable the type must not be deferred
|
||||||
|
|
||||||
return resolveLocalVariableDescriptorWithType(containingDeclaration, property, type);
|
return resolveLocalVariableDescriptorWithType(containingDeclaration, property, type);
|
||||||
}
|
}
|
||||||
@@ -548,9 +549,9 @@ public class DescriptorResolver {
|
|||||||
? ReceiverDescriptor.NO_RECEIVER
|
? ReceiverDescriptor.NO_RECEIVER
|
||||||
: new ExtensionReceiver(propertyDescriptor, receiverType);
|
: 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;
|
JetType inType = isVar ? type : null;
|
||||||
propertyDescriptor.setType(inType, type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), receiverDescriptor);
|
propertyDescriptor.setType(inType, type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), receiverDescriptor);
|
||||||
@@ -580,7 +581,7 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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?
|
// TODO : receiver?
|
||||||
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
||||||
|
|
||||||
@@ -598,8 +599,7 @@ public class DescriptorResolver {
|
|||||||
LazyValue<JetType> lazyValue = new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
|
LazyValue<JetType> lazyValue = new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
|
||||||
@Override
|
@Override
|
||||||
protected JetType compute() {
|
protected JetType compute() {
|
||||||
//JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
|
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo);
|
||||||
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (allowDeferred) {
|
if (allowDeferred) {
|
||||||
|
|||||||
+6
-2
@@ -48,7 +48,11 @@ public class ExpressionTypingServices {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
|
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) {
|
if (type != null) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -61,7 +65,7 @@ public class ExpressionTypingServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@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(
|
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||||
semanticServices,
|
semanticServices,
|
||||||
new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
|
new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
|
||||||
|
|||||||
+1
-1
@@ -85,7 +85,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter));
|
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();
|
JetExpression initializer = property.getInitializer();
|
||||||
if (property.getPropertyTypeRef() != null && initializer != null) {
|
if (property.getPropertyTypeRef() != null && initializer != null) {
|
||||||
JetType outType = propertyDescriptor.getOutType();
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user