Data flow analysis: unnecessary assignment removed (related to complex expressions)

This commit is contained in:
Mikhail Glukhikh
2016-07-25 12:43:14 +03:00
parent 1c9f08e986
commit e515d7f773
4 changed files with 5 additions and 38 deletions
@@ -172,14 +172,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (innerExpression == null) { if (innerExpression == null) {
return TypeInfoFactoryKt.noTypeInfo(context); return TypeInfoFactoryKt.noTypeInfo(context);
} }
KotlinTypeInfo result = facade.getTypeInfo(innerExpression, context.replaceScope(context.scope)); return facade.getTypeInfo(innerExpression, context.replaceScope(context.scope));
KotlinType resultType = result.getType();
if (resultType != null) {
DataFlowValue innerValue = DataFlowValueFactory.createDataFlowValue(innerExpression, resultType, context);
DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, resultType, context);
result = result.replaceDataFlowInfo(result.getDataFlowInfo().assign(resultValue, innerValue));
}
return result;
} }
@Override @Override
@@ -1235,10 +1228,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
} }
DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context); DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
dataFlowInfo = dataFlowInfo.assign(resultValue, leftValue).disequate(resultValue, nullValue); dataFlowInfo = dataFlowInfo.disequate(resultValue, nullValue);
if (!jumpInRight) { if (!jumpInRight) {
DataFlowValue rightValue = DataFlowValueFactory.createDataFlowValue(right, rightType, context);
rightDataFlowInfo = rightDataFlowInfo.assign(resultValue, rightValue);
dataFlowInfo = dataFlowInfo.or(rightDataFlowInfo); dataFlowInfo = dataFlowInfo.or(rightDataFlowInfo);
} }
} }
@@ -154,13 +154,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KotlinType elseType = elseTypeInfo.getType(); KotlinType elseType = elseTypeInfo.getType();
DataFlowInfo thenDataFlowInfo = thenTypeInfo.getDataFlowInfo(); DataFlowInfo thenDataFlowInfo = thenTypeInfo.getDataFlowInfo();
DataFlowInfo elseDataFlowInfo = elseTypeInfo.getDataFlowInfo(); DataFlowInfo elseDataFlowInfo = elseTypeInfo.getDataFlowInfo();
if (resultType != null && thenType != null && elseType != null) {
DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(ifExpression, resultType, context);
DataFlowValue thenValue = DataFlowValueFactory.createDataFlowValue(thenBranch, thenType, context);
thenDataFlowInfo = thenDataFlowInfo.assign(resultValue, thenValue);
DataFlowValue elseValue = DataFlowValueFactory.createDataFlowValue(elseBranch, elseType, context);
elseDataFlowInfo = elseDataFlowInfo.assign(resultValue, elseValue);
}
loopBreakContinuePossible |= thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible(); loopBreakContinuePossible |= thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible();
@@ -246,13 +246,6 @@ public class ExpressionTypingServices {
result = getTypeOfLastExpressionInBlock( result = getTypeOfLastExpressionInBlock(
statementExpression, newContext.replaceExpectedType(context.expectedType), coercionStrategyForLastExpression, statementExpression, newContext.replaceExpectedType(context.expectedType), coercionStrategyForLastExpression,
blockLevelVisitor); blockLevelVisitor);
if (result.getType() != null && statementExpression.getParent() instanceof KtBlockExpression) {
DataFlowValue lastExpressionValue = DataFlowValueFactory.createDataFlowValue(
statementExpression, result.getType(), context);
DataFlowValue blockExpressionValue = DataFlowValueFactory.createDataFlowValue(
(KtBlockExpression) statementExpression.getParent(), result.getType(), context);
result = result.replaceDataFlowInfo(result.getDataFlowInfo().assign(blockExpressionValue, lastExpressionValue));
}
} }
else { else {
result = blockLevelVisitor result = blockLevelVisitor
@@ -86,10 +86,8 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
val dataFlowInfoForEntries = analyzeConditionsInWhenEntries(expression, contextAfterSubject, subjectDataFlowValue, subjectType) val dataFlowInfoForEntries = analyzeConditionsInWhenEntries(expression, contextAfterSubject, subjectDataFlowValue, subjectType)
val whenReturnType = inferTypeForWhenExpression(expression, contextWithExpectedType, contextAfterSubject, dataFlowInfoForEntries) val whenReturnType = inferTypeForWhenExpression(expression, contextWithExpectedType, contextAfterSubject, dataFlowInfoForEntries)
val whenResultValue = whenReturnType?.let { DataFlowValueFactory.createDataFlowValue(expression, it, contextAfterSubject) }
val branchesTypeInfo = val branchesTypeInfo = joinWhenExpressionBranches(expression, contextAfterSubject, whenReturnType, jumpOutPossibleInSubject)
joinWhenExpressionBranches(expression, contextAfterSubject, whenReturnType, jumpOutPossibleInSubject, whenResultValue)
val isExhaustive = WhenChecker.isWhenExhaustive(expression, trace) val isExhaustive = WhenChecker.isWhenExhaustive(expression, trace)
@@ -174,8 +172,7 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
expression: KtWhenExpression, expression: KtWhenExpression,
contextAfterSubject: ExpressionTypingContext, contextAfterSubject: ExpressionTypingContext,
resultType: KotlinType?, resultType: KotlinType?,
jumpOutPossibleInSubject: Boolean, jumpOutPossibleInSubject: Boolean
whenResultValue: DataFlowValue?
): KotlinTypeInfo { ): KotlinTypeInfo {
val bindingContext = contextAfterSubject.trace.bindingContext val bindingContext = contextAfterSubject.trace.bindingContext
@@ -192,14 +189,7 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
errorTypeExistInBranch = true errorTypeExistInBranch = true
} }
val entryDataFlowInfo = val entryDataFlowInfo = entryTypeInfo.dataFlowInfo
if (whenResultValue != null && entryType != null) {
val entryValue = DataFlowValueFactory.createDataFlowValue(entryExpression, entryType, contextAfterSubject)
entryTypeInfo.dataFlowInfo.assign(whenResultValue, entryValue)
}
else {
entryTypeInfo.dataFlowInfo
}
currentDataFlowInfo = currentDataFlowInfo =
if (entryType != null && KotlinBuiltIns.isNothing(entryType)) if (entryType != null && KotlinBuiltIns.isNothing(entryType))