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