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 2017/06/24 02:50:47 UTC

[1/2] groovy git commit: Support JSR308

Repository: groovy
Updated Branches:
  refs/heads/master 05f1e28f7 -> bc2f4eb50


Support JSR308


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

Branch: refs/heads/master
Commit: c659f4ad8c48181a8f19b866bbd93b7baf97cfa6
Parents: 141fccf
Author: sunlan <su...@apache.org>
Authored: Tue Jun 20 22:08:55 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Tue Jun 20 22:08:55 2017 +0800

----------------------------------------------------------------------
 .../apache/groovy/parser/antlr4/GroovyParser.g4 |  57 +++++--
 .../apache/groovy/parser/antlr4/AstBuilder.java | 147 ++++++++++++++-----
 .../parser/antlr4/GroovyParserTest.groovy       |   4 +-
 .../src/test/resources/bugs/GROOVY-8228.groovy  |  92 ++++++++++++
 4 files changed, 249 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/c659f4ad/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 b/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
index 6f644ef..b7efd4f 100644
--- a/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
+++ b/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
@@ -334,19 +334,38 @@ variableInitializers
     :   variableInitializer nls (COMMA nls variableInitializer nls)* nls COMMA?
     ;
 
+dims
+    :   (annotationsOpt LBRACK RBRACK)+
+    ;
+
+dimsOpt
+    :   dims?
+    ;
+
 standardType
 options { baseContext = type; }
-    :   primitiveType (LBRACK RBRACK)*
-    |   standardClassOrInterfaceType (LBRACK RBRACK)*
+    :   annotationsOpt
+        (
+            primitiveType
+        |
+            standardClassOrInterfaceType
+        )
+        dimsOpt
     ;
 
 type
-    :   (   primitiveType
+    :   annotationsOpt
+        (
+            (
+                primitiveType
+            |
+                 // !!! ERROR ALTERNATIVE !!!
+                 VOID { require(false, "void is not allowed here", -4); }
+            )
         |
-            // !!! ERROR ALTERNATIVE !!!
-            VOID { require(false, "void is not allowed here", -4); }
-        ) (LBRACK RBRACK)*
-    |   generalClassOrInterfaceType (LBRACK RBRACK)*
+                generalClassOrInterfaceType
+        )
+        dimsOpt
     ;
 
 classOrInterfaceType
@@ -375,11 +394,15 @@ typeArguments
 
 typeArgument
     :   type
-    |   QUESTION ((EXTENDS | SUPER) nls type)?
+    |   annotationsOpt QUESTION ((EXTENDS | SUPER) nls type)?
+    ;
+
+annotatedQualifiedClassName
+    :   annotationsOpt qualifiedClassName
     ;
 
 qualifiedClassNameList
-    :   qualifiedClassName (COMMA nls qualifiedClassName)*
+    :   annotatedQualifiedClassName (COMMA nls annotatedQualifiedClassName)*
     ;
 
 formalParameters
@@ -387,10 +410,14 @@ formalParameters
     ;
 
 formalParameterList
-    :   formalParameter (COMMA nls formalParameter)* (COMMA nls lastFormalParameter)?
+    :   (formalParameter | thisFormalParameter) (COMMA nls formalParameter)* (COMMA nls lastFormalParameter)?
     |   lastFormalParameter
     ;
 
+thisFormalParameter
+    :   type THIS
+    ;
+
 formalParameter
     :   variableModifiersOpt type?          variableDeclaratorId (nls ASSIGN nls expression)?
     ;
@@ -1079,8 +1106,8 @@ mapEntryLabel
 creator
     :   createdName
         (   nls arguments anonymousInnerClassDeclaration[0]?
-        |   (LBRACK expression RBRACK)+ (b+=LBRACK RBRACK)*
-        |   (b+=LBRACK RBRACK)+ nls arrayInitializer
+        |   (annotationsOpt LBRACK expression RBRACK)+ dimsOpt
+        |   dims nls arrayInitializer
         )
     ;
 
@@ -1096,8 +1123,10 @@ anonymousInnerClassDeclaration[int t]
     ;
 
 createdName
