src/share/classes/com/sun/tools/javac/parser/JavacParser.java

Print this page

        

@@ -129,10 +129,11 @@
         this.allowAsserts = source.allowAsserts();
         this.allowEnums = source.allowEnums();
         this.allowForeach = source.allowForeach();
         this.allowStaticImport = source.allowStaticImport();
         this.allowAnnotations = source.allowAnnotations();
+        this.allowTWR = source.allowTryWithResources();
         this.allowDiamond = source.allowDiamond();
         this.allowMulticatch = source.allowMulticatch();
         this.allowTypeAnnotations = source.allowTypeAnnotations();
         this.keepDocComments = keepDocComments;
         if (keepDocComments)

@@ -184,10 +185,14 @@
 
     /** Switch: should we recognize type annotations?
      */
     boolean allowTypeAnnotations;
 
+    /** Switch: should we recognize automatic resource management?
+     */
+    boolean allowTWR;
+
     /** Switch: should we keep docComments?
      */
     boolean keepDocComments;
 
     /** Switch: should we keep line table?

@@ -1844,10 +1849,11 @@
      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
      *     | FOR "(" FormalParameter : Expression ")" Statement
      *     | WHILE ParExpression Statement
      *     | DO Statement WHILE ParExpression ";"
      *     | TRY Block ( Catches | [Catches] FinallyPart )
+     *     | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
      *     | SYNCHRONIZED ParExpression Block
      *     | RETURN [Expression] ";"
      *     | THROW Expression ";"
      *     | BREAK [Ident] ";"

@@ -1914,23 +1920,34 @@
             accept(SEMI);
             return t;
         }
         case TRY: {
             S.nextToken();
+            List<JCTree> resources = List.<JCTree>nil();
+            if (S.token() == LPAREN) {
+                checkAutomaticResourceManagement();
+                S.nextToken();
+                resources = resources();
+                accept(RPAREN);
+            }
             JCBlock body = block();
             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
             JCBlock finalizer = null;
             if (S.token() == CATCH || S.token() == FINALLY) {
                 while (S.token() == CATCH) catchers.append(catchClause());
                 if (S.token() == FINALLY) {
                     S.nextToken();
                     finalizer = block();
                 }
             } else {
+                if (allowTWR) {
+                    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(resources, body, catchers.toList(), finalizer);
         }
         case SWITCH: {
             S.nextToken();
             JCExpression selector = parExpression();
             accept(LBRACE);

@@ -2387,10 +2404,43 @@
         if ((mods.flags & Flags.VARARGS) == 0)
             type = bracketsOpt(type);
         return toP(F.at(pos).VarDef(mods, name, type, null));
     }
 
+    /** Resources = Resource { ";" Resources }
+     */
+    List<JCTree> resources() {
+        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
+        defs.append(resource());
+        while (S.token() == SEMI) {
+            // All but last of multiple declarators subsume a semicolon
+            storeEnd(defs.elems.last(), S.endPos());
+            S.nextToken();
+            defs.append(resource());
+        }
+        return defs.toList();
+    }
+
+    /** Resource =
+     *    VariableModifiers Type VariableDeclaratorId = Expression
+     *  | Expression
+     */
+    JCTree resource() {
+        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() {
         int pos = S.pos();
         JCExpression pid = null;

@@ -3220,6 +3270,12 @@
         if (!allowMulticatch) {
             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
             allowMulticatch = true;
             }
     }
+    void checkAutomaticResourceManagement() {
+        if (!allowTWR) {
+            log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
+            allowTWR = true;
+        }
+    }
 }