KT-1041 Add check that thrown/catched expression is of Throwable type

This commit is contained in:
Svetlana Isakova
2012-02-20 13:46:34 +04:00
parent 3d3b41da4f
commit 046c13a264
12 changed files with 47 additions and 13 deletions
+6
View File
@@ -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) {
@@ -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);
}