Mon, 03 May 2010 17:12:59 -0700
6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
Reviewed-by: jjg, darcy
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/source/tree/DisjointTypeTree.java Mon May 03 17:12:59 2010 -0700 1.3 @@ -0,0 +1,40 @@ 1.4 +/* 1.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.source.tree; 1.30 + 1.31 +import java.util.List; 1.32 + 1.33 +/** 1.34 + * A tree node for a disjoint type expression in a multicatch var declaration. 1.35 + * 1.36 + * 1.37 + * @author Maurizio Cimadamore 1.38 + * 1.39 + * @since 1.7 1.40 + */ 1.41 +public interface DisjointTypeTree extends Tree { 1.42 + List<? extends Tree> getTypeComponents(); 1.43 +} 1.44 \ No newline at end of file
2.1 --- a/src/share/classes/com/sun/source/tree/Tree.java Sun May 02 15:55:02 2010 -0700 2.2 +++ b/src/share/classes/com/sun/source/tree/Tree.java Mon May 03 17:12:59 2010 -0700 2.3 @@ -234,6 +234,11 @@ 2.4 PARAMETERIZED_TYPE(ParameterizedTypeTree.class), 2.5 2.6 /** 2.7 + * Used for instances of {@link DisjointTypeTree}. 2.8 + */ 2.9 + DISJOINT_TYPE(DisjointTypeTree.class), 2.10 + 2.11 + /** 2.12 * Used for instances of {@link TypeCastTree}. 2.13 */ 2.14 TYPE_CAST(TypeCastTree.class),
3.1 --- a/src/share/classes/com/sun/source/tree/TreeVisitor.java Sun May 02 15:55:02 2010 -0700 3.2 +++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java Mon May 03 17:12:59 2010 -0700 3.3 @@ -96,6 +96,7 @@ 3.4 R visitCompilationUnit(CompilationUnitTree node, P p); 3.5 R visitTry(TryTree node, P p); 3.6 R visitParameterizedType(ParameterizedTypeTree node, P p); 3.7 + R visitDisjointType(DisjointTypeTree node, P p); 3.8 R visitArrayType(ArrayTypeTree node, P p); 3.9 R visitTypeCast(TypeCastTree node, P p); 3.10 R visitPrimitiveType(PrimitiveTypeTree node, P p);
4.1 --- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Sun May 02 15:55:02 2010 -0700 4.2 +++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Mon May 03 17:12:59 2010 -0700 4.3 @@ -228,6 +228,10 @@ 4.4 return defaultAction(node, p); 4.5 } 4.6 4.7 + public R visitDisjointType(DisjointTypeTree node, P p) { 4.8 + return defaultAction(node, p); 4.9 + } 4.10 + 4.11 public R visitTypeParameter(TypeParameterTree node, P p) { 4.12 return defaultAction(node, p); 4.13 }
5.1 --- a/src/share/classes/com/sun/source/util/TreeScanner.java Sun May 02 15:55:02 2010 -0700 5.2 +++ b/src/share/classes/com/sun/source/util/TreeScanner.java Mon May 03 17:12:59 2010 -0700 5.3 @@ -354,6 +354,10 @@ 5.4 return r; 5.5 } 5.6 5.7 + public R visitDisjointType(DisjointTypeTree node, P p) { 5.8 + return scan(node.getTypeComponents(), p); 5.9 + } 5.10 + 5.11 public R visitTypeParameter(TypeParameterTree node, P p) { 5.12 R r = scan(node.getAnnotations(), p); 5.13 r = scanAndReduce(node.getBounds(), p, r);
6.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Sun May 02 15:55:02 2010 -0700 6.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Mon May 03 17:12:59 2010 -0700 6.3 @@ -230,6 +230,11 @@ 6.4 */ 6.5 public static final long PROPRIETARY = 1L<<38; 6.6 6.7 + /** 6.8 + * Flag that marks a disjoint var in a multi-catch clause 6.9 + */ 6.10 + public static final long DISJOINT = 1L<<39; 6.11 + 6.12 /** Modifier masks. 6.13 */ 6.14 public static final int
7.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java Sun May 02 15:55:02 2010 -0700 7.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Mon May 03 17:12:59 2010 -0700 7.3 @@ -125,6 +125,9 @@ 7.4 public boolean allowDiamond() { 7.5 return compareTo(JDK1_7) >= 0; 7.6 } 7.7 + public boolean allowMulticatch() { 7.8 + return compareTo(JDK1_7) >= 0; 7.9 + } 7.10 public boolean allowEnums() { 7.11 return compareTo(JDK1_5) >= 0; 7.12 }
8.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Sun May 02 15:55:02 2010 -0700 8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon May 03 17:12:59 2010 -0700 8.3 @@ -988,6 +988,13 @@ 8.4 Env<AttrContext> catchEnv = 8.5 env.dup(c, env.info.dup(env.info.scope.dup())); 8.6 Type ctype = attribStat(c.param, catchEnv); 8.7 + if (TreeInfo.isMultiCatch(c)) { 8.8 + //check that multi-catch parameter is marked as final 8.9 + if ((c.param.sym.flags() & FINAL) == 0) { 8.10 + log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym); 8.11 + } 8.12 + c.param.sym.flags_field = c.param.sym.flags() | DISJOINT; 8.13 + } 8.14 if (c.param.type.tsym.kind == Kinds.VAR) { 8.15 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER); 8.16 } 8.17 @@ -2735,6 +2742,11 @@ 8.18 result = check(tree, owntype, TYP, pkind, pt); 8.19 } 8.20 8.21 + public void visitTypeDisjoint(JCTypeDisjoint tree) { 8.22 + List<Type> componentTypes = attribTypes(tree.components, env); 8.23 + tree.type = result = check(tree, types.lub(componentTypes), TYP, pkind, pt); 8.24 + } 8.25 + 8.26 public void visitTypeParameter(JCTypeParameter tree) { 8.27 TypeVar a = (TypeVar)tree.type; 8.28 Set<Type> boundSet = new HashSet<Type>();
9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Sun May 02 15:55:02 2010 -0700 9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon May 03 17:12:59 2010 -0700 9.3 @@ -27,6 +27,8 @@ 9.4 9.5 package com.sun.tools.javac.comp; 9.6 9.7 +import java.util.HashMap; 9.8 + 9.9 import com.sun.tools.javac.code.*; 9.10 import com.sun.tools.javac.tree.*; 9.11 import com.sun.tools.javac.util.*; 9.12 @@ -184,6 +186,7 @@ 9.13 private final Check chk; 9.14 private TreeMaker make; 9.15 private Lint lint; 9.16 + private final boolean allowRethrowAnalysis; 9.17 9.18 public static Flow instance(Context context) { 9.19 Flow instance = context.get(flowKey); 9.20 @@ -194,13 +197,14 @@ 9.21 9.22 protected Flow(Context context) { 9.23 context.put(flowKey, this); 9.24 - 9.25 names = Names.instance(context); 9.26 log = Log.instance(context); 9.27 syms = Symtab.instance(context); 9.28 types = Types.instance(context); 9.29 chk = Check.instance(context); 9.30 lint = Lint.instance(context); 9.31 + Source source = Source.instance(context); 9.32 + allowRethrowAnalysis = source.allowMulticatch(); 9.33 } 9.34 9.35 /** A flag that indicates whether the last statement could 9.36 @@ -216,6 +220,8 @@ 9.37 */ 9.38 Bits uninits; 9.39 9.40 + HashMap<Symbol, List<Type>> multicatchTypes; 9.41 + 9.42 /** The set of variables that are definitely unassigned everywhere 9.43 * in current try block. This variable is maintained lazily; it is 9.44 * updated only when something gets removed from uninits, 9.45 @@ -355,8 +361,14 @@ 9.46 if (sym.adr >= firstadr && trackable(sym)) { 9.47 if ((sym.flags() & FINAL) != 0) { 9.48 if ((sym.flags() & PARAMETER) != 0) { 9.49 - log.error(pos, "final.parameter.may.not.be.assigned", 9.50 + if ((sym.flags() & DISJOINT) != 0) { //multi-catch parameter 9.51 + log.error(pos, "multicatch.parameter.may.not.be.assigned", 9.52 + sym); 9.53 + } 9.54 + else { 9.55 + log.error(pos, "final.parameter.may.not.be.assigned", 9.56 sym); 9.57 + } 9.58 } else if (!uninits.isMember(sym.adr)) { 9.59 log.error(pos, 9.60 loopPassTwo 9.61 @@ -952,8 +964,14 @@ 9.62 List<Type> caughtPrev = caught; 9.63 List<Type> thrownPrev = thrown; 9.64 thrown = List.nil(); 9.65 - for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) 9.66 - caught = chk.incl(l.head.param.type, caught); 9.67 + for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { 9.68 + List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ? 9.69 + ((JCTypeDisjoint)l.head.param.vartype).components : 9.70 + List.of(l.head.param.vartype); 9.71 + for (JCExpression ct : subClauses) { 9.72 + caught = chk.incl(ct.type, caught); 9.73 + } 9.74 + } 9.75 Bits uninitsTryPrev = uninitsTry; 9.76 ListBuffer<PendingExit> prevPendingExits = pendingExits; 9.77 pendingExits = new ListBuffer<PendingExit>(); 9.78 @@ -973,27 +991,39 @@ 9.79 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { 9.80 alive = true; 9.81 JCVariableDecl param = l.head.param; 9.82 - Type exc = param.type; 9.83 - if (chk.subset(exc, caughtInTry)) { 9.84 - log.error(l.head.pos(), 9.85 - "except.already.caught", exc); 9.86 - } else if (!chk.isUnchecked(l.head.pos(), exc) && 9.87 - exc.tsym != syms.throwableType.tsym && 9.88 - exc.tsym != syms.exceptionType.tsym && 9.89 - !chk.intersects(exc, thrownInTry)) { 9.90 - log.error(l.head.pos(), 9.91 - "except.never.thrown.in.try", exc); 9.92 + List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ? 9.93 + ((JCTypeDisjoint)l.head.param.vartype).components : 9.94 + List.of(l.head.param.vartype); 9.95 + List<Type> ctypes = List.nil(); 9.96 + List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry); 9.97 + for (JCExpression ct : subClauses) { 9.98 + Type exc = ct.type; 9.99 + ctypes = ctypes.append(exc); 9.100 + if (types.isSameType(exc, syms.objectType)) 9.101 + continue; 9.102 + if (chk.subset(exc, caughtInTry)) { 9.103 + log.error(l.head.pos(), 9.104 + "except.already.caught", exc); 9.105 + } else if (!chk.isUnchecked(l.head.pos(), exc) && 9.106 + exc.tsym != syms.throwableType.tsym && 9.107 + exc.tsym != syms.exceptionType.tsym && 9.108 + !chk.intersects(exc, thrownInTry)) { 9.109 + log.error(l.head.pos(), 9.110 + "except.never.thrown.in.try", exc); 9.111 + } 9.112 + caughtInTry = chk.incl(exc, caughtInTry); 9.113 } 9.114 - caughtInTry = chk.incl(exc, caughtInTry); 9.115 inits = initsTry.dup(); 9.116 uninits = uninitsTry.dup(); 9.117 scan(param); 9.118 inits.incl(param.sym.adr); 9.119 uninits.excl(param.sym.adr); 9.120 + multicatchTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes)); 9.121 scanStat(l.head.body); 9.122 initsEnd.andSet(inits); 9.123 uninitsEnd.andSet(uninits); 9.124 nextadr = nextadrCatch; 9.125 + multicatchTypes.remove(param.sym); 9.126 aliveEnd |= alive; 9.127 } 9.128 if (tree.finalizer != null) { 9.129 @@ -1121,7 +1151,19 @@ 9.130 9.131 public void visitThrow(JCThrow tree) { 9.132 scanExpr(tree.expr); 9.133 - markThrown(tree, tree.expr.type); 9.134 + Symbol sym = TreeInfo.symbol(tree.expr); 9.135 + if (sym != null && 9.136 + sym.kind == VAR && 9.137 + (sym.flags() & FINAL) != 0 && 9.138 + multicatchTypes.get(sym) != null && 9.139 + allowRethrowAnalysis) { 9.140 + for (Type t : multicatchTypes.get(sym)) { 9.141 + markThrown(tree, t); 9.142 + } 9.143 + } 9.144 + else { 9.145 + markThrown(tree, tree.expr.type); 9.146 + } 9.147 markDead(); 9.148 } 9.149 9.150 @@ -1308,6 +1350,7 @@ 9.151 firstadr = 0; 9.152 nextadr = 0; 9.153 pendingExits = new ListBuffer<PendingExit>(); 9.154 + multicatchTypes = new HashMap<Symbol, List<Type>>(); 9.155 alive = true; 9.156 this.thrown = this.caught = null; 9.157 this.classDef = null;
10.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Sun May 02 15:55:02 2010 -0700 10.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon May 03 17:12:59 2010 -0700 10.3 @@ -1454,20 +1454,26 @@ 10.4 int startpc, int endpc, 10.5 List<Integer> gaps) { 10.6 if (startpc != endpc) { 10.7 - int catchType = makeRef(tree.pos(), tree.param.type); 10.8 - while (gaps.nonEmpty()) { 10.9 - int end = gaps.head.intValue(); 10.10 - registerCatch(tree.pos(), 10.11 - startpc, end, code.curPc(), 10.12 - catchType); 10.13 - gaps = gaps.tail; 10.14 - startpc = gaps.head.intValue(); 10.15 - gaps = gaps.tail; 10.16 + List<JCExpression> subClauses = TreeInfo.isMultiCatch(tree) ? 10.17 + ((JCTypeDisjoint)tree.param.vartype).components : 10.18 + List.of(tree.param.vartype); 10.19 + for (JCExpression subCatch : subClauses) { 10.20 + int catchType = makeRef(tree.pos(), subCatch.type); 10.21 + List<Integer> lGaps = gaps; 10.22 + while (lGaps.nonEmpty()) { 10.23 + int end = lGaps.head.intValue(); 10.24 + registerCatch(tree.pos(), 10.25 + startpc, end, code.curPc(), 10.26 + catchType); 10.27 + lGaps = lGaps.tail; 10.28 + startpc = lGaps.head.intValue(); 10.29 + lGaps = lGaps.tail; 10.30 + } 10.31 + if (startpc < endpc) 10.32 + registerCatch(tree.pos(), 10.33 + startpc, endpc, code.curPc(), 10.34 + catchType); 10.35 } 10.36 - if (startpc < endpc) 10.37 - registerCatch(tree.pos(), 10.38 - startpc, endpc, code.curPc(), 10.39 - catchType); 10.40 VarSymbol exparam = tree.param.sym; 10.41 code.statBegin(tree.pos); 10.42 code.markStatBegin();
11.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Sun May 02 15:55:02 2010 -0700 11.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon May 03 17:12:59 2010 -0700 11.3 @@ -132,6 +132,7 @@ 11.4 this.allowStaticImport = source.allowStaticImport(); 11.5 this.allowAnnotations = source.allowAnnotations(); 11.6 this.allowDiamond = source.allowDiamond(); 11.7 + this.allowMulticatch = source.allowMulticatch(); 11.8 this.allowTypeAnnotations = source.allowTypeAnnotations(); 11.9 this.keepDocComments = keepDocComments; 11.10 if (keepDocComments) 11.11 @@ -153,6 +154,10 @@ 11.12 */ 11.13 boolean allowDiamond; 11.14 11.15 + /** Switch: Should multicatch clause be accepted? 11.16 + */ 11.17 + boolean allowMulticatch; 11.18 + 11.19 /** Switch: Should varargs be recognized? 11.20 */ 11.21 boolean allowVarargs; 11.22 @@ -2011,14 +2016,28 @@ 11.23 int pos = S.pos(); 11.24 accept(CATCH); 11.25 accept(LPAREN); 11.26 - JCVariableDecl formal = 11.27 - variableDeclaratorId(optFinal(Flags.PARAMETER), 11.28 - qualident()); 11.29 + JCModifiers mods = optFinal(Flags.PARAMETER); 11.30 + List<JCExpression> catchTypes = catchTypes(); 11.31 + JCExpression paramType = catchTypes.size() > 1 ? 11.32 + toP(F.at(catchTypes.head.getStartPosition()).TypeDisjoint(catchTypes)) : 11.33 + catchTypes.head; 11.34 + JCVariableDecl formal = variableDeclaratorId(mods, paramType); 11.35 accept(RPAREN); 11.36 JCBlock body = block(); 11.37 return F.at(pos).Catch(formal, body); 11.38 } 11.39 11.40 + List<JCExpression> catchTypes() { 11.41 + ListBuffer<JCExpression> catchTypes = ListBuffer.lb(); 11.42 + catchTypes.add(parseType()); 11.43 + while (S.token() == BAR) { 11.44 + checkMulticatch(); 11.45 + S.nextToken(); 11.46 + catchTypes.add(qualident()); 11.47 + } 11.48 + return catchTypes.toList(); 11.49 + } 11.50 + 11.51 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 11.52 * SwitchBlockStatementGroup = SwitchLabel BlockStatements 11.53 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 11.54 @@ -3193,4 +3212,10 @@ 11.55 allowDiamond = true; 11.56 } 11.57 } 11.58 + void checkMulticatch() { 11.59 + if (!allowMulticatch) { 11.60 + log.error(S.pos(), "multicatch.not.supported.in.source", source.name); 11.61 + allowMulticatch = true; 11.62 + } 11.63 + } 11.64 }
12.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sun May 02 15:55:02 2010 -0700 12.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon May 03 17:12:59 2010 -0700 12.3 @@ -172,6 +172,10 @@ 12.4 12.5 compiler.err.final.parameter.may.not.be.assigned=\ 12.6 final parameter {0} may not be assigned 12.7 +compiler.err.multicatch.parameter.may.not.be.assigned=\ 12.8 + multi-catch parameter {0} may not be assigned 12.9 +compiler.err.multicatch.param.must.be.final=\ 12.10 + multi-catch parameter {0} must be final 12.11 compiler.err.finally.without.try=\ 12.12 ''finally'' without ''try'' 12.13 compiler.err.foreach.not.applicable.to.type=\ 12.14 @@ -1235,6 +1239,10 @@ 12.15 enums are not supported in -source {0}\n\ 12.16 (use -source 5 or higher to enable enums) 12.17 12.18 +compiler.err.multicatch.not.supported.in.source=\ 12.19 + multi-catch statement is not supported in -source {0}\n\ 12.20 +(use -source 7 or higher to enable multi-catch statement) 12.21 + 12.22 compiler.err.string.switch.not.supported.in.source=\ 12.23 strings in switch are not supported in -source {0}\n\ 12.24 (use -source 7 or higher to enable strings in switch)
13.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Sun May 02 15:55:02 2010 -0700 13.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Mon May 03 17:12:59 2010 -0700 13.3 @@ -236,9 +236,13 @@ 13.4 */ 13.5 public static final int TYPEAPPLY = TYPEARRAY + 1; 13.6 13.7 + /** Disjunctive types, of type TypeDisjoint. 13.8 + */ 13.9 + public static final int TYPEDISJOINT = TYPEAPPLY + 1; 13.10 + 13.11 /** Formal type parameters, of type TypeParameter. 13.12 */ 13.13 - public static final int TYPEPARAMETER = TYPEAPPLY + 1; 13.14 + public static final int TYPEPARAMETER = TYPEDISJOINT + 1; 13.15 13.16 /** Type argument. 13.17 */ 13.18 @@ -1863,6 +1867,34 @@ 13.19 } 13.20 13.21 /** 13.22 + * A disjoint type, T1 | T2 | ... Tn (used in multicatch statements) 13.23 + */ 13.24 + public static class JCTypeDisjoint extends JCExpression implements DisjointTypeTree { 13.25 + 13.26 + public List<JCExpression> components; 13.27 + 13.28 + protected JCTypeDisjoint(List<JCExpression> components) { 13.29 + this.components = components; 13.30 + } 13.31 + @Override 13.32 + public void accept(Visitor v) { v.visitTypeDisjoint(this); } 13.33 + 13.34 + public Kind getKind() { return Kind.DISJOINT_TYPE; } 13.35 + 13.36 + public List<JCExpression> getTypeComponents() { 13.37 + return components; 13.38 + } 13.39 + @Override 13.40 + public <R,D> R accept(TreeVisitor<R,D> v, D d) { 13.41 + return v.visitDisjointType(this, d); 13.42 + } 13.43 + @Override 13.44 + public int getTag() { 13.45 + return TYPEDISJOINT; 13.46 + } 13.47 + } 13.48 + 13.49 + /** 13.50 * A formal class parameter. 13.51 * @param name name 13.52 * @param bounds bounds 13.53 @@ -2220,6 +2252,7 @@ 13.54 public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); } 13.55 public void visitTypeArray(JCArrayTypeTree that) { visitTree(that); } 13.56 public void visitTypeApply(JCTypeApply that) { visitTree(that); } 13.57 + public void visitTypeDisjoint(JCTypeDisjoint that) { visitTree(that); } 13.58 public void visitTypeParameter(JCTypeParameter that) { visitTree(that); } 13.59 public void visitWildcard(JCWildcard that) { visitTree(that); } 13.60 public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); }
14.1 --- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java Sun May 02 15:55:02 2010 -0700 14.2 +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java Mon May 03 17:12:59 2010 -0700 14.3 @@ -1182,6 +1182,14 @@ 14.4 } 14.5 } 14.6 14.7 + public void visitTypeDisjoint(JCTypeDisjoint tree) { 14.8 + try { 14.9 + printExprs(tree.components, " | "); 14.10 + } catch (IOException e) { 14.11 + throw new UncheckedIOException(e); 14.12 + } 14.13 + } 14.14 + 14.15 public void visitTypeParameter(JCTypeParameter tree) { 14.16 try { 14.17 print(tree.name);
15.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Sun May 02 15:55:02 2010 -0700 15.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Mon May 03 17:12:59 2010 -0700 15.3 @@ -345,6 +345,12 @@ 15.4 return M.at(t.pos).TypeApply(clazz, arguments); 15.5 } 15.6 15.7 + public JCTree visitDisjointType(DisjointTypeTree node, P p) { 15.8 + JCTypeDisjoint t = (JCTypeDisjoint) node; 15.9 + List<JCExpression> components = copy(t.components, p); 15.10 + return M.at(t.pos).TypeDisjoint(components); 15.11 + } 15.12 + 15.13 public JCTree visitArrayType(ArrayTypeTree node, P p) { 15.14 JCArrayTypeTree t = (JCArrayTypeTree) node; 15.15 JCExpression elemtype = copy(t.elemtype, p);
16.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Sun May 02 15:55:02 2010 -0700 16.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Mon May 03 17:12:59 2010 -0700 16.3 @@ -118,6 +118,10 @@ 16.4 return false; 16.5 } 16.6 16.7 + public static boolean isMultiCatch(JCCatch catchClause) { 16.8 + return catchClause.param.vartype.getTag() == JCTree.TYPEDISJOINT; 16.9 + } 16.10 + 16.11 /** Is statement an initializer for a synthetic field? 16.12 */ 16.13 public static boolean isSyntheticInit(JCTree stat) {
17.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Sun May 02 15:55:02 2010 -0700 17.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Mon May 03 17:12:59 2010 -0700 17.3 @@ -444,6 +444,12 @@ 17.4 return tree; 17.5 } 17.6 17.7 + public JCTypeDisjoint TypeDisjoint(List<JCExpression> components) { 17.8 + JCTypeDisjoint tree = new JCTypeDisjoint(components); 17.9 + tree.pos = pos; 17.10 + return tree; 17.11 + } 17.12 + 17.13 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) { 17.14 return TypeParameter(name, bounds, List.<JCTypeAnnotation>nil()); 17.15 }
18.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Sun May 02 15:55:02 2010 -0700 18.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Mon May 03 17:12:59 2010 -0700 18.3 @@ -275,6 +275,10 @@ 18.4 scan(tree.arguments); 18.5 } 18.6 18.7 + public void visitTypeDisjoint(JCTypeDisjoint tree) { 18.8 + scan(tree.components); 18.9 + } 18.10 + 18.11 public void visitTypeParameter(JCTypeParameter tree) { 18.12 scan(tree.annotations); 18.13 scan(tree.bounds);
19.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Sun May 02 15:55:02 2010 -0700 19.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Mon May 03 17:12:59 2010 -0700 19.3 @@ -367,6 +367,11 @@ 19.4 result = tree; 19.5 } 19.6 19.7 + public void visitTypeDisjoint(JCTypeDisjoint tree) { 19.8 + tree.components = translate(tree.components); 19.9 + result = tree; 19.10 + } 19.11 + 19.12 public void visitTypeParameter(JCTypeParameter tree) { 19.13 tree.annotations = translate(tree.annotations); 19.14 tree.bounds = translate(tree.bounds);
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javac/multicatch/Neg01.java Mon May 03 17:12:59 2010 -0700 20.3 @@ -0,0 +1,28 @@ 20.4 +/* 20.5 + * @test /nodynamiccopyright/ 20.6 + * @bug 6943289 20.7 + * 20.8 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 20.9 + * @author darcy 20.10 + * @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java 20.11 + * @compile -source 6 -XDrawDiagnostics Neg01.java 20.12 + * 20.13 + */ 20.14 + 20.15 +class Neg01 { 20.16 + static class A extends Exception {} 20.17 + static class B1 extends A {} 20.18 + static class B2 extends A {} 20.19 + 20.20 + class Test { 20.21 + void m() throws A { 20.22 + try { 20.23 + throw new B1(); 20.24 + } catch (final A ex1) { 20.25 + try { 20.26 + throw ex1; // used to throw A, now throws B1! 20.27 + } catch (B2 ex2) { }//unreachable 20.28 + } 20.29 + } 20.30 + } 20.31 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/tools/javac/multicatch/Neg01.out Mon May 03 17:12:59 2010 -0700 21.3 @@ -0,0 +1,2 @@ 21.4 +Neg01.java:24:19: compiler.err.except.never.thrown.in.try: Neg01.B2 21.5 +1 error
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javac/multicatch/Neg02.java Mon May 03 17:12:59 2010 -0700 22.3 @@ -0,0 +1,25 @@ 22.4 +/* 22.5 + * @test /nodynamiccopyright/ 22.6 + * @bug 6943289 22.7 + * 22.8 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 22.9 + * @author mcimadamore 22.10 + * @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java 22.11 + * 22.12 + */ 22.13 + 22.14 +class Neg02 { 22.15 + static class A extends Exception {} 22.16 + static class B extends Exception {} 22.17 + 22.18 + void m() { 22.19 + try { 22.20 + if (true) { 22.21 + throw new A(); 22.22 + } 22.23 + else { 22.24 + throw new B(); 22.25 + } 22.26 + } catch (A | B ex) { } 22.27 + } 22.28 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/tools/javac/multicatch/Neg02.out Mon May 03 17:12:59 2010 -0700 23.3 @@ -0,0 +1,2 @@ 23.4 +Neg02.java:23:24: compiler.err.multicatch.param.must.be.final: ex 23.5 +1 error
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/tools/javac/multicatch/Neg03.java Mon May 03 17:12:59 2010 -0700 24.3 @@ -0,0 +1,27 @@ 24.4 +/* 24.5 + * @test /nodynamiccopyright/ 24.6 + * @bug 6943289 24.7 + * 24.8 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 24.9 + * @author mcimadamore 24.10 + * @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java 24.11 + * 24.12 + */ 24.13 + 24.14 +class Neg03 { 24.15 + static class A extends Exception {} 24.16 + static class B extends Exception {} 24.17 + 24.18 + void m() { 24.19 + try { 24.20 + if (true) { 24.21 + throw new A(); 24.22 + } 24.23 + else { 24.24 + throw new B(); 24.25 + } 24.26 + } catch (final A | B ex) { 24.27 + ex = new B(); 24.28 + } 24.29 + } 24.30 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/test/tools/javac/multicatch/Neg03.out Mon May 03 17:12:59 2010 -0700 25.3 @@ -0,0 +1,2 @@ 25.4 +Neg03.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex 25.5 +1 error
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/test/tools/javac/multicatch/Neg04.java Mon May 03 17:12:59 2010 -0700 26.3 @@ -0,0 +1,31 @@ 26.4 +/* 26.5 + * @test /nodynamiccopyright/ 26.6 + * @bug 6943289 26.7 + * 26.8 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 26.9 + * @author mcimadamore 26.10 + * @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java 26.11 + * 26.12 + */ 26.13 + 26.14 +class Neg04 { 26.15 + static class A extends Exception {} 26.16 + static class B extends Exception {} 26.17 + 26.18 + void test() throws B { 26.19 + try { 26.20 + if (true) { 26.21 + throw new A(); 26.22 + } else if (false) { 26.23 + throw new B(); 26.24 + } else { 26.25 + throw (Throwable)new Exception(); 26.26 + } 26.27 + } 26.28 + catch (A e) {} 26.29 + catch (final Exception e) { 26.30 + throw e; 26.31 + } 26.32 + catch (Throwable t) {} 26.33 + } 26.34 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/tools/javac/multicatch/Neg04.out Mon May 03 17:12:59 2010 -0700 27.3 @@ -0,0 +1,2 @@ 27.4 +Neg04.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception 27.5 +1 error
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/tools/javac/multicatch/Pos01.java Mon May 03 17:12:59 2010 -0700 28.3 @@ -0,0 +1,59 @@ 28.4 +/* 28.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.7 + * 28.8 + * This code is free software; you can redistribute it and/or modify it 28.9 + * under the terms of the GNU General Public License version 2 only, as 28.10 + * published by the Free Software Foundation. 28.11 + * 28.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.15 + * version 2 for more details (a copy is included in the LICENSE file that 28.16 + * accompanied this code). 28.17 + * 28.18 + * You should have received a copy of the GNU General Public License version 28.19 + * 2 along with this work; if not, write to the Free Software Foundation, 28.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.21 + * 28.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 28.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 28.24 + * have any questions. 28.25 + */ 28.26 + 28.27 +/* 28.28 + * @test 28.29 + * @bug 6943289 28.30 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 28.31 + * 28.32 + */ 28.33 + 28.34 +public class Pos01 { 28.35 + 28.36 + static class A extends Exception {} 28.37 + static class B extends Exception {} 28.38 + 28.39 + static int caughtExceptions = 0; 28.40 + 28.41 + static void test(boolean b) { 28.42 + try { 28.43 + if (b) { 28.44 + throw new A(); 28.45 + } 28.46 + else { 28.47 + throw new B(); 28.48 + } 28.49 + } 28.50 + catch (final A | B ex) { 28.51 + caughtExceptions++; 28.52 + } 28.53 + } 28.54 + 28.55 + public static void main(String[] args) { 28.56 + test(true); 28.57 + test(false); 28.58 + if (caughtExceptions != 2) { 28.59 + throw new AssertionError("Exception handler called " + caughtExceptions + "times"); 28.60 + } 28.61 + } 28.62 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/tools/javac/multicatch/Pos02.java Mon May 03 17:12:59 2010 -0700 29.3 @@ -0,0 +1,81 @@ 29.4 +/* 29.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. 29.11 + * 29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.15 + * version 2 for more details (a copy is included in the LICENSE file that 29.16 + * accompanied this code). 29.17 + * 29.18 + * You should have received a copy of the GNU General Public License version 29.19 + * 2 along with this work; if not, write to the Free Software Foundation, 29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.21 + * 29.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 29.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 29.24 + * have any questions. 29.25 + */ 29.26 + 29.27 +/* 29.28 + * @test 29.29 + * @bug 6943289 29.30 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 29.31 + * 29.32 + */ 29.33 + 29.34 +public class Pos02 { 29.35 + 29.36 + static class A extends Exception {} 29.37 + static class B extends Exception {} 29.38 + static class C extends Exception {} 29.39 + static class C1 extends C {} 29.40 + static class C2 extends C {} 29.41 + 29.42 + enum ExceptionKind { 29.43 + A, 29.44 + B, 29.45 + C1, 29.46 + C2 29.47 + } 29.48 + 29.49 + static int caughtExceptions = 0; 29.50 + static int caughtRethrownExceptions = 0; 29.51 + 29.52 + static void test(ExceptionKind ekind) throws A, C1 { 29.53 + try { 29.54 + switch (ekind) { 29.55 + case A : throw new A(); 29.56 + case B : throw new B(); 29.57 + case C1: throw new C1(); 29.58 + case C2 : throw new C2(); 29.59 + } 29.60 + } 29.61 + catch (final C2 | B ex) { 29.62 + caughtExceptions++; 29.63 + } 29.64 + catch (final C | A ex) { 29.65 + caughtExceptions++; 29.66 + throw ex; 29.67 + } 29.68 + } 29.69 + 29.70 + public static void main(String[] args) { 29.71 + for (ExceptionKind ekind : ExceptionKind.values()) { 29.72 + try { 29.73 + test(ekind); 29.74 + } 29.75 + catch (final C1 | A ex) { 29.76 + caughtRethrownExceptions++; 29.77 + } 29.78 + } 29.79 + if (caughtExceptions != 4 && caughtRethrownExceptions == 2) { 29.80 + throw new AssertionError("Exception handler called " + caughtExceptions + "times" + 29.81 + " rethrown handler called " + caughtRethrownExceptions + "times"); 29.82 + } 29.83 + } 29.84 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/tools/javac/multicatch/Pos03.java Mon May 03 17:12:59 2010 -0700 30.3 @@ -0,0 +1,50 @@ 30.4 +/* 30.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 30.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 30.24 + * have any questions. 30.25 + */ 30.26 + 30.27 +/* 30.28 + * @test 30.29 + * @bug 6943289 30.30 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 30.31 + * @compile Pos03.java 30.32 + */ 30.33 + 30.34 +class Pos03 { 30.35 + 30.36 + static class A extends Exception { public void m() {}; public Object f;} 30.37 + static class B1 extends A {} 30.38 + static class B2 extends A {} 30.39 + 30.40 + void m() { 30.41 + try { 30.42 + if (true) { 30.43 + throw new B1(); 30.44 + } 30.45 + else { 30.46 + throw new B2(); 30.47 + } 30.48 + } catch (final B1 | B2 ex) { 30.49 + ex.m(); 30.50 + System.out.println(ex.f); 30.51 + } 30.52 + } 30.53 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/tools/javac/multicatch/Pos04.java Mon May 03 17:12:59 2010 -0700 31.3 @@ -0,0 +1,92 @@ 31.4 +/* 31.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 31.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 31.24 + * have any questions. 31.25 + */ 31.26 + 31.27 +/* 31.28 + * @test 31.29 + * @bug 6943289 31.30 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 31.31 + */ 31.32 + 31.33 +import java.lang.annotation.*; 31.34 + 31.35 +public class Pos04 { 31.36 + 31.37 + enum ExceptionKind { 31.38 + A(1), 31.39 + B(2), 31.40 + C(1); 31.41 + 31.42 + int expectedValue; 31.43 + 31.44 + ExceptionKind(int expectedValue) { 31.45 + this.expectedValue = expectedValue; 31.46 + } 31.47 + } 31.48 + 31.49 + @Retention(RetentionPolicy.RUNTIME) 31.50 + @interface CatchNumber { 31.51 + int value(); 31.52 + } 31.53 + 31.54 + @CatchNumber(1) 31.55 + static class A extends Exception { } 31.56 + 31.57 + @CatchNumber(2) 31.58 + static class B extends Exception { } 31.59 + 31.60 + @CatchNumber(1) 31.61 + static class C extends Exception { } 31.62 + 31.63 + static int sum = 0; 31.64 + 31.65 + public static void main(String[] args) { 31.66 + for (ExceptionKind ekind : ExceptionKind.values()) { 31.67 + test(ekind); 31.68 + } 31.69 + if (sum != 4) { 31.70 + throw new Error("bad checksum - expected:4, found:" + sum); 31.71 + } 31.72 + } 31.73 + 31.74 + public static void test(ExceptionKind ekind) { 31.75 + try { 31.76 + switch(ekind) { 31.77 + case A: throw new A(); 31.78 + case B: throw new B(); 31.79 + case C: throw new C(); 31.80 + } 31.81 + } catch(final A | C ex) {// Catch number 1 31.82 + CatchNumber catchNumber = ex.getClass().getAnnotation(CatchNumber.class); 31.83 + if (catchNumber == null || catchNumber.value() != ekind.expectedValue) { 31.84 + throw new Error("was expecting 1 - got " + catchNumber); 31.85 + } 31.86 + sum += catchNumber.value(); 31.87 + } catch (final B ex) { // Catch number 2 31.88 + CatchNumber catchNumber = ex.getClass().getAnnotation(CatchNumber.class); 31.89 + if (catchNumber == null || catchNumber.value() != ekind.expectedValue) { 31.90 + throw new Error("was expecting 2 - got " + catchNumber); 31.91 + } 31.92 + sum += catchNumber.value(); 31.93 + } 31.94 + } 31.95 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/tools/javac/multicatch/Pos05.java Mon May 03 17:12:59 2010 -0700 32.3 @@ -0,0 +1,117 @@ 32.4 +/* 32.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 32.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 32.24 + * have any questions. 32.25 + */ 32.26 + 32.27 +/* 32.28 + * @test 32.29 + * @bug 6943289 32.30 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') 32.31 + * @run main Pos05 32.32 + */ 32.33 + 32.34 +import com.sun.tools.classfile.Attribute; 32.35 +import com.sun.tools.classfile.ClassFile; 32.36 +import com.sun.tools.classfile.Code_attribute; 32.37 +import com.sun.tools.classfile.Code_attribute.Exception_data; 32.38 +import com.sun.tools.classfile.Method; 32.39 +import java.io.*; 32.40 + 32.41 +public class Pos05 { 32.42 + 32.43 + static class Pos05sub { 32.44 + 32.45 + class A extends Exception {} 32.46 + class B extends Exception {} 32.47 + class C extends Exception {} 32.48 + 32.49 + void test(boolean b1, boolean b2) { 32.50 + try { 32.51 + if (b1) { 32.52 + throw new A(); 32.53 + } 32.54 + else if (b2) { 32.55 + throw new B(); 32.56 + } 32.57 + else { 32.58 + throw new C(); 32.59 + } 32.60 + } 32.61 + catch (final A | B | C ex) { 32.62 + System.out.println("Exception caught"); 32.63 + } 32.64 + } 32.65 + } 32.66 + 32.67 + static final int TYPES_IN_MULTICATCH = 3; 32.68 + static final String SUBTEST_NAME = Pos05sub.class.getName() + ".class"; 32.69 + static final String TEST_METHOD_NAME = "test"; 32.70 + 32.71 + public static void main(String... args) throws Exception { 32.72 + new Pos05().run(); 32.73 + } 32.74 + 32.75 + public void run() throws Exception { 32.76 + String workDir = System.getProperty("test.classes"); 32.77 + File compiledTest = new File(workDir, SUBTEST_NAME); 32.78 + verifyMulticatchExceptionRanges(compiledTest); 32.79 + } 32.80 + 32.81 + void verifyMulticatchExceptionRanges(File f) { 32.82 + System.err.println("verify: " + f); 32.83 + try { 32.84 + int count = 0; 32.85 + ClassFile cf = ClassFile.read(f); 32.86 + Method testMethod = null; 32.87 + for (Method m : cf.methods) { 32.88 + if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) { 32.89 + testMethod = m; 32.90 + break; 32.91 + } 32.92 + } 32.93 + if (testMethod == null) { 32.94 + throw new Error("Test method not found"); 32.95 + } 32.96 + Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code); 32.97 + if (testMethod == null) { 32.98 + throw new Error("Code attribute for test() method not found"); 32.99 + } 32.100 + Exception_data firstExceptionTable = null; 32.101 + for (int i = 0 ; i < ea.exception_table_langth; i++) { 32.102 + if (firstExceptionTable == null) { 32.103 + firstExceptionTable = ea.exception_table[i]; 32.104 + } 32.105 + if (ea.exception_table[i].handler_pc != firstExceptionTable.handler_pc || 32.106 + ea.exception_table[i].start_pc != firstExceptionTable.start_pc || 32.107 + ea.exception_table[i].end_pc != firstExceptionTable.end_pc) { 32.108 + throw new Error("Multiple overlapping catch clause found in generated code"); 32.109 + } 32.110 + count++; 32.111 + } 32.112 + if (count != TYPES_IN_MULTICATCH) { 32.113 + throw new Error("Wrong number of exception data found: " + count); 32.114 + } 32.115 + } catch (Exception e) { 32.116 + e.printStackTrace(); 32.117 + throw new Error("error reading " + f +": " + e); 32.118 + } 32.119 + } 32.120 +}