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.diagnostics.Errors;
028    import org.jetbrains.kotlin.psi.*;
029    import org.jetbrains.kotlin.resolve.*;
030    import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
031    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
032    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
033    import org.jetbrains.kotlin.resolve.inline.InlineUtil;
034    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
035    import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
036    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
037    import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
038    import org.jetbrains.kotlin.resolve.scopes.utils.UtilsPackage;
039    import org.jetbrains.kotlin.types.CommonSupertypes;
040    import org.jetbrains.kotlin.types.ErrorUtils;
041    import org.jetbrains.kotlin.types.JetType;
042    import org.jetbrains.kotlin.types.TypeUtils;
043    import org.jetbrains.kotlin.types.checker.JetTypeChecker;
044    import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryPackage;
045    
046    import java.util.ArrayList;
047    import java.util.Collections;
048    import java.util.List;
049    
050    import static org.jetbrains.kotlin.diagnostics.Errors.*;
051    import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
052    import static org.jetbrains.kotlin.resolve.BindingContext.*;
053    import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
054    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
055    import static org.jetbrains.kotlin.types.TypeUtils.*;
056    import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
057    import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall;
058    import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
059    
060    public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
061    
062        public static final String RETURN_NOT_ALLOWED_MESSAGE = "Return not allowed";
063    
064        protected ControlStructureTypingVisitor(@NotNull ExpressionTypingInternals facade) {
065            super(facade);
066        }
067    
068        @NotNull
069        private DataFlowInfo checkCondition(@NotNull LexicalScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) {
070            if (condition != null) {
071                JetTypeInfo typeInfo = facade.getTypeInfo(condition, context.replaceScope(scope)
072                        .replaceExpectedType(components.builtIns.getBooleanType()).replaceContextDependency(INDEPENDENT));
073                JetType conditionType = typeInfo.getType();
074    
075                if (conditionType != null && !components.builtIns.isBooleanOrSubtype(conditionType)) {
076                    context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType));
077                }
078    
079                return typeInfo.getDataFlowInfo();
080            }
081            return context.dataFlowInfo;
082        }
083    
084        ////////////////////////////////////////////////////////////////////////////////////////////////////
085    
086    
087        @Override
088        public JetTypeInfo visitIfExpression(@NotNull JetIfExpression expression, ExpressionTypingContext context) {
089            return visitIfExpression(expression, context, false);
090        }
091    
092        public JetTypeInfo visitIfExpression(JetIfExpression ifExpression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
093            ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
094            JetExpression condition = ifExpression.getCondition();
095            DataFlowInfo conditionDataFlowInfo = checkCondition(context.scope, condition, context);
096    
097            JetExpression elseBranch = ifExpression.getElse();
098            JetExpression thenBranch = ifExpression.getThen();
099    
100            LexicalWritableScope thenScope = newWritableScopeImpl(context, "Then scope");
101            LexicalWritableScope elseScope = newWritableScopeImpl(context, "Else scope");
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                    JetTypeInfo result = getTypeInfoWhenOnlyOneBranchIsPresent(
108                            thenBranch, thenScope, thenInfo, elseInfo, contextWithExpectedType, ifExpression, isStatement);
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 TypeInfoFactoryPackage.createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast(
115                                                                     components.builtIns.getUnitType(), ifExpression,
116                                                                     contextWithExpectedType, isStatement
117                                                             ),
118                                                             thenInfo.or(elseInfo)
119                );
120            }
121            if (thenBranch == null) {
122                return getTypeInfoWhenOnlyOneBranchIsPresent(
123                        elseBranch, elseScope, elseInfo, thenInfo, contextWithExpectedType, ifExpression, isStatement);
124            }
125            JetPsiFactory psiFactory = JetPsiFactory(ifExpression);
126            JetBlockExpression thenBlock = psiFactory.wrapInABlockWrapper(thenBranch);
127            JetBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch);
128            Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock));
129            MutableDataFlowInfoForArguments dataFlowInfoForArguments =
130                        createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo);
131            ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
132                    callForIf, "If", Lists.newArrayList("thenBranch", "elseBranch"),
133                    Lists.newArrayList(false, false),
134                    contextWithExpectedType, dataFlowInfoForArguments);
135    
136            BindingContext bindingContext = context.trace.getBindingContext();
137            JetTypeInfo thenTypeInfo = BindingContextUtils.getRecordedTypeInfo(thenBranch, bindingContext);
138            JetTypeInfo elseTypeInfo = BindingContextUtils.getRecordedTypeInfo(elseBranch, bindingContext);
139            assert thenTypeInfo != null : "'Then' branch of if expression  was not processed: " + ifExpression;
140            assert elseTypeInfo != null : "'Else' branch of if expression  was not processed: " + ifExpression;
141            boolean loopBreakContinuePossible = thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible();
142    
143            JetType thenType = thenTypeInfo.getType();
144            JetType elseType = elseTypeInfo.getType();
145            DataFlowInfo thenDataFlowInfo = thenTypeInfo.getDataFlowInfo();
146            DataFlowInfo elseDataFlowInfo = elseTypeInfo.getDataFlowInfo();
147    
148            boolean jumpInThen = thenType != null && KotlinBuiltIns.isNothing(thenType);
149            boolean jumpInElse = elseType != null && KotlinBuiltIns.isNothing(elseType);
150    
151            DataFlowInfo resultDataFlowInfo;
152            if (thenType == null && elseType == null) {
153                resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
154            }
155            else if (thenType == null || (jumpInThen && !jumpInElse)) {
156                resultDataFlowInfo = elseDataFlowInfo;
157            }
158            else if (elseType == null || (jumpInElse && !jumpInThen)) {
159                resultDataFlowInfo = thenDataFlowInfo;
160            }
161            else {
162                resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
163            }
164    
165            JetType resultType = resolvedCall.getResultingDescriptor().getReturnType();
166            // If break or continue was possible, take condition check info as the jump info
167            return TypeInfoFactoryPackage
168                    .createTypeInfo(components.dataFlowAnalyzer.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement),
169                                    resultDataFlowInfo, loopBreakContinuePossible, conditionDataFlowInfo);
170        }
171    
172        @NotNull
173        private JetTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent(
174                @NotNull JetExpression presentBranch,
175                @NotNull LexicalWritableScope presentScope,
176                @NotNull DataFlowInfo presentInfo,
177                @NotNull DataFlowInfo otherInfo,
178                @NotNull ExpressionTypingContext context,
179                @NotNull JetIfExpression ifExpression,
180                boolean isStatement
181        ) {
182            ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE)
183                    .replaceContextDependency(INDEPENDENT);
184            JetTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
185                    presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext);
186            JetType type = typeInfo.getType();
187            DataFlowInfo dataFlowInfo;
188            if (type != null && KotlinBuiltIns.isNothing(type)) {
189                dataFlowInfo = otherInfo;
190            } else {
191                dataFlowInfo = typeInfo.getDataFlowInfo().or(otherInfo);
192            }
193            return components.dataFlowAnalyzer.checkImplicitCast(
194                    components.dataFlowAnalyzer.checkType(
195                            typeInfo.replaceType(components.builtIns.getUnitType()),
196                            ifExpression,
197                            context
198                    ),
199                    ifExpression,
200                    context,
201                    isStatement
202            ).replaceDataFlowInfo(dataFlowInfo);
203        }
204    
205        @Override
206        public JetTypeInfo visitWhileExpression(@NotNull JetWhileExpression expression, ExpressionTypingContext context) {
207            return visitWhileExpression(expression, context, false);
208        }
209    
210        public JetTypeInfo visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
211            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
212    
213            ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(
214                    INDEPENDENT);
215            // Preliminary analysis
216            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
217            context = context.replaceDataFlowInfo(
218                    loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo)
219            );
220    
221            JetExpression condition = expression.getCondition();
222            // Extract data flow info from condition itself without taking value into account
223            DataFlowInfo dataFlowInfo = checkCondition(context.scope, condition, context);
224    
225            JetExpression body = expression.getBody();
226            JetTypeInfo bodyTypeInfo;
227            DataFlowInfo conditionInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo);
228            if (body != null) {
229                LexicalWritableScope scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition");
230                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
231                        scopeToExtend, Collections.singletonList(body),
232                        CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo));
233            }
234            else {
235                bodyTypeInfo = TypeInfoFactoryPackage.noTypeInfo(conditionInfo);
236            }
237    
238            // Condition is false at this point only if there is no jumps outside
239            if (!containsJumpOutOfLoop(expression, context)) {
240                dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(dataFlowInfo);
241            }
242    
243            // Special case: while (true)
244            // In this case we must record data flow information at the nearest break / continue and
245            // .and it with entrance data flow information, because while body until break is executed at least once in this case
246            // See KT-6284
247            if (body != null && JetPsiUtil.isTrueConstant(condition)) {
248                // We should take data flow info from the first jump point,
249                // but without affecting changing variables
250                dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo()));
251            }
252            return components.dataFlowAnalyzer
253                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
254                    .replaceDataFlowInfo(dataFlowInfo);
255        }
256    
257        private boolean containsJumpOutOfLoop(final JetLoopExpression loopExpression, final ExpressionTypingContext context) {
258            final boolean[] result = new boolean[1];
259            result[0] = false;
260            //todo breaks in inline function literals
261            loopExpression.accept(new JetTreeVisitor<List<JetLoopExpression>>() {
262                @Override
263                public Void visitBreakExpression(@NotNull JetBreakExpression breakExpression, List<JetLoopExpression> outerLoops) {
264                    JetSimpleNameExpression targetLabel = breakExpression.getTargetLabel();
265                    PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null;
266                    if (element == loopExpression || (targetLabel == null && outerLoops.get(outerLoops.size() - 1) == loopExpression)) {
267                        result[0] = true;
268                    }
269                    return null;
270                }
271    
272                @Override
273                public Void visitContinueExpression(@NotNull JetContinueExpression expression, List<JetLoopExpression> outerLoops) {
274                    // continue@someOuterLoop is also considered as break
275                    JetSimpleNameExpression targetLabel = expression.getTargetLabel();
276                    if (targetLabel != null) {
277                        PsiElement element = context.trace.get(LABEL_TARGET, targetLabel);
278                        if (element instanceof JetLoopExpression && !outerLoops.contains(element)) {
279                            result[0] = true;
280                        }
281                    }
282                    return null;
283                }
284    
285                @Override
286                public Void visitLoopExpression(@NotNull JetLoopExpression loopExpression, List<JetLoopExpression> outerLoops) {
287                    List<JetLoopExpression> newOuterLoops = Lists.newArrayList(outerLoops);
288                    newOuterLoops.add(loopExpression);
289                    return super.visitLoopExpression(loopExpression, newOuterLoops);
290                }
291            }, Lists.newArrayList(loopExpression));
292    
293            return result[0];
294        }
295    
296        @Override
297        public JetTypeInfo visitDoWhileExpression(@NotNull JetDoWhileExpression expression, ExpressionTypingContext context) {
298            return visitDoWhileExpression(expression, context, false);
299        }
300    
301        public JetTypeInfo visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
302            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
303    
304            ExpressionTypingContext context =
305                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
306            JetExpression body = expression.getBody();
307            LexicalScope conditionScope = context.scope;
308            // Preliminary analysis
309            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
310            context = context.replaceDataFlowInfo(
311                    loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo)
312            );
313            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
314            // .and it with entrance data flow information, because do-while body is executed at least once
315            // See KT-6283
316            JetTypeInfo bodyTypeInfo;
317            if (body instanceof JetFunctionLiteralExpression) {
318                // As a matter of fact, function literal is always unused at this point
319                bodyTypeInfo = facade.getTypeInfo(body, context.replaceScope(context.scope));
320            }
321            else if (body != null) {
322                LexicalWritableScope writableScope = newWritableScopeImpl(context, "do..while body scope");
323                conditionScope = writableScope;
324                List<JetExpression> block;
325                if (body instanceof JetBlockExpression) {
326                    block = ((JetBlockExpression)body).getStatements();
327                }
328                else {
329                    block = Collections.singletonList(body);
330                }
331                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
332                        writableScope, block, CoercionStrategy.NO_COERCION, context);
333            }
334            else {
335                bodyTypeInfo = TypeInfoFactoryPackage.noTypeInfo(context);
336            }
337            JetExpression condition = expression.getCondition();
338            DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context);
339            DataFlowInfo dataFlowInfo;
340            // Without jumps out, condition is entered and false, with jumps out, we know nothing about it
341            if (!containsJumpOutOfLoop(expression, context)) {
342                dataFlowInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
343            }
344            else {
345                dataFlowInfo = context.dataFlowInfo;
346            }
347            // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and
348            // .and it with entrance data flow information, because do-while body is executed at least once
349            // See KT-6283
350            // NB: it's really important to do it for non-empty body which is not a function literal
351            // If it's a function literal, it appears always unused so it's no matter what we do at this point
352            if (body != null) {
353                // We should take data flow info from the first jump point,
354                // but without affecting changing variables
355                dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo()));
356            }
357            return components.dataFlowAnalyzer
358                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
359                    .replaceDataFlowInfo(dataFlowInfo);
360        }
361    
362        @Override
363        public JetTypeInfo visitForExpression(@NotNull JetForExpression expression, ExpressionTypingContext context) {
364            return visitForExpression(expression, context, false);
365        }
366    
367        public JetTypeInfo visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
368            if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
369    
370            ExpressionTypingContext context =
371                    contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
372            // Preliminary analysis
373            PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
374            context = context.replaceDataFlowInfo(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo));
375    
376            JetExpression loopRange = expression.getLoopRange();
377            JetType expectedParameterType = null;
378            JetTypeInfo loopRangeInfo;
379            if (loopRange != null) {
380                ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope));
381                loopRangeInfo = facade.getTypeInfo(loopRange, context);
382                if (loopRangeReceiver != null) {
383                    expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention(loopRangeReceiver, context);
384                }
385            }
386            else {
387                loopRangeInfo = TypeInfoFactoryPackage.noTypeInfo(context);
388            }
389    
390            LexicalWritableScope loopScope = newWritableScopeImpl(context, "Scope with for-loop index");
391    
392            JetParameter loopParameter = expression.getLoopParameter();
393            if (loopParameter != null) {
394                VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
395    
396                loopScope.addVariableDescriptor(variableDescriptor);
397            }
398            else {
399                JetMultiDeclaration multiParameter = expression.getMultiParameter();
400                if (multiParameter != null && loopRange != null) {
401                    JetType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
402                    TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
403                    components.annotationResolver.resolveAnnotationsWithArguments(loopScope, multiParameter.getModifierList(), context.trace);
404                    components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(
405                            loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
406                    );
407                }
408            }
409    
410            JetExpression body = expression.getBody();
411            JetTypeInfo bodyTypeInfo;
412            if (body != null) {
413                bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body),
414                        CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()));
415            }
416            else {
417                bodyTypeInfo = loopRangeInfo;
418            }
419    
420            return components.dataFlowAnalyzer
421                    .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType)
422                    .replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo());
423        }
424    
425        private VariableDescriptor createLoopParameterDescriptor(
426                JetParameter loopParameter,
427                JetType expectedParameterType,
428                ExpressionTypingContext context
429        ) {
430            components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(loopParameter, VAL_OR_VAR_ON_LOOP_PARAMETER);
431    
432            JetTypeReference typeReference = loopParameter.getTypeReference();
433            VariableDescriptor variableDescriptor;
434            if (typeReference != null) {
435                variableDescriptor = components.descriptorResolver.
436                        resolveLocalVariableDescriptor(context.scope, loopParameter, context.trace);
437                JetType actualParameterType = variableDescriptor.getType();
438                if (expectedParameterType != null &&
439                        !JetTypeChecker.DEFAULT.isSubtypeOf(expectedParameterType, actualParameterType)) {
440                    context.trace.report(TYPE_MISMATCH_IN_FOR_LOOP.on(typeReference, expectedParameterType, actualParameterType));
441                }
442            }
443            else {
444                if (expectedParameterType == null) {
445                    expectedParameterType = ErrorUtils.createErrorType("Error");
446                }
447                variableDescriptor = components.descriptorResolver.
448                        resolveLocalVariableDescriptor(loopParameter, expectedParameterType, context.trace, context.scope);
449            }
450    
451            {
452                // http://youtrack.jetbrains.net/issue/KT-527
453    
454                VariableDescriptor olderVariable = UtilsPackage.getLocalVariable(context.scope, variableDescriptor.getName());
455                if (olderVariable != null && isLocal(context.scope.getOwnerDescriptor(), olderVariable)) {
456                    PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(variableDescriptor);
457                    context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString()));
458                }
459            }
460            return variableDescriptor;
461        }
462    
463        @Override
464        public JetTypeInfo visitTryExpression(@NotNull JetTryExpression expression, ExpressionTypingContext typingContext) {
465            ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT);
466            JetExpression tryBlock = expression.getTryBlock();
467            List<JetCatchClause> catchClauses = expression.getCatchClauses();
468            JetFinallySection finallyBlock = expression.getFinallyBlock();
469            List<JetType> types = new ArrayList<JetType>();
470            for (JetCatchClause catchClause : catchClauses) {
471                JetParameter catchParameter = catchClause.getCatchParameter();
472                JetExpression catchBody = catchClause.getCatchBody();
473                if (catchParameter != null) {
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                    JetType 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                        JetType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType();
486                        if (type != null) {
487                            types.add(type);
488                        }
489                    }
490                }
491            }
492    
493            JetTypeInfo result = TypeInfoFactoryPackage.noTypeInfo(context);
494            if (finallyBlock != null) {
495                result = facade.getTypeInfo(finallyBlock.getFinalExpression(),
496                                            context.replaceExpectedType(NO_EXPECTED_TYPE));
497            }
498    
499            JetType 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 JetTypeInfo visitThrowExpression(@NotNull JetThrowExpression expression, ExpressionTypingContext context) {
513            JetExpression thrownExpression = expression.getThrownExpression();
514            if (thrownExpression != null) {
515                JetType 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 JetTypeInfo visitReturnExpression(@NotNull JetReturnExpression expression, ExpressionTypingContext context) {
524            JetElement labelTargetElement = LabelResolver.INSTANCE.resolveControlLabel(expression, context);
525    
526            JetExpression returnedExpression = expression.getReturnedExpression();
527    
528            JetType expectedType = NO_EXPECTED_TYPE;
529            JetType resultType = components.builtIns.getNothingType();
530            JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(expression, JetDeclaration.class);
531    
532            if (parentDeclaration instanceof JetParameter) {
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 JetMultiDeclaration) {
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, JetDeclaration.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, (JetElement) 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 JetSecondaryConstructor);
598        }
599    
600        @Override
601        public JetTypeInfo visitBreakExpression(@NotNull JetBreakExpression 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 JetTypeInfo visitContinueExpression(@NotNull JetContinueExpression 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 JetType getFunctionExpectedReturnType(
616                @NotNull FunctionDescriptor descriptor,
617                @NotNull JetElement function,
618                @NotNull ExpressionTypingContext context
619        ) {
620            JetType expectedType;
621            if (function instanceof JetSecondaryConstructor) {
622                expectedType = getBuiltIns(descriptor).getUnitType();
623            }
624            else if (function instanceof JetFunction) {
625                JetFunction jetFunction = (JetFunction) function;
626                expectedType = context.trace.get(EXPECTED_RETURN_TYPE, jetFunction);
627    
628                if ((expectedType == null) && (jetFunction.getTypeReference() != null || jetFunction.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    }