diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index adb1d676230..348b203428a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -404,7 +404,8 @@ public class BodyResolver { JetExpression bodyExpression = declaration.getBodyExpression(); if (bodyExpression != null) { - expressionTypingServices.checkFunctionReturnType(scopeForConstructorBody, declaration, descriptor, JetStandardClasses.getUnitType(), trace); + expressionTypingServices.checkFunctionReturnType(scopeForConstructorBody, declaration, descriptor, DataFlowInfo.EMPTY, + JetStandardClasses.getUnitType(), trace); } checkDefaultParameterValues(declaration.getValueParameters(), descriptor.getValueParameters(), scopeForConstructorBody); @@ -548,7 +549,7 @@ public class BodyResolver { JetExpression bodyExpression = function.getBodyExpression(); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace); if (bodyExpression != null) { - expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, trace); + expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, null, trace); } List valueParameters = function.getValueParameters(); 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 d63355109b3..ab67e6e0e12 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 @@ -531,10 +531,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression receiverExpression = expression.getReceiverExpression(); ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE); - JetType receiverType = facade.getType(receiverExpression, - contextWithNoExpectedType - .replaceExpectedReturnType(NO_EXPECTED_TYPE) - .replaceNamespacesAllowed(true)); + JetType receiverType = facade.getType(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true)); if (selectorExpression == null) return null; if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); @@ -686,8 +683,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { referencedName = referencedName == null ? " " : referencedName; context.labelResolver.enterLabeledElement(referencedName.substring(1), baseExpression); // TODO : Some processing for the label? - ExpressionTypingContext newContext = context.replaceExpectedReturnType(context.expectedType); - JetType type = facade.getType(baseExpression, newContext, isStatement); + JetType type = facade.getType(baseExpression, context, isStatement); context.labelResolver.exitLabeledElement(baseExpression); return DataFlowUtils.checkType(type, expression, context); } 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 c0a400931f8..1c5bfea7e71 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 @@ -102,14 +102,14 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { if (returnTypeRef != null) { returnType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, returnTypeRef, context.trace, true); context.expressionTypingServices.checkFunctionReturnType(expression, context.replaceScope(functionInnerScope). - replaceExpectedType(returnType).replaceExpectedReturnType(returnType).replaceDataFlowInfo(context.dataFlowInfo), context.trace); + replaceExpectedType(returnType).replaceDataFlowInfo(context.dataFlowInfo), context.trace); } else { if (functionTypeExpected) { returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); } returnType = context.expressionTypingServices.getBlockReturnedType(functionInnerScope, bodyExpression, CoercionStrategy.COERCION_TO_UNIT, - context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType), context.trace); + context.replaceExpectedType(returnType), context.trace); } JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("") : returnType; functionDescriptor.setReturnType(safeReturnType); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 6db02920ecc..bf421054e47 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -51,10 +51,9 @@ public class ExpressionTypingContext { @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, - @NotNull JetType expectedReturnType, boolean namespacesAllowed) { return new ExpressionTypingContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, - labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + labelResolver, trace, scope, dataFlowInfo, expectedType, namespacesAllowed); } // @NotNull @@ -74,7 +73,6 @@ public class ExpressionTypingContext { public final DataFlowInfo dataFlowInfo; public final JetType expectedType; - public final JetType expectedReturnType; public final Map patternsToDataFlowInfo; public final Map> patternsToBoundVariableLists; @@ -94,7 +92,6 @@ public class ExpressionTypingContext { @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, - @NotNull JetType expectedReturnType, boolean namespacesAllowed) { this.expressionTypingServices = expressionTypingServices; this.trace = trace; @@ -104,43 +101,36 @@ public class ExpressionTypingContext { this.scope = scope; this.dataFlowInfo = dataFlowInfo; this.expectedType = expectedType; - this.expectedReturnType = expectedReturnType; this.namespacesAllowed = namespacesAllowed; } @NotNull public ExpressionTypingContext replaceNamespacesAllowed(boolean namespacesAllowed) { if (namespacesAllowed == this.namespacesAllowed) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, namespacesAllowed); } @NotNull public ExpressionTypingContext replaceDataFlowInfo(DataFlowInfo newDataFlowInfo) { if (newDataFlowInfo == dataFlowInfo) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, newDataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, newDataFlowInfo, expectedType, namespacesAllowed); } public ExpressionTypingContext replaceExpectedType(@Nullable JetType newExpectedType) { if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); if (expectedType == newExpectedType) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, newExpectedType, expectedReturnType, namespacesAllowed); - } - - public ExpressionTypingContext replaceExpectedReturnType(@Nullable JetType newExpectedReturnType) { - if (newExpectedReturnType == null) return replaceExpectedReturnType(TypeUtils.NO_EXPECTED_TYPE); - if (expectedReturnType == newExpectedReturnType) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, newExpectedReturnType, namespacesAllowed); + return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, newExpectedType, namespacesAllowed); } public ExpressionTypingContext replaceBindingTrace(@NotNull BindingTrace newTrace) { if (newTrace == trace) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, newTrace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, newTrace, scope, dataFlowInfo, expectedType, namespacesAllowed); } @NotNull public ExpressionTypingContext replaceScope(@NotNull JetScope newScope) { if (newScope == scope) return this; - return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, newScope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + return newContext(expressionTypingServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, newScope, dataFlowInfo, expectedType, namespacesAllowed); } ///////////// LAZY ACCESSORS 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 9db4806364c..984afc97d4b 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 @@ -125,7 +125,7 @@ public class ExpressionTypingServices { ExpressionTypingContext context = ExpressionTypingContext.newContext( this, new HashMap(), new HashMap>(), new LabelResolver(), - trace, scope, dataFlowInfo, expectedType, FORBIDDEN, false + trace, scope, dataFlowInfo, expectedType, false ); return expressionTypingFacade.getType(expression, context); } @@ -134,8 +134,7 @@ public class ExpressionTypingServices { ExpressionTypingContext context = ExpressionTypingContext.newContext( this, new HashMap(), new HashMap>(), new LabelResolver(), - trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, FORBIDDEN, - true); + trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, true); return expressionTypingFacade.getType(expression, context); // return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); } @@ -150,20 +149,9 @@ public class ExpressionTypingServices { } - public void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, BindingTrace trace) { - checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, null, trace); - } + ///////////////////////////////////////////////////////// - public void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @Nullable JetType expectedReturnType, BindingTrace trace) { - checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, expectedReturnType, trace); - } -///////////////////////////////////////////////////////// - - /*package*/ void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull DataFlowInfo dataFlowInfo, BindingTrace trace) { - checkFunctionReturnType(functionInnerScope, function, functionDescriptor, dataFlowInfo, null, trace); - } - - /*package*/ void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedReturnType, BindingTrace trace) { + public void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedReturnType, BindingTrace trace) { if (expectedReturnType == null) { expectedReturnType = functionDescriptor.getReturnType(); if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) { @@ -173,7 +161,7 @@ public class ExpressionTypingServices { checkFunctionReturnType(function, ExpressionTypingContext.newContext( this, new HashMap(), new HashMap>(), new LabelResolver(), - trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE, expectedReturnType, false + trace, functionInnerScope, dataFlowInfo, expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE, false ), trace); } @@ -185,7 +173,7 @@ public class ExpressionTypingServices { final ExpressionTypingContext newContext = blockBody ? context.replaceExpectedType(NO_EXPECTED_TYPE) - : context.replaceExpectedType(context.expectedReturnType == FORBIDDEN ? NO_EXPECTED_TYPE : context.expectedReturnType).replaceExpectedReturnType(FORBIDDEN); + : context; if (function instanceof JetFunctionLiteralExpression) { JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) function; @@ -222,7 +210,7 @@ public class ExpressionTypingServices { expressionTypingFacade.getType(bodyExpression, ExpressionTypingContext.newContext( this, new HashMap(), new HashMap>(), new LabelResolver(), - trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, FORBIDDEN, false), !function.hasBlockBody()); + trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, false), !function.hasBlockBody()); //todo function literals final Collection returnedExpressions = Lists.newArrayList(); if (function.hasBlockBody()) { @@ -272,7 +260,7 @@ public class ExpressionTypingServices { } ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(scope); - ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE); JetType result = null; for (Iterator iterator = block.iterator(); iterator.hasNext(); ) { @@ -287,13 +275,13 @@ public class ExpressionTypingServices { TemporaryBindingTrace temporaryTraceExpectingUnit = TemporaryBindingTrace.create(trace); final boolean[] mismatch = new boolean[1]; ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch); - newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); + newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType); result = blockLevelVisitor.getType(statementExpression, newContext, true); if (mismatch[0]) { TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace); mismatch[0] = false; ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch); - newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE); result = blockLevelVisitor.getType(statementExpression, newContext, true); if (mismatch[0]) { temporaryTraceExpectingUnit.commit(); @@ -307,7 +295,7 @@ public class ExpressionTypingServices { } } else { - newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); + newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType); result = blockLevelVisitor.getType(statementExpression, newContext, true); } } @@ -342,16 +330,17 @@ public class ExpressionTypingServices { newDataFlowInfo = context.dataFlowInfo; } if (newDataFlowInfo != context.dataFlowInfo) { - newContext = createContext(newContext, trace, scope, newDataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + newContext = createContext(newContext, trace, scope, newDataFlowInfo, NO_EXPECTED_TYPE); } blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(scope); } return result; } - private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType, JetType expectedReturnType) { + private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType) { return ExpressionTypingContext.newContext( - this, oldContext.patternsToDataFlowInfo, oldContext.patternsToBoundVariableLists, oldContext.labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, oldContext.namespacesAllowed); + this, oldContext.patternsToDataFlowInfo, oldContext.patternsToBoundVariableLists, oldContext.labelResolver, + trace, scope, dataFlowInfo, expectedType, oldContext.namespacesAllowed); } private ObservableBindingTrace makeTraceInterceptingTypeMismatch(final BindingTrace trace, final JetExpression expressionToWatch, final boolean[] mismatchFound) { 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 a3917558293..50334d9da34 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 @@ -163,7 +163,6 @@ public class ExpressionTypingUtils { scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE, - TypeUtils.NO_EXPECTED_TYPE, false ); return ControlStructureTypingVisitor.checkIterableConvention(expressionReceiver, context) != null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index 8863af6785e..7567c279c18 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -25,11 +25,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; -import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; +import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsUtil; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; @@ -132,7 +128,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace); scope.addFunctionDescriptor(functionDescriptor); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace); - context.expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, context.trace); + context.expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace); return DataFlowUtils.checkStatementType(function, context); } @@ -174,7 +170,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito //There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there) TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(contextWithExpectedType.trace); - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceExpectedReturnType(TypeUtils.NO_EXPECTED_TYPE).replaceBindingTrace(temporaryBindingTrace); + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceBindingTrace(temporaryBindingTrace); JetSimpleNameExpression operationSign = expression.getOperationReference(); IElementType operationType = operationSign.getReferencedNameElementType(); @@ -234,7 +230,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito } protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceExpectedReturnType(TypeUtils.NO_EXPECTED_TYPE); + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); JetExpression right = expression.getRight(); if (left instanceof JetArrayAccessExpression) {