Retain data flow info after assignment operations (+= etc)
#KT-2825 In Progress
This commit is contained in:
+14
-14
@@ -184,24 +184,21 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
public JetTypeInfo visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext context) {
|
public JetTypeInfo visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext context) {
|
||||||
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||||
IElementType operationType = operationSign.getReferencedNameElementType();
|
IElementType operationType = operationSign.getReferencedNameElementType();
|
||||||
JetType result;
|
JetTypeInfo result;
|
||||||
DataFlowInfo dataFlowInfo;
|
|
||||||
if (operationType == JetTokens.EQ) {
|
if (operationType == JetTokens.EQ) {
|
||||||
JetTypeInfo typeInfo = visitAssignment(expression, context);
|
result = visitAssignment(expression, context);
|
||||||
result = typeInfo.getType();
|
|
||||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
|
||||||
}
|
}
|
||||||
else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
|
else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
|
||||||
result = visitAssignmentOperation(expression, context);
|
result = visitAssignmentOperation(expression, context);
|
||||||
dataFlowInfo = context.dataFlowInfo;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return facade.getTypeInfo(expression, context);
|
return facade.getTypeInfo(expression, context);
|
||||||
}
|
}
|
||||||
return DataFlowUtils.checkType(result, expression, context, dataFlowInfo);
|
return DataFlowUtils.checkType(result.getType(), expression, context, result.getDataFlowInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JetType visitAssignmentOperation(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
|
@NotNull
|
||||||
|
protected JetTypeInfo visitAssignmentOperation(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
|
||||||
//There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there)
|
//There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there)
|
||||||
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
|
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
|
||||||
contextWithExpectedType.trace, "trace to resolve array set method for binary expression", expression);
|
contextWithExpectedType.trace, "trace to resolve array set method for binary expression", expression);
|
||||||
@@ -209,20 +206,22 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
|
|
||||||
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||||
IElementType operationType = operationSign.getReferencedNameElementType();
|
IElementType operationType = operationSign.getReferencedNameElementType();
|
||||||
JetType leftType = facade.getTypeInfo(expression.getLeft(), context).getType();
|
JetTypeInfo leftInfo = facade.getTypeInfo(expression.getLeft(), context);
|
||||||
|
JetType leftType = leftInfo.getType();
|
||||||
|
DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo();
|
||||||
|
|
||||||
JetExpression right = expression.getRight();
|
JetExpression right = expression.getRight();
|
||||||
JetExpression left = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression.getLeft());
|
JetExpression left = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression.getLeft());
|
||||||
if (right == null || left == null) {
|
if (right == null || left == null) {
|
||||||
temporaryBindingTrace.commit();
|
temporaryBindingTrace.commit();
|
||||||
return null;
|
return JetTypeInfo.create(null, dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftType == null) {
|
if (leftType == null) {
|
||||||
facade.getTypeInfo(right, context);
|
dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo();
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(operationSign));
|
context.trace.report(UNRESOLVED_REFERENCE.on(operationSign));
|
||||||
temporaryBindingTrace.commit();
|
temporaryBindingTrace.commit();
|
||||||
return null;
|
return JetTypeInfo.create(null, dataFlowInfo);
|
||||||
}
|
}
|
||||||
ExpressionReceiver receiver = new ExpressionReceiver(left, leftType);
|
ExpressionReceiver receiver = new ExpressionReceiver(left, leftType);
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
for (ResolvedCall<? extends FunctionDescriptor> call : ambiguityResolutionResults.getResultingCalls()) {
|
for (ResolvedCall<? extends FunctionDescriptor> call : ambiguityResolutionResults.getResultingCalls()) {
|
||||||
descriptors.add(call.getResultingDescriptor());
|
descriptors.add(call.getResultingDescriptor());
|
||||||
}
|
}
|
||||||
facade.getTypeInfo(right, context);
|
dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo();
|
||||||
context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors);
|
context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors);
|
||||||
}
|
}
|
||||||
else if (assignmentOperationType != null) {
|
else if (assignmentOperationType != null) {
|
||||||
@@ -264,10 +263,11 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
contextWithExpectedType.trace, "trace to resolve array set method for assignment", expression));
|
contextWithExpectedType.trace, "trace to resolve array set method for assignment", expression));
|
||||||
basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace);
|
basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace);
|
||||||
}
|
}
|
||||||
|
dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo();
|
||||||
}
|
}
|
||||||
basic.checkLValue(context.trace, expression.getLeft());
|
basic.checkLValue(context.trace, expression.getLeft());
|
||||||
temporaryBindingTrace.commit();
|
temporaryBindingTrace.commit();
|
||||||
return checkAssignmentType(type, expression, contextWithExpectedType);
|
return JetTypeInfo.create(checkAssignmentType(type, expression, contextWithExpectedType), dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
fun bar1(x: Number, var y: Int) {
|
||||||
|
y += x as Int
|
||||||
|
x : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar2(x: Number) {
|
||||||
|
<!UNRESOLVED_REFERENCE!>y<!> <!UNRESOLVED_REFERENCE!>+=<!> x as Int
|
||||||
|
x : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar3(x: Number, y: Array<Int>) {
|
||||||
|
y[0] += x as Int
|
||||||
|
x : Int
|
||||||
|
}
|
||||||
@@ -1151,6 +1151,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/AssignmentInInitializer.kt");
|
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/AssignmentInInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("AssignmentOperation.kt")
|
||||||
|
public void testAssignmentOperation() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/AssignmentOperation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("BinaryExpression.kt")
|
@TestMetadata("BinaryExpression.kt")
|
||||||
public void testBinaryExpression() throws Exception {
|
public void testBinaryExpression() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpression.kt");
|
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpression.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user