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