@Override public KotlinTypeInfo visitTryExpression( @NotNull KtTryExpression expression, ExpressionTypingContext typingContext) { ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT); KtExpression tryBlock = expression.getTryBlock(); List<KtCatchClause> catchClauses = expression.getCatchClauses(); KtFinallySection finallyBlock = expression.getFinallyBlock(); List<KotlinType> types = new ArrayList<KotlinType>(); for (KtCatchClause catchClause : catchClauses) { KtParameter catchParameter = catchClause.getCatchParameter(); KtExpression catchBody = catchClause.getCatchBody(); if (catchParameter != null) { components.identifierChecker.checkDeclaration(catchParameter, context.trace); ModifiersChecker.ModifiersCheckingProcedure modifiersChecking = components.modifiersChecker.withTrace(context.trace); modifiersChecking.checkParameterHasNoValOrVar( catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER); ModifierCheckerCore.INSTANCE$.check(catchParameter, context.trace, null); VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor( context.scope, catchParameter, context.trace); KotlinType throwableType = components.builtIns.getThrowable().getDefaultType(); components.dataFlowAnalyzer.checkType( variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType)); if (catchBody != null) { LexicalWritableScope catchScope = newWritableScopeImpl(context, "Catch scope"); catchScope.addVariableDescriptor(variableDescriptor); KotlinType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType(); if (type != null) { types.add(type); } } } } KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(context); if (finallyBlock != null) { result = facade.getTypeInfo( finallyBlock.getFinalExpression(), context.replaceExpectedType(NO_EXPECTED_TYPE)); } KotlinType type = facade.getTypeInfo(tryBlock, context).getType(); if (type != null) { types.add(type); } if (types.isEmpty()) { return result.clearType(); } else { return result.replaceType(CommonSupertypes.commonSupertype(types)); } }
@NotNull public KotlinTypeInfo getBlockReturnedType( @NotNull KtBlockExpression expression, @NotNull CoercionStrategy coercionStrategyForLastExpression, @NotNull ExpressionTypingContext context) { List<KtExpression> block = StatementFilterKt.filterStatements(statementFilter, expression); DeclarationDescriptor containingDescriptor = context.scope.getOwnerDescriptor(); LexicalWritableScope scope = new LexicalWritableScope( context.scope, containingDescriptor, false, null, new TraceBasedRedeclarationHandler(context.trace), LexicalScopeKind.CODE_BLOCK); scope.changeLockLevel(LexicalWritableScope.LockLevel.BOTH); KotlinTypeInfo r; if (block.isEmpty()) { r = expressionTypingComponents.dataFlowAnalyzer.createCheckedTypeInfo( expressionTypingComponents.builtIns.getUnitType(), context, expression); } else { r = getBlockReturnedTypeWithWritableScope( scope, block, coercionStrategyForLastExpression, context.replaceStatementFilter(statementFilter)); } scope.changeLockLevel(LexicalWritableScope.LockLevel.READING); if (containingDescriptor instanceof ScriptDescriptor) { context.trace.record( BindingContext.SCRIPT_SCOPE, (ScriptDescriptor) containingDescriptor, scope); } return r; }
public KotlinTypeInfo visitForExpression( KtForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { if (!isStatement) return components.dataFlowAnalyzer.illegalStatementType( expression, contextWithExpectedType, facade); ExpressionTypingContext context = contextWithExpectedType .replaceExpectedType(NO_EXPECTED_TYPE) .replaceContextDependency(INDEPENDENT); // Preliminary analysis PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression); context = context.replaceDataFlowInfo( loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo)); KtExpression loopRange = expression.getLoopRange(); KotlinType expectedParameterType = null; KotlinTypeInfo loopRangeInfo; if (loopRange != null) { ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope)); loopRangeInfo = facade.getTypeInfo(loopRange, context); if (loopRangeReceiver != null) { expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention( loopRangeReceiver, context); } } else { loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context); } LexicalWritableScope loopScope = newWritableScopeImpl(context, "Scope with for-loop index"); KtParameter loopParameter = expression.getLoopParameter(); if (loopParameter != null) { VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context); components .modifiersChecker .withTrace(context.trace) .checkModifiersForLocalDeclaration(loopParameter, variableDescriptor); components.identifierChecker.checkDeclaration(loopParameter, context.trace); loopScope.addVariableDescriptor(variableDescriptor); } else { KtMultiDeclaration multiParameter = expression.getMultiParameter(); if (multiParameter != null && loopRange != null) { KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType; TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType); components.annotationResolver.resolveAnnotationsWithArguments( loopScope, multiParameter.getModifierList(), context.trace); components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration( loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context); components .modifiersChecker .withTrace(context.trace) .checkModifiersForMultiDeclaration(multiParameter); components .modifiersChecker .withTrace(context.trace) .checkParameterHasNoValOrVar(multiParameter, VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER); components.identifierChecker.checkDeclaration(multiParameter, context.trace); } } KtExpression body = expression.getBody(); KotlinTypeInfo bodyTypeInfo; if (body != null) { bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( loopScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo())); } else { bodyTypeInfo = loopRangeInfo; } return components .dataFlowAnalyzer .checkType( bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) .replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()); }