From e46792a80e5c856026b35eed5969a224eddc4915 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 3 May 2011 12:25:54 +0400 Subject: [PATCH] Fixed the typechecking for try..catch --- .../jet/lang/types/JetTypeChecker.java | 1 + .../jet/lang/types/JetTypeInferrer.java | 37 ++++++++++++++----- idea/testData/resolve/TryCatch.jet | 21 +++++++++++ .../jetbrains/jet/resolve/JetResolveTest.java | 4 ++ 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 idea/testData/resolve/TryCatch.jet diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 30c82645c95..0e3063979a4 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -75,6 +75,7 @@ public class JetTypeChecker { boolean nullable = false; for (Iterator iterator = typeSet.iterator(); iterator.hasNext();) { JetType type = iterator.next(); + assert type != null; // TODO : This admits 'Nothing?'. Review if (JetStandardClasses.isNothing(type)) { iterator.remove(); diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 09900473793..6ff6a22f8d6 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -959,19 +959,38 @@ public class JetTypeInferrer { List catchClauses = expression.getCatchClauses(); JetFinallySection finallyBlock = expression.getFinallyBlock(); List types = new ArrayList(); - if (finallyBlock == null) { - for (JetCatchClause catchClause : catchClauses) { - // TODO: change scope here - JetExpression catchBody = catchClause.getCatchBody(); + for (JetCatchClause catchClause : catchClauses) { + JetParameter catchParameter = catchClause.getCatchParameter(); + JetExpression catchBody = catchClause.getCatchBody(); + if (catchParameter != null) { + VariableDescriptor variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, catchParameter); if (catchBody != null) { - types.add(getType(scope, catchBody, true)); + WritableScope catchScope = semanticServices.createWritableScope(scope, scope.getContainingDeclaration()); + catchScope.addVariableDescriptor(variableDescriptor); + JetType type = getType(catchScope, catchBody, true); + if (type != null) { + types.add(type); + } } } - } else { - types.add(getType(scope, finallyBlock.getFinalExpression(), true)); } - types.add(getType(scope, tryBlock, true)); - result = semanticServices.getTypeChecker().commonSupertype(types); + if (finallyBlock != null) { + types.clear(); // Do not need the list for the check, but need the code above to typecheck catch bodies + JetType type = getType(scope, finallyBlock.getFinalExpression(), true); + if (type != null) { + types.add(type); + } + } + JetType type = getType(scope, tryBlock, true); + if (type != null) { + types.add(type); + } + if (types.isEmpty()) { + result = null; + } + else { + result = semanticServices.getTypeChecker().commonSupertype(types); + } } @Override diff --git a/idea/testData/resolve/TryCatch.jet b/idea/testData/resolve/TryCatch.jet new file mode 100644 index 00000000000..26c86007a3d --- /dev/null +++ b/idea/testData/resolve/TryCatch.jet @@ -0,0 +1,21 @@ +fun test() { + ~x~val x = 1 + try { + ~y~val y = `x`x + } + catch (~e1~e : Exception) { + val z = `e1`e + val zz = `!`y + val zzz = `x`x + } + catch (~e2~e : Exception) { + val z = `e2`e + val zz = `!`y + val zzz = `x`x + } + finally { + val z = `!`e + val zz = `!`y + val zzz = `x`x + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index 3a96087952a..1c90bb5ff5c 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -151,4 +151,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase { doTest("/resolve/Namespaces.jet", true, true); } + public void testTryCatch() throws Exception { + doTest("/resolve/TryCatch.jet", true, true); + } + } \ No newline at end of file