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