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

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

commit 4cafae822961b51775b49d3b7201b20939e967b1
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri May 24 11:45:47 2019 +1000

    GROOVY-9141: add null check for classNode when checking for abstract method 
with body (tweaks)
---
 .../codehaus/groovy/antlr/AntlrParserPlugin.java   |  9 +++--
 src/test/groovy/bugs/Groovy9141.groovy             | 38 ++++++++++++++--------
 .../apache/groovy/parser/antlr4/AstBuilder.java    |  6 ++--
 3 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java 
b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
index 81ac6a4..dee0a95 100644
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
+++ b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
@@ -921,12 +921,11 @@ public class AntlrParserPlugin extends ASTHelper 
implements ParserPlugin, Groovy
         modifiers &= ~Opcodes.ACC_SYNTHETIC;
         methodNode = new MethodNode(name, modifiers, returnType, parameters, 
exceptions, code);
         if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) {
-            if (node != null) {
-                assertNodeType(SLIST, node);
-                code = statementList(node);
-            } else {
-                throw new ASTRuntimeException(methodDef, "You defined a method 
without body. Try adding a body, or declare it abstract.");
+            if (node == null) {
+                throw new ASTRuntimeException(methodDef, "You defined a method 
without a body. Try adding a body, or declare it abstract.");
             }
+            assertNodeType(SLIST, node);
+            code = statementList(node);
         } else if (node != null) {
             if (classNode != null && classNode.isAnnotationDefinition()) {
                 code = statement(node);
diff --git a/src/test/groovy/bugs/Groovy9141.groovy 
b/src/test/groovy/bugs/Groovy9141.groovy
index 32dd3a4..0889d36 100644
--- a/src/test/groovy/bugs/Groovy9141.groovy
+++ b/src/test/groovy/bugs/Groovy9141.groovy
@@ -20,27 +20,39 @@ package groovy.bugs
 
 import gls.CompilableTestSupport
 import groovy.transform.CompileStatic
+import org.codehaus.groovy.control.CompilerConfiguration
+
+import static org.codehaus.groovy.control.ParserVersion.V_2
 
 @CompileStatic
 final class Groovy9141 extends CompilableTestSupport {
+    private static final String METHOD_DEF = '''
+        abstract meth() {
+            println 42
+        }
+    '''
 
-    void testAbstractMethodWithBody1() {
-        def err = shouldNotCompile '''\
-            abstract def meth() {
-              println 42
-            }
-            '''.stripIndent()
-        assert err =~ / You can not define a abstract method\[meth\]  in the 
script. Try removing the 'abstract' /
+    void testAbstractMethodWithBodyInScript() {
+        def err = shouldNotCompile METHOD_DEF
+        assert err =~ / You cannot define an abstract method\[meth\] in the 
script. Try removing the 'abstract' /
     }
 
-    void testAbstractMethodWithBody2() {
-        def err = shouldNotCompile '''\
+    void testAbstractMethodWithBodyInClass() {
+        def err = shouldNotCompile """
             class Main {
-              abstract def meth() {
-                println 42
-              }
+                $METHOD_DEF
             }
-            '''.stripIndent()
+        """
+        // not a language requirement but class level check takes precedence 
in current implementation
         assert err =~ / Can't have an abstract method in a non-abstract class. 
/
     }
+
+    void testAbstractMethodWithBodyInScript_oldParser() {
+        def cc = new CompilerConfiguration(parserVersion: V_2)
+        def err = shouldFail {
+            new GroovyShell(cc).evaluate METHOD_DEF
+        }
+        assert err =~ / Abstract methods do not define a body/
+    }
+
 }
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 0e54bb9..bd93781 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
@@ -1637,7 +1637,7 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> implements Groov
 
         if (9 == ctx.ct) { // script
             if (isAbstractMethod || !hasMethodBody) { // method should not be 
declared abstract in the script
-                throw createParsingFailedException("You can not define a " + 
(isAbstractMethod ? "abstract" : "") + " method[" + methodNode.getName() + "] " 
+ (!hasMethodBody ? "without method body" : "") + " in the script. Try " + 
(isAbstractMethod ? "removing the 'abstract'" : "") + (isAbstractMethod && 
!hasMethodBody ? " and" : "") + (!hasMethodBody ? " adding a method body" : 
""), methodNode);
+                throw createParsingFailedException("You cannot define " + 
(isAbstractMethod ? "an abstract" : "a") + " method[" + methodNode.getName() + 
"] " + (!hasMethodBody ? "without method body " : "") + "in the script. Try " + 
(isAbstractMethod ? "removing the 'abstract'" : "") + (isAbstractMethod && 
!hasMethodBody ? " and" : "") + (!hasMethodBody ? " adding a method body" : 
""), methodNode);
             }
         } else {
             if (4 == ctx.ct) { // trait
@@ -1647,12 +1647,12 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> implements Groov
             }
 
             if (!isAbstractMethod && !hasMethodBody) { // non-abstract method 
without body in the non-script(e.g. class, enum, trait) is not allowed!
-                throw createParsingFailedException("You defined a method[" + 
methodNode.getName() + "] without body. Try adding a method body, or declare it 
abstract", methodNode);
+                throw createParsingFailedException("You defined a method[" + 
methodNode.getName() + "] without a body. Try adding a method body, or declare 
it abstract", methodNode);
             }
 
             boolean isInterfaceOrAbstractClass = asBoolean(classNode) && 
classNode.isAbstract() && !classNode.isAnnotationDefinition();
             if (isInterfaceOrAbstractClass && 
!modifierManager.containsAny(DEFAULT) && isAbstractMethod && hasMethodBody) {
-                throw createParsingFailedException("You defined an abstract 
method[" + methodNode.getName() + "] with body. Try removing the method body" + 
(classNode.isInterface() ? ", or declare it default" : ""), methodNode);
+                throw createParsingFailedException("You defined an abstract 
method[" + methodNode.getName() + "] with a body. Try removing the method body" 
+ (classNode.isInterface() ? ", or declare it default" : ""), methodNode);
             }
         }
 

Reply via email to