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