Perform additional checks on catch parameter declaration
KT-8320 It should not be possible to catch a type parameter type KT-7645 Prohibit default value for `catch`-block parameter
This commit is contained in:
@@ -152,6 +152,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtTypeArgumentList> TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtParameter> REIFIED_TYPE_IN_CATCH_CLAUSE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtParameter> TYPE_PARAMETER_IN_CATCH_CLAUSE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeParameterList> GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtTypeAlias> TOPLEVEL_TYPEALIASES_ONLY = DiagnosticFactory0.create(ERROR);
|
||||
@@ -527,6 +528,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtParameter> DATA_CLASS_VARARG_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtParameter> DATA_CLASS_NOT_PROPERTY_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtParameter> CATCH_PARAMETER_WITH_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Multi-platform projects
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> HEADER_DECLARATION_WITH_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
+3
@@ -621,6 +621,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED, "Type arguments for outer class are redundant when nested class is referenced");
|
||||
|
||||
MAP.put(REIFIED_TYPE_IN_CATCH_CLAUSE, "Reified type is forbidden for catch parameter");
|
||||
MAP.put(TYPE_PARAMETER_IN_CATCH_CLAUSE, "Type parameter is forbidden for catch parameter");
|
||||
MAP.put(GENERIC_THROWABLE_SUBCLASS, "Subclass of 'Throwable' may not have type parameters");
|
||||
|
||||
MAP.put(TYPE_MISMATCH_IN_FOR_LOOP, "The loop iterates over values of type {0} but the parameter is declared to be {1}", RENDER_TYPE,
|
||||
@@ -797,6 +798,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(DATA_CLASS_VARARG_PARAMETER, "Primary constructor vararg parameters are forbidden for data classes");
|
||||
MAP.put(DATA_CLASS_NOT_PROPERTY_PARAMETER, "Data class primary constructor must have only property (val / var) parameters");
|
||||
|
||||
MAP.put(CATCH_PARAMETER_WITH_DEFAULT_VALUE, "Catch clause parameter may not have a default value");
|
||||
|
||||
MAP.put(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED, "Right-hand side has anonymous type. Please specify type explicitly", TO_STRING);
|
||||
MAP.put(KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE,
|
||||
"Declaration has an inconsistent return type. Please add upper bound Any for type parameter ''{0}'' or specify return type explicitly", NAME);
|
||||
|
||||
+26
-7
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
@@ -486,17 +487,12 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
KtExpression catchBody = catchClause.getCatchBody();
|
||||
boolean nothingInCatchBranch = false;
|
||||
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, components.languageVersionSettings);
|
||||
checkCatchParameterDeclaration(catchParameter, context);
|
||||
|
||||
VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor(
|
||||
context.scope, catchParameter, context.trace);
|
||||
KotlinType catchParameterType = variableDescriptor.getType();
|
||||
if (TypeUtils.isReifiedTypeParameter(catchParameterType)) {
|
||||
context.trace.report(REIFIED_TYPE_IN_CATCH_CLAUSE.on(catchParameter));
|
||||
}
|
||||
checkCatchParameterType(catchParameter, catchParameterType, context);
|
||||
|
||||
KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
|
||||
components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType));
|
||||
@@ -539,6 +535,29 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCatchParameterType(KtParameter catchParameter, KotlinType catchParameterType, ExpressionTypingContext context) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(catchParameterType);
|
||||
if (typeParameterDescriptor != null) {
|
||||
if (typeParameterDescriptor.isReified()) {
|
||||
context.trace.report(REIFIED_TYPE_IN_CATCH_CLAUSE.on(catchParameter));
|
||||
}
|
||||
else {
|
||||
context.trace.report(TYPE_PARAMETER_IN_CATCH_CLAUSE.on(catchParameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCatchParameterDeclaration(KtParameter catchParameter, ExpressionTypingContext context) {
|
||||
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, components.languageVersionSettings);
|
||||
|
||||
if (catchParameter.hasDefaultValue()) {
|
||||
context.trace.report(Errors.CATCH_PARAMETER_WITH_DEFAULT_VALUE.on(catchParameter));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitThrowExpression(@NotNull KtThrowExpression expression, ExpressionTypingContext context) {
|
||||
KtExpression thrownExpression = expression.getThrownExpression();
|
||||
|
||||
Reference in New Issue
Block a user