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(
constructionName.toUpperCase(), argumentNames, isArgumentNullable);
TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName);
TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName, context);
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(call, function);
CallResolver callResolver = expressionTypingServices.getCallResolver();
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate(
@@ -248,7 +248,8 @@ public class ControlStructureTypingUtils {
@NotNull
/*package*/ static TracingStrategy createTracingForSpecialConstruction(
final @NotNull Call call,
final @NotNull String constructionName
final @NotNull String constructionName,
final @NotNull ExpressionTypingContext context
) {
class CheckTypeContext {
public BindingTrace trace;
@@ -272,7 +273,15 @@ public class ControlStructureTypingUtils {
if (typeInfo == null) return false;
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();
}
@@ -156,49 +156,41 @@ public class DataFlowUtils {
@Nullable
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
public static JetType checkType(
@Nullable JetType expressionType, @NotNull JetExpression expressionToCheck,
@NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace
) {
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 final JetType expressionType,
@NotNull JetExpression expressionToCheck,
@NotNull final ResolutionContext c,
@Nullable Ref<Boolean> hasError
) {
if (hasError != null) hasError.set(false);
final JetExpression expression = JetPsiUtil.safeDeparenthesize(expressionToCheck, false);
recordExpectedType(trace, expression, expectedType);
recordExpectedType(c.trace, expression, c.expectedType);
if (expressionType == null) return null;
if (noExpectedType(expectedType) || !expectedType.getConstructor().isDenotable() ||
JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)) {
if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() ||
JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, c.expectedType)) {
if (!noExpectedType(expectedType)) {
Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, expectedType,
if (!noExpectedType(c.expectedType)) {
Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, c.expectedType,
new Approximation.DataFlowExtras() {
private DataFlowValue getDataFlowValue() {
return DataFlowValueFactory.createDataFlowValue(expression, expressionType, trace.getBindingContext());
return DataFlowValueFactory.createDataFlowValue(expression, expressionType, c.trace.getBindingContext());
}
@Override
public boolean getCanBeNull() {
return dataFlowInfo.getNullability(getDataFlowValue()).canBeNull();
return c.dataFlowInfo.getNullability(getDataFlowValue()).canBeNull();
}
@NotNull
@Override
public Set<JetType> getPossibleTypes() {
return dataFlowInfo.getPossibleTypes(getDataFlowValue());
return c.dataFlowInfo.getPossibleTypes(getDataFlowValue());
}
@NotNull
@@ -209,7 +201,7 @@ public class DataFlowUtils {
}
);
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) {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, trace, expectedType);
CompileTimeConstant<?> value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, c.trace, c.expectedType);
if (value instanceof IntegerValueTypeConstant) {
value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, expectedType);
value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, c.expectedType);
}
boolean error = new CompileTimeConstantChecker(trace, true)
.checkConstantExpressionType(value, (JetConstantExpression) expression, expectedType);
boolean error = new CompileTimeConstantChecker(c.trace, true)
.checkConstantExpressionType(value, (JetConstantExpression) expression, c.expectedType);
if (hasError != null) hasError.set(error);
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)) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) {
SmartCastUtils.recordCastOrError(expression, possibleType, trace, dataFlowValue.isStableIdentifier(), false);
for (JetType possibleType : c.dataFlowInfo.getPossibleTypes(dataFlowValue)) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, c.expectedType)) {
SmartCastUtils.recordCastOrError(expression, possibleType, c.trace, dataFlowValue.isStableIdentifier(), false);
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);
return expressionType;
}
@@ -307,7 +307,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace);
}
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);
}
temporary.commit();