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