From be98c4f96d2ca8fcde1fd0cd38814d16947e79b0 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Wed, 22 Jul 2015 16:09:23 +0300 Subject: [PATCH] DataFlowUtils -> DataFlowAnalyzer and make it a component --- .../kotlin/resolve/calls/CallCompleter.kt | 5 +- .../resolve/calls/CallExpressionResolver.java | 16 +++-- .../BasicExpressionTypingVisitor.java | 58 ++++++++--------- .../ControlStructureTypingUtils.java | 11 +++- .../ControlStructureTypingVisitor.java | 57 +++++++++-------- ...taFlowUtils.java => DataFlowAnalyzer.java} | 63 ++++++++++++++----- .../ExpressionTypingComponents.java | 8 ++- .../expressions/ExpressionTypingServices.java | 7 +-- .../expressions/ExpressionTypingUtils.java | 23 ------- .../ExpressionTypingVisitorForStatements.java | 24 +++---- .../expressions/FunctionsTypingVisitor.kt | 13 ++-- .../PatternMatchingTypingVisitor.java | 14 ++--- .../types/expressions/TypeInfoFactory.kt | 5 +- 13 files changed, 167 insertions(+), 137 deletions(-) rename compiler/frontend/src/org/jetbrains/kotlin/types/expressions/{DataFlowUtils.java => DataFlowAnalyzer.java} (80%) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt index 69ffa02fe24..19a0de7c7c6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt @@ -41,13 +41,14 @@ import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.expressions.DataFlowUtils +import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer import java.util.ArrayList public class CallCompleter( private val argumentTypeResolver: ArgumentTypeResolver, private val candidateResolver: CandidateResolver, private val symbolUsageValidator: SymbolUsageValidator, + private val dataFlowAnalyzer: DataFlowAnalyzer, private val builtIns: KotlinBuiltIns ) { fun completeCall( @@ -260,7 +261,7 @@ public class CallCompleter( argumentTypeResolver.getCallableReferenceTypeInfo(expression, callableReferenceArgument, context, RESOLVE_FUNCTION_ARGUMENTS) } - DataFlowUtils.checkType(updatedType, deparenthesized, context) + dataFlowAnalyzer.checkType(updatedType, deparenthesized, context) } private fun completeCallForArgument( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java index 8689435670e..572f25a8911 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java @@ -45,7 +45,10 @@ import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator; import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeUtils; -import org.jetbrains.kotlin.types.expressions.*; +import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer; +import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext; +import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices; +import org.jetbrains.kotlin.types.expressions.JetTypeInfo; import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryPackage; import javax.inject.Inject; @@ -63,15 +66,18 @@ public class CallExpressionResolver { private final CallResolver callResolver; private final ConstantExpressionEvaluator constantExpressionEvaluator; private final SymbolUsageValidator symbolUsageValidator; + private final DataFlowAnalyzer dataFlowAnalyzer; public CallExpressionResolver( @NotNull CallResolver callResolver, @NotNull ConstantExpressionEvaluator constantExpressionEvaluator, - @NotNull SymbolUsageValidator symbolUsageValidator + @NotNull SymbolUsageValidator symbolUsageValidator, + @NotNull DataFlowAnalyzer dataFlowAnalyzer ) { this.callResolver = callResolver; this.constantExpressionEvaluator = constantExpressionEvaluator; this.symbolUsageValidator = symbolUsageValidator; + this.dataFlowAnalyzer = dataFlowAnalyzer; } private ExpressionTypingServices expressionTypingServices; @@ -182,7 +188,7 @@ public class CallExpressionResolver { ) { JetTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck(callExpression, receiver, callOperationNode, context); if (context.contextDependency == INDEPENDENT) { - DataFlowUtils.checkType(typeInfo.getType(), callExpression, context); + dataFlowAnalyzer.checkType(typeInfo.getType(), callExpression, context); } return typeInfo; } @@ -379,7 +385,7 @@ public class CallExpressionResolver { CompileTimeConstant value = constantExpressionEvaluator.evaluateExpression(expression, context.trace, context.expectedType); if (value != null && value.getIsPure()) { - return ExpressionTypingUtils.createCompileTimeConstantTypeInfo(value, expression, context); + return dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, context); } JetTypeInfo typeInfo; @@ -424,7 +430,7 @@ public class CallExpressionResolver { } } if (context.contextDependency == INDEPENDENT) { - DataFlowUtils.checkType(typeInfo.getType(), expression, context); + dataFlowAnalyzer.checkType(typeInfo.getType(), expression, context); } return typeInfo; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 11bc0988cd6..ccf61c3a6bb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -96,7 +96,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // TODO : type substitutions??? CallExpressionResolver callExpressionResolver = components.callExpressionResolver; JetTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context); - return DataFlowUtils.checkType(typeInfo, expression, context); // TODO : Extensions to this + return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this } @Override @@ -125,7 +125,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } assert compileTimeConstant != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText(); - return createCompileTimeConstantTypeInfo(compileTimeConstant, expression, context); + return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(compileTimeConstant, expression, context); } @NotNull @@ -175,7 +175,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetTypeInfo typeInfo = facade.getTypeInfo(left, contextWithNoExpectedType.replaceExpectedType(targetType)); checkBinaryWithTypeRHS(expression, context, targetType, typeInfo.getType()); - return DataFlowUtils.checkType(typeInfo.replaceType(targetType), expression, context); + return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(targetType), expression, context); } JetTypeInfo typeInfo = facade.getTypeInfo(left, contextWithNoExpectedType); @@ -193,7 +193,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } JetType result = operationType == AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType; - return DataFlowUtils.checkType(typeInfo.replaceType(result), expression, context); + return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result), expression, context); } private void checkBinaryWithTypeRHS( @@ -241,7 +241,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.report(USELESS_CAST.on(expression)); return; } - Collection possibleTypes = DataFlowUtils.getAllPossibleTypes( + Collection possibleTypes = components.dataFlowAnalyzer.getAllPossibleTypes( expression.getLeft(), context.dataFlowInfo, actualType, context); boolean checkExactType = checkExactTypeForUselessCast(expression); @@ -295,7 +295,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.recordType(expression.getInstanceReference(), result); break; } - return TypeInfoFactoryPackage.createCheckedTypeInfo(result, context, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(result, context, expression); } @Override @@ -319,7 +319,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (result != null) { context.trace.recordType(expression.getInstanceReference(), result); } - return TypeInfoFactoryPackage.createCheckedTypeInfo(result, context, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(result, context, expression); } throw new IllegalStateException("Unknown code: " + resolutionResult.getCode()); } @@ -509,7 +509,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { public JetTypeInfo visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, ExpressionTypingContext c) { JetType type = resolveClassLiteral(expression, c); if (type != null && !type.isError()) { - return TypeInfoFactoryPackage.createCheckedTypeInfo( + return components.dataFlowAnalyzer.createCheckedTypeInfo( components.reflectionTypes.getKClassType(Annotations.EMPTY, type), c, expression ); } @@ -604,11 +604,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (callableReference.getReferencedName().isEmpty()) { c.trace.report(UNRESOLVED_REFERENCE.on(callableReference, callableReference)); JetType errorType = ErrorUtils.createErrorType("Empty callable reference"); - return TypeInfoFactoryPackage.createCheckedTypeInfo(errorType, c, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(errorType, c, expression); } JetType result = getCallableReferenceType(expression, receiverType, c); - return TypeInfoFactoryPackage.createCheckedTypeInfo(result, c, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(result, c, expression); } @Override @@ -651,9 +651,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } } // Breaks are not possible inside constructor arguments, so jumpPossible or jumpFlowInfo are not necessary here - JetTypeInfo resultTypeInfo = DataFlowUtils.checkType(TypeInfoFactoryPackage.createTypeInfo(result[0], resultFlowInfo), - expression, - context); + JetTypeInfo resultTypeInfo = components.dataFlowAnalyzer.checkType(TypeInfoFactoryPackage.createTypeInfo(result[0], resultFlowInfo), + expression, + context); // We have to record it here, // otherwise ExpressionTypingVisitorDispatcher records wrong information context.trace.record(EXPRESSION_TYPE_INFO, expression, resultTypeInfo); @@ -781,12 +781,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType ); if (value != null) { - return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType); + return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType); } - return DataFlowUtils.checkType(typeInfo.replaceType(result), - expression, - contextWithExpectedType.replaceDataFlowInfo(typeInfo.getDataFlowInfo())); + return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result), + expression, + contextWithExpectedType.replaceDataFlowInfo(typeInfo.getDataFlowInfo())); } private JetTypeInfo visitExclExclExpression(@NotNull JetUnaryExpression expression, @NotNull ExpressionTypingContext context) { @@ -820,7 +820,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } // The call to checkType() is only needed here to execute additionalTypeCheckers, hence the NO_EXPECTED_TYPE - return DataFlowUtils.checkType(baseTypeInfo.replaceType(resultingType), expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); + return components.dataFlowAnalyzer.checkType(baseTypeInfo.replaceType(resultingType), expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); } @Override @@ -977,9 +977,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType ); if (value != null) { - return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType); + return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType); } - return DataFlowUtils.checkType(result, expression, contextWithExpectedType); + return components.dataFlowAnalyzer.checkType(result, expression, contextWithExpectedType); } private JetTypeInfo visitEquality( @@ -1092,7 +1092,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { WritableScopeImpl leftScope = newWritableScopeImpl(context, "Left scope of && or ||"); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition boolean isAnd = operationType == JetTokens.ANDAND; - DataFlowInfo flowInfoLeft = DataFlowUtils.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo); + DataFlowInfo flowInfoLeft = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo); WritableScopeImpl rightScope = isAnd ? leftScope : newWritableScopeImpl(context, "Right scope of && or ||"); ExpressionTypingContext contextForRightExpr = @@ -1149,10 +1149,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } // If break or continue was possible, take condition check info as the jump info - return TypeInfoFactoryPackage.createTypeInfo(DataFlowUtils.checkType(type, expression, contextWithExpectedType), - dataFlowInfo, - loopBreakContinuePossible, - context.dataFlowInfo); + return TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkType(type, expression, contextWithExpectedType), + dataFlowInfo, + loopBreakContinuePossible, + context.dataFlowInfo); } @NotNull @@ -1265,7 +1265,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetTypeInfo visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression, ExpressionTypingContext context) { - return DataFlowUtils.checkType(resolveArrayAccessGetMethod(expression, context), expression, context); + return components.dataFlowAnalyzer.checkType(resolveArrayAccessGetMethod(expression, context), expression, context); } @NotNull @@ -1345,9 +1345,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { entry.accept(visitor); } components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, contextWithExpectedType.expectedType); - return DataFlowUtils.checkType(visitor.typeInfo.replaceType(components.builtIns.getStringType()), - expression, - contextWithExpectedType); + return components.dataFlowAnalyzer.checkType(visitor.typeInfo.replaceType(components.builtIns.getStringType()), + expression, + contextWithExpectedType); } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java index 24c4ac42f9f..74131e533bd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java @@ -60,9 +60,14 @@ public class ControlStructureTypingUtils { private static final Logger LOG = Logger.getInstance(ControlStructureTypingUtils.class); private final CallResolver callResolver; + private final DataFlowAnalyzer dataFlowAnalyzer; - public ControlStructureTypingUtils(@NotNull CallResolver callResolver) { + public ControlStructureTypingUtils( + @NotNull CallResolver callResolver, + @NotNull DataFlowAnalyzer dataFlowAnalyzer + ) { this.callResolver = callResolver; + this.dataFlowAnalyzer = dataFlowAnalyzer; } /*package*/ ResolvedCall resolveSpecialConstructionAsCall( @@ -245,7 +250,7 @@ public class ControlStructureTypingUtils { } @NotNull - /*package*/ static TracingStrategy createTracingForSpecialConstruction( + /*package*/ TracingStrategy createTracingForSpecialConstruction( final @NotNull Call call, @NotNull String constructionName, final @NotNull ExpressionTypingContext context @@ -272,7 +277,7 @@ public class ControlStructureTypingUtils { if (typeInfo == null) return false; Ref hasError = Ref.create(); - DataFlowUtils.checkType( + dataFlowAnalyzer.checkType( typeInfo.getType(), expression, context diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java index 87d4ce6a51e..1c3aaa01fc4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java @@ -26,7 +26,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.*; +import org.jetbrains.kotlin.resolve.BindingContext; +import org.jetbrains.kotlin.resolve.BindingContextUtils; +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; +import org.jetbrains.kotlin.resolve.ModifiersChecker; import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; @@ -99,8 +102,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { WritableScopeImpl thenScope = newWritableScopeImpl(context, "Then scope"); WritableScopeImpl elseScope = newWritableScopeImpl(context, "Else scope"); - DataFlowInfo thenInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo); - DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); + DataFlowInfo thenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo); + DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); if (elseBranch == null) { if (thenBranch != null) { @@ -111,7 +114,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { ? result.replaceJumpOutPossible(true).replaceJumpFlowInfo(conditionDataFlowInfo) : result; } - return TypeInfoFactoryPackage.createTypeInfo(DataFlowUtils.checkImplicitCast( + return TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast( components.builtIns.getUnitType(), ifExpression, contextWithExpectedType, isStatement ), @@ -165,7 +168,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { JetType resultType = resolvedCall.getResultingDescriptor().getReturnType(); // If break or continue was possible, take condition check info as the jump info return TypeInfoFactoryPackage - .createTypeInfo(DataFlowUtils.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement), + .createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement), resultDataFlowInfo, loopBreakContinuePossible, conditionDataFlowInfo); } @@ -190,12 +193,16 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } else { dataFlowInfo = typeInfo.getDataFlowInfo().or(otherInfo); } - return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(typeInfo.replaceType(components.builtIns.getUnitType()), - ifExpression, - context), - ifExpression, - context, - isStatement).replaceDataFlowInfo(dataFlowInfo); + return components.dataFlowAnalyzer.checkImplicitCast( + components.dataFlowAnalyzer.checkType( + typeInfo.replaceType(components.builtIns.getUnitType()), + ifExpression, + context + ), + ifExpression, + context, + isStatement + ).replaceDataFlowInfo(dataFlowInfo); } @Override @@ -204,7 +211,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { - if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency( INDEPENDENT); @@ -220,7 +227,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { JetExpression body = expression.getBody(); JetTypeInfo bodyTypeInfo; - DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); + DataFlowInfo conditionInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); if (body != null) { WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition"); bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( @@ -233,7 +240,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { // Condition is false at this point only if there is no jumps outside if (!containsJumpOutOfLoop(expression, context)) { - dataFlowInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(dataFlowInfo); + dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(dataFlowInfo); } // Special case: while (true) @@ -245,7 +252,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { // but without affecting changing variables dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo())); } - return DataFlowUtils + return components.dataFlowAnalyzer .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) .replaceDataFlowInfo(dataFlowInfo); } @@ -295,7 +302,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { - if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT); @@ -335,7 +342,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { DataFlowInfo dataFlowInfo; // Without jumps out, condition is entered and false, with jumps out, we know nothing about it if (!containsJumpOutOfLoop(expression, context)) { - dataFlowInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); + dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); } else { dataFlowInfo = context.dataFlowInfo; @@ -350,7 +357,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { // but without affecting changing variables dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo())); } - return DataFlowUtils + return components.dataFlowAnalyzer .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) .replaceDataFlowInfo(dataFlowInfo); } @@ -361,7 +368,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { - if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT); @@ -413,7 +420,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { bodyTypeInfo = loopRangeInfo; } - return DataFlowUtils + return components.dataFlowAnalyzer .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) .replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()); } @@ -472,7 +479,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor( context.scope, catchParameter, context.trace); JetType throwableType = components.builtIns.getThrowable().getDefaultType(); - DataFlowUtils.checkType(variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType)); + components.dataFlowAnalyzer.checkType(variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType)); if (catchBody != null) { WritableScope catchScope = newWritableScopeImpl(context, "Catch scope"); catchScope.addVariableDescriptor(variableDescriptor); @@ -510,7 +517,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { facade.getTypeInfo(thrownExpression, context .replaceExpectedType(throwableType).replaceScope(context.scope).replaceContextDependency(INDEPENDENT)); } - return TypeInfoFactoryPackage.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression); } @Override @@ -583,7 +590,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.trace.report(RETURN_TYPE_MISMATCH.on(expression, expectedType)); } } - return TypeInfoFactoryPackage.createCheckedTypeInfo(resultType, context, expression); + return components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, expression); } private static boolean isClassInitializer(@NotNull Pair containingFunInfo) { @@ -594,14 +601,14 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Override public JetTypeInfo visitBreakExpression(@NotNull JetBreakExpression expression, ExpressionTypingContext context) { LabelResolver.INSTANCE.resolveControlLabel(expression, context); - return TypeInfoFactoryPackage.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression). + return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression). replaceJumpOutPossible(true); } @Override public JetTypeInfo visitContinueExpression(@NotNull JetContinueExpression expression, ExpressionTypingContext context) { LabelResolver.INSTANCE.resolveControlLabel(expression, context); - return TypeInfoFactoryPackage.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression). + return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression). replaceJumpOutPossible(true); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java similarity index 80% rename from compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java rename to compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java index c189ca513b3..d59205ff35c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java @@ -26,13 +26,13 @@ import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingTrace; +import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver; import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory; import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils; -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker; -import org.jetbrains.kotlin.resolve.constants.ConstantValue; +import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeUtils; @@ -46,12 +46,10 @@ import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT; import static org.jetbrains.kotlin.types.TypeUtils.*; -public class DataFlowUtils { - private DataFlowUtils() { - } +public class DataFlowAnalyzer { @NotNull - public static DataFlowInfo extractDataFlowInfoFromCondition( + public DataFlowInfo extractDataFlowInfoFromCondition( @Nullable JetExpression condition, final boolean conditionValue, final ExpressionTypingContext context @@ -143,17 +141,17 @@ public class DataFlowUtils { } @Nullable - public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) { + public JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) { return checkType(expressionType, expression, context, null); } @NotNull - public static JetTypeInfo checkType(@NotNull JetTypeInfo typeInfo, @NotNull JetExpression expression, @NotNull ResolutionContext context) { + public JetTypeInfo checkType(@NotNull JetTypeInfo typeInfo, @NotNull JetExpression expression, @NotNull ResolutionContext context) { return typeInfo.replaceType(checkType(typeInfo.getType(), expression, context)); } @Nullable - public static JetType checkType( + public JetType checkType( @Nullable JetType expressionType, @NotNull JetExpression expressionToCheck, @NotNull ResolutionContext c, @@ -195,7 +193,7 @@ public class DataFlowUtils { } @Nullable - public static JetType checkPossibleCast( + public JetType checkPossibleCast( @NotNull JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext c @@ -212,7 +210,7 @@ public class DataFlowUtils { return null; } - public static void recordExpectedType(@NotNull BindingTrace trace, @NotNull JetExpression expression, @NotNull JetType expectedType) { + public void recordExpectedType(@NotNull BindingTrace trace, @NotNull JetExpression expression, @NotNull JetType expectedType) { if (expectedType != NO_EXPECTED_TYPE) { JetType normalizeExpectedType = expectedType == UNIT_EXPECTED_TYPE ? KotlinBuiltIns.getInstance().getUnitType() : expectedType; trace.record(BindingContext.EXPECTED_EXPRESSION_TYPE, expression, normalizeExpectedType); @@ -220,7 +218,7 @@ public class DataFlowUtils { } @Nullable - public static JetType checkStatementType(@NotNull JetExpression expression, @NotNull ResolutionContext context) { + public JetType checkStatementType(@NotNull JetExpression expression, @NotNull ResolutionContext context) { if (!noExpectedType(context.expectedType) && !KotlinBuiltIns.isUnit(context.expectedType) && !context.expectedType.isError()) { context.trace.report(EXPECTED_TYPE_MISMATCH.on(expression, context.expectedType)); return null; @@ -229,7 +227,7 @@ public class DataFlowUtils { } @Nullable - public static JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) { + public JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) { if (expressionType != null && context.expectedType == NO_EXPECTED_TYPE && context.contextDependency == INDEPENDENT && !isStatement && (KotlinBuiltIns.isUnit(expressionType) || KotlinBuiltIns.isAnyOrNullableAny(expressionType)) && !TypesPackage.isDynamic(expressionType)) { @@ -239,12 +237,12 @@ public class DataFlowUtils { } @NotNull - public static JetTypeInfo checkImplicitCast(@NotNull JetTypeInfo typeInfo, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) { + public JetTypeInfo checkImplicitCast(@NotNull JetTypeInfo typeInfo, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) { return typeInfo.replaceType(checkImplicitCast(typeInfo.getType(), expression, context, isStatement)); } @NotNull - public static JetTypeInfo illegalStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull ExpressionTypingInternals facade) { + public JetTypeInfo illegalStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull ExpressionTypingInternals facade) { facade.checkStatementType( expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT)); context.trace.report(EXPRESSION_EXPECTED.on(expression, expression)); @@ -252,7 +250,7 @@ public class DataFlowUtils { } @NotNull - public static Collection getAllPossibleTypes( + public Collection getAllPossibleTypes( @NotNull JetExpression expression, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType type, @@ -265,4 +263,37 @@ public class DataFlowUtils { } return possibleTypes; } + + @NotNull + public JetTypeInfo createCheckedTypeInfo( + @Nullable JetType type, + @NotNull ResolutionContext context, + @NotNull JetExpression expression + ) { + return checkType(TypeInfoFactoryPackage.createTypeInfo(type, context), expression, context); + } + + @NotNull + public JetTypeInfo createCompileTimeConstantTypeInfo( + @NotNull CompileTimeConstant value, + @NotNull JetExpression expression, + @NotNull ExpressionTypingContext context + ) { + JetType expressionType; + if (value instanceof IntegerValueTypeConstant) { + IntegerValueTypeConstant integerValueTypeConstant = (IntegerValueTypeConstant) value; + if (context.contextDependency == INDEPENDENT) { + expressionType = integerValueTypeConstant.getType(context.expectedType); + ArgumentTypeResolver.updateNumberType(expressionType, expression, context.statementFilter, context.trace); + } + else { + expressionType = integerValueTypeConstant.getUnknownIntegerType(); + } + } + else { + expressionType = ((TypedCompileTimeConstant) value).getType(); + } + + return createCheckedTypeInfo(expressionType, context, expression); + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java index 2ab29e3cded..5cea9eeeca1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java @@ -52,6 +52,7 @@ public class ExpressionTypingComponents { /*package*/ MultiDeclarationResolver multiDeclarationResolver; /*package*/ ConstantExpressionEvaluator constantExpressionEvaluator; /*package*/ ModifiersChecker modifiersChecker; + /*package*/ DataFlowAnalyzer dataFlowAnalyzer; @Inject public void setGlobalContext(@NotNull GlobalContext globalContext) { @@ -164,7 +165,12 @@ public class ExpressionTypingComponents { } @Inject - public void setModifiersChecker(ModifiersChecker modifiersChecker) { + public void setModifiersChecker(@NotNull ModifiersChecker modifiersChecker) { this.modifiersChecker = modifiersChecker; } + + @Inject + public void setDataFlowAnalyzer(@NotNull DataFlowAnalyzer dataFlowAnalyzer) { + this.dataFlowAnalyzer = dataFlowAnalyzer; + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java index 3eeab94b725..8f684718174 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java @@ -21,18 +21,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.analyzer.AnalyzerPackage; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.ScriptDescriptor; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.*; -import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesPackage; -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode; import org.jetbrains.kotlin.resolve.calls.context.ContextDependency; import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext; -import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.resolve.scopes.WritableScope; @@ -174,7 +170,8 @@ public class ExpressionTypingServices { JetTypeInfo r; if (block.isEmpty()) { - r = TypeInfoFactoryPackage.createCheckedTypeInfo(expressionTypingComponents.builtIns.getUnitType(), context, expression); + r = expressionTypingComponents.dataFlowAnalyzer + .createCheckedTypeInfo(expressionTypingComponents.builtIns.getUnitType(), context, expression); } else { r = getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingUtils.java index 92932bd142e..97c9b6e9082 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingUtils.java @@ -242,27 +242,4 @@ public class ExpressionTypingUtils { private ExpressionTypingUtils() { } - @NotNull - public static JetTypeInfo createCompileTimeConstantTypeInfo( - @NotNull CompileTimeConstant value, - @NotNull JetExpression expression, - @NotNull ExpressionTypingContext context - ) { - JetType expressionType; - if (value instanceof IntegerValueTypeConstant) { - IntegerValueTypeConstant integerValueTypeConstant = (IntegerValueTypeConstant) value; - if (context.contextDependency == INDEPENDENT) { - expressionType = integerValueTypeConstant.getType(context.expectedType); - ArgumentTypeResolver.updateNumberType(expressionType, expression, context.statementFilter, context.trace); - } - else { - expressionType = integerValueTypeConstant.getUnknownIntegerType(); - } - } - else { - expressionType = ((TypedCompileTimeConstant) value).getType(); - } - - return TypeInfoFactoryPackage.createCheckedTypeInfo(expressionType, context, expression); - } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java index 2d6c0b3c9e9..13300a50328 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java @@ -29,7 +29,9 @@ import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.*; +import org.jetbrains.kotlin.resolve.AnnotationResolver; +import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.TemporaryBindingTrace; import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults; @@ -80,7 +82,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito } @Nullable - private static JetType checkAssignmentType( + private JetType checkAssignmentType( @Nullable JetType assignmentType, @NotNull JetBinaryExpression expression, @NotNull ExpressionTypingContext context @@ -90,7 +92,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito context.trace.report(Errors.ASSIGNMENT_TYPE_MISMATCH.on(expression, context.expectedType)); return null; } - return DataFlowUtils.checkStatementType(expression, context); + return components.dataFlowAnalyzer.checkStatementType(expression, context); } @Override @@ -99,7 +101,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration); - return TypeInfoFactoryPackage.createTypeInfo(DataFlowUtils.checkStatementType(declaration, context), context); + return TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkStatementType(declaration, context), context); } @Override @@ -163,7 +165,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito scope.addVariableDescriptor(propertyDescriptor); components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor); - return typeInfo.replaceType(DataFlowUtils.checkStatementType(property, context)); + return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(property, context)); } @Override @@ -183,7 +185,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito return TypeInfoFactoryPackage.noTypeInfo(context); } components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context); - return typeInfo.replaceType(DataFlowUtils.checkStatementType(multiDeclaration, context)); + return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(multiDeclaration, context)); } @Override @@ -197,7 +199,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass); - return TypeInfoFactoryPackage.createTypeInfo(DataFlowUtils.checkStatementType(klass, context), context); + return TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkStatementType(klass, context), context); } @Override @@ -208,7 +210,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito @Override public JetTypeInfo visitDeclaration(@NotNull JetDeclaration dcl, ExpressionTypingContext context) { - return TypeInfoFactoryPackage.createTypeInfo(DataFlowUtils.checkStatementType(dcl, context), context); + return TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkStatementType(dcl, context), context); } @Override @@ -225,7 +227,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito else { return facade.getTypeInfo(expression, context); } - return DataFlowUtils.checkType(result, expression, context); + return components.dataFlowAnalyzer.checkType(result, expression, context); } @NotNull @@ -320,7 +322,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace); } rightInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(leftInfo.getDataFlowInfo())); - DataFlowUtils.checkType(binaryOperationType, expression, context.replaceExpectedType(leftType).replaceDataFlowInfo(rightInfo.getDataFlowInfo())); + components.dataFlowAnalyzer.checkType(binaryOperationType, expression, context.replaceExpectedType(leftType).replaceDataFlowInfo(rightInfo.getDataFlowInfo())); basic.checkLValue(context.trace, context, leftOperand, right); } temporary.commit(); @@ -368,7 +370,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito if (leftType != null && leftOperand != null) { //if leftType == null, some other error has been generated basic.checkLValue(context.trace, context, leftOperand, right); } - return resultInfo.replaceType(DataFlowUtils.checkStatementType(expression, contextWithExpectedType)); + return resultInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(expression, contextWithExpectedType)); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt index d3ee6f82cc3..540bc53a134 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -27,8 +27,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries -import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE +import org.jetbrains.kotlin.resolve.BindingContextUtils +import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.scopes.WritableScope import org.jetbrains.kotlin.resolve.source.toSourceElement @@ -39,9 +42,7 @@ import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE import org.jetbrains.kotlin.types.TypeUtils.noExpectedType import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.expressions.CoercionStrategy.COERCION_TO_UNIT -import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createCheckedTypeInfo import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo -import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo import org.jetbrains.kotlin.utils.addIfNotNull public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : ExpressionTypingVisitor(facade) { @@ -109,10 +110,10 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express } if (isStatement) { - return createTypeInfo(DataFlowUtils.checkStatementType(function, context), context) + return createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context) } else { - return createCheckedTypeInfo(createFunctionType(functionDescriptor), context, function) + return components.dataFlowAnalyzer.createCheckedTypeInfo(createFunctionType(functionDescriptor), context, function) } } @@ -151,7 +152,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express return createTypeInfo(resultType, context) } - return createCheckedTypeInfo(resultType, context, expression) + return components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, expression) } private fun createFunctionLiteralDescriptor( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.java index 7b3bfc36917..2f8951c6f35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.java @@ -67,7 +67,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { DataFlowInfo newDataFlowInfo = conditionInfo.and(typeInfo.getDataFlowInfo()); context.trace.record(BindingContext.DATAFLOW_INFO_AFTER_CONDITION, expression, newDataFlowInfo); } - return DataFlowUtils.checkType(typeInfo.replaceType(components.builtIns.getBooleanType()), expression, contextWithExpectedType); + return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(components.builtIns.getBooleanType()), expression, contextWithExpectedType); } @Override @@ -76,7 +76,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitWhenExpression(JetWhenExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { - DataFlowUtils.recordExpectedType(contextWithExpectedType.trace, expression, contextWithExpectedType.expectedType); + components.dataFlowAnalyzer.recordExpectedType(contextWithExpectedType.trace, expression, contextWithExpectedType.expectedType); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT); // TODO :change scope according to the bound value in the when header @@ -94,7 +94,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { assert subjectType != null; if (TypeUtils.isNullableType(subjectType) && !WhenChecker.containsNullCase(expression, context.trace)) { ExpressionTypingContext subjectContext = context.replaceExpectedType(TypeUtils.makeNotNullable(subjectType)); - DataFlowUtils.checkPossibleCast(subjectType, JetPsiUtil.safeDeparenthesize(subjectExpression, false), subjectContext); + components.dataFlowAnalyzer.checkPossibleCast(subjectType, JetPsiUtil.safeDeparenthesize(subjectExpression, false), subjectContext); } context = context.replaceDataFlowInfo(typeInfo.getDataFlowInfo()); } @@ -143,8 +143,8 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { commonDataFlowInfo = commonDataFlowInfo.or(context.dataFlowInfo); } - return TypeInfoFactoryPackage.createTypeInfo(expressionTypes.isEmpty() ? null : DataFlowUtils.checkType( - DataFlowUtils.checkImplicitCast( + return TypeInfoFactoryPackage.createTypeInfo(expressionTypes.isEmpty() ? null : components.dataFlowAnalyzer.checkType( + components.dataFlowAnalyzer.checkImplicitCast( CommonSupertypes.commonSupertype(expressionTypes), expression, contextWithExpectedType, isStatement), expression, contextWithExpectedType), @@ -280,8 +280,8 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(expression, type)); } else { - DataFlowInfo ifInfo = DataFlowUtils.extractDataFlowInfoFromCondition(expression, true, context); - DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(expression, false, context); + DataFlowInfo ifInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(expression, true, context); + DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(expression, false, context); return new DataFlowInfos(ifInfo, elseInfo); } return noChange(context); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/TypeInfoFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/TypeInfoFactory.kt index 16808b5843f..b25fb6d7d6d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/TypeInfoFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/TypeInfoFactory.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.expressions.DataFlowUtils +import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer import org.jetbrains.kotlin.types.expressions.JetTypeInfo /* @@ -39,6 +39,3 @@ public fun createTypeInfo(type: JetType?, context: ResolutionContext<*>): JetTyp public fun noTypeInfo(dataFlowInfo: DataFlowInfo): JetTypeInfo = createTypeInfo(null, dataFlowInfo) public fun noTypeInfo(context: ResolutionContext<*>): JetTypeInfo = noTypeInfo(context.dataFlowInfo) - -public fun createCheckedTypeInfo(type: JetType?, context: ResolutionContext<*>, expression: JetExpression): JetTypeInfo = - DataFlowUtils.checkType(createTypeInfo(type, context), expression, context)