--- old/src/share/classes/com/sun/tools/javac/parser/JavacParser.java 2010-07-01 10:48:41.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/parser/JavacParser.java 2010-07-01 10:48:41.000000000 -0700 @@ -131,6 +131,7 @@ this.allowForeach = source.allowForeach(); this.allowStaticImport = source.allowStaticImport(); this.allowAnnotations = source.allowAnnotations(); + this.allowARM = source.allowAutomaticResourceManagement(); this.allowDiamond = source.allowDiamond(); this.allowMulticatch = source.allowMulticatch(); this.allowTypeAnnotations = source.allowTypeAnnotations(); @@ -186,6 +187,10 @@ */ boolean allowTypeAnnotations; + /** Switch: should we recognize automatic resource management? + */ + boolean allowARM; + /** Switch: should we keep docComments? */ boolean keepDocComments; @@ -1912,6 +1917,13 @@ } case TRY: { S.nextToken(); + List resources = List.nil(); + if (S.token() == LPAREN) { + checkAutomaticResourceManagement(); + S.nextToken(); + resources = resourceDeclarators(); + accept(RPAREN); + } JCBlock body = block(); ListBuffer catchers = new ListBuffer(); JCBlock finalizer = null; @@ -1922,9 +1934,13 @@ finalizer = block(); } } else { - log.error(pos, "try.without.catch.or.finally"); + if (allowARM) { + if (resources.isEmpty()) + log.error(pos, "try.without.catch.finally.or.resource.decls"); + } else + log.error(pos, "try.without.catch.or.finally"); } - return F.at(pos).Try(body, catchers.toList(), finalizer); + return F.at(pos).Try(body, catchers.toList(), finalizer, resources); } case SWITCH: { S.nextToken(); @@ -2385,6 +2401,36 @@ return toP(F.at(pos).VarDef(mods, name, type, null)); } + /** ResourceDeclarators = ResourceDeclarator { "," ResourceDeclarator } + */ + List resourceDeclarators() { + ListBuffer defs = new ListBuffer(); + defs.append(resourceDeclarator()); + while (S.token() == SEMI) { + // All but last of multiple declarators subsume a semicolon + storeEnd(defs.elems.last(), S.endPos()); + S.nextToken(); + defs.append(resourceDeclarator()); + } + return defs.toList(); + } + + /** ResourceDeclarator = LocalVariableDeclaration */ + JCTree resourceDeclarator() { + int pos = S.pos(); + if (S.token() == FINAL || S.token() == MONKEYS_AT) { + return variableDeclaratorRest(pos, optFinal(0), parseType(), + ident(), true, null); + } else { + JCExpression t = term(EXPR | TYPE); + if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER) + return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t, + ident(), true, null); + else + return t; + } + } + /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} */ public JCTree.JCCompilationUnit parseCompilationUnit() { @@ -3218,4 +3264,10 @@ allowMulticatch = true; } } + void checkAutomaticResourceManagement() { + if (!allowARM) { + log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name); + allowARM = true; + } + } }