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