This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 5597fb6449 GROOVY-11208: `String m() default ""` only for annotation 
declaration
5597fb6449 is described below

commit 5597fb6449aac8831378bb77dbd07d71edf7fe5c
Author: Eric Milles <[email protected]>
AuthorDate: Wed Jan 21 10:43:40 2026 -0600

    GROOVY-11208: `String m() default ""` only for annotation declaration
---
 src/antlr/GroovyParser.g4                          |  9 ++--
 ..._10x.groovy => AnnotationDeclaration_02.groovy} | 29 +++++++------
 .../fail/AnnotationDeclaration_01x.groovy          | 22 ----------
 .../fail/InterfaceDeclaration_01.groovy            | 21 ----------
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |  8 +---
 .../groovy/parser/antlr4/SyntaxErrorTest.groovy    | 48 +++++++++++++++++++---
 6 files changed, 65 insertions(+), 72 deletions(-)

diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index b41faad333..e97417c651 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -275,15 +275,16 @@ memberDeclaration[int t]
 
 /**
  *  t   0: *class member* all kinds of method declaration AND constructor 
declaration,
- *      1: normal method declaration, 2: abstract method declaration
- *      3: normal method declaration OR abstract method declaration
+ *      1: normal method declaration,
+ *      2: abstract method declaration
+ *      3: method declaration OR abstract method declaration
  *  ct  9: script, other see the comment of classDeclaration
  */
 methodDeclaration[int t, int ct]
     :   modifiersOpt typeParameters? (returnType[$ct] nls)?
         methodName formalParameters
