You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/05/24 11:43:20 UTC
groovy git commit: GROOVY-8586: Support Java 9 ARM blocks
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_6_X 3f5b9fd38 -> 5f540e893
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/5f540e89
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/5f540e89
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/5f540e89
Branch: refs/heads/GROOVY_2_6_X
Commit: 5f540e8933ed3412d3acaede1483d09dfdb8c5dc
Parents: 3f5b9fd
Author: danielsun1106 <re...@hotmail.com>
Authored: Thu May 24 19:43:11 2018 +0800
Committer: danielsun1106 <re...@hotmail.com>
Committed: Thu May 24 19:43:28 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 | 311 +++++++++++++++++++
4 files changed, 352 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/5f540e89/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/5f540e89/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 2942439..fb3895e 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
@@ -801,7 +801,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) {
for (ExpressionStatement e : this.visitResources(ctx.resources())) {
tryCatchStatement.addResource(e);
}
@@ -847,14 +847,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(
@@ -873,6 +899,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/5f540e89/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 6535b69..0d55a39 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
@@ -273,6 +273,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/5f540e89/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..95d0767
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/core/TryWithResources_02x.groovy
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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
+