KT-1041 Add check that thrown/catched expression is of Throwable type
This commit is contained in:
@@ -59,3 +59,9 @@ class String() : Comparable<String>, CharSequence {
|
||||
|
||||
fun equals(other : Any?) : Boolean
|
||||
}
|
||||
|
||||
class Throwable(message : String? = null, cause: Throwable? = null) {
|
||||
fun getMessage() : String?
|
||||
fun getCause() : Throwable?
|
||||
fun printStackTrace() : Unit
|
||||
}
|
||||
@@ -72,14 +72,16 @@ public class JetStandardLibrary {
|
||||
private ClassDescriptor iterableClass;
|
||||
private ClassDescriptor comparableClass;
|
||||
private ClassDescriptor volatileClass;
|
||||
private ClassDescriptor throwableClass;
|
||||
|
||||
private JetType stringType;
|
||||
private JetType volatileType;
|
||||
private JetType nullableStringType;
|
||||
private JetType charSequenceType;
|
||||
private JetType nullableCharSequenceType;
|
||||
|
||||
private JetType nullableTuple0Type;
|
||||
private JetType throwableType;
|
||||
private JetType nullableThrowableType;
|
||||
|
||||
private JetType tuple0Type;
|
||||
|
||||
@@ -143,6 +145,7 @@ public class JetStandardLibrary {
|
||||
this.charSequenceClass = (ClassDescriptor) libraryScope.getClassifier("CharSequence");
|
||||
this.arrayClass = (ClassDescriptor) libraryScope.getClassifier("Array");
|
||||
this.volatileClass = (ClassDescriptor) libraryScope.getClassifier("volatile");
|
||||
this.throwableClass = (ClassDescriptor) libraryScope.getClassifier("Throwable");
|
||||
|
||||
this.iterableClass = (ClassDescriptor) libraryScope.getClassifier("Iterable");
|
||||
this.comparableClass = (ClassDescriptor) libraryScope.getClassifier("Comparable");
|
||||
@@ -153,6 +156,8 @@ public class JetStandardLibrary {
|
||||
this.nullableCharSequenceType = TypeUtils.makeNullable(charSequenceType);
|
||||
this.nullableStringType = TypeUtils.makeNullable(stringType);
|
||||
this.volatileType = new JetTypeImpl(getVolatile());
|
||||
this.throwableType = new JetTypeImpl(getThrowable());
|
||||
this.nullableThrowableType = TypeUtils.makeNullable(throwableType);
|
||||
|
||||
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
|
||||
this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type);
|
||||
@@ -270,6 +275,12 @@ public class JetStandardLibrary {
|
||||
return comparableClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getThrowable() {
|
||||
initStdClasses();
|
||||
return throwableClass;
|
||||
}
|
||||
|
||||
public Set<FunctionDescriptor> getTypeInfoFunctions() {
|
||||
initStdClasses();
|
||||
return typeInfoFunction;
|
||||
@@ -393,6 +404,17 @@ public class JetStandardLibrary {
|
||||
initStdClasses();
|
||||
return nullableCharSequenceType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getThrowableType() {
|
||||
initStdClasses();
|
||||
return throwableType;
|
||||
}
|
||||
|
||||
public JetType getNullableThrowableType() {
|
||||
initStdClasses();
|
||||
return nullableThrowableType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getNullablePrimitiveJetType(PrimitiveType primitiveType) {
|
||||
|
||||
+4
-2
@@ -400,6 +400,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetExpression catchBody = catchClause.getCatchBody();
|
||||
if (catchParameter != null) {
|
||||
VariableDescriptor variableDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), context.scope, catchParameter);
|
||||
JetType throwableType = context.semanticServices.getStandardLibrary().getThrowable().getDefaultType();
|
||||
DataFlowUtils.checkType(variableDescriptor.getOutType(), catchParameter, context.replaceExpectedType(throwableType));
|
||||
if (catchBody != null) {
|
||||
WritableScope catchScope = newWritableScopeImpl(context).setDebugName("Catch scope");
|
||||
catchScope.addVariableDescriptor(variableDescriptor);
|
||||
@@ -433,8 +435,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
public JetType visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext context) {
|
||||
JetExpression thrownExpression = expression.getThrownExpression();
|
||||
if (thrownExpression != null) {
|
||||
JetType type = facade.getType(thrownExpression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(context.scope));
|
||||
// TODO : check that it inherits Throwable
|
||||
JetType throwableType = context.semanticServices.getStandardLibrary().getThrowable().getDefaultType();
|
||||
facade.getType(thrownExpression, context.replaceExpectedType(throwableType).replaceScope(context.scope));
|
||||
}
|
||||
return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user