ResolutionContext used always for checkType()

This commit is contained in:
Andrey Breslav
2015-01-30 15:18:01 +03:00
parent 0e972acf8c
commit 82ace2b251
3 changed files with 35 additions and 34 deletions
@@ -75,7 +75,7 @@ public class ControlStructureTypingUtils {
) { ) {
SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction(
constructionName.toUpperCase(), argumentNames, isArgumentNullable); constructionName.toUpperCase(), argumentNames, isArgumentNullable);
TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName, context);
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(call, function); ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(call, function);
CallResolver callResolver = expressionTypingServices.getCallResolver(); CallResolver callResolver = expressionTypingServices.getCallResolver();
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate( OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate(
@@ -248,7 +248,8 @@ public class ControlStructureTypingUtils {
@NotNull @NotNull
/*package*/ static TracingStrategy createTracingForSpecialConstruction( /*package*/ static TracingStrategy createTracingForSpecialConstruction(
final @NotNull Call call, final @NotNull Call call,
final @NotNull String constructionName final @NotNull String constructionName,
final @NotNull ExpressionTypingContext context
) { ) {
class CheckTypeContext { class CheckTypeContext {
public BindingTrace trace; public BindingTrace trace;
@@ -272,7 +273,15 @@ public class ControlStructureTypingUtils {
if (typeInfo == null) return false; if (typeInfo == null) return false;
Ref<Boolean> hasError = Ref.create(); Ref<Boolean> hasError = Ref.create();
DataFlowUtils.checkType(typeInfo.getType(), expression, c.expectedType, typeInfo.getDataFlowInfo(), c.trace, hasError); DataFlowUtils.checkType(
typeInfo.getType(),
expression,
context
.replaceExpectedType(c.expectedType)
.replaceDataFlowInfo(typeInfo.getDataFlowInfo())
.replaceBindingTrace(c.trace),
hasError
);
return hasError.get(); return hasError.get();
} }
@@ -156,49 +156,41 @@ public class DataFlowUtils {
@Nullable @Nullable
public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) { public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) {
return checkType(expressionType, expression, context.expectedType, context.dataFlowInfo, context.trace); return checkType(expressionType, expression, context, (Ref<Boolean>) null);
} }
@Nullable @Nullable
public static JetType checkType( public static JetType checkType(
@Nullable JetType expressionType, @NotNull JetExpression expressionToCheck, @Nullable final JetType expressionType,
@NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace @NotNull JetExpression expressionToCheck,
) { @NotNull final ResolutionContext c,
return checkType(expressionType, expressionToCheck, expectedType, dataFlowInfo, trace, null);
}
@Nullable
public static JetType checkType(
@Nullable final JetType expressionType, @NotNull JetExpression expressionToCheck,
@NotNull JetType expectedType, @NotNull final DataFlowInfo dataFlowInfo, @NotNull final BindingTrace trace,
@Nullable Ref<Boolean> hasError @Nullable Ref<Boolean> hasError
) { ) {
if (hasError != null) hasError.set(false); if (hasError != null) hasError.set(false);
final JetExpression expression = JetPsiUtil.safeDeparenthesize(expressionToCheck, false); final JetExpression expression = JetPsiUtil.safeDeparenthesize(expressionToCheck, false);
recordExpectedType(trace, expression, expectedType); recordExpectedType(c.trace, expression, c.expectedType);
if (expressionType == null) return null; if (expressionType == null) return null;
if (noExpectedType(expectedType) || !expectedType.getConstructor().isDenotable() || if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() ||
JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)) { JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, c.expectedType)) {
if (!noExpectedType(expectedType)) { if (!noExpectedType(c.expectedType)) {
Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, expectedType, Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, c.expectedType,
new Approximation.DataFlowExtras() { new Approximation.DataFlowExtras() {
private DataFlowValue getDataFlowValue() { private DataFlowValue getDataFlowValue() {
return DataFlowValueFactory.createDataFlowValue(expression, expressionType, trace.getBindingContext()); return DataFlowValueFactory.createDataFlowValue(expression, expressionType, c.trace.getBindingContext());
} }
@Override @Override
public boolean getCanBeNull() { public boolean getCanBeNull() {
return dataFlowInfo.getNullability(getDataFlowValue()).canBeNull(); return c.dataFlowInfo.getNullability(getDataFlowValue()).canBeNull();
} }
@NotNull
@Override @Override
public Set<JetType> getPossibleTypes() { public Set<JetType> getPossibleTypes() {
return dataFlowInfo.getPossibleTypes(getDataFlowValue()); return c.dataFlowInfo.getPossibleTypes(getDataFlowValue());
} }
@NotNull @NotNull
@@ -209,7 +201,7 @@ public class DataFlowUtils {
} }
); );
if (approximationInfo != null) { if (approximationInfo != null) {
trace.record(BindingContext.EXPRESSION_RESULT_APPROXIMATION, expression, approximationInfo); c.trace.record(BindingContext.EXPRESSION_RESULT_APPROXIMATION, expression, approximationInfo);
} }
} }
@@ -217,25 +209,25 @@ public class DataFlowUtils {
} }
if (expression instanceof JetConstantExpression) { if (expression instanceof JetConstantExpression) {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, trace, expectedType); CompileTimeConstant<?> value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, c.trace, c.expectedType);
if (value instanceof IntegerValueTypeConstant) { if (value instanceof IntegerValueTypeConstant) {
value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, expectedType); value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, c.expectedType);
} }
boolean error = new CompileTimeConstantChecker(trace, true) boolean error = new CompileTimeConstantChecker(c.trace, true)
.checkConstantExpressionType(value, (JetConstantExpression) expression, expectedType); .checkConstantExpressionType(value, (JetConstantExpression) expression, c.expectedType);
if (hasError != null) hasError.set(error); if (hasError != null) hasError.set(error);
return expressionType; return expressionType;
} }
DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, expressionType, trace.getBindingContext()); DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, expressionType, c.trace.getBindingContext());
for (JetType possibleType : dataFlowInfo.getPossibleTypes(dataFlowValue)) { for (JetType possibleType : c.dataFlowInfo.getPossibleTypes(dataFlowValue)) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) { if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, c.expectedType)) {
SmartCastUtils.recordCastOrError(expression, possibleType, trace, dataFlowValue.isStableIdentifier(), false); SmartCastUtils.recordCastOrError(expression, possibleType, c.trace, dataFlowValue.isStableIdentifier(), false);
return possibleType; return possibleType;
} }
} }
trace.report(TYPE_MISMATCH.on(expression, expectedType, expressionType)); c.trace.report(TYPE_MISMATCH.on(expression, c.expectedType, expressionType));
if (hasError != null) hasError.set(true); if (hasError != null) hasError.set(true);
return expressionType; return expressionType;
} }
@@ -307,7 +307,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace); basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace);
} }
dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo(); dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo();
DataFlowUtils.checkType(binaryOperationType, expression, leftType, dataFlowInfo, context.trace); DataFlowUtils.checkType(binaryOperationType, expression, context.replaceExpectedType(leftType).replaceDataFlowInfo(dataFlowInfo));
BasicExpressionTypingVisitor.checkLValue(context.trace, leftOperand); BasicExpressionTypingVisitor.checkLValue(context.trace, leftOperand);
} }
temporary.commit(); temporary.commit();