-        (
-            DEFAULT nls elementValue
+        (   { $ct == 3 }? // GROOVY-11208: @interface only
+            (DEFAULT nls elementValue)
         |
             (nls THROWS nls qualifiedClassNameList)?
             (nls methodBody)?
diff --git a/src/test-resources/core/Annotation_10x.groovy 
b/src/test-resources/core/AnnotationDeclaration_02.groovy
similarity index 71%
rename from src/test-resources/core/Annotation_10x.groovy
rename to src/test-resources/core/AnnotationDeclaration_02.groovy
index 1ee354bd4c..b520673302 100644
--- a/src/test-resources/core/Annotation_10x.groovy
+++ b/src/test-resources/core/AnnotationDeclaration_02.groovy
@@ -16,23 +16,26 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-import java.lang.annotation.RetentionPolicy
 import java.lang.annotation.Retention
-
-def closureClass = 
NestedAnnotationWithDefault.getAnnotation(AnnWithNestedAnnWithDefault).elem().elem()
-def closure = closureClass.newInstance(null, null)
-assert closure.call() == 3
-
-
-@AnnWithNestedAnnWithDefault(elem = @AnnWithDefaultValue())
-class NestedAnnotationWithDefault {}
+import java.lang.annotation.RetentionPolicy
 
 @Retention(RetentionPolicy.RUNTIME)
-@interface AnnWithDefaultValue {
-    Class elem() default { 1 + 2 }
+@interface ClassValueWithDefault {
+    Class value() default { 1 + 2 }
 }
 
 @Retention(RetentionPolicy.RUNTIME)
-@interface AnnWithNestedAnnWithDefault {
-    AnnWithDefaultValue elem()
+@interface AnnotationValue {
+    ClassValueWithDefault value()
 }
+
+@AnnotationValue(@ClassValueWithDefault())
+class TypeWithAnnotationWithAnnotationWithClosure {
+}
+
+def closureClass = 
TypeWithAnnotationWithAnnotationWithClosure.getAnnotation(AnnotationValue).value().value()
+def closure = closureClass.newInstance(null, null)
+def value = closure.call()
+
+assert value instanceof Integer
+assert value == 3
diff --git a/src/test-resources/fail/AnnotationDeclaration_01x.groovy 
b/src/test-resources/fail/AnnotationDeclaration_01x.groovy
deleted file mode 100644
index c32699ecac..0000000000
--- a/src/test-resources/fail/AnnotationDeclaration_01x.groovy
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- *  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.
- */
-
-@interface A {
-    void a()
-}
diff --git a/src/test-resources/fail/InterfaceDeclaration_01.groovy 
b/src/test-resources/fail/InterfaceDeclaration_01.groovy
deleted file mode 100644
index 312818e086..0000000000
--- a/src/test-resources/fail/InterfaceDeclaration_01.groovy
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- *  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.
- */
-interface Foo {
-    def doit( String param = "Groovy", int o )
-}
diff --git 
a/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy 
b/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 60973387db..8dd54cf55b 100644
--- a/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -145,7 +145,8 @@ final class GroovyParserTest {
         doTest('core/Annotation_07.groovy')
         doTest('core/Annotation_08.groovy')
         doTest('core/Annotation_09.groovy')
-        doRunAndTestAntlr4('core/Annotation_10x.groovy')
+        doTest('core/AnnotationDeclaration_01.groovy')
+        doRunAndTestAntlr4('core/AnnotationDeclaration_02.groovy')
     }
 
     @Test
@@ -413,11 +414,6 @@ final class GroovyParserTest {
         doRunAndTestAntlr4('core/RecordDeclaration_14x.groovy')
     }
 
-    @Test
-    void 'groovy core - AnnotationDeclaration'() {
-        doTest('core/AnnotationDeclaration_01.groovy')
-    }
-
     @Test
     void 'groovy core - SealedTypeDeclaration'() {
         doRunAndTestAntlr4('core/SealedTypeDeclaration_01x.groovy')
diff --git 
a/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy 
b/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
index 9d5b789773..788f47e8ef 100644
--- a/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
+++ b/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
@@ -22,8 +22,8 @@ import groovy.test.NotYetImplemented
 import groovy.transform.AutoFinal
 import org.codehaus.groovy.control.CompilationUnit
 import org.codehaus.groovy.control.Phases
-import org.junit.Assert
-import org.junit.Test
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Test
 
 import static 
org.apache.groovy.parser.antlr4.util.ASTComparatorCategory.LOCATION_IGNORE_LIST
 
@@ -285,7 +285,17 @@ final class SyntaxErrorTest {
 
     @Test
     void 'groovy core - AnnotationDeclaration 1'() {
-        TestUtils.doRunAndShouldFail('fail/AnnotationDeclaration_01x.groovy')
+        expectParseError '''\
+            |@interface A {
+            |    void a()
+            |}
+            |'''.stripMargin(), '''\
+            |annotation method cannot have void return type @ line 2, column 5.
+            |       void a()
+            |       ^
+            |
+            |1 error
+            |'''.stripMargin()
     }
 
     @Test
@@ -379,7 +389,17 @@ final class SyntaxErrorTest {
 
     @Test
     void 'groovy core - InterfaceDeclaration 1'() {
-        TestUtils.shouldFail('fail/InterfaceDeclaration_01.groovy')
+        expectParseError '''\
+            |interface Foo {
+            |    def doit( String param = "Groovy", int o )
+            |}
+            |'''.stripMargin(), '''\
+            |Cannot specify default value for method parameter 'param = 
Groovy' inside an interface @ line 2, column 15.
+            |       def doit( String param = "Groovy", int o )
+            |                 ^
+            |
+            |1 error
+            |'''.stripMargin()
     }
 
     @Test
@@ -395,6 +415,22 @@ final class SyntaxErrorTest {
             |'''.stripMargin()
     }
 
+    // GROOVY-11208
+    @Test
+    void 'groovy core - InterfaceDeclaration 3'() {
+        expectParseError '''\
+            |interface I {
+            |    def m() default {1}
+            |}
+            |'''.stripMargin(), '''\
+            |Unexpected input: 'default' @ line 2, column 13.
+            |       def m() default {1}
+            |               ^
+            |
+            |1 error
+            |'''.stripMargin()
+    }
+
     @Test
     void 'groovy core - void'() {
         TestUtils.doRunAndShouldFail('fail/Void_01x.groovy')
@@ -600,10 +636,10 @@ final class SyntaxErrorTest {
                 compile(Phases.CONVERSION)
                 getAST()
             }
-            Assert.fail('expected parse to fail')
+            Assertions.fail('expected parse to fail')
         } catch (e) {
             def line = (expect =~ /@ line (\d+),/)[0][1]
-            Assert.assertEquals("startup failed:\ntest.groovy: $line: 
$expect".toString(), e.message.replace('\r\n', '\n'))
+            Assertions.assertEquals("startup failed:\ntest.groovy: $line: 
$expect".toString(), e.message.replace('\r\n', '\n'))
         }
     }
 

Reply via email to