001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.types.expressions;
018    
019    import com.google.common.collect.Lists;
020    import com.intellij.openapi.util.Pair;
021    import com.intellij.psi.PsiElement;
022    import com.intellij.psi.util.PsiTreeUtil;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.annotations.Nullable;
025    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
026    import org.jetbrains.kotlin.descriptors.*;
027    import org.jetbrains.kotlin.psi.*;
028    import org.jetbrains.kotlin.resolve.BindingContext;
029    import org.jetbrains.kotlin.resolve.BindingContextUtils;
030    import org.jetbrains.kotlin.resolve.ModifierCheckerCore;
031    import org.jetbrains.kotlin.resolve.ModifiersChecker;
032    import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
033    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
034    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
035    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
036    import org.jetbrains.kotlin.resolve.inline.InlineUtil;
037    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
038    import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
039    import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
040    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
041    import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
042    import org.jetbrains.kotlin.types.*;
043    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
044    import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
045    import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
046    
047    import java.util.ArrayList;
048    import java.util.Collections;
049    import java.util.List;
050    
051    import static org.jetbrains.kotlin.diagnostics.Errors.*;
052    import static org.jetbrains.kotlin.resolve.BindingContext.*;
053    import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
054    import static org.jetbrains.kotlin.types.TypeUtils.*;
055    import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
056    import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall;
057    import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
058    
059    public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
060    
061        public static final String RETURN_NOT_ALLOWED_MESSAGE = "Return not allowed";
062    
063        protected ControlStructureTypingVisitor(@NotNull ExpressionTypingInternals facade) {
064            super(facade);
065        }
066    
067        @NotNull
068        private DataFlowInfo checkCondition(@NotNull LexicalScope scope, @Nullable KtExpression condition, ExpressionTypingContext context) {
069            if (condition != null) {
070                KotlinTypeInfo typeInfo = facade.getTypeInfo(condition, context.replaceScope(scope)
071                        .replaceExpectedType(components.builtIns.getBooleanType()).replaceContextDependency(INDEPENDENT));
072                KotlinType conditionType = typeInfo.getType();
073    
074                if (conditionType != null && !components.builtIns.isBooleanOrSubtype(conditionType)) {
075                    context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType));
076                }
077    
078                return typeInfo.getDataFlowInfo();
079            }
080            return context.dataFlowInfo;
081        }
082    
083        ////////////////////////////////////////////////////////////////////////////////////////////////////
084    
085    
086        @Override
087        public KotlinTypeInfo visitIfExpression(@NotNull KtIfExpression expression, ExpressionTypingContext context) {
088            return visitIfExpression(expression, context, false);
089        }
090    
091        public KotlinTypeInfo visitIfExpression(KtIfExpression ifExpression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
092            ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
093            KtExpression condition = ifExpression.getCondition();
094            DataFlowInfo conditionDataFlowInfo = checkCondition(context.scope, condition, context);
095    
096            KtExpression elseBranch = ifExpression.getElse();
097            KtExpression thenBranch = ifExpression.getThen();
098    
099            LexicalWritableScope thenScope = newWritableScopeImpl(context, LexicalScopeKind.THEN);
100            LexicalWritableScope elseScope = newWritableScopeImpl(context, LexicalScopeKind.ELSE);
101            DataFlowInfo thenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo);
102            DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
103    
104            if (elseBranch == null) {
105                if (thenBranch != null) {
106                    KotlinTypeInfo result = getTypeInfoWhenOnlyOneBranchIsPresent(
107                            thenBranch, thenScope, thenInfo, elseInfo, contextWithExpectedType, ifExpression, isStatement);
108                    // If jump was possible, take condition check info as the jump info
109                    return result.getJumpOutPossible()
110                           ? result.replaceJumpOutPossible(true).replaceJumpFlowInfo(conditionDataFlowInfo)
111                           : result;
112                }
113                return TypeInfoFactoryKt.createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast(
114                                                                     components.builtIns.getUnitType(), ifExpression,
115                                                                     contextWithExpectedType, isStatement
116                                                             ),
117                                                        thenInfo.or(elseInfo)
118                );
119            }
120            if (thenBranch == null) {
121                return getTypeInfoWhenOnlyOneBranchIsPresent(
122                        elseBranch, elseScope, elseInfo, thenInfo, contextWithExpectedType, ifExpression, isStatement);
123            }
124            KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(ifExpression);
125            KtBlockExpression thenBlock = psiFactory.wrapInABlockWrapper(thenBranch);
126            KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch);
127            Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock));
128            MutableDataFlowInfoForArguments dataFlowInfoForArguments =
129                        createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo);
130            ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
131                    callForIf, ResolveConstruct.IF, Lists.newArrayList("thenBranch", "elseBranch"),
132                    Lists.newArrayList(false, false),
133                    contextWithExpectedType, dataFlowInfoForArguments);
134    
135            BindingContext bindingContext = context.trace.getBindingContext();
136            KotlinTypeInfo thenTypeInfo = BindingContextUtils.getRecordedTypeInfo(thenBranch, bindingContext);
137            KotlinTypeInfo elseTypeInfo = BindingContextUtils.getRecordedTypeInfo(elseBranch, bindingContext);
138            assert thenTypeInfo != null : "'Then' branch of if expression  was not processed: " + ifExpression;
139            assert elseTypeInfo != null : "'Else' branch of if expression  was not processed: " + ifExpression;
140            boolean loopBreakContinuePossible = thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible();
141    
142            KotlinType thenType = thenTypeInfo.getType();
143            KotlinType elseType = elseTypeInfo.getType();
144            DataFlowInfo thenDataFlowInfo = thenTypeInfo.getDataFlowInfo();
145            DataFlowInfo elseDataFlowInfo = elseTypeInfo.getDataFlowInfo();
146    
147            boolean jumpInThen = thenType != null && KotlinBuiltIns.isNothing(thenType);
148            boolean jumpInElse = elseType != null && KotlinBuiltIns.isNothing(elseType);
149    
150            DataFlowInfo resultDataFlowInfo;
151            if (thenType == null && elseType == null) {
152                resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
153            }
154            else if (thenType == null || (jumpInThen && !jumpInElse)) {
155                resultDataFlowInfo = elseDataFlowInfo;
156            }
157            else if (elseType == null || (jumpInElse && !jumpInThen)) {
158                resultDataFlowInfo = thenDataFlowInfo;
159            }
160            else {
161                resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
162            }
163    
164            KotlinType resultType = resolvedCall.getResultingDescriptor().getReturnType();
165            // If break or continue was possible, take condition check info as the jump info
166            return TypeInfoFactoryKt
167                    .createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement),
168                                    resultDataFlowInfo, loopBreakContinuePossible, conditionDataFlowInfo);
169        }
170    
171        @NotNull
172        private KotlinTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent(
173                @NotNull KtExpression presentBranch,
174                @NotNull LexicalWritableScope presentScope,
175                @NotNull DataFlowInfo presentInfo,
176                @NotNull DataFlowInfo otherInfo,
177                @NotNull ExpressionTypingContext context,
178                @NotNull KtIfExpression ifExpression,
179                boolean isStatement
180        ) {
181            ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE)
182                    .replaceContextDependency(INDEPENDENT);
183            KotlinTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
184                    presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext);
185            KotlinType type = typeInfo.getType();
186            DataFlowInfo dataFlowInfo;
187            if (type != null && KotlinBuiltIns.isNothing(type)) {
188                dataFlowInfo = otherInfo;
189            } else {
190                dataFlowInfo = typeInfo.getDataFlowInfo().or(otherInfo);
191            }
192            return components.dataFlowAnalyzer.checkImplicitCast(
193                    components.dataFlowAnalyzer.checkType(
194                            typeInfo.replaceType(components.builtIns.getUnitType()),
195                            ifExpression,
196                            context
197                    ),
198                    ifExpression,
199                    context,
200                    isStatement
201            ).replaceDataFlowInfo(dataFlowInfo);
202        }
203    
204        @Override
205        public KotlinTypeInfo visitWhileExpression(@NotNull KtWhileExpression expression, ExpressionTypingContext context) {
206            return visitWhileExpression(expression, context, false);
207        }
208    
209        public KotlinTypeInfo visitWhileExpression(KtWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
210            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
211    
212            ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(
213                    INDEPENDENT);
214            // Preliminary analysis
215            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
216            context = context.replaceDataFlowInfo(
217                    loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo)
218            );
219    
220            KtExpression condition = expression.getCondition();
221            // Extract data flow info from condition itself without taking value into account
222            DataFlowInfo dataFlowInfo = checkCondition(context.scope, condition, context);
223    
224            KtExpression body = expression.getBody();
225            KotlinTypeInfo bodyTypeInfo;
226            DataFlowInfo conditionInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo);
227            if (body != null) {
228                LexicalWritableScope scopeToExtend = newWritableScopeImpl(context, LexicalScopeKind.WHILE_BODY);
229                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
230                        scopeToExtend, Collections.singletonList(body),
231                        CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo));
232            }
233            else {
234                bodyTypeInfo = TypeInfoFactoryKt.noTypeInfo(conditionInfo);
235            }
236    
237            // Condition is false at this point only if there is no jumps outside
238            if (!containsJumpOutOfLoop(expression, context)) {
239                dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(dataFlowInfo);
240            }
241    
242            // Special case: while (true)
243            // In this case we must record data flow information at the nearest break / continue and
244            // .and it with entrance data flow information, because while body until break is executed at least once in this case
245            // See KT-6284
246            if (body != null && KtPsiUtil.isTrueConstant(condition)) {
247                // We should take data flow info from the first jump point,
248                // but without affecting changing variables
249                dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo()));
250            }
251            return components.dataFlowAnalyzer
252                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
253                    .replaceDataFlowInfo(dataFlowInfo);
254        }
255    
256        private boolean containsJumpOutOfLoop(final KtLoopExpression loopExpression, final ExpressionTypingContext context) {
257            final boolean[] result = new boolean[1];
258            result[0] = false;
259            //todo breaks in inline function literals
260            loopExpression.accept(new KtTreeVisitor<List<KtLoopExpression>>() {
261                @Override
262                public Void visitBreakExpression(@NotNull KtBreakExpression breakExpression, List<KtLoopExpression> outerLoops) {
263                    KtSimpleNameExpression targetLabel = breakExpression.getTargetLabel();
264                    PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null;
265                    if (element == loopExpression || (targetLabel == null && outerLoops.get(outerLoops.size() - 1) == loopExpression)) {
266                        result[0] = true;
267                    }
268                    return null;
269                }
270    
271                @Override
272                public Void visitContinueExpression(@NotNull KtContinueExpression expression, List<KtLoopExpression> outerLoops) {
273                    // continue@someOuterLoop is also considered as break
274                    KtSimpleNameExpression targetLabel = expression.getTargetLabel();
275                    if (targetLabel != null) {
276                        PsiElement element = context.trace.get(LABEL_TARGET, targetLabel);
277                        if (element instanceof KtLoopExpression && !outerLoops.contains(element)) {
278                            result[0] = true;
279                        }
280                    }
281                    return null;
282                }
283    
284                @Override
285                public Void visitLoopExpression(@NotNull KtLoopExpression loopExpression, List<KtLoopExpression> outerLoops) {
286                    List<KtLoopExpression> newOuterLoops = Lists.newArrayList(outerLoops);
287                    newOuterLoops.add(loopExpression);
288                    return super.visitLoopExpression(loopExpression, newOuterLoops);
289                }
290            }, Lists.newArrayList(loopExpression));
291    
292            return result[0];
293        }
294    
295        @Override
296        public KotlinTypeInfo visitDoWhileExpression(@NotNull KtDoWhileExpression expression, ExpressionTypingContext context) {
297            return visitDoWhileExpression(expression, context, false);
298        }
299    
300        public KotlinTypeInfo visitDoWhileExpression(KtDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
301            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
302    
303            ExpressionTypingContext context =
304                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
305            KtExpression body = expression.getBody();
306            LexicalScope conditionScope = context.scope;
307            // Preliminary analysis
308            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
309            context = context.replaceDataFlowInfo(
310                    loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo)
311            );
312            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
313            // .and it with entrance data flow information, because do-while body is executed at least once
314            // See KT-6283
315            KotlinTypeInfo bodyTypeInfo;
316            if (body instanceof KtFunctionLiteralExpression) {
317                // As a matter of fact, function literal is always unused at this point
318                bodyTypeInfo = facade.getTypeInfo(body, context.replaceScope(context.scope));
319            }
320            else if (body != null) {
321                LexicalWritableScope writableScope = newWritableScopeImpl(context, LexicalScopeKind.DO_WHILE_BODY);
322                conditionScope = writableScope;
323                List<KtExpression> block;
324                if (body instanceof KtBlockExpression) {
325                    block = ((KtBlockExpression)body).getStatements();
326                }
327                else {
328                    block = Collections.singletonList(body);
329                }
330                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
331                        writableScope, block, CoercionStrategy.NO_COERCION, context);
332            }
333            else {
334                bodyTypeInfo = TypeInfoFactoryKt.noTypeInfo(context);
335            }
336            KtExpression condition = expression.getCondition();
337            DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context);
338            DataFlowInfo dataFlowInfo;
339            // Without jumps out, condition is entered and false, with jumps out, we know nothing about it
340            if (!containsJumpOutOfLoop(expression, context)) {
341                dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
342            }
343            else {
344                dataFlowInfo = context.dataFlowInfo;
345            }
346            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
347            // .and it with entrance data flow information, because do-while body is executed at least once
348            // See KT-6283
349            // NB: it's really important to do it for non-empty body which is not a function literal
350            // If it's a function literal, it appears always unused so it's no matter what we do at this point
351            if (body != null) {
352                // We should take data flow info from the first jump point,
353                // but without affecting changing variables
354                dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo()));
355            }
356            return components.dataFlowAnalyzer
357                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
358                    .replaceDataFlowInfo(dataFlowInfo);
359        }
360    
361        @Override
362        public KotlinTypeInfo visitForExpression(@NotNull KtForExpression expression, ExpressionTypingContext context) {
363            return visitForExpression(expression, context, false);
364        }
365    
366        public KotlinTypeInfo visitForExpression(KtForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
367            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
368    
369            ExpressionTypingContext context =
370                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
371            // Preliminary analysis
372            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
373            context = context.replaceDataFlowInfo(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo));
374    
375            KtExpression loopRange = expression.getLoopRange();
376            KotlinType expectedParameterType = null;
377            KotlinTypeInfo loopRangeInfo;
378            if (loopRange != null) {
379                ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope));
380                loopRangeInfo = facade.getTypeInfo(loopRange, context);
381                if (loopRangeReceiver != null) {
382                    expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention(loopRangeReceiver, context);
383                }
384            }
385            else {
386                loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context);
387            }
388    
389            LexicalWritableScope loopScope = newWritableScopeImpl(context, LexicalScopeKind.FOR);
390    
391            KtParameter loopParameter = expression.getLoopParameter();
392            if (loopParameter != null) {
393                VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
394                components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
395                components.identifierChecker.checkDeclaration(loopParameter, context.trace);
396    
397                loopScope.addVariableDescriptor(variableDescriptor);
398            }
399            else {
400                KtMultiDeclaration multiParameter = expression.getMultiParameter();
401                if (multiParameter != null && loopRange != null) {
402                    KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
403                    TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
404                    components.annotationResolver.resolveAnnotationsWithArguments(loopScope, multiParameter.getModifierList(), context.trace);
405                    components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(
406                            loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
407                    );
408                    components.modifiersChecker.withTrace(context.trace).checkModifiersForMultiDeclaration(multiParameter);
409                    components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(multiParameter, VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER);
410                    components.identifierChecker.checkDeclaration(multiParameter, context.trace);
411                }
412            }
413    
414            KtExpression body = expression.getBody();
415            KotlinTypeInfo bodyTypeInfo;
416            if (body != null) {
417                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body),
418                        CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()));
419            }
420            else {
421                bodyTypeInfo = loopRangeInfo;
422            }
423    
424            return components.dataFlowAnalyzer
425                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
426                    .replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo());
427        }
428    
429        private VariableDescriptor createLoopParameterDescriptor(
430                KtParameter loopParameter,
431                KotlinType expectedParameterType,
432                ExpressionTypingContext context
433        ) {
434            components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(loopParameter, VAL_OR_VAR_ON_LOOP_PARAMETER);
435    
436            KtTypeReference typeReference = loopParameter.getTypeReference();
437            VariableDescriptor variableDescriptor;
438            if (typeReference != null) {
439                variableDescriptor = components.descriptorResolver.
440                        resolveLocalVariableDescriptor(context.scope, loopParameter, context.trace);
441                KotlinType actualParameterType = variableDescriptor.getType();
442                if (expectedParameterType != null &&
443                        !KotlinTypeChecker.DEFAULT.isSubtypeOf(expectedParameterType, actualParameterType)) {
444                    context.trace.report(TYPE_MISMATCH_IN_FOR_LOOP.on(typeReference, expectedParameterType, actualParameterType));
445                }
446            }
447            else {
448                if (expectedParameterType == null) {
449                    expectedParameterType = ErrorUtils.createErrorType("Error");
450                }
451                variableDescriptor = components.descriptorResolver.
452                        resolveLocalVariableDescriptor(loopParameter, expectedParameterType, context.trace, context.scope);
453            }
454    
455            checkVariableShadowing(context.scope, context.trace, variableDescriptor);
456    
457            return variableDescriptor;
458        }
459    
460        @Override
461        public KotlinTypeInfo visitTryExpression(@NotNull KtTryExpression expression, ExpressionTypingContext typingContext) {
462            ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT);
463            KtExpression tryBlock = expression.getTryBlock();
464            List<KtCatchClause> catchClauses = expression.getCatchClauses();
465            KtFinallySection finallyBlock = expression.getFinallyBlock();
466            List<KotlinType> types = new ArrayList<KotlinType>();
467            for (KtCatchClause catchClause : catchClauses) {
468                KtParameter catchParameter = catchClause.getCatchParameter();
469                KtExpression catchBody = catchClause.getCatchBody();
470                if (catchParameter != null) {
471                    components.identifierChecker.checkDeclaration(catchParameter, context.trace);
472                    ModifiersChecker.ModifiersCheckingProcedure modifiersChecking = components.modifiersChecker.withTrace(context.trace);
473                    modifiersChecking.checkParameterHasNoValOrVar(catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER);
474                    ModifierCheckerCore.INSTANCE$.check(catchParameter, context.trace, null);
475    
476                    VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor(
477                            context.scope, catchParameter, context.trace);
478                    KotlinType catchParameterType = variableDescriptor.getType();
479                    if (TypeUtils.isReifiedTypeParameter(catchParameterType)) {
480                        context.trace.report(REIFIED_TYPE_IN_CATCH_CLAUSE.on(catchParameter));
481                    }
482    
483                    KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
484                    components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType));
485                    if (catchBody != null) {
486                        LexicalWritableScope catchScope = newWritableScopeImpl(context, LexicalScopeKind.CATCH);
487                        catchScope.addVariableDescriptor(variableDescriptor);
488                        KotlinType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType();
489                        if (type != null) {
490                            types.add(type);
491                        }
492                    }
493                }
494            }
495    
496            KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(context);
497            if (finallyBlock != null) {
498                result = facade.getTypeInfo(finallyBlock.getFinalExpression(),
499                                            context.replaceExpectedType(NO_EXPECTED_TYPE));
500            }
501    
502            KotlinType type = facade.getTypeInfo(tryBlock, context).getType();
503            if (type != null) {
504                types.add(type);
505            }
506            if (types.isEmpty()) {
507                return result.clearType();
508            }
509            else {
510                return result.replaceType(CommonSupertypes.commonSupertype(types));
511            }
512        }
513    
514        @Override
515        public KotlinTypeInfo visitThrowExpression(@NotNull KtThrowExpression expression, ExpressionTypingContext context) {
516            KtExpression thrownExpression = expression.getThrownExpression();
517            if (thrownExpression != null) {
518                KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
519                facade.getTypeInfo(thrownExpression, context
520                        .replaceExpectedType(throwableType).replaceScope(context.scope).replaceContextDependency(INDEPENDENT));
521            }
522            return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression);
523        }
524    
525        @Override
526        public KotlinTypeInfo visitReturnExpression(@NotNull KtReturnExpression expression, ExpressionTypingContext context) {
527            KtElement labelTargetElement = LabelResolver.INSTANCE.resolveControlLabel(expression, context);
528    
529            KtExpression returnedExpression = expression.getReturnedExpression();
530    
531            KotlinType expectedType = NO_EXPECTED_TYPE;
532            KotlinType resultType = components.builtIns.getNothingType();
533            KtDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(expression, KtDeclaration.class);
534    
535            if (parentDeclaration instanceof KtParameter) {
536                // In a default value for parameter
537                context.trace.report(RETURN_NOT_ALLOWED.on(expression));
538            }
539    
540            if (expression.getTargetLabel() == null) {
541                while (parentDeclaration instanceof KtMultiDeclaration) {
542                    //TODO: It's hacking fix for KT-5100: Strange "Return is not allowed here" for multi-declaration initializer with elvis expression
543                    parentDeclaration = PsiTreeUtil.getParentOfType(parentDeclaration, KtDeclaration.class);
544                }
545    
546                assert parentDeclaration != null : "Can't find parent declaration for " + expression.getText();
547                DeclarationDescriptor declarationDescriptor = context.trace.get(DECLARATION_TO_DESCRIPTOR, parentDeclaration);
548                Pair<FunctionDescriptor, PsiElement> containingFunInfo =
549                        BindingContextUtils.getContainingFunctionSkipFunctionLiterals(declarationDescriptor, false);
550                FunctionDescriptor containingFunctionDescriptor = containingFunInfo.getFirst();
551    
552                if (containingFunctionDescriptor != null) {
553                    if (!InlineUtil.checkNonLocalReturnUsage(containingFunctionDescriptor, expression, context.trace) ||
554                        isClassInitializer(containingFunInfo)) {
555                        // Unqualified, in a function literal
556                        context.trace.report(RETURN_NOT_ALLOWED.on(expression));
557                        resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
558                    }
559    
560                    expectedType = getFunctionExpectedReturnType(containingFunctionDescriptor, (KtElement) containingFunInfo.getSecond(), context);
561                }
562                else {
563                    // Outside a function
564                    context.trace.report(RETURN_NOT_ALLOWED.on(expression));
565                    resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
566                }
567            }
568            else if (labelTargetElement != null) {
569                SimpleFunctionDescriptor functionDescriptor = context.trace.get(FUNCTION, labelTargetElement);
570                if (functionDescriptor != null) {
571                    expectedType = getFunctionExpectedReturnType(functionDescriptor, labelTargetElement, context);
572                    if (!InlineUtil.checkNonLocalReturnUsage(functionDescriptor, expression, context.trace)) {
573                        // Qualified, non-local
574                        context.trace.report(RETURN_NOT_ALLOWED.on(expression));
575                        resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
576                    }
577                }
578                else {
579                    context.trace.report(NOT_A_RETURN_LABEL.on(expression, expression.getLabelName()));
580                }
581            }
582            if (returnedExpression != null) {
583                facade.getTypeInfo(returnedExpression, context.replaceExpectedType(expectedType).replaceScope(context.scope)
584                        .replaceContextDependency(INDEPENDENT));
585            }
586            else {
587                if (expectedType != null &&
588                    !noExpectedType(expectedType) &&
589                    !KotlinBuiltIns.isUnit(expectedType) &&
590                    !isDontCarePlaceholder(expectedType)) // for lambda with implicit return type Unit
591                {
592                    context.trace.report(RETURN_TYPE_MISMATCH.on(expression, expectedType));
593                }
594            }
595            return components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, expression);
596        }
597    
598        private static boolean isClassInitializer(@NotNull Pair<FunctionDescriptor, PsiElement> containingFunInfo) {
599            return containingFunInfo.getFirst() instanceof ConstructorDescriptor &&
600                   !(containingFunInfo.getSecond() instanceof KtSecondaryConstructor);
601        }
602    
603        @Override
604        public KotlinTypeInfo visitBreakExpression(@NotNull KtBreakExpression expression, ExpressionTypingContext context) {
605            LabelResolver.INSTANCE.resolveControlLabel(expression, context);
606            return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression).
607                    replaceJumpOutPossible(true);
608        }
609    
610        @Override
611        public KotlinTypeInfo visitContinueExpression(@NotNull KtContinueExpression expression, ExpressionTypingContext context) {
612            LabelResolver.INSTANCE.resolveControlLabel(expression, context);
613            return components.dataFlowAnalyzer.createCheckedTypeInfo(components.builtIns.getNothingType(), context, expression).
614                    replaceJumpOutPossible(true);
615        }
616    
617        @NotNull
618        private static KotlinType getFunctionExpectedReturnType(
619                @NotNull FunctionDescriptor descriptor,
620                @NotNull KtElement function,
621                @NotNull ExpressionTypingContext context
622        ) {
623            KotlinType expectedType;
624            if (function instanceof KtSecondaryConstructor) {
625                expectedType = DescriptorUtilsKt.getBuiltIns(descriptor).getUnitType();
626            }
627            else if (function instanceof KtFunction) {
628                KtFunction ktFunction = (KtFunction) function;
629                expectedType = context.trace.get(EXPECTED_RETURN_TYPE, ktFunction);
630    
631                if ((expectedType == null) && (ktFunction.getTypeReference() != null || ktFunction.hasBlockBody())) {
632                    expectedType = descriptor.getReturnType();
633                }
634            }
635            else {
636                expectedType = descriptor.getReturnType();
637            }
638            return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE;
639        }
640    }