-    :   primitiveType
-    |   qualifiedClassName typeArgumentsOrDiamond?
+    :   annotationsOpt
+        (   primitiveType
+        |   qualifiedClassName typeArgumentsOrDiamond?
+        )
     ;
 
 nonWildcardTypeArguments

http://git-wip-us.apache.org/repos/asf/groovy/blob/c659f4ad/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 7ac33a0..aa2d0f8 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
@@ -262,7 +262,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
         PackageNode packageNode = moduleNode.getPackage();
 
-        this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(packageNode::addAnnotation);
+        packageNode.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
 
         return this.configureAST(packageNode, ctx);
     }
@@ -1028,7 +1028,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                         this.visitIdentifier(ctx.identifier()),
                         createEnumConstantInitExpression(ctx.arguments(), anonymousInnerClassNode));
 
-        this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(enumConstant::addAnnotation);
+        enumConstant.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
 
         groovydocManager.handle(enumConstant, ctx);
 
@@ -2739,28 +2739,35 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                     ctx);
         }
 
-        if (asBoolean(ctx.LBRACK())) { // create array
+        if (asBoolean(ctx.LBRACK()) || asBoolean(ctx.dims())) { // create array
+            ArrayExpression arrayExpression;
+            List<List<AnnotationNode>> allDimList;
+
             if (asBoolean(ctx.arrayInitializer())) {
-                ClassNode arrayType = classNode;
-                for (int i = 0, n = ctx.b.size() - 1; i < n; i++) {
-                    arrayType = arrayType.makeArray();
+                ClassNode elementType = classNode;
+                allDimList = this.visitDims(ctx.dims());
+
+                for (int i = 0, n = allDimList.size() - 1; i < n; i++) {
+                    elementType = elementType.makeArray();
                 }
 
-                return this.configureAST(
+                arrayExpression =
                         new ArrayExpression(
-                                arrayType,
-                                this.visitArrayInitializer(ctx.arrayInitializer())),
-                        ctx);
+                            elementType,
+                            this.visitArrayInitializer(ctx.arrayInitializer()));
+
             } else {
                 Expression[] empties;
-                if (asBoolean(ctx.b)) {
-                    empties = new Expression[ctx.b.size()];
+                List<List<AnnotationNode>> emptyDimList = this.visitDimsOpt(ctx.dimsOpt());
+
+                if (asBoolean(emptyDimList)) {
+                    empties = new Expression[emptyDimList.size()];
                     Arrays.setAll(empties, i -> ConstantExpression.EMPTY_EXPRESSION);
                 } else {
                     empties = new Expression[0];
                 }
 
-                return this.configureAST(
+                arrayExpression =
                         new ArrayExpression(
                                 classNode,
                                 null,
@@ -2768,14 +2775,33 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                                         ctx.expression().stream()
                                                 .map(e -> (Expression) this.visit(e)),
                                         Arrays.stream(empties)
-                                ).collect(Collectors.toList())),
-                        ctx);
+                                ).collect(Collectors.toList()));
+
+
+                List<List<AnnotationNode>> exprDimList = ctx.annotationsOpt().stream().map(this::visitAnnotationsOpt).collect(Collectors.toList());
+                allDimList = new ArrayList<>(exprDimList);
+                Collections.reverse(emptyDimList);
+                allDimList.addAll(emptyDimList);
+                Collections.reverse(allDimList);
             }
+
+            arrayExpression.setType(createArrayType(classNode, allDimList));
+
+            return this.configureAST(arrayExpression, ctx);
         }
 
         throw createParsingFailedException("Unsupported creator: " + ctx.getText(), ctx);
     }
 
