From 38e7dde8f6d7605a456434042193d362857321a2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 13 Jun 2012 17:14:37 +0400 Subject: [PATCH] visitor methods return JetTypeInfo instead of JetType --- .../jet/lang/resolve/ScriptBodyResolver.java | 2 +- .../jetbrains/jet/lang/types/JetTypeInfo.java | 50 +++++++ .../BasicExpressionTypingVisitor.java | 140 +++++++++--------- .../ClosureExpressionsTypingVisitor.java | 14 +- .../ControlStructureTypingVisitor.java | 68 ++++----- .../lang/types/expressions/DataFlowUtils.java | 22 ++- .../expressions/ExpressionTypingFacade.java | 12 +- .../expressions/ExpressionTypingServices.java | 23 +-- .../expressions/ExpressionTypingUtils.java | 4 +- .../expressions/ExpressionTypingVisitor.java | 4 +- .../ExpressionTypingVisitorDispatcher.java | 71 ++++----- .../ExpressionTypingVisitorForStatements.java | 61 ++++---- .../PatternMatchingTypingVisitor.java | 21 +-- 13 files changed, 283 insertions(+), 209 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInfo.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ScriptBodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ScriptBodyResolver.java index d3d8262d944..857150b7bc6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ScriptBodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ScriptBodyResolver.java @@ -77,7 +77,7 @@ public class ScriptBodyResolver { DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, false); - JetType returnType = expressionTypingServices.getBlockReturnedType(scope, declaration.getBlockExpression(), CoercionStrategy.NO_COERCION, context, trace); + JetType returnType = expressionTypingServices.getBlockReturnedType(scope, declaration.getBlockExpression(), CoercionStrategy.NO_COERCION, context, trace).getType(); if (returnType == null) { returnType = ErrorUtils.createErrorType("getBlockReturnedType returned null"); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInfo.java new file mode 100644 index 00000000000..b1c3c131831 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInfo.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; + +/** + * @author udalov + */ +public class JetTypeInfo { + + @NotNull + public static JetTypeInfo create(@Nullable JetType type, @NotNull DataFlowInfo dataFlowInfo) { + return new JetTypeInfo(type, dataFlowInfo); + } + + private final JetType type; + private final DataFlowInfo dataFlowInfo; + + private JetTypeInfo(@Nullable JetType type, @NotNull DataFlowInfo dataFlowInfo) { + this.type = type; + this.dataFlowInfo = dataFlowInfo; + } + + @Nullable + public JetType getType() { + return type; + } + + @NotNull + public DataFlowInfo getDataFlowInfo() { + return dataFlowInfo; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 131c84d9432..a8973e53394 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -69,12 +69,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitSimpleNameExpression(JetSimpleNameExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitSimpleNameExpression(JetSimpleNameExpression expression, ExpressionTypingContext context) { // TODO : other members // TODO : type substitutions??? JetType type = DataFlowUtils.checkType(getSelectorReturnType(NO_RECEIVER, null, expression, context), expression, context); ExpressionTypingUtils.checkWrappingInRef(expression, context); - return type; // TODO : Extensions to this + return JetTypeInfo.create(type, context.dataFlowInfo); // TODO : Extensions to this } @Nullable @@ -137,20 +137,21 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context) { return visitParenthesizedExpression(expression, context, false); } - public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context, boolean isStatement) { + public JetTypeInfo visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context, boolean isStatement) { JetExpression innerExpression = expression.getExpression(); if (innerExpression == null) { - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } - return DataFlowUtils.checkType(facade.getType(innerExpression, context.replaceScope(context.scope), isStatement), expression, context); + JetTypeInfo typeInfo = facade.getType(innerExpression, context.replaceScope(context.scope), isStatement); + return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); } @Override - public JetType visitConstantExpression(JetConstantExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitConstantExpression(JetConstantExpression expression, ExpressionTypingContext context) { ASTNode node = expression.getNode(); IElementType elementType = node.getElementType(); String text = node.getText(); @@ -179,16 +180,16 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (value instanceof ErrorValue) { ErrorValue errorValue = (ErrorValue) value; context.trace.report(ERROR_COMPILE_TIME_VALUE.on(node.getPsi(), errorValue.getMessage())); - return getDefaultType(elementType); + return JetTypeInfo.create(getDefaultType(elementType), context.dataFlowInfo); } else { context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, value); - return DataFlowUtils.checkType(value.getType(standardLibrary), expression, context); + return DataFlowUtils.checkType(value.getType(standardLibrary), expression, context, context.dataFlowInfo); } } @Override - public JetType visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) { + public JetTypeInfo visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) { JetTypeReference right = expression.getRight(); JetType result = null; if (right != null) { @@ -214,12 +215,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { else { facade.getType(expression.getLeft(), context.replaceExpectedType(NO_EXPECTED_TYPE)); } - return DataFlowUtils.checkType(result, expression, context); + return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo); } private boolean checkBinaryWithTypeRHS(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context, @NotNull JetType targetType) { - JetType actualType = facade.getType(expression.getLeft(), context); + JetType actualType = facade.getType(expression.getLeft(), context).getType(); if (actualType == null) return false; JetSimpleNameExpression operationSign = expression.getOperationSign(); @@ -345,7 +346,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) { List entries = expression.getEntries(); List types = new ArrayList(); for (JetExpression entry : entries) { @@ -354,11 +355,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (context.expectedType != NO_EXPECTED_TYPE && JetStandardClasses.isTupleType(context.expectedType)) { List enrichedTypes = checkArgumentTypes(types, entries, context.expectedType.getArguments(), context); if (enrichedTypes != types) { - return JetStandardClasses.getTupleType(enrichedTypes); + return JetTypeInfo.create(JetStandardClasses.getTupleType(enrichedTypes), context.dataFlowInfo); } } // TODO : labels - return DataFlowUtils.checkType(JetStandardClasses.getTupleType(types), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getTupleType(types), expression, context, context.dataFlowInfo); } @NotNull @@ -374,7 +375,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) { JetType result = null; ReceiverDescriptor thisReceiver = resolveToReceiver(expression, context, false); @@ -387,19 +388,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getInstanceReference(), result); } } - return DataFlowUtils.checkType(result, expression, context); + return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo); } @Override - public JetType visitSuperExpression(JetSuperExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitSuperExpression(JetSuperExpression expression, ExpressionTypingContext context) { if (!context.namespacesAllowed) { context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(expression, expression.getText())); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } JetType result = null; ReceiverDescriptor thisReceiver = resolveToReceiver(expression, context, true); - if (thisReceiver == null) return null; + if (thisReceiver == null) return JetTypeInfo.create(null, context.dataFlowInfo); if (!thisReceiver.exists()) { context.trace.report(SUPER_NOT_AVAILABLE.on(expression)); @@ -476,7 +477,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } } } - return DataFlowUtils.checkType(result, expression, context); + return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo); } @Nullable // No class receivers @@ -509,30 +510,31 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { return visitBlockExpression(expression, context, false); } - public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context, boolean isStatement) { + public JetTypeInfo visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context, boolean isStatement) { return context.expressionTypingServices.getBlockReturnedType(context.scope, expression, isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION, context, context.trace); } @Override - public JetType visitHashQualifiedExpression(JetHashQualifiedExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitHashQualifiedExpression(JetHashQualifiedExpression expression, ExpressionTypingContext context) { context.trace.report(UNSUPPORTED.on(expression, getClass().getCanonicalName())); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } @Override - public JetType visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext context) { // TODO : functions as values JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression receiverExpression = expression.getReceiverExpression(); ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE); - JetType receiverType = facade.getType(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true)); - if (selectorExpression == null) return null; + JetTypeInfo receiverTypeInfo = facade.getType(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true)); + JetType receiverType = receiverTypeInfo.getType(); + if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo); if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); if (selectorExpression instanceof JetSimpleNameExpression) { @@ -555,7 +557,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (result != null) { context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, result); } - return DataFlowUtils.checkType(result, expression, context); + return DataFlowUtils.checkType(result, expression, context, receiverTypeInfo.getDataFlowInfo()); } private void propagateConstantValues(JetQualifiedExpression expression, ExpressionTypingContext context, JetSimpleNameExpression selectorExpression) { @@ -740,19 +742,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { JetType expressionType = getCallExpressionType(expression, NO_RECEIVER, null, context); - return DataFlowUtils.checkType(expressionType, expression, context); + return DataFlowUtils.checkType(expressionType, expression, context, context.dataFlowInfo); } @Override - public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { return visitUnaryExpression(expression, context, false); } - public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context, boolean isStatement) { + public JetTypeInfo visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context, boolean isStatement) { JetExpression baseExpression = expression.getBaseExpression(); - if (baseExpression == null) return null; + if (baseExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo); JetSimpleNameExpression operationSign = expression.getOperationReference(); @@ -762,32 +764,34 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { referencedName = referencedName == null ? " " : referencedName; context.labelResolver.enterLabeledElement(new LabelName(referencedName.substring(1)), baseExpression); // TODO : Some processing for the label? - JetType type = facade.getType(baseExpression, context, isStatement); + JetTypeInfo typeInfo = facade.getType(baseExpression, context, isStatement); context.labelResolver.exitLabeledElement(baseExpression); - return DataFlowUtils.checkType(type, expression, context); + return DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); } IElementType operationType = operationSign.getReferencedNameElementType(); // Type check the base expression - JetType type = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE)); + JetTypeInfo typeInfo = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE)); + JetType type = typeInfo.getType(); if (type == null) { - return null; + return typeInfo; } + DataFlowInfo dataFlowInfo = typeInfo.getDataFlowInfo(); // Special case for expr!! if (operationType == JetTokens.EXCLEXCL) { if (isKnownToBeNotNull(baseExpression, context)) { context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, type)); } - return DataFlowUtils.checkType(TypeUtils.makeNotNullable(type), expression, context); + return DataFlowUtils.checkType(TypeUtils.makeNotNullable(type), expression, context, dataFlowInfo); } // Conventions for unary operations Name name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType); if (name == null) { context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression")); - return null; + return JetTypeInfo.create(null, dataFlowInfo); } // a[i]++/-- takes special treatment because it is actually let j = i, arr = a in arr.set(j, a.get(j).inc()) @@ -808,7 +812,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { name); if (!resolutionResults.isSuccess()) { - return null; + return JetTypeInfo.create(null, dataFlowInfo); } // Computing the return type @@ -836,7 +840,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { else { result = returnType; } - return DataFlowUtils.checkType(result, expression, context); + return DataFlowUtils.checkType(result, expression, context, dataFlowInfo); } private boolean isKnownToBeNotNull(JetExpression expression, ExpressionTypingContext context) { @@ -871,13 +875,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitIdeTemplateExpression(JetIdeTemplateExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitIdeTemplateExpression(JetIdeTemplateExpression expression, ExpressionTypingContext context) { context.trace.report(UNRESOLVED_IDE_TEMPLATE.on(expression, ObjectUtils.notNull(expression.getText(), ""))); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } @Override - public JetType visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetTypeInfo visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); JetSimpleNameExpression operationSign = expression.getOperationReference(); @@ -951,13 +955,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) { if (right == null) { result = ErrorUtils.createErrorType("No right argument"); // TODO - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } checkInExpression(expression, expression.getOperationReference(), expression.getLeft(), expression.getRight(), context); result = booleanType; } else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) { - JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); 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 WritableScopeImpl rightScope = operationType == JetTokens.ANDAND @@ -965,7 +969,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { : newWritableScopeImpl(context, "Right scope of && or ||"); JetType rightType = right == null ? null - : facade.getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)); + : facade.getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)).getType(); if (leftType != null && !isBoolean(leftType)) { context.trace.report(TYPE_MISMATCH.on(left, booleanType, leftType)); } @@ -975,17 +979,17 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { result = booleanType; } else if (operationType == JetTokens.ELVIS) { - JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); JetType rightType = right == null ? null - : facade.getType(right, contextWithExpectedType.replaceScope(context.scope)); + : facade.getType(right, contextWithExpectedType.replaceScope(context.scope)).getType(); if (leftType != null) { if (!leftType.isNullable()) { context.trace.report(USELESS_ELVIS.on(left, leftType)); } if (rightType != null) { DataFlowUtils.checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType); - return TypeUtils.makeNullableAsSpecified(CommonSupertypes.commonSupertype(Arrays.asList(leftType, rightType)), rightType.isNullable()); + return JetTypeInfo.create(TypeUtils.makeNullableAsSpecified(CommonSupertypes.commonSupertype(Arrays.asList(leftType, rightType)), rightType.isNullable()), context.dataFlowInfo); } } } @@ -993,7 +997,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation")); } } - return DataFlowUtils.checkType(result, expression, contextWithExpectedType); + return DataFlowUtils.checkType(result, expression, contextWithExpectedType, context.dataFlowInfo); } public boolean checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { @@ -1014,9 +1018,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetExpression right = expression.getRight(); // TODO : duplicated effort for == and != - JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + JetType leftType = facade.getType(left, context.replaceScope(context.scope)).getType(); if (leftType != null && right != null) { - JetType rightType = facade.getType(right, context.replaceScope(context.scope)); + JetType rightType = facade.getType(right, context.replaceScope(context.scope)).getType(); if (rightType != null) { if (TypeUtils.isIntersectionEmpty(leftType, rightType)) { @@ -1049,10 +1053,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitArrayAccessExpression(JetArrayAccessExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitArrayAccessExpression(JetArrayAccessExpression expression, ExpressionTypingContext context) { JetType type = resolveArrayAccessGetMethod(expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); DataFlowUtils.checkType(type, expression, context); - return type; + return JetTypeInfo.create(type, context.dataFlowInfo); } @Nullable @@ -1072,23 +1076,23 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitDeclaration(JetDeclaration dcl, ExpressionTypingContext context) { + public JetTypeInfo visitDeclaration(JetDeclaration dcl, ExpressionTypingContext context) { context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } @Override - public JetType visitRootNamespaceExpression(JetRootNamespaceExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitRootNamespaceExpression(JetRootNamespaceExpression expression, ExpressionTypingContext context) { if (context.namespacesAllowed) { - return DataFlowUtils.checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context); + return DataFlowUtils.checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context, context.dataFlowInfo); } context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression)); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } @Override - public JetType visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetTypeInfo visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) { final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); final StringBuilder builder = new StringBuilder(); final CompileTimeConstant[] value = new CompileTimeConstant[1]; @@ -1127,22 +1131,22 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (value[0] != CompileTimeConstantResolver.OUT_OF_RANGE) { context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new StringValue(builder.toString())); } - return DataFlowUtils.checkType(JetStandardLibrary.getInstance().getStringType(), expression, contextWithExpectedType); + return DataFlowUtils.checkType(JetStandardLibrary.getInstance().getStringType(), expression, contextWithExpectedType, context.dataFlowInfo); } @Override - public JetType visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext data) { + public JetTypeInfo visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext data) { JetExpression baseExpression = expression.getBaseExpression(); if (baseExpression == null) { - return null; + return JetTypeInfo.create(null, data.dataFlowInfo); } return facade.getType(baseExpression, data); } @Override - public JetType visitJetElement(JetElement element, ExpressionTypingContext context) { + public JetTypeInfo visitJetElement(JetElement element, ExpressionTypingContext context) { context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } @Nullable @@ -1161,7 +1165,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @NotNull ExpressionTypingContext context, @NotNull BindingTrace traceForResolveResult, boolean isGet) { - JetType arrayType = facade.getType(arrayAccessExpression.getArrayExpression(), context); + JetType arrayType = facade.getType(arrayAccessExpression.getArrayExpression(), context).getType(); if (arrayType == null) return null; ExpressionReceiver receiver = new ExpressionReceiver(arrayAccessExpression.getArrayExpression(), arrayType); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java index 928d5abd6e9..2104323bb1c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -50,12 +50,12 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitObjectLiteralExpression(final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { + public JetTypeInfo visitObjectLiteralExpression(final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { DelegatingBindingTrace delegatingBindingTrace = context.trace.get(TRACE_DELTAS_CACHE, expression.getObjectDeclaration()); if (delegatingBindingTrace != null) { delegatingBindingTrace.addAllMyDataTo(context.trace); JetType type = context.trace.get(EXPRESSION_TYPE, expression); - return DataFlowUtils.checkType(type, expression, context); + return DataFlowUtils.checkType(type, expression, context, context.dataFlowInfo); } final JetType[] result = new JetType[1]; final TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); @@ -87,11 +87,11 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { temporaryTrace.addAllMyDataTo(cloneDelta); context.trace.record(TRACE_DELTAS_CACHE, expression.getObjectDeclaration(), cloneDelta); temporaryTrace.commit(); - return DataFlowUtils.checkType(result[0], expression, context); + return DataFlowUtils.checkType(result[0], expression, context, context.dataFlowInfo); } @Override - public JetType visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, ExpressionTypingContext context) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); JetBlockExpression bodyExpression = functionLiteral.getBodyExpression(); if (bodyExpression == null) return null; @@ -123,7 +123,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); } returnType = context.expressionTypingServices.getBlockReturnedType(functionInnerScope, bodyExpression, CoercionStrategy.COERCION_TO_UNIT, - context.replaceExpectedType(returnType).replaceBindingTrace(temporaryTrace), temporaryTrace); + context.replaceExpectedType(returnType).replaceBindingTrace(temporaryTrace), temporaryTrace).getType(); } temporaryTrace.commit(new Predicate() { @Override @@ -140,11 +140,11 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); if (JetStandardClasses.isUnit(expectedReturnType)) { functionDescriptor.setReturnType(JetStandardClasses.getUnitType()); - return DataFlowUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), receiver, parameterTypes, JetStandardClasses.getUnitType()), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), receiver, parameterTypes, JetStandardClasses.getUnitType()), expression, context, context.dataFlowInfo); } } - return DataFlowUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), receiver, parameterTypes, safeReturnType), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), receiver, parameterTypes, safeReturnType), expression, context, context.dataFlowInfo); } private SimpleFunctionDescriptorImpl createFunctionDescriptor(JetFunctionLiteralExpression expression, ExpressionTypingContext context, boolean functionTypeExpected) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index c5acf6daa01..9e302b454ee 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -65,7 +65,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { if (condition != null) { - JetType conditionType = facade.getType(condition, context.replaceScope(scope)); + JetType conditionType = facade.getType(condition, context.replaceScope(scope)).getType(); if (conditionType != null && !isBoolean(conditionType)) { context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); @@ -77,11 +77,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Override - public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitIfExpression(JetIfExpression expression, ExpressionTypingContext context) { return visitIfExpression(expression, context, false); } - public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + public JetTypeInfo visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression condition = expression.getCondition(); checkCondition(context.scope, condition, context); @@ -96,24 +96,24 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (elseBranch == null) { if (thenBranch != null) { - JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(thenInfo), context.trace); + JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(thenInfo), context.trace).getType(); if (type != null && JetStandardClasses.isNothing(type)) { facade.setResultingDataFlowInfo(elseInfo); } - return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement); + return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement, context.dataFlowInfo); } - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } if (thenBranch == null) { - JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(elseInfo), context.trace); + JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(elseInfo), context.trace).getType(); if (type != null && JetStandardClasses.isNothing(type)) { facade.setResultingDataFlowInfo(thenInfo); } - return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement); + return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement, context.dataFlowInfo); } CoercionStrategy coercionStrategy = isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION; - JetType thenType = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(thenInfo), context.trace); - JetType elseType = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(elseInfo), context.trace); + JetType thenType = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(thenInfo), context.trace).getType(); + JetType elseType = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(elseInfo), context.trace).getType(); JetType result; if (thenType == null) { @@ -135,16 +135,16 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { else if (jumpInElse && !jumpInThen) { facade.setResultingDataFlowInfo(thenInfo); } - if (result == null) return null; - return DataFlowUtils.checkImplicitCast(result, expression, contextWithExpectedType, isStatement); + if (result == null) return JetTypeInfo.create(null, context.dataFlowInfo); + return DataFlowUtils.checkImplicitCast(result, expression, contextWithExpectedType, isStatement, context.dataFlowInfo); } @Override - public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext context) { return visitWhileExpression(expression, context, false); } - public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + public JetTypeInfo visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); @@ -159,7 +159,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (!containsBreak(expression, context)) { facade.setResultingDataFlowInfo(DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, null, context)); } - return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType, context.dataFlowInfo); } private boolean containsBreak(final JetLoopExpression loopExpression, final ExpressionTypingContext context) { @@ -187,10 +187,10 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext context) { return visitDoWhileExpression(expression, context, false); } - public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + public JetTypeInfo visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); @@ -225,15 +225,15 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (!containsBreak(expression, context)) { facade.setResultingDataFlowInfo(DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, null, context)); } - return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType, context.dataFlowInfo); } @Override - public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitForExpression(JetForExpression expression, ExpressionTypingContext context) { return visitForExpression(expression, context, false); } - public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + public JetTypeInfo visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); @@ -286,7 +286,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context, context.trace); } - return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType, context.dataFlowInfo); } @Nullable @@ -403,7 +403,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitTryExpression(JetTryExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitTryExpression(JetTryExpression expression, ExpressionTypingContext context) { JetExpression tryBlock = expression.getTryBlock(); List catchClauses = expression.getCatchClauses(); JetFinallySection finallyBlock = expression.getFinallyBlock(); @@ -419,7 +419,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (catchBody != null) { WritableScope catchScope = newWritableScopeImpl(context, "Catch scope"); catchScope.addVariableDescriptor(variableDescriptor); - JetType type = facade.getType(catchBody, context.replaceScope(catchScope)); + JetType type = facade.getType(catchBody, context.replaceScope(catchScope)).getType(); if (type != null) { types.add(type); } @@ -429,30 +429,30 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (finallyBlock != null) { facade.getType(finallyBlock.getFinalExpression(), context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); } - JetType type = facade.getType(tryBlock, context); + JetType type = facade.getType(tryBlock, context).getType(); if (type != null) { types.add(type); } if (types.isEmpty()) { - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } else { - return CommonSupertypes.commonSupertype(types); + return JetTypeInfo.create(CommonSupertypes.commonSupertype(types), context.dataFlowInfo); } } @Override - public JetType visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext context) { JetExpression thrownExpression = expression.getThrownExpression(); if (thrownExpression != null) { JetType throwableType = JetStandardLibrary.getInstance().getThrowable().getDefaultType(); facade.getType(thrownExpression, context.replaceExpectedType(throwableType).replaceScope(context.scope)); } - return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo); } @Override - public JetType visitReturnExpression(JetReturnExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitReturnExpression(JetReturnExpression expression, ExpressionTypingContext context) { JetElement element = context.labelResolver.resolveLabel(expression, context); JetExpression returnedExpression = expression.getReturnedExpression(); @@ -508,18 +508,18 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.trace.report(RETURN_TYPE_MISMATCH.on(expression, expectedType)); } } - return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo); } @Override - public JetType visitBreakExpression(JetBreakExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitBreakExpression(JetBreakExpression expression, ExpressionTypingContext context) { context.labelResolver.resolveLabel(expression, context); - return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo); } @Override - public JetType visitContinueExpression(JetContinueExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitContinueExpression(JetContinueExpression expression, ExpressionTypingContext context) { context.labelResolver.resolveLabel(expression, context); - return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context); + return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context, context.dataFlowInfo); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java index d2f9a040861..80c82d152f7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; @@ -151,6 +152,11 @@ public class DataFlowUtils { return context.dataFlowInfo.and(result.get()); } + @NotNull + public static JetTypeInfo checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull DataFlowInfo dataFlowInfo) { + return JetTypeInfo.create(checkType(expressionType, expression, context), dataFlowInfo); + } + @Nullable public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { if (expressionType == null || context.expectedType == null || context.expectedType == TypeUtils.NO_EXPECTED_TYPE || @@ -174,6 +180,11 @@ public class DataFlowUtils { return expressionType; } + @NotNull + public static JetTypeInfo checkStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull DataFlowInfo dataFlowInfo) { + return JetTypeInfo.create(checkStatementType(expression, context), dataFlowInfo); + } + @Nullable public static JetType checkStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { if (context.expectedType != TypeUtils.NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(context.expectedType)) { @@ -183,6 +194,11 @@ public class DataFlowUtils { return JetStandardClasses.getUnitType(); } + @NotNull + public static JetTypeInfo checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context, boolean isStatement, DataFlowInfo dataFlowInfo) { + return JetTypeInfo.create(checkImplicitCast(expressionType, expression, context, isStatement), dataFlowInfo); + } + @Nullable public static JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context, boolean isStatement) { if (expressionType != null && context.expectedType == TypeUtils.NO_EXPECTED_TYPE && !isStatement && @@ -193,10 +209,10 @@ public class DataFlowUtils { return expressionType; } - @Nullable - public static JetType illegalStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull ExpressionTypingInternals facade) { + @NotNull + public static JetTypeInfo illegalStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull ExpressionTypingInternals facade) { facade.checkStatementType(expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); context.trace.report(EXPRESSION_EXPECTED.on(expression, expression)); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java index e337c2781ee..9311190026a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java @@ -19,18 +19,18 @@ package org.jetbrains.jet.lang.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeInfo; /** * @author abreslav */ public interface ExpressionTypingFacade { @NotNull - JetType safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context); + JetTypeInfo safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context); - @Nullable - JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context); + @NotNull + JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context); - @Nullable - JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement); + @NotNull + JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java index da74017946c..3bf1540bee6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.types.CommonSupertypes; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lexer.JetTokens; @@ -119,13 +120,13 @@ public class ExpressionTypingServices { ExpressionTypingContext context = ExpressionTypingContext.newContext( this, trace, scope, dataFlowInfo, expectedType, false ); - return expressionTypingFacade.getType(expression, context); + return expressionTypingFacade.getType(expression, context).getType(); } public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull BindingTrace trace) { ExpressionTypingContext context = ExpressionTypingContext.newContext( this, trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, true); - return expressionTypingFacade.getType(expression, context); + return expressionTypingFacade.getType(expression, context).getType(); // return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); } @@ -174,8 +175,8 @@ public class ExpressionTypingServices { } } - @Nullable - public JetType getBlockReturnedType(@NotNull JetScope outerScope, @NotNull JetBlockExpression expression, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context, BindingTrace trace) { + @NotNull + public JetTypeInfo getBlockReturnedType(@NotNull JetScope outerScope, @NotNull JetBlockExpression expression, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context, BindingTrace trace) { List block = expression.getStatements(); DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration(); @@ -190,9 +191,9 @@ public class ExpressionTypingServices { outerScope, containingDescriptor, new TraceBasedRedeclarationHandler(context.trace), "getBlockReturnedType"); scope.changeLockLevel(WritableScope.LockLevel.BOTH); - JetType r; + JetTypeInfo r; if (block.isEmpty()) { - r = DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, context); + r = DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, context, context.dataFlowInfo); } else { r = getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, context, trace); @@ -262,15 +263,15 @@ public class ExpressionTypingServices { /*package*/ @SuppressWarnings("SuspiciousMethodCalls") - JetType getBlockReturnedTypeWithWritableScope(@NotNull WritableScope scope, @NotNull List block, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context, BindingTrace trace) { + JetTypeInfo getBlockReturnedTypeWithWritableScope(@NotNull WritableScope scope, @NotNull List block, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context, BindingTrace trace) { if (block.isEmpty()) { - return JetStandardClasses.getUnitType(); + return JetTypeInfo.create(JetStandardClasses.getUnitType(), context.dataFlowInfo); } ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(scope); ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE); - JetType result = null; + JetTypeInfo result = JetTypeInfo.create(null, context.dataFlowInfo); for (Iterator iterator = block.iterator(); iterator.hasNext(); ) { final JetElement statement = iterator.next(); trace.record(STATEMENT, statement); @@ -323,8 +324,8 @@ public class ExpressionTypingServices { } if (mightBeUnit) { // ExpressionTypingVisitorForStatements should return only null or Unit for declarations and assignments - assert result == null || JetStandardClasses.isUnit(result); - result = JetStandardClasses.getUnitType(); + assert result.getType() == null || JetStandardClasses.isUnit(result.getType()); + result = JetTypeInfo.create(JetStandardClasses.getUnitType(), newContext.dataFlowInfo); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index e0c2c1386a9..ff35f88cf7b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -71,12 +71,12 @@ public class ExpressionTypingUtils { @Nullable protected static ExpressionReceiver getExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { - return getExpressionReceiver(expression, facade.getType(expression, context)); + return getExpressionReceiver(expression, facade.getType(expression, context).getType()); } @NotNull protected static ExpressionReceiver safeGetExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { - return new ExpressionReceiver(expression, facade.safeGetType(expression, context)); + return new ExpressionReceiver(expression, facade.safeGetType(expression, context).getType()); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java index 35db609ede3..3591da4a02c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java @@ -18,12 +18,12 @@ package org.jetbrains.jet.lang.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetVisitor; -import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeInfo; /** * @author abreslav */ -/*package*/ abstract class ExpressionTypingVisitor extends JetVisitor { +/*package*/ abstract class ExpressionTypingVisitor extends JetVisitor { protected final ExpressionTypingInternals facade; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java index 37281751222..d95f0d34bd7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.DeferredType; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException; import static org.jetbrains.jet.lang.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM; @@ -34,10 +35,10 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO /** * @author abreslav */ -public class ExpressionTypingVisitorDispatcher extends JetVisitor implements ExpressionTypingInternals { +public class ExpressionTypingVisitorDispatcher extends JetVisitor implements ExpressionTypingInternals { @Override - public JetType visitIdeTemplateExpression(JetIdeTemplateExpression expression, ExpressionTypingContext data) { + public JetTypeInfo visitIdeTemplateExpression(JetIdeTemplateExpression expression, ExpressionTypingContext data) { return basic.visitIdeTemplateExpression(expression, data); } @@ -91,22 +92,22 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor visitor) { + @NotNull + private JetTypeInfo getType(@NotNull JetExpression expression, ExpressionTypingContext context, JetVisitor visitor) { if (context.trace.get(BindingContext.PROCESSED, expression)) { - return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); + return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), context.dataFlowInfo); } - JetType result; + JetTypeInfo result; try { result = expression.accept(visitor, context); // Some recursive definitions (object expressions) must put their types in the cache manually: if (context.trace.get(BindingContext.PROCESSED, expression)) { - return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); + return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), result.getDataFlowInfo()); } - if (result instanceof DeferredType) { - result = ((DeferredType) result).getActualType(); + if (result.getType() instanceof DeferredType) { + result = JetTypeInfo.create(((DeferredType) result.getType()).getActualType(), context.dataFlowInfo); } - if (result != null) { - context.trace.record(BindingContext.EXPRESSION_TYPE, expression, result); + if (result.getType() != null) { + context.trace.record(BindingContext.EXPRESSION_TYPE, expression, result.getType()); } } catch (ReenteringLazyValueComputationException e) { context.trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(expression)); - result = null; + result = JetTypeInfo.create(null, context.dataFlowInfo); } if (!context.trace.get(BindingContext.PROCESSED, expression) && !(expression instanceof JetReferenceExpression)) { @@ -159,78 +160,78 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor"))); - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java index 4dc1782cd92..216fe3d86de 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java @@ -52,27 +52,28 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetTypeInfo visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression leftHandSide = expression.getLeftHandSide(); - JetType knownType = facade.safeGetType(leftHandSide, context.replaceScope(context.scope)); + JetType knownType = facade.safeGetType(leftHandSide, context.replaceScope(context.scope)).getType(); JetPattern pattern = expression.getPattern(); + DataFlowInfo newDataFlowInfo = context.dataFlowInfo; if (pattern != null) { WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in 'is'"); DataFlowValue dataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(leftHandSide, knownType, context.trace.getBindingContext()); - DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, false, scopeToExtend, context, dataFlowValue); + newDataFlowInfo = checkPatternType(pattern, knownType, false, scopeToExtend, context, dataFlowValue); context.patternsToDataFlowInfo.put(pattern, newDataFlowInfo); context.patternsToBoundVariableLists.put(pattern, scopeToExtend.getDeclaredVariables()); } - return DataFlowUtils.checkType(JetStandardLibrary.getInstance().getBooleanType(), expression, contextWithExpectedType); + return DataFlowUtils.checkType(JetStandardLibrary.getInstance().getBooleanType(), expression, contextWithExpectedType, newDataFlowInfo); } @Override - public JetType visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext context) { + public JetTypeInfo visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext context) { return visitWhenExpression(expression, context, false); } - public JetType visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + public JetTypeInfo visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); // TODO :change scope according to the bound value in the when header final JetExpression subjectExpression = expression.getSubjectExpression(); @@ -122,7 +123,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { if (bodyExpression != null) { ExpressionTypingContext newContext = contextWithExpectedType.replaceScope(scopeToExtend).replaceDataFlowInfo(newDataFlowInfo); CoercionStrategy coercionStrategy = isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION; - JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(scopeToExtend, Collections.singletonList(bodyExpression), coercionStrategy, newContext, context.trace); + JetType type = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(scopeToExtend, Collections.singletonList(bodyExpression), coercionStrategy, newContext, context.trace).getType(); if (type != null) { expressionTypes.add(type); } @@ -130,9 +131,9 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { } if (!expressionTypes.isEmpty()) { - return DataFlowUtils.checkImplicitCast(CommonSupertypes.commonSupertype(expressionTypes), expression, contextWithExpectedType, isStatement); + return DataFlowUtils.checkImplicitCast(CommonSupertypes.commonSupertype(expressionTypes), expression, contextWithExpectedType, isStatement, context.dataFlowInfo); } - return null; + return JetTypeInfo.create(null, context.dataFlowInfo); } private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final boolean expectedCondition, final JetType subjectType, JetWhenCondition condition, final WritableScope scopeToExtend, final ExpressionTypingContext context, final DataFlowValue... subjectVariables) { @@ -245,7 +246,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { public void visitExpressionPattern(JetExpressionPattern pattern) { JetExpression expression = pattern.getExpression(); if (expression == null) return; - JetType type = facade.getType(expression, context.replaceScope(scopeToExtend)); + JetType type = facade.getType(expression, context.replaceScope(scopeToExtend)).getType(); if (conditionExpected) { JetType booleanType = JetStandardLibrary.getInstance().getBooleanType(); if (type != null && !JetTypeChecker.INSTANCE.equalTypes(booleanType, type)) {