getType -> getTypeInfo

This commit is contained in:
Alexander Udalov
2012-06-13 17:19:26 +04:00
parent 38e7dde8f6
commit 3e79d3c834
8 changed files with 66 additions and 60 deletions
@@ -146,7 +146,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (innerExpression == null) { if (innerExpression == null) {
return JetTypeInfo.create(null, context.dataFlowInfo); return JetTypeInfo.create(null, context.dataFlowInfo);
} }
JetTypeInfo typeInfo = facade.getType(innerExpression, context.replaceScope(context.scope), isStatement); JetTypeInfo typeInfo = facade.getTypeInfo(innerExpression, context.replaceScope(context.scope), isStatement);
return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo());
} }
@@ -213,14 +213,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType; result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
} }
else { else {
facade.getType(expression.getLeft(), context.replaceExpectedType(NO_EXPECTED_TYPE)); facade.getTypeInfo(expression.getLeft(), context.replaceExpectedType(NO_EXPECTED_TYPE));
} }
return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo); return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo);
} }
private boolean checkBinaryWithTypeRHS(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context, @NotNull JetType targetType) { private boolean checkBinaryWithTypeRHS(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context, @NotNull JetType targetType) {
JetType actualType = facade.getType(expression.getLeft(), context).getType(); JetType actualType = facade.getTypeInfo(expression.getLeft(), context).getType();
if (actualType == null) return false; if (actualType == null) return false;
JetSimpleNameExpression operationSign = expression.getOperationSign(); JetSimpleNameExpression operationSign = expression.getOperationSign();
@@ -532,7 +532,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression(); JetExpression receiverExpression = expression.getReceiverExpression();
ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE); ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
JetTypeInfo receiverTypeInfo = facade.getType(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true)); JetTypeInfo receiverTypeInfo = facade.getTypeInfo(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true));
JetType receiverType = receiverTypeInfo.getType(); JetType receiverType = receiverTypeInfo.getType();
if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo); if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo);
if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());
@@ -764,7 +764,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
referencedName = referencedName == null ? " <?>" : referencedName; referencedName = referencedName == null ? " <?>" : referencedName;
context.labelResolver.enterLabeledElement(new LabelName(referencedName.substring(1)), baseExpression); context.labelResolver.enterLabeledElement(new LabelName(referencedName.substring(1)), baseExpression);
// TODO : Some processing for the label? // TODO : Some processing for the label?
JetTypeInfo typeInfo = facade.getType(baseExpression, context, isStatement); JetTypeInfo typeInfo = facade.getTypeInfo(baseExpression, context, isStatement);
context.labelResolver.exitLabeledElement(baseExpression); context.labelResolver.exitLabeledElement(baseExpression);
return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo());
} }
@@ -772,7 +772,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
IElementType operationType = operationSign.getReferencedNameElementType(); IElementType operationType = operationSign.getReferencedNameElementType();
// Type check the base expression // Type check the base expression
JetTypeInfo typeInfo = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE)); JetTypeInfo typeInfo = facade.getTypeInfo(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
JetType type = typeInfo.getType(); JetType type = typeInfo.getType();
if (type == null) { if (type == null) {
return typeInfo; return typeInfo;
@@ -961,7 +961,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
result = booleanType; result = booleanType;
} }
else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) { else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) {
JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); JetType leftType = facade.getTypeInfo(left, context.replaceScope(context.scope)).getType();
WritableScopeImpl leftScope = newWritableScopeImpl(context, "Left scope of && or ||"); WritableScopeImpl leftScope = newWritableScopeImpl(context, "Left scope of && or ||");
DataFlowInfo flowInfoLeft = DataFlowUtils.extractDataFlowInfoFromCondition(left, operationType == JetTokens.ANDAND, leftScope, context); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition DataFlowInfo flowInfoLeft = DataFlowUtils.extractDataFlowInfoFromCondition(left, operationType == JetTokens.ANDAND, leftScope, context); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition
WritableScopeImpl rightScope = operationType == JetTokens.ANDAND WritableScopeImpl rightScope = operationType == JetTokens.ANDAND
@@ -969,7 +969,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
: newWritableScopeImpl(context, "Right scope of && or ||"); : newWritableScopeImpl(context, "Right scope of && or ||");
JetType rightType = right == null JetType rightType = right == null
? null ? null
: facade.getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)).getType(); : facade.getTypeInfo(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)).getType();
if (leftType != null && !isBoolean(leftType)) { if (leftType != null && !isBoolean(leftType)) {
context.trace.report(TYPE_MISMATCH.on(left, booleanType, leftType)); context.trace.report(TYPE_MISMATCH.on(left, booleanType, leftType));
} }
@@ -979,17 +979,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
result = booleanType; result = booleanType;
} }
else if (operationType == JetTokens.ELVIS) { else if (operationType == JetTokens.ELVIS) {
JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); JetType leftType = facade.getTypeInfo(left, context.replaceScope(context.scope)).getType();
JetType rightType = right == null JetType rightType = right == null
? null ? null
: facade.getType(right, contextWithExpectedType.replaceScope(context.scope)).getType(); : facade.getTypeInfo(right, contextWithExpectedType.replaceScope(context.scope)).getType();
if (leftType != null) { if (leftType != null) {
if (!leftType.isNullable()) { if (!leftType.isNullable()) {
context.trace.report(USELESS_ELVIS.on(left, leftType)); context.trace.report(USELESS_ELVIS.on(left, leftType));
} }
if (rightType != null) { if (rightType != null) {
DataFlowUtils.checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType); DataFlowUtils.checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType);
return JetTypeInfo.create(TypeUtils.makeNullableAsSpecified(CommonSupertypes.commonSupertype(Arrays.asList(leftType, rightType)), rightType.isNullable()), context.dataFlowInfo); return JetTypeInfo.create(TypeUtils.makeNullableAsSpecified(
CommonSupertypes.commonSupertype(Arrays.asList(leftType, rightType)), rightType.isNullable()),
context.dataFlowInfo);
} }
} }
} }
@@ -1018,9 +1020,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetExpression right = expression.getRight(); JetExpression right = expression.getRight();
// TODO : duplicated effort for == and != // TODO : duplicated effort for == and !=
JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); JetType leftType = facade.getTypeInfo(left, context.replaceScope(context.scope)).getType();
if (leftType != null && right != null) { if (leftType != null && right != null) {
JetType rightType = facade.getType(right, context.replaceScope(context.scope)).getType(); JetType rightType = facade.getTypeInfo(right, context.replaceScope(context.scope)).getType();
if (rightType != null) { if (rightType != null) {
if (TypeUtils.isIntersectionEmpty(leftType, rightType)) { if (TypeUtils.isIntersectionEmpty(leftType, rightType)) {
@@ -1103,7 +1105,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry) { public void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry) {
JetExpression entryExpression = entry.getExpression(); JetExpression entryExpression = entry.getExpression();
if (entryExpression != null) { if (entryExpression != null) {
facade.getType(entryExpression, context); facade.getTypeInfo(entryExpression, context);
} }
value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; value[0] = CompileTimeConstantResolver.OUT_OF_RANGE;
} }
@@ -1140,7 +1142,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (baseExpression == null) { if (baseExpression == null) {
return JetTypeInfo.create(null, data.dataFlowInfo); return JetTypeInfo.create(null, data.dataFlowInfo);
} }
return facade.getType(baseExpression, data); return facade.getTypeInfo(baseExpression, data);
} }
@Override @Override
@@ -1165,7 +1167,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull BindingTrace traceForResolveResult, @NotNull BindingTrace traceForResolveResult,
boolean isGet) { boolean isGet) {
JetType arrayType = facade.getType(arrayAccessExpression.getArrayExpression(), context).getType(); JetType arrayType = facade.getTypeInfo(arrayAccessExpression.getArrayExpression(), context).getType();
if (arrayType == null) return null; if (arrayType == null) return null;
ExpressionReceiver receiver = new ExpressionReceiver(arrayAccessExpression.getArrayExpression(), arrayType); ExpressionReceiver receiver = new ExpressionReceiver(arrayAccessExpression.getArrayExpression(), arrayType);
@@ -65,7 +65,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) {
if (condition != null) { if (condition != null) {
JetType conditionType = facade.getType(condition, context.replaceScope(scope)).getType(); JetType conditionType = facade.getTypeInfo(condition, context.replaceScope(scope)).getType();
if (conditionType != null && !isBoolean(conditionType)) { if (conditionType != null && !isBoolean(conditionType)) {
context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType));
@@ -100,7 +100,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (type != null && JetStandardClasses.isNothing(type)) { if (type != null && JetStandardClasses.isNothing(type)) {
facade.setResultingDataFlowInfo(elseInfo); facade.setResultingDataFlowInfo(elseInfo);
} }
return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement, context.dataFlowInfo); return DataFlowUtils.checkImplicitCast(
DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression,
contextWithExpectedType, isStatement, context.dataFlowInfo);
} }
return JetTypeInfo.create(null, context.dataFlowInfo); return JetTypeInfo.create(null, context.dataFlowInfo);
} }
@@ -205,7 +207,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
context.trace.record(BindingContext.BLOCK, function); context.trace.record(BindingContext.BLOCK, function);
} }
else { else {
facade.getType(body, context.replaceScope(context.scope)); facade.getTypeInfo(body, context.replaceScope(context.scope));
} }
} }
else if (body != null) { else if (body != null) {
@@ -419,7 +421,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (catchBody != null) { if (catchBody != null) {
WritableScope catchScope = newWritableScopeImpl(context, "Catch scope"); WritableScope catchScope = newWritableScopeImpl(context, "Catch scope");
catchScope.addVariableDescriptor(variableDescriptor); catchScope.addVariableDescriptor(variableDescriptor);
JetType type = facade.getType(catchBody, context.replaceScope(catchScope)).getType(); JetType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType();
if (type != null) { if (type != null) {
types.add(type); types.add(type);
} }
@@ -427,9 +429,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
} }
} }
if (finallyBlock != null) { if (finallyBlock != null) {
facade.getType(finallyBlock.getFinalExpression(), context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); facade.getTypeInfo(finallyBlock.getFinalExpression(), context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE));
} }
JetType type = facade.getType(tryBlock, context).getType(); JetType type = facade.getTypeInfo(tryBlock, context).getType();
if (type != null) { if (type != null) {
types.add(type); types.add(type);
} }
@@ -446,7 +448,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
JetExpression thrownExpression = expression.getThrownExpression(); JetExpression thrownExpression = expression.getThrownExpression();
if (thrownExpression != null) { if (thrownExpression != null) {
JetType throwableType = JetStandardLibrary.getInstance().getThrowable().getDefaultType(); JetType throwableType = JetStandardLibrary.getInstance().getThrowable().getDefaultType();
facade.getType(thrownExpression, context.replaceExpectedType(throwableType).replaceScope(context.scope)); facade.getTypeInfo(thrownExpression, context.replaceExpectedType(throwableType).replaceScope(context.scope));
} }
return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo); return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo);
} }
@@ -501,7 +503,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
} }
} }
if (returnedExpression != null) { if (returnedExpression != null) {
facade.getType(returnedExpression, context.replaceExpectedType(expectedType).replaceScope(context.scope)); facade.getTypeInfo(returnedExpression, context.replaceExpectedType(expectedType).replaceScope(context.scope));
} }
else { else {
if (expectedType != TypeUtils.NO_EXPECTED_TYPE && expectedType != null && !JetStandardClasses.isUnit(expectedType)) { if (expectedType != TypeUtils.NO_EXPECTED_TYPE && expectedType != null && !JetStandardClasses.isUnit(expectedType)) {
@@ -26,11 +26,11 @@ import org.jetbrains.jet.lang.types.JetTypeInfo;
*/ */
public interface ExpressionTypingFacade { public interface ExpressionTypingFacade {
@NotNull @NotNull
JetTypeInfo safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context); JetTypeInfo safeGetTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context);
@NotNull @NotNull
JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context); JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context);
@NotNull @NotNull
JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement); JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement);
} }
@@ -120,13 +120,13 @@ public class ExpressionTypingServices {
ExpressionTypingContext context = ExpressionTypingContext.newContext( ExpressionTypingContext context = ExpressionTypingContext.newContext(
this, trace, scope, dataFlowInfo, expectedType, false this, trace, scope, dataFlowInfo, expectedType, false
); );
return expressionTypingFacade.getType(expression, context).getType(); return expressionTypingFacade.getTypeInfo(expression, context).getType();
} }
public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull BindingTrace trace) { public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull BindingTrace trace) {
ExpressionTypingContext context = ExpressionTypingContext.newContext( ExpressionTypingContext context = ExpressionTypingContext.newContext(
this, trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, true); this, trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, true);
return expressionTypingFacade.getType(expression, context).getType(); return expressionTypingFacade.getTypeInfo(expression, context).getType();
// return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); // return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE));
} }
@@ -171,7 +171,7 @@ public class ExpressionTypingServices {
getBlockReturnedType(newContext.scope, blockExpression, CoercionStrategy.COERCION_TO_UNIT, context, trace); getBlockReturnedType(newContext.scope, blockExpression, CoercionStrategy.COERCION_TO_UNIT, context, trace);
} }
else { else {
expressionTypingFacade.getType(bodyExpression, newContext, !blockBody); expressionTypingFacade.getTypeInfo(bodyExpression, newContext, !blockBody);
} }
} }
@@ -215,7 +215,7 @@ public class ExpressionTypingServices {
JetExpression bodyExpression = function.getBodyExpression(); JetExpression bodyExpression = function.getBodyExpression();
assert bodyExpression != null; assert bodyExpression != null;
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
expressionTypingFacade.getType(bodyExpression, ExpressionTypingContext.newContext( expressionTypingFacade.getTypeInfo(bodyExpression, ExpressionTypingContext.newContext(
this, this,
trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, false), !function.hasBlockBody()); trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, false), !function.hasBlockBody());
//todo function literals //todo function literals
@@ -285,13 +285,13 @@ public class ExpressionTypingServices {
final boolean[] mismatch = new boolean[1]; final boolean[] mismatch = new boolean[1];
ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch); ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch);
newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType); newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType);
result = blockLevelVisitor.getType(statementExpression, newContext, true); result = blockLevelVisitor.getTypeInfo(statementExpression, newContext, true);
if (mismatch[0]) { if (mismatch[0]) {
TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace); TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace);
mismatch[0] = false; mismatch[0] = false;
ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch); ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch);
newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE); newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE);
result = blockLevelVisitor.getType(statementExpression, newContext, true); result = blockLevelVisitor.getTypeInfo(statementExpression, newContext, true);
if (mismatch[0]) { if (mismatch[0]) {
temporaryTraceExpectingUnit.commit(); temporaryTraceExpectingUnit.commit();
} }
@@ -305,11 +305,11 @@ public class ExpressionTypingServices {
} }
else { else {
newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType); newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType);
result = blockLevelVisitor.getType(statementExpression, newContext, true); result = blockLevelVisitor.getTypeInfo(statementExpression, newContext, true);
} }
} }
else { else {
result = blockLevelVisitor.getType(statementExpression, newContext, true); result = blockLevelVisitor.getTypeInfo(statementExpression, newContext, true);
if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) { if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) {
boolean mightBeUnit = false; boolean mightBeUnit = false;
if (statementExpression instanceof JetDeclaration) { if (statementExpression instanceof JetDeclaration) {
@@ -331,7 +331,7 @@ public class ExpressionTypingServices {
} }
} }
else { else {
result = blockLevelVisitor.getType(statementExpression, newContext, true); result = blockLevelVisitor.getTypeInfo(statementExpression, newContext, true);
} }
DataFlowInfo newDataFlowInfo = blockLevelVisitor.getResultingDataFlowInfo(); DataFlowInfo newDataFlowInfo = blockLevelVisitor.getResultingDataFlowInfo();
@@ -71,12 +71,12 @@ public class ExpressionTypingUtils {
@Nullable @Nullable
protected static ExpressionReceiver getExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { protected static ExpressionReceiver getExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) {
return getExpressionReceiver(expression, facade.getType(expression, context).getType()); return getExpressionReceiver(expression, facade.getTypeInfo(expression, context).getType());
} }
@NotNull @NotNull
protected static ExpressionReceiver safeGetExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { protected static ExpressionReceiver safeGetExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) {
return new ExpressionReceiver(expression, facade.safeGetType(expression, context).getType()); return new ExpressionReceiver(expression, facade.safeGetTypeInfo(expression, context).getType());
} }
@NotNull @NotNull
@@ -92,8 +92,8 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
@Override @Override
@NotNull @NotNull
public final JetTypeInfo safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context) { public final JetTypeInfo safeGetTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context) {
JetTypeInfo typeInfo = getType(expression, context); JetTypeInfo typeInfo = getTypeInfo(expression, context);
if (typeInfo.getType() != null) { if (typeInfo.getType() != null) {
return typeInfo; return typeInfo;
} }
@@ -102,17 +102,17 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
@Override @Override
@NotNull @NotNull
public final JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context) { public final JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context) {
return getType(expression, context, this); return getTypeInfo(expression, context, this);
} }
@NotNull @NotNull
public final JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement) { public final JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement) {
if (!isStatement) return getType(expression, context); if (!isStatement) return getTypeInfo(expression, context);
if (statements != null) { if (statements != null) {
return getType(expression, context, statements); return getTypeInfo(expression, context, statements);
} }
return getType(expression, context, createStatementVisitor(context)); return getTypeInfo(expression, context, createStatementVisitor(context));
} }
private ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) { private ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
@@ -125,16 +125,18 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
} }
@NotNull @NotNull
private JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context, JetVisitor<JetTypeInfo, ExpressionTypingContext> visitor) { private JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, JetVisitor<JetTypeInfo, ExpressionTypingContext> visitor) {
if (context.trace.get(BindingContext.PROCESSED, expression)) { if (context.trace.get(BindingContext.PROCESSED, expression)) {
return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), context.dataFlowInfo); return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression),
context.dataFlowInfo);
} }
JetTypeInfo result; JetTypeInfo result;
try { try {
result = expression.accept(visitor, context); result = expression.accept(visitor, context);
// Some recursive definitions (object expressions) must put their types in the cache manually: // Some recursive definitions (object expressions) must put their types in the cache manually:
if (context.trace.get(BindingContext.PROCESSED, expression)) { if (context.trace.get(BindingContext.PROCESSED, expression)) {
return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), result.getDataFlowInfo()); return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression),
result.getDataFlowInfo());
} }
if (result.getType() instanceof DeferredType) { if (result.getType() instanceof DeferredType) {
@@ -112,7 +112,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
JetExpression initializer = property.getInitializer(); JetExpression initializer = property.getInitializer();
if (property.getPropertyTypeRef() != null && initializer != null) { if (property.getPropertyTypeRef() != null && initializer != null) {
JetType outType = propertyDescriptor.getType(); JetType outType = propertyDescriptor.getType();
JetType initializerType = facade.getType(initializer, context.replaceExpectedType(outType).replaceScope(scope)).getType(); JetType initializerType = facade.getTypeInfo(initializer, context.replaceExpectedType(outType).replaceScope(scope)).getType();
} }
{ {
@@ -169,7 +169,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
result = visitAssignmentOperation(expression, context); result = visitAssignmentOperation(expression, context);
} }
else { else {
return facade.getType(expression, context); return facade.getTypeInfo(expression, context);
} }
return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo); return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo);
} }
@@ -187,9 +187,9 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
if (left == null) return null; if (left == null) return null;
JetType leftType = facade.getType(left, context).getType(); JetType leftType = facade.getTypeInfo(left, context).getType();
if (leftType == null) { if (leftType == null) {
facade.getType(right, context); facade.getTypeInfo(right, context);
context.trace.report(UNRESOLVED_REFERENCE.on(operationSign)); context.trace.report(UNRESOLVED_REFERENCE.on(operationSign));
temporaryBindingTrace.commit(); temporaryBindingTrace.commit();
return null; return null;
@@ -217,7 +217,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.getType(right, context); facade.getTypeInfo(right, context);
context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors); context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors);
} }
else if (assignmentOperationType != null) { else if (assignmentOperationType != null) {
@@ -250,9 +250,9 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
basic.checkLValue(context.trace, arrayAccessExpression); basic.checkLValue(context.trace, arrayAccessExpression);
return checkAssignmentType(assignmentType, expression, contextWithExpectedType); return checkAssignmentType(assignmentType, expression, contextWithExpectedType);
} }
JetType leftType = facade.getType(expression.getLeft(), context.replaceScope(scope)).getType(); JetType leftType = facade.getTypeInfo(expression.getLeft(), context.replaceScope(scope)).getType();
if (right != null) { if (right != null) {
JetType rightType = facade.getType(right, context.replaceExpectedType(leftType).replaceScope(scope)).getType(); JetType rightType = facade.getTypeInfo(right, context.replaceExpectedType(leftType).replaceScope(scope)).getType();
} }
if (leftType != null) { //if leftType == null, some another error has been generated if (leftType != null) { //if leftType == null, some another error has been generated
basic.checkLValue(context.trace, expression.getLeft()); basic.checkLValue(context.trace, expression.getLeft());
@@ -263,7 +263,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override @Override
public JetTypeInfo visitExpression(JetExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitExpression(JetExpression expression, ExpressionTypingContext context) {
return facade.getType(expression, context); return facade.getTypeInfo(expression, context);
} }
@Override @Override
@@ -55,7 +55,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
public JetTypeInfo visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) { public JetTypeInfo visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) {
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
JetExpression leftHandSide = expression.getLeftHandSide(); JetExpression leftHandSide = expression.getLeftHandSide();
JetType knownType = facade.safeGetType(leftHandSide, context.replaceScope(context.scope)).getType(); JetType knownType = facade.safeGetTypeInfo(leftHandSide, context.replaceScope(context.scope)).getType();
JetPattern pattern = expression.getPattern(); JetPattern pattern = expression.getPattern();
DataFlowInfo newDataFlowInfo = context.dataFlowInfo; DataFlowInfo newDataFlowInfo = context.dataFlowInfo;
if (pattern != null) { if (pattern != null) {
@@ -146,7 +146,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
if (rangeExpression == null) return; if (rangeExpression == null) return;
if (expectedCondition) { if (expectedCondition) {
context.trace.report(EXPECTED_CONDITION.on(condition)); context.trace.report(EXPECTED_CONDITION.on(condition));
facade.getType(rangeExpression, context); facade.getTypeInfo(rangeExpression, context);
return; return;
} }
if (!facade.checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context)) { if (!facade.checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context)) {
@@ -246,7 +246,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
public void visitExpressionPattern(JetExpressionPattern pattern) { public void visitExpressionPattern(JetExpressionPattern pattern) {
JetExpression expression = pattern.getExpression(); JetExpression expression = pattern.getExpression();
if (expression == null) return; if (expression == null) return;
JetType type = facade.getType(expression, context.replaceScope(scopeToExtend)).getType(); JetType type = facade.getTypeInfo(expression, context.replaceScope(scopeToExtend)).getType();
if (conditionExpected) { if (conditionExpected) {
JetType booleanType = JetStandardLibrary.getInstance().getBooleanType(); JetType booleanType = JetStandardLibrary.getInstance().getBooleanType();
if (type != null && !JetTypeChecker.INSTANCE.equalTypes(booleanType, type)) { if (type != null && !JetTypeChecker.INSTANCE.equalTypes(booleanType, type)) {