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 }