+    private ClassNode createArrayType(ClassNode classNode, List<List<AnnotationNode>> dimList) {
+        ClassNode arrayType = classNode;
+        for (int i = 0, n = dimList.size(); i < n; i++) {
+            arrayType = arrayType.makeArray();
+            arrayType.addAnnotations(dimList.get(i));
+        }
+        return arrayType;
+    }
+
 
     private String genAnonymousClassName(String outerClassName) {
         return outerClassName + "$" + this.anonymousInnerClassCounter++;
@@ -2819,24 +2845,30 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
     @Override
     public ClassNode visitCreatedName(CreatedNameContext ctx) {
+        ClassNode classNode = null;
+
         if (asBoolean(ctx.qualifiedClassName())) {
-            ClassNode classNode = this.visitQualifiedClassName(ctx.qualifiedClassName());
+            classNode = this.visitQualifiedClassName(ctx.qualifiedClassName());
 
             if (asBoolean(ctx.typeArgumentsOrDiamond())) {
                 classNode.setGenericsTypes(
                         this.visitTypeArgumentsOrDiamond(ctx.typeArgumentsOrDiamond()));
             }
 
-            return this.configureAST(classNode, ctx);
-        }
-
-        if (asBoolean(ctx.primitiveType())) {
-            return this.configureAST(
+            classNode = this.configureAST(classNode, ctx);
+        } else if (asBoolean(ctx.primitiveType())) {
+            classNode = this.configureAST(
                     this.visitPrimitiveType(ctx.primitiveType()),
                     ctx);
         }
 
-        throw createParsingFailedException("Unsupported created name: " + ctx.getText(), ctx);
+        if (!asBoolean(classNode)) {
+            throw createParsingFailedException("Unsupported created name: " + ctx.getText(), ctx);
+        }
+
+        classNode.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
+
+        return classNode;
     }
 
 
@@ -3232,6 +3264,10 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
         List<Parameter> parameterList = new LinkedList<>();
 
+        if (asBoolean(ctx.thisFormalParameter())) {
+            parameterList.add(this.visitThisFormalParameter(ctx.thisFormalParameter()));
+        }
+
         if (asBoolean(ctx.formalParameter())) {
             parameterList.addAll(
                     ctx.formalParameter().stream()
@@ -3252,6 +3288,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
     }
 
     @Override
+    public Parameter visitThisFormalParameter(ThisFormalParameterContext ctx) {
+        return this.configureAST(new Parameter(this.visitType(ctx.type()), THIS_STR), ctx);
+    }
+
+    @Override
     public Parameter visitLastFormalParameter(LastFormalParameterContext ctx) {
         return this.processFormalParameter(ctx, ctx.variableModifiersOpt(), ctx.type(), ctx.ELLIPSIS(), ctx.variableDeclaratorId(), ctx.expression());
     }
@@ -3345,6 +3386,26 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                 .collect(Collectors.toList());
     }
 
+    @Override
+    public List<List<AnnotationNode>> visitDims(DimsContext ctx) {
+        List<List<AnnotationNode>> dimList =
+                ctx.annotationsOpt().stream()
+                        .map(this::visitAnnotationsOpt)
+                        .collect(Collectors.toList());
+
+        Collections.reverse(dimList);
+
+        return dimList;
+    }
+
+    @Override
+    public List<List<AnnotationNode>> visitDimsOpt(DimsOptContext ctx) {
+        if (!asBoolean(ctx.dims())) {
+            return Collections.emptyList();
+        }
+
+        return this.visitDims(ctx.dims());
+    }
 
     // type {       --------------------------------------------------------------------
     @Override
@@ -3358,24 +3419,23 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         if (asBoolean(ctx.classOrInterfaceType())) {
             ctx.classOrInterfaceType().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, ctx.getNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR));
             classNode = this.visitClassOrInterfaceType(ctx.classOrInterfaceType());
+        } else if (asBoolean(ctx.primitiveType())) {
+            classNode = this.visitPrimitiveType(ctx.primitiveType());
         }
 
-        if (asBoolean(ctx.primitiveType())) {
-            classNode = this.visitPrimitiveType(ctx.primitiveType());
+        if (!asBoolean(classNode)) {
+            throw createParsingFailedException("Unsupported type: " + ctx.getText(), ctx);
         }
 
-        if (asBoolean(ctx.LBRACK())) {
+        classNode.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
+
+        List<List<AnnotationNode>> dimList = this.visitDimsOpt(ctx.dimsOpt());
+        if (asBoolean(dimList)) {
             // clear array's generics type info. Groovy's bug? array's generics type will be ignored. e.g. List<String>[]... p
             classNode.setGenericsTypes(null);
             classNode.setUsingGenerics(false);
 
-            for (int i = 0, n = ctx.LBRACK().size(); i < n; i++) {
-                classNode = this.configureAST(classNode.makeArray(), classNode);
-            }
-        }
-
-        if (!asBoolean(classNode)) {
-            throw createParsingFailedException("Unsupported type: " + ctx.getText(), ctx);
+            classNode = this.createArrayType(classNode, dimList);
         }
 
         return this.configureAST(classNode, ctx);
@@ -3424,6 +3484,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         if (asBoolean(ctx.QUESTION())) {
             ClassNode baseType = this.configureAST(ClassHelper.makeWithoutCaching(QUESTION_STR), ctx.QUESTION());
 
+            baseType.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
+
             if (!asBoolean(ctx.type())) {
                 GenericsType genericsType = new GenericsType(baseType);
                 genericsType.setWildcard(true);
@@ -3637,13 +3699,22 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
     }
 
     @Override
+    public ClassNode visitAnnotatedQualifiedClassName(AnnotatedQualifiedClassNameContext ctx) {
+        ClassNode classNode = this.visitQualifiedClassName(ctx.qualifiedClassName());
+
+        this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(classNode::addAnnotation);
+
+        return classNode;
+    }
+
+    @Override
     public ClassNode[] visitQualifiedClassNameList(QualifiedClassNameListContext ctx) {
         if (!asBoolean(ctx)) {
             return new ClassNode[0];
         }
 
-        return ctx.qualifiedClassName().stream()
-                .map(this::visitQualifiedClassName)
+        return ctx.annotatedQualifiedClassName().stream()
+                .map(this::visitAnnotatedQualifiedClassName)
                 .toArray(ClassNode[]::new);
     }
 
@@ -3754,8 +3825,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                 new ModifierManager(this, this.visitVariableModifiersOpt(variableModifiersOptContext))
                         .processParameter(
                                 this.configureAST(
-                                        new Parameter(classNode, this.visitVariableDeclaratorId(variableDeclaratorIdContext).getName()),
-                                        ctx)
+                                        new Parameter(
+                                                classNode,
+                                                this.visitVariableDeclaratorId(variableDeclaratorIdContext).getName()
+                                        ),
+                                        ctx
+                                )
                         );
 
         if (asBoolean(expressionContext)) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/c659f4ad/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 480d2ab..8e3ec65 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
@@ -357,12 +357,14 @@ class GroovyParserTest extends GroovyTestCase {
 
     void "test groovy core - BUG"() {
         doRunAndTest('bugs/BUG-GROOVY-4757.groovy');
-        doRunAndTest('bugs/GROOVY-3898.groovy');
         doRunAndTest('bugs/BUG-GROOVY-5652.groovy');
         doRunAndTest('bugs/BUG-GROOVY-4762.groovy');
         doRunAndTest('bugs/BUG-GROOVY-4438.groovy');
         doRunAndTest('bugs/BUG-GROOVY-6038.groovy');
         doRunAndTest('bugs/BUG-GROOVY-2324.groovy');
         doTest('bugs/BUG-GROOVY-8161.groovy');
+
+        doRunAndTest('bugs/GROOVY-3898.groovy');
+        doRunAndTest('bugs/GROOVY-8228.groovy');
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/c659f4ad/subprojects/parser-antlr4/src/test/resources/bugs/GROOVY-8228.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/bugs/GROOVY-8228.groovy b/subprojects/parser-antlr4/src/test/resources/bugs/GROOVY-8228.groovy
new file mode 100644
index 0000000..a82c58d
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/bugs/GROOVY-8228.groovy
@@ -0,0 +1,92 @@
+/*
+ *  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 java.lang.annotation.Retention
+import java.lang.annotation.Target
+import java.lang.reflect.Field
+import java.lang.reflect.Method
+import java.lang.reflect.Parameter
+import java.lang.reflect.TypeVariable
+import java.sql.SQLException
+
+import static java.lang.annotation.ElementType.*
+import static java.lang.annotation.RetentionPolicy.RUNTIME
+
+@Target([PARAMETER, FIELD, METHOD, ANNOTATION_TYPE, TYPE_USE, LOCAL_VARIABLE])
+@Retention(RUNTIME)
+@interface JSR308 { }
+
+class JSR308BaseClass<T> {}
+interface JSR308Interface1<T> {}
+interface JSR308Interface2<T extends @JSR308 CharSequence> {}
+
+class JSR308Class extends @JSR308 JSR308BaseClass<@JSR308 List> implements @JSR308 JSR308Interface1<@JSR308 String>, @JSR308 JSR308Interface2<@JSR308 String> {
+    @JSR308 private  String name;
+
+    @JSR308 List<@JSR308 String> test(@JSR308 List<@JSR308 ? extends @JSR308 Object> list) throws @JSR308 IOException, @JSR308 java.sql.SQLException {
+        @JSR308 List<@JSR308 String> localVar = new @JSR308 ArrayList<@JSR308 String>();
+
+        try {
+            for (e in list) {
+                String t = (@JSR308 String) e;
+                localVar.add(t);
+            }
+        } catch (@JSR308 Exception e) {
+        }
+
+        String @JSR308 []  strs = new String @JSR308 [] { 'a' }
+        String @JSR308 [] @JSR308 [] strs2 = new String @JSR308 [] @JSR308 [] { new String[] {'a', 'b'} }
+        String @JSR308 [] @JSR308 [] @JSR308 [] strs3 = new String @JSR308 [1] @JSR308 [2] @JSR308 []
+        String @JSR308 [] @JSR308 [] @JSR308 [] @JSR308 [] strs4 = new String @JSR308 [1] @JSR308 [2] @JSR308 [] @JSR308 []
+
+        localVar.add(strs[0])
+        localVar.add(strs2[0][1])
+        assert null != strs3
+        assert null != strs4
+
+        return localVar
+    }
+
+    void test2(@JSR308 JSR308Class this) {}
+}
+
+def jsr308Class = new JSR308Class();
+def list = new ArrayList<@JSR308 String>();
+list.addAll(["1", "2"]);
+def result = jsr308Class.test(list)
+assert ['1', '2', 'a', 'b'] == result
+
+assert 'JSR308BaseClass<java.util.List>' == JSR308Class.class.getAnnotatedSuperclass().type.typeName
+assert ['JSR308Interface1<java.lang.String>', 'JSR308Interface2<java.lang.String>'] == JSR308Class.class.getAnnotatedInterfaces().collect(e -> e.type.typeName)
+
+Method testMethod = JSR308Class.class.getDeclaredMethods().find(e -> e.name == 'test')
+assert [IOException, SQLException] == testMethod.getAnnotatedExceptionTypes().collect(e -> e.type)
+assert 'java.util.List<java.lang.String>' == testMethod.getAnnotatedReturnType().type.typeName
+assert ['java.util.List<?>'] == testMethod.getAnnotatedParameterTypes().collect(e -> e.type.typeName)
+
+Method test2Method = JSR308Class.class.getDeclaredMethods().find(e -> e.name == 'test2')
+assert JSR308Class.class == test2Method.getAnnotatedReceiverType().type
+
+Parameter listParameter = testMethod.getParameters()[0]
+assert 'java.util.List<?>' == listParameter.getAnnotatedType().type.typeName
+
+Field nameField = JSR308Class.class.getDeclaredField('name');
+assert String.class == nameField.getAnnotatedType().type
+
+TypeVariable tv = JSR308Interface2.class.getTypeParameters()[0]
+assert [CharSequence.class] == tv.getAnnotatedBounds().collect(e -> e.type)


[2/2] groovy git commit: Merge branch 'jsr308' of https://git-wip-us.apache.org/repos/asf/groovy

Posted by su...@apache.org.
Merge branch 'jsr308' of https://git-wip-us.apache.org/repos/asf/groovy


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

Branch: refs/heads/master
Commit: bc2f4eb50a56b2d1a336734448f145f629fe4ab8
Parents: 05f1e28 c659f4a
Author: sunlan <su...@apache.org>
Authored: Sat Jun 24 10:48:56 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Sat Jun 24 10:48:56 2017 +0800

----------------------------------------------------------------------
 .../apache/groovy/parser/antlr4/GroovyParser.g4 |  57 +++++--
 .../apache/groovy/parser/antlr4/AstBuilder.java | 147 ++++++++++++++-----
 .../parser/antlr4/GroovyParserTest.groovy       |   4 +-
 .../src/test/resources/bugs/GROOVY-8228.groovy  |  92 ++++++++++++
 4 files changed, 249 insertions(+), 51 deletions(-)
----------------------------------------------------------------------