groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject [1/2] groovy git commit: GROOVY-8586: Support Java 9 ARM blocks
Date Thu, 24 May 2018 11:13:42 GMT
Repository: groovy
Updated Branches:
  refs/heads/master 622b1487a -> 7ff08accd


GROOVY-8586: Support Java 9 ARM blocks


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/50f6057a
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/50f6057a
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/50f6057a

Branch: refs/heads/master
Commit: 50f6057a379b35ec57b0ec3a1ffceafe7cd2ecd2
Parents: 622b148
Author: Daniel Sun <realbluesun@hotmail.com>
Authored: Mon May 21 22:59:59 2018 +0800
Committer: danielsun1106 <realbluesun@hotmail.com>
Committed: Thu May 24 19:12:50 2018 +0800

----------------------------------------------------------------------
 .../groovy/ast/stmt/TryCatchStatement.java      |   5 +-
 .../apache/groovy/parser/antlr4/AstBuilder.java |  43 ++-
 .../parser/antlr4/GroovyParserTest.groovy       |   1 +
 .../resources/core/TryWithResources_02x.groovy  | 292 +++++++++++++++++++
 4 files changed, 333 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/50f6057a/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
index f05460f..aee7176 100644
--- a/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
@@ -20,6 +20,7 @@ package org.codehaus.groovy.ast.stmt;
 
 import org.codehaus.groovy.ast.GroovyCodeVisitor;
 import org.codehaus.groovy.ast.expr.DeclarationExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -63,8 +64,8 @@ public class TryCatchStatement extends Statement {
     }
 
     public void addResource(ExpressionStatement resourceStatement) {
-        if (!(resourceStatement.getExpression() instanceof DeclarationExpression)) {
-            throw new IllegalArgumentException("resourceStatement should be a variable declaration
statement");
+        if (!(resourceStatement.getExpression() instanceof DeclarationExpression || resourceStatement.getExpression()
instanceof VariableExpression)) {
+            throw new IllegalArgumentException("resourceStatement should be a variable declaration
statement or a variable");
         }
 
         resourceStatements.add(resourceStatement);

http://git-wip-us.apache.org/repos/asf/groovy/blob/50f6057a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 37f951d..031680f 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -790,7 +790,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
                 new TryCatchStatement((Statement) this.visit(ctx.block()),
                         this.visitFinallyBlock(ctx.finallyBlock()));
 
-        if (asBoolean(ctx.resources())) {
+        if (resourcesExists) {
             this.visitResources(ctx.resources()).forEach(tryCatchStatement::addResource);
         }
 
@@ -830,14 +830,40 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
             return declarationStatements.get(0);
         } else if (asBoolean(ctx.expression())) {
             Expression expression = (Expression) this.visit(ctx.expression());
-            if (!(expression instanceof BinaryExpression
+            boolean isVariableDeclaration = expression instanceof BinaryExpression
                     && Types.ASSIGN == ((BinaryExpression) expression).getOperation().getType()
-                    && ((BinaryExpression) expression).getLeftExpression() instanceof
VariableExpression)) {
+                    && ((BinaryExpression) expression).getLeftExpression() instanceof
VariableExpression;
+            boolean isVariableAccess = expression instanceof VariableExpression;
 
-                throw createParsingFailedException("Only variable declarations are allowed
to declare resource", ctx);
+            if (!(isVariableDeclaration || isVariableAccess)) {
+                throw createParsingFailedException("Only variable declarations or variable
access are allowed to declare resource", ctx);
+            }
+            BinaryExpression assignmentExpression;
+
+            if (isVariableDeclaration) {
+                assignmentExpression = (BinaryExpression) expression;
+            } else if (isVariableAccess) {
+                /* See https://docs.oracle.com/javase/specs/jls/se9/html/jls-14.html
+                 * 14.20.3.1. Basic try-with-resources
+                 *
+                 * If a basic try-with-resource statement is of the form:
+                 * try (VariableAccess ...)
+                 *      Block
+                 *
+                 * then the resource is first converted to a local variable declaration by
the following translation:
+                 * try (T #r = VariableAccess ...) {
+                 *      Block
+                 * }
+                 */
+                assignmentExpression =
+                        new BinaryExpression(
+                                new VariableExpression(genResourceName()),
+                                org.codehaus.groovy.syntax.Token.newSymbol(Types.ASSIGN,
-1, -1),
+                                expression
+                        );
+            } else {
+                throw createParsingFailedException("Unsupported resource declaration", ctx);
             }
-
-            BinaryExpression assignmentExpression = (BinaryExpression) expression;
 
             return configureAST(
                     new ExpressionStatement(
@@ -856,6 +882,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
         throw createParsingFailedException("Unsupported resource declaration: " + ctx.getText(),
ctx);
     }
 
+    private int resourceCnt = 0;
+    private String genResourceName() {
+        return "__$$resource" + resourceCnt++;
+    }
+
     /**
      * Multi-catch(1..*) clause will be unpacked to several normal catch clauses, so the
return type is List
      *

http://git-wip-us.apache.org/repos/asf/groovy/blob/50f6057a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index fe74a08..196b371 100644
--- a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -266,6 +266,7 @@ class GroovyParserTest extends GroovyTestCase {
 
     void "test groovy core - TryWithResources"() {
         doRunAndTestAntlr4('core/TryWithResources_01x.groovy')
+        doRunAndTestAntlr4('core/TryWithResources_02x.groovy')
     }
 
     void "test groovy core - SafeIndex"() {

http://git-wip-us.apache.org/repos/asf/groovy/blob/50f6057a/subprojects/parser-antlr4/src/test/resources/core/TryWithResources_02x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/core/TryWithResources_02x.groovy
b/subprojects/parser-antlr4/src/test/resources/core/TryWithResources_02x.groovy
new file mode 100644
index 0000000..e0a304b
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/core/TryWithResources_02x.groovy
@@ -0,0 +1,292 @@
+import groovy.transform.CompileStatic
+
+import java.io.*
+
+
+class Resource implements Closeable {
+    int resourceId;
+    static closedResourceIds = [];
+    static exMsg = "failed to close";
+
+    public Resource(int resourceId) {
+        this.resourceId = resourceId;
+    }
+
+    public void close() {
+        if (3 == resourceId) throw new IOException(exMsg);
+
+        closedResourceIds << resourceId
+    }
+}
+
+// test case 1
+def a = 1;
+Resource resource1 = new Resource(1)
+try (resource1) {
+    a = 2;
+}
+assert Resource.closedResourceIds == [1]
+assert 2 == a
+
+// test case 2
+Resource.closedResourceIds = []
+final exMsg = "resource not found";
+try {
+    // try { ... } should throw the IOException, while the resource should be closed
+    Resource r1 = new Resource(2)
+    try (r1) {
+        throw new FileNotFoundException(exMsg)
+    }
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+}
+assert Resource.closedResourceIds == [2]
+
+// test case 3
+Resource.closedResourceIds = []
+a = 1;
+try {
+    Resource r1 = new Resource(3)
+    try (r1) {
+        a = 2;
+    }
+} catch (IOException e) {
+    assert Resource.exMsg == e.getMessage()
+}
+assert 2 == a;
+assert Resource.closedResourceIds == []
+
+// test case 4
+Resource.closedResourceIds = []
+try {
+    // try { ... } should throw the IOException, while the resource should be closed
+    Resource r1 = new Resource(3)
+    try (r1) {
+        throw new FileNotFoundException(exMsg)
+    }
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+
+    def suppressedExceptions = e.getSuppressed();
+    assert suppressedExceptions.length == 1
+    assert suppressedExceptions[0] instanceof IOException
+    assert suppressedExceptions[0].getMessage() == Resource.exMsg
+}
+assert Resource.closedResourceIds == []
+
+
+// test case 5
+Resource.closedResourceIds = []
+a = 1;
+Resource rr1 = new Resource(5)
+try (rr1;
+Resource r2 = new Resource(6);) {
+    a = 2;
+}
+assert Resource.closedResourceIds == [6, 5]
+assert 2 == a
+
+// test case 6
+Resource.closedResourceIds = []
+a = 1;
+Resource rr2 = new Resource(6)
+try (Resource r1 = new Resource(5);
+rr2;
+Resource r3 = new Resource(7);) {
+    a = 2;
+}
+assert Resource.closedResourceIds == [7, 6, 5]
+assert 2 == a
+
+
+// test case 7
+Resource.closedResourceIds = []
+Resource rrr1 = new Resource(7)
+try (rrr1) {
+    throw new FileNotFoundException(exMsg)
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+}
+assert Resource.closedResourceIds == [7]
+
+// test case 8
+Resource rrr2 = new Resource(8)
+Resource.closedResourceIds = []
+try (Resource r1 = new Resource(7);
+rrr2) {
+    throw new FileNotFoundException(exMsg)
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+}
+assert Resource.closedResourceIds == [8, 7]
+
+
+// test case 9
+Resource.closedResourceIds = []
+a = 1;
+Resource rrrr1 = new Resource(3)
+try (rrrr1) {
+    a = 2;
+} catch (IOException e) {
+    assert Resource.exMsg == e.getMessage()
+}
+assert 2 == a;
+assert Resource.closedResourceIds == []
+
+
+// test case 10
+Resource.closedResourceIds = []
+a = 1;
+Resource rrrrr1 = new Resource(3);
+Resource rrrrr2 = new Resource(4);
+try (rrrrr1; rrrrr2) {
+    a = 2;
+} catch (IOException e) {
+    assert Resource.exMsg == e.getMessage()
+}
+assert 2 == a;
+assert Resource.closedResourceIds == [4]
+
+// test case 11
+Resource.closedResourceIds = []
+a = 1;
+Resource rrrrrr0 = new Resource(2);
+Resource rrrrrr2 = new Resource(4)
+try (rrrrrr0;
+Resource rrrrrr1 = new Resource(3); rrrrrr2) {
+    a = 2;
+} catch (IOException e) {
+    assert Resource.exMsg == e.getMessage()
+}
+assert 2 == a;
+assert Resource.closedResourceIds == [4, 2]
+
+
+// test case 12
+Resource.closedResourceIds = []
+Resource rrrrrrr1 = new Resource(3);
+Resource rrrrrrr2 = new Resource(4)
+try (rrrrrrr1;
+rrrrrrr2) {
+    throw new FileNotFoundException(exMsg)
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+
+    def suppressedExceptions = e.getSuppressed();
+    assert suppressedExceptions.length == 1
+    assert suppressedExceptions[0] instanceof IOException
+    assert suppressedExceptions[0].getMessage() == Resource.exMsg
+}
+assert Resource.closedResourceIds == [4]
+
+// test case 13
+Resource.closedResourceIds = []
+Resource rrrrrrrr2 = new Resource(4)
+try (Resource r0 = new Resource(2);
+Resource r1 = new Resource(3);
+rrrrrrrr2) {
+    throw new FileNotFoundException(exMsg)
+} catch(FileNotFoundException e) {
+    assert exMsg == e.getMessage()
+
+    def suppressedExceptions = e.getSuppressed();
+    assert suppressedExceptions.length == 1
+    assert suppressedExceptions[0] instanceof IOException
+    assert suppressedExceptions[0].getMessage() == Resource.exMsg
+}
+assert Resource.closedResourceIds == [4, 2]
+
+// test case 14
+Resource.closedResourceIds = []
+a = 1;
+Resource rrrrrrrrr1 = new Resource(1)
+try (rrrrrrrrr1) {
+    a += 2;
+    Resource rrrrrrrrr2 = new Resource(2);
+    Resource rrrrrrrrr4 = new Resource(4)
+    try (rrrrrrrrr2; rrrrrrrrr4) {
+        a += 3;
+        Resource rrrrrrrrr6 = new Resource(6)
+        try (Resource r5 = new Resource(5); rrrrrrrrr6; Resource r7 = new Resource(7)) {
+            a += 4;
+            try {
+                Resource rrrrrrrrr3 = new Resource(3)
+                try (rrrrrrrrr3) {
+                    a += 5;
+                }
+            } catch (IOException e) {
+                assert Resource.exMsg == e.getMessage()
+            }
+        }
+    } catch(Exception e) {
+        // ignored
+    } finally {
+        a += 10
+    }
+}
+assert Resource.closedResourceIds == [7, 6, 5, 4, 2, 1]
+assert 25 == a
+
+// test case 15
+@CompileStatic
+void tryWithResources() {
+    Resource.closedResourceIds = []
+    int cs = 1;
+    Resource r1 = new Resource(1)
+    try (r1) {
+        cs += 2;
+        Resource r2 = new Resource(2);
+        Resource r4 = new Resource(4)
+        try (r2; r4) {
+            cs += 3;
+            Resource r6 = new Resource(6);
+            try (Resource r5 = new Resource(5); r6; Resource r7 = new Resource(7)) {
+                cs += 4;
+                try {
+                    Resource r3 = new Resource(3)
+                    try (r3) {
+                        cs += 5;
+                    }
+                } catch (IOException e) {
+                    assert Resource.exMsg == e.getMessage()
+                }
+            }
+        } catch(Exception e) {
+            // ignored
+        } finally {
+            cs += 10
+        }
+    }
+    assert Resource.closedResourceIds == [7, 6, 5, 4, 2, 1]
+    assert 25 == cs
+}
+
+tryWithResources()
+
+
+// test case 16
+Resource.closedResourceIds = []
+a = 1;
+Resource rrrrrrrrrr1 = new Resource(
+        1
+)
+try (
+        rrrrrrrrrr1
+        Resource r2 = new Resource(2)
+) {
+    a = 2;
+}
+assert Resource.closedResourceIds == [2, 1]
+assert 2 == a
+
+// test case 17
+Resource.closedResourceIds = []
+a = 1;
+rrrrrrrrrrr2 = new Resource(2)
+try (r1 = new Resource(1)
+rrrrrrrrrrr2) {
+    a = 2;
+}
+assert Resource.closedResourceIds == [2, 1]
+assert 2 == a
+


Mime
View raw message