groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject [groovy] branch GROOVY_2_5_X updated: GROOVY-9176: fix line and column of error for property-generated method (closes #959)
Date Tue, 02 Jul 2019 06:48:41 GMT
This is an automated email from the ASF dual-hosted git repository.

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


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new d8c5b4d  GROOVY-9176: fix line and column of error for property-generated method
(closes #959)
d8c5b4d is described below

commit d8c5b4dae18fb527fa5495be9b8ca23119a86a68
Author: Eric Milles <eric.milles@thomsonreuters.com>
AuthorDate: Mon Jul 1 11:18:52 2019 -0500

    GROOVY-9176: fix line and column of error for property-generated method (closes #959)
---
 .../org/codehaus/groovy/classgen/Verifier.java     | 38 +++++++++++++++-----
 src/test/groovy/bugs/Groovy9176.groovy             | 42 ++++++++++++++++++++++
 2 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index bd4e40f..0ed2678 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -25,6 +25,7 @@ import groovy.transform.Generated;
 import groovy.transform.Internal;
 import org.apache.groovy.ast.tools.ClassNodeUtils;
 import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
@@ -91,9 +92,11 @@ import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
 import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.getPropertyName;
 import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptorWithoutReturnType;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
+import static org.codehaus.groovy.ast.tools.PropertyNodeUtils.adjustPropertyModifiersForMethod;
 
 /**
  * Verifies the AST node and adds any default AST code before bytecode generation occurs.
@@ -292,10 +295,10 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
             if (descriptors.contains(mySig)) {
                 if (mn.isScriptBody() || mySig.equals(scriptBodySignatureWithoutReturnType(cn)))
{
                     throw new RuntimeParserException("The method " + mn.getText() +
-                            " is a duplicate of the one declared for this script's body code",
mn);
+                            " is a duplicate of the one declared for this script's body code",
sourceOf(mn));
                 } else {
                     throw new RuntimeParserException("The method " + mn.getText() +
-                            " duplicates another method of the same signature", mn);
+                            " duplicates another method of the same signature", sourceOf(mn));
                 }
             }
             descriptors.add(mySig);
@@ -712,7 +715,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
         String getterName = "get" + capitalize(name);
         String setterName = "set" + capitalize(name);
 
-        int accessorModifiers = PropertyNodeUtils.adjustPropertyModifiersForMethod(node);
+        int accessorModifiers = adjustPropertyModifiersForMethod(node);
 
         Statement getterBlock = node.getGetterBlock();
         if (getterBlock == null) {
@@ -869,7 +872,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                             "The method with default parameters \"" + method.getTypeDescriptor()
+
                                     "\" defines a method \"" + newMethod.getTypeDescriptor()
+
                                     "\" that is already defined.",
-                            method);
+                            sourceOf(method));
                 }
                 addPropertyMethod(newMethod);
                 newMethod.setGenericsTypes(method.getGenericsTypes());
@@ -1264,7 +1267,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                     && !m.isPublic() && !m.isStaticConstructor()) {
                 throw new RuntimeParserException("The method " + m.getName() +
                         " should be public as it implements the corresponding method from
interface " +
-                        intfMethod.getDeclaringClass(), m);
+                        intfMethod.getDeclaringClass(), sourceOf(m));
 
             }
         }
@@ -1354,7 +1357,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                             " in " + overridingMethod.getDeclaringClass().getName() +
                             " is incompatible with " + testmr.getName() +
                             " in " + oldMethod.getDeclaringClass().getName(),
-                    overridingMethod);
+                    sourceOf(overridingMethod));
         }
 
         if (equalReturnType && normalEqualParameters) return null;
@@ -1364,7 +1367,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                     "Cannot override final method " +
                             oldMethod.getTypeDescriptor() +
                             " in " + oldMethod.getDeclaringClass().getName(),
-                    overridingMethod);
+                    sourceOf(overridingMethod));
         }
         if (oldMethod.isStatic() != overridingMethod.isStatic()) {
             throw new RuntimeParserException(
@@ -1372,7 +1375,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                             oldMethod.getTypeDescriptor() +
                             " in " + oldMethod.getDeclaringClass().getName() +
                             " with disparate static modifier",
-                    overridingMethod);
+                    sourceOf(overridingMethod));
         }
         if (!equalReturnType) {
             boolean oldM = ClassHelper.isPrimitiveType(oldMethod.getReturnType());
@@ -1391,7 +1394,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
                                 oldMethod.getTypeDescriptor() +
                                 " in " + oldMethod.getDeclaringClass().getName() +
                                 message,
-                        overridingMethod);
+                        sourceOf(overridingMethod));
             }
         }
 
@@ -1537,6 +1540,23 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
         return swapInitRequired;
     }
 
+    private static ASTNode sourceOf(MethodNode methodNode) {
+        if (methodNode.getLineNumber() < 1) {
+            ClassNode declaringClass = methodNode.getDeclaringClass();
+            if (methodNode.isSynthetic()) {
+                String propertyName = getPropertyName(methodNode);
+                if (propertyName != null) {
+                    PropertyNode propertyNode = declaringClass.getProperty(propertyName);
+                    if (propertyNode != null && propertyNode.getLineNumber() >
0) {
+                        return propertyNode;
+                    }
+                }
+            }
+            return declaringClass;
+        }
+        return methodNode;
+    }
+
     /**
      * When constant expressions are created, the value is always wrapped to a non primitive
type.
      * Some constant expressions are optimized to return primitive types, but not all primitives
are
diff --git a/src/test/groovy/bugs/Groovy9176.groovy b/src/test/groovy/bugs/Groovy9176.groovy
new file mode 100644
index 0000000..7d0a562
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9176.groovy
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.control.CompilationFailedException
+
+@CompileStatic
+final class Groovy9176 extends GroovyTestCase {
+
+    void testGroovyPropertyCovariantMethodCheck() {
+        def err = shouldFail CompilationFailedException, '''
+            class Pojo {
+                private String title;
+                public String getTitle() { return this.title; }
+                public void setTitle(String title) { this.title = title; }
+            }
+            class Test extends Pojo {
+                // property "title" with type that is incompatible with "String"
+                java.util.regex.Pattern title
+            }
+        '''
+
+        assert err =~ / The return type of java.util.regex.Pattern getTitle\(\) in Test is
incompatible with java.lang.String in Pojo\n\. At \[9:17\] /
+    }
+}


Mime
View raw message