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, components.overloadChecker);
103            LexicalWritableScope elseScope = newWritableScopeImpl(context, LexicalScopeKind.ELSE, components.overloadChecker);
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, components.languageVersionSettings);
159                    DataFlowValue elseValue = DataFlowValueFactory.createDataFlowValue(elseBranch, elseType, context);
160                    elseDataFlowInfo = elseDataFlowInfo.assign(resultValue, elseValue, components.languageVersionSettings);
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, components.languageVersionSettings)
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, components.overloadChecker);
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                                                                                                       components.languageVersionSettings));
266            }
267            return components.dataFlowAnalyzer
268                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
269                    .replaceDataFlowInfo(dataFlowInfo);
270        }
271    
272        private boolean containsJumpOutOfLoop(@NotNull final KtExpression expression, final ExpressionTypingContext context) {
273            final boolean[] result = new boolean[1];
274            result[0] = false;
275            //todo breaks in inline function literals
276            expression.accept(new KtTreeVisitor<List<KtLoopExpression>>() {
277                @Override
278                public Void visitBreakExpression(@NotNull KtBreakExpression breakExpression, List<KtLoopExpression> outerLoops) {
279                    KtSimpleNameExpression targetLabel = breakExpression.getTargetLabel();
280                    PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null;
281                    if (outerLoops.isEmpty() || element == expression ||
282                        (targetLabel == null && outerLoops.get(outerLoops.size() - 1) == expression)) {
283                        result[0] = true;
284                    }
285                    return null;
286                }
287    
288                @Override
289                public Void visitContinueExpression(@NotNull KtContinueExpression expression, List<KtLoopExpression> outerLoops) {
290                    // continue@someOuterLoop is also considered as break
291                    KtSimpleNameExpression targetLabel = expression.getTargetLabel();
292                    if (targetLabel != null) {
293                        PsiElement element = context.trace.get(LABEL_TARGET, targetLabel);
294                        if (element instanceof KtLoopExpression && !outerLoops.contains(element)) {
295                            result[0] = true;
296                        }
297                    }
298                    return null;
299                }
300    
301                @Override
302                public Void visitLoopExpression(@NotNull KtLoopExpression loopExpression, List<KtLoopExpression> outerLoops) {
303                    List<KtLoopExpression> newOuterLoops = Lists.newArrayList(outerLoops);
304                    newOuterLoops.add(loopExpression);
305                    return super.visitLoopExpression(loopExpression, newOuterLoops);
306                }
307            }, expression instanceof KtLoopExpression
308               ? Lists.newArrayList((KtLoopExpression) expression)
309               : Lists.<KtLoopExpression>newArrayList());
310    
311            return result[0];
312        }
313    
314        @Override
315        public KotlinTypeInfo visitDoWhileExpression(@NotNull KtDoWhileExpression expression, ExpressionTypingContext context) {
316            return visitDoWhileExpression(expression, context, false);
317        }
318    
319        public KotlinTypeInfo visitDoWhileExpression(KtDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
320            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
321    
322            ExpressionTypingContext context =
323                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
324            KtExpression body = expression.getBody();
325            LexicalScope conditionScope = context.scope;
326            // Preliminary analysis
327            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
328            context = context.replaceDataFlowInfo(
329                    loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo, components.languageVersionSettings)
330            );
331            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
332            // .and it with entrance data flow information, because do-while body is executed at least once
333            // See KT-6283
334            KotlinTypeInfo bodyTypeInfo;
335            if (body instanceof KtLambdaExpression) {
336                // As a matter of fact, function literal is always unused at this point
337                bodyTypeInfo = facade.getTypeInfo(body, context.replaceScope(context.scope));
338            }
339            else if (body != null) {
340                LexicalWritableScope writableScope = newWritableScopeImpl(context, LexicalScopeKind.DO_WHILE_BODY, components.overloadChecker);
341                conditionScope = writableScope;
342                List<KtExpression> block;
343                if (body instanceof KtBlockExpression) {
344                    block = ((KtBlockExpression)body).getStatements();
345                }
346                else {
347                    block = Collections.singletonList(body);
348                }
349                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
350                        writableScope, block, CoercionStrategy.NO_COERCION, context);
351            }
352            else {
353                bodyTypeInfo = TypeInfoFactoryKt.noTypeInfo(context);
354            }
355            KtExpression condition = expression.getCondition();
356            DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context);
357            DataFlowInfo dataFlowInfo;
358            // Without jumps out, condition is entered and false, with jumps out, we know nothing about it
359            if (!containsJumpOutOfLoop(expression, context)) {
360                dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
361            }
362            else {
363                dataFlowInfo = context.dataFlowInfo;
364            }
365            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
366            // .and it with entrance data flow information, because do-while body is executed at least once
367            // See KT-6283
368            // NB: it's really important to do it for non-empty body which is not a function literal
369            // If it's a function literal, it appears always unused so it's no matter what we do at this point
370            if (body != null) {
371                // We should take data flow info from the first jump point,
372                // but without affecting changing variables
373                dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo(),
374                                                                                                       components.languageVersionSettings));
375            }
376            return components.dataFlowAnalyzer
377                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
378                    .replaceDataFlowInfo(dataFlowInfo);
379        }
380    
381        @Override
382        public KotlinTypeInfo visitForExpression(@NotNull KtForExpression expression, ExpressionTypingContext context) {
383            return visitForExpression(expression, context, false);
384        }
385    
386        public KotlinTypeInfo visitForExpression(KtForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
387            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
388    
389            ExpressionTypingContext context =
390                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
391            // Preliminary analysis
392            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
393            context = context.replaceDataFlowInfo(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo,
394                                                                                                         components.languageVersionSettings));
395    
396            KtExpression loopRange = expression.getLoopRange();
397            KotlinType expectedParameterType = null;
398            KotlinTypeInfo loopRangeInfo;
399            if (loopRange != null) {
400                ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope));
401                loopRangeInfo = facade.getTypeInfo(loopRange, context);
402                if (loopRangeReceiver != null) {
403                    expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention(loopRangeReceiver, context);
404                }
405            }
406            else {
407                loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context);
408            }
409    
410            LexicalWritableScope loopScope = newWritableScopeImpl(context, LexicalScopeKind.FOR, components.overloadChecker);
411    
412            KtParameter loopParameter = expression.getLoopParameter();
413            if (loopParameter != null) {
414                VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
415                ModifiersChecker.ModifiersCheckingProcedure modifiersCheckingProcedure = components.modifiersChecker.withTrace(context.trace);
416                modifiersCheckingProcedure.checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
417                components.identifierChecker.checkDeclaration(loopParameter, context.trace);
418                loopScope.addVariableDescriptor(variableDescriptor);
419                KtDestructuringDeclaration multiParameter = loopParameter.getDestructuringDeclaration();
420                if (multiParameter != null) {
421                    KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
422                    TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
423                    components.annotationResolver.resolveAnnotationsWithArguments(loopScope, loopParameter.getModifierList(), context.trace);
424                    components.destructuringDeclarationResolver.defineLocalVariablesFromDestructuringDeclaration(
425                            loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
426                    );
427                    modifiersCheckingProcedure.checkModifiersForDestructuringDeclaration(multiParameter);
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, components.languageVersionSettings);
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, components.overloadChecker);
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    
614            if (returnedExpression != null) {
615                facade.getTypeInfo(returnedExpression, context.replaceExpectedType(expectedType).replaceScope(context.scope)
616                        .replaceContextDependency(INDEPENDENT));
617            }
618            else {
619                // for lambda with implicit return type Unit
620                if (!noExpectedType(expectedType) && !KotlinBuiltIns.isUnit(expectedType) && !isDontCarePlaceholder(expectedType)) {
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    }