6991528: Support making Throwable.suppressedExceptions immutable

Reviewed-by: mcimadamore
This commit is contained in:
Joe Darcy 2010-11-14 07:16:46 -08:00
parent 67135065d9
commit f9f932a9f3
4 changed files with 35 additions and 33 deletions
langtools
src/share/classes/com/sun/tools/javac
test/tools/javac/TryWithResources

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1509,17 +1509,17 @@ public class Lower extends TreeTranslator {
} }
private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) { private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressedException(catchException); // primaryException.addSuppressed(catchException);
VarSymbol catchException = VarSymbol catchException =
new VarSymbol(0, make.paramName(2), new VarSymbol(0, make.paramName(2),
syms.throwableType, syms.throwableType,
currentMethodSym); currentMethodSym);
JCStatement addSuppressionStatement = JCStatement addSuppressionStatement =
make.Exec(makeCall(make.Ident(primaryException), make.Exec(makeCall(make.Ident(primaryException),
names.fromString("addSuppressedException"), names.addSuppressed,
List.<JCExpression>of(make.Ident(catchException)))); List.<JCExpression>of(make.Ident(catchException))));
// try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); } // try { resource.close(); } catch (e) { primaryException.addSuppressed(e); }
JCBlock tryBlock = JCBlock tryBlock =
make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource))); make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource)));
JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null); JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -150,6 +150,7 @@ public class Names {
public final Name finalize; public final Name finalize;
public final Name java_lang_AutoCloseable; public final Name java_lang_AutoCloseable;
public final Name close; public final Name close;
public final Name addSuppressed;
public final Name.Table table; public final Name.Table table;
@ -268,6 +269,7 @@ public class Names {
java_lang_AutoCloseable = fromString("java.lang.AutoCloseable"); java_lang_AutoCloseable = fromString("java.lang.AutoCloseable");
close = fromString("close"); close = fromString("close");
addSuppressed = fromString("addSuppressed");
} }
protected Name.Table createTable(Options options) { protected Name.Table createTable(Options options) {

@ -36,7 +36,7 @@ public class TwrSuppression implements AutoCloseable {
throw new RuntimeException(); throw new RuntimeException();
} }
} catch(RuntimeException e) { } catch(RuntimeException e) {
Throwable[] suppressedExceptions = e.getSuppressedExceptions(); Throwable[] suppressedExceptions = e.getSuppressed();
int length = suppressedExceptions.length; int length = suppressedExceptions.length;
if (length != 2) if (length != 2)
throw new RuntimeException("Unexpected length " + length); throw new RuntimeException("Unexpected length " + length);

@ -90,7 +90,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
} }
@ -112,7 +112,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
} }
@ -134,7 +134,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -158,7 +158,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -181,7 +181,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -207,7 +207,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -231,7 +231,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -259,7 +259,7 @@ public class TwrTests {
} catch (Resource.CreateFailException e) { } catch (Resource.CreateFailException e) {
creationFailuresDetected++; creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId); checkCreateFailureId(e.resourceId(), createFailureId);
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e); throw new AssertionError("Secondary exception suppression failed:" + e);
} }
@ -310,7 +310,7 @@ public class TwrTests {
* Check for proper suppressed exceptions in proper order. * Check for proper suppressed exceptions in proper order.
* *
* @param suppressedExceptions the suppressed exceptions array returned by * @param suppressedExceptions the suppressed exceptions array returned by
* getSuppressedExceptions() * getSuppressed()
* @bitmap a bitmap indicating which suppressed exceptions are expected. * @bitmap a bitmap indicating which suppressed exceptions are expected.
* Bit i is set iff id should throw a CloseFailException. * Bit i is set iff id should throw a CloseFailException.
*/ */
@ -376,7 +376,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -388,7 +388,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 1); checkClosedList(closedList, 1);
} }
@ -409,7 +409,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -421,7 +421,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 2); checkClosedList(closedList, 2);
} }
@ -443,7 +443,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -455,7 +455,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 2); checkClosedList(closedList, 2);
} }
@ -477,7 +477,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -489,7 +489,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 3); checkClosedList(closedList, 3);
} }
@ -513,7 +513,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -525,7 +525,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 3); checkClosedList(closedList, 3);
} }
@ -548,7 +548,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -560,7 +560,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 4); checkClosedList(closedList, 4);
} }
@ -586,7 +586,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -598,7 +598,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 4); checkClosedList(closedList, 4);
} }
@ -621,7 +621,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -633,7 +633,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 5); checkClosedList(closedList, 5);
} }
@ -660,7 +660,7 @@ public class TwrTests {
} catch (MyKindOfException e) { } catch (MyKindOfException e) {
if (failure == 0) if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException"); throw new AssertionError("Unexpected MyKindOfException");
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) { } catch (Resource.CloseFailException e) {
if (failure == 1) if (failure == 1)
throw new AssertionError("Secondary exception suppression failed"); throw new AssertionError("Secondary exception suppression failed");
@ -672,7 +672,7 @@ public class TwrTests {
throw new AssertionError("CloseFailException: got id " + id throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")"); + ", expected lg(" + highestCloseFailBit +")");
} }
checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
} }
checkClosedList(closedList, 5); checkClosedList(closedList, 5);
} }