@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)); } }
@Nullable public static <T extends PsiElement> T getDirectParentOfTypeForBlock( @NotNull KtBlockExpression block, @NotNull Class<T> aClass) { T parent = PsiTreeUtil.getParentOfType(block, aClass); if (parent instanceof KtIfExpression) { KtIfExpression ifExpression = (KtIfExpression) parent; if (ifExpression.getElse() == block || ifExpression.getThen() == block) { return parent; } } if (parent instanceof KtWhenExpression) { KtWhenExpression whenExpression = (KtWhenExpression) parent; for (KtWhenEntry whenEntry : whenExpression.getEntries()) { if (whenEntry.getExpression() == block) { return parent; } } } if (parent instanceof KtFunctionLiteral) { KtFunctionLiteral functionLiteral = (KtFunctionLiteral) parent; if (functionLiteral.getBodyExpression() == block) { return parent; } } if (parent instanceof KtTryExpression) { KtTryExpression tryExpression = (KtTryExpression) parent; if (tryExpression.getTryBlock() == block) { return parent; } for (KtCatchClause clause : tryExpression.getCatchClauses()) { if (clause.getCatchBody() == block) { return parent; } } } return null; }