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