Repository: groovy Updated Branches: refs/heads/parrot 37175956f -> 2ca95086e
GROOVY-8005: [parrot] NPE when using try-with-resources with a missing semi-colon Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/2ca95086 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/2ca95086 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/2ca95086 Branch: refs/heads/parrot Commit: 2ca95086e6ed7554536d4d0ea12317e26903e3c7 Parents: 3717595 Author: Daniel Sun <sun...@apache.org> Authored: Sat Nov 26 14:55:18 2016 +0800 Committer: Daniel Sun <sun...@apache.org> Committed: Sat Nov 26 14:55:18 2016 +0800 ---------------------------------------------------------------------- .../apache/groovy/parser/antlr4/GroovyLexer.g4 | 49 +++++++++++++++++--- .../apache/groovy/parser/antlr4/GroovyParser.g4 | 4 +- .../resources/core/TryWithResources_01x.groovy | 14 ++++++ 3 files changed, 59 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/2ca95086/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 ---------------------------------------------------------------------- diff --git a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 index 0e5a263..74d76be 100644 --- a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 +++ b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 @@ -85,6 +85,38 @@ lexer grammar GroovyLexer; */ protected void rollbackOneChar() {} + private static class Paren { + private String text; + private int lastTokenType; + + public Paren(String text, int lastTokenType) { + this.text = text; + this.lastTokenType = lastTokenType; + } + + public String getText() { + return this.text; + } + + public int getLastTokenType() { + return this.lastTokenType; + } + + @Override + public int hashCode() { + return text.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Paren)) { + return false; + } + + return this.text.equals(((Paren) obj).text); + } + } + private static final Map<String, String> PAREN_MAP = Collections.unmodifiableMap(new HashMap<String, String>() { { put("(", ")"); @@ -92,25 +124,30 @@ lexer grammar GroovyLexer; put("{", "}"); } }); - private final Deque<String> parenStack = new ArrayDeque<>(32); + + private final Deque<Paren> parenStack = new ArrayDeque<>(32); private void enterParen() { - parenStack.push(getText()); + parenStack.push(new Paren(getText(), this.lastTokenType)); } private void exitParen() { - String paren = parenStack.peek(); + Paren paren = parenStack.peek(); String text = getText(); assert null != paren: "Too many '" + text + "' " + genPositionInfo(); - assert text.equals(PAREN_MAP.get(paren)): "'" + text + "' can not match '" + paren + "' " + genPositionInfo(); + assert text.equals(PAREN_MAP.get(paren.getText())): "'" + text + "' can not match '" + paren.getText() + "' " + genPositionInfo(); parenStack.pop(); } private boolean isInsideParens() { - String paren = parenStack.peek(); + Paren paren = parenStack.peek(); // We just care about "(" and "[", inside which the new lines will be ignored. // Notice: the new lines between "{" and "}" can not be ignored. - return "(".equals(paren) || "[".equals(paren); + if (null == paren) { + return false; + } + return ("(".equals(paren.getText()) && TRY != paren.getLastTokenType()) // we don't treat try-paren(i.e. try (....)) as parenthesis + || "[".equals(paren.getText()); } private void ignoreTokenInsideParens() { if (!this.isInsideParens()) { http://git-wip-us.apache.org/repos/asf/groovy/blob/2ca95086/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 ---------------------------------------------------------------------- diff --git a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 index 144ccb1..8bdb6b8 100644 --- a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 +++ b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 @@ -679,11 +679,11 @@ finallyBlock resources - : LPAREN resourceList SEMI? RPAREN + : LPAREN nls resourceList sep? RPAREN ; resourceList - : resource (SEMI resource)* + : resource (sep resource)* ; resource http://git-wip-us.apache.org/repos/asf/groovy/blob/2ca95086/subprojects/groovy-antlr4-grammar/src/test/resources/core/TryWithResources_01x.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-antlr4-grammar/src/test/resources/core/TryWithResources_01x.groovy b/subprojects/groovy-antlr4-grammar/src/test/resources/core/TryWithResources_01x.groovy index 95ed48a..38f8da8 100644 --- a/subprojects/groovy-antlr4-grammar/src/test/resources/core/TryWithResources_01x.groovy +++ b/subprojects/groovy-antlr4-grammar/src/test/resources/core/TryWithResources_01x.groovy @@ -239,3 +239,17 @@ void tryWithResources() { tryWithResources() + +// test case 16 +Resource.closedResourceIds = [] +a = 1; +try ( + Resource r1 = new Resource( + 1 +) + Resource r2 = new Resource(2) + ) { + a = 2; +} +assert Resource.closedResourceIds == [2, 1] +assert 2 == a