You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2018/11/10 10:41:25 UTC
[1/3] groovy git commit: GROOVY-8872: Populate the parameter names
from the byte code when available (closes #820)
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_5_X 2ed7b2de8 -> eb3494ef7
GROOVY-8872: Populate the parameter names from the byte code when available (closes #820)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/c8944a5b
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/c8944a5b
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/c8944a5b
Branch: refs/heads/GROOVY_2_5_X
Commit: c8944a5b9321df491b8feadd9c24324c6d79b406
Parents: 2ed7b2d
Author: jameskleeh <ja...@gmail.com>
Authored: Thu Nov 8 23:44:59 2018 -0500
Committer: Paul King <pa...@asert.com.au>
Committed: Sat Nov 10 20:39:47 2018 +1000
----------------------------------------------------------------------
.../groovy/ast/decompiled/AsmDecompiler.java | 6 ++
.../groovy/ast/decompiled/ClassStub.java | 1 +
.../ast/decompiled/MemberSignatureParser.java | 10 ++-
.../groovy/groovy/ant/Groovy8872Test.groovy | 88 ++++++++++++++++++++
4 files changed, 104 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/c8944a5b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmDecompiler.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmDecompiler.java b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmDecompiler.java
index 6286ff9..4e0f922 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmDecompiler.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmDecompiler.java
@@ -158,6 +158,12 @@ public abstract class AsmDecompiler {
}
};
}
+
+ @Override
+ public void visitParameter(String name, int access) {
+ if (stub.parameterNames == null) stub.parameterNames = new ArrayList<String>();
+ stub.parameterNames.add(name);
+ }
};
}
return null;
http://git-wip-us.apache.org/repos/asf/groovy/blob/c8944a5b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassStub.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassStub.java b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassStub.java
index 43b10df..96df728 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassStub.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassStub.java
@@ -65,6 +65,7 @@ class MethodStub extends MemberStub {
final String signature;
final String[] exceptions;
Map<Integer, List<AnnotationStub>> parameterAnnotations;
+ List<String> parameterNames;
Object annotationDefault;
public MethodStub(String methodName, int accessModifiers, String desc, String signature, String[] exceptions) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/c8944a5b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
index ecb1028..436c02c 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
@@ -97,8 +97,16 @@ class MemberSignatureParser {
}
Parameter[] parameters = new Parameter[parameterTypes.length];
+ List<String> parameterNames = method.parameterNames;
for (int i = 0; i < parameterTypes.length; i++) {
- parameters[i] = new Parameter(parameterTypes[i], "param" + i);
+ String parameterName = "param" + i;
+ if (parameterNames != null && i < parameterNames.size()) {
+ String decompiledName = parameterNames.get(i);
+ if (decompiledName != null) {
+ parameterName = decompiledName;
+ }
+ }
+ parameters[i] = new Parameter(parameterTypes[i], parameterName);
}
if (method.parameterAnnotations != null) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/c8944a5b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
new file mode 100644
index 0000000..1cd46e7
--- /dev/null
+++ b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
@@ -0,0 +1,88 @@
+/*
+ * 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.ant
+
+class Groovy8669Test extends AntTestCase {
+ private scriptAllOnPath = '''
+ def anno = AnnotatedClass.annotations[0]
+ def type = anno.annotationType()
+ assert type.name == 'MyAnnotation'
+ assert type.getDeclaredMethod('value').invoke(anno).name == 'ValueClass'
+ '''
+
+ private scriptNoValueClass = '''
+ // using annotations will cause ValueClass not to be found
+ // but should still be able to use the class otherwise
+ assert AnnotatedClass.name.size() == 14
+ '''
+
+ private scriptNoAnnotationOnPath = '''
+ // class should be usable but won't have annotations
+ assert !AnnotatedClass.annotations
+ '''
+
+ void testCreateZip() {
+// def debugLogger = new org.apache.tools.ant.DefaultLogger()
+// debugLogger.setMessageOutputLevel(4)
+// debugLogger.setOutputPrintStream(System.out)
+// debugLogger.setErrorPrintStream(System.err)
+
+ doInTmpDir { ant, baseDir ->
+ baseDir.src {
+ 'ValueClass.java'('''
+ public class ValueClass{ }
+ ''')
+ 'MyAnnotation.java'('''
+ import java.lang.annotation.*;
+
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MyAnnotation {
+ Class<ValueClass> value();
+ }
+ ''')
+ 'AnnotatedClass.java'('''
+ @MyAnnotation(ValueClass.class)
+ class AnnotatedClass { }
+ ''')
+ }
+// ant.project.addBuildListener(debugLogger)
+ ant.mkdir(dir: 'build')
+ ant.javac(classpath: '.', destdir: 'build', srcdir: 'src',
+ includes: '*.java', includeantruntime: 'false', fork: 'true')
+ ['ValueClass', 'MyAnnotation', 'AnnotatedClass'].each { name ->
+ ant.mkdir(dir: "build$name")
+ ant.copy(file: "build/${name}.class", todir: "build$name")
+ }
+ ant.taskdef(name: 'groovy', classname: 'org.codehaus.groovy.ant.Groovy')
+ ant.groovy(scriptAllOnPath) {
+ classpath { pathelement(path: 'buildValueClass') }
+ classpath { pathelement(path: 'buildMyAnnotation') }
+ classpath { pathelement(path: 'buildAnnotatedClass') }
+ }
+ ant.groovy(scriptNoValueClass) {
+ classpath { pathelement(path: 'buildMyAnnotation') }
+ classpath { pathelement(path: 'buildAnnotatedClass') }
+ }
+ ant.groovy(scriptNoAnnotationOnPath) {
+ classpath { pathelement(path: 'buildAnnotatedClass') }
+ }
+ }
+ }
+}
[2/3] groovy git commit: GROOVY-8872: Populate the parameter names
from the byte code when available (add test)
Posted by pa...@apache.org.
GROOVY-8872: Populate the parameter names from the byte code when available (add test)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/66c87071
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/66c87071
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/66c87071
Branch: refs/heads/GROOVY_2_5_X
Commit: 66c8707165081d201d90dd79e9ff9610147dd4c6
Parents: c8944a5
Author: Paul King <pa...@asert.com.au>
Authored: Sat Nov 10 17:28:56 2018 +1000
Committer: Paul King <pa...@asert.com.au>
Committed: Sat Nov 10 20:39:48 2018 +1000
----------------------------------------------------------------------
.../codehaus/groovy/ast/tools/GeneralUtils.java | 4 +
.../groovy/groovy/ant/Groovy8872Test.groovy | 100 +++++++++++--------
2 files changed, 61 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/66c87071/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index a312b2f..f0b20e0 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -619,6 +619,10 @@ public class GeneralUtils {
return new BooleanExpression(new BinaryExpression(expr, EQ, new ConstantExpression(0)));
}
+ public static ListExpression listX(List<Expression> args) {
+ return new ListExpression(args);
+ }
+
public static ListExpression list2args(List args) {
ListExpression result = new ListExpression();
for (Object o : args) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/66c87071/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
index 1cd46e7..e43714a 100644
--- a/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
+++ b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
@@ -18,26 +18,19 @@
*/
package groovy.ant
-class Groovy8669Test extends AntTestCase {
- private scriptAllOnPath = '''
- def anno = AnnotatedClass.annotations[0]
- def type = anno.annotationType()
- assert type.name == 'MyAnnotation'
- assert type.getDeclaredMethod('value').invoke(anno).name == 'ValueClass'
- '''
-
- private scriptNoValueClass = '''
- // using annotations will cause ValueClass not to be found
- // but should still be able to use the class otherwise
- assert AnnotatedClass.name.size() == 14
- '''
+class Groovy8872Test extends AntTestCase {
+ private scriptParamNameCheck = '''
+ @ExtractParamNames
+ abstract class DummyClass implements JavaInterface, GroovyInterface {}
- private scriptNoAnnotationOnPath = '''
- // class should be usable but won't have annotations
- assert !AnnotatedClass.annotations
+ def paramNames = DummyClass.paramNames
+ assert paramNames == [
+ ['name', 'dob', 'vip'],
+ ['id', 'eventName', 'dateOfEvent']
+ ]
'''
- void testCreateZip() {
+ void testParameterNamesSeenInAST() {
// def debugLogger = new org.apache.tools.ant.DefaultLogger()
// debugLogger.setMessageOutputLevel(4)
// debugLogger.setOutputPrintStream(System.out)
@@ -45,43 +38,64 @@ class Groovy8669Test extends AntTestCase {
doInTmpDir { ant, baseDir ->
baseDir.src {
- 'ValueClass.java'('''
- public class ValueClass{ }
+ 'JavaInterface.java'('''
+ import java.util.Date;
+
+ public interface JavaInterface {
+ void addPerson(String name, Date dob, boolean vip);
+ }
+ ''')
+ 'GroovyInterface.groovy'('''
+ interface GroovyInterface {
+ void addEvent(int id, String eventName, Date dateOfEvent)
+ }
''')
- 'MyAnnotation.java'('''
- import java.lang.annotation.*;
+ 'ExtractParamNames.groovy'('''
+ import org.codehaus.groovy.transform.GroovyASTTransformationClass
+ import java.lang.annotation.*
+ /**
+ * Test transform adds a static method to a class that returns a map from the name
+ * for each found method to its parameter names.
+ */
+ @java.lang.annotation.Documented
+ @Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MyAnnotation {
- Class<ValueClass> value();
- }
+ @GroovyASTTransformationClass("ExtractParamNamesTransformation")
+ @interface ExtractParamNames { }
''')
- 'AnnotatedClass.java'('''
- @MyAnnotation(ValueClass.class)
- class AnnotatedClass { }
+ 'ExtractParamNamesTransformation.groovy'('''
+ import org.codehaus.groovy.ast.*
+ import org.codehaus.groovy.ast.expr.*
+ import org.codehaus.groovy.ast.stmt.*
+ import org.codehaus.groovy.transform.*
+ import org.codehaus.groovy.control.*
+ import static org.codehaus.groovy.ast.tools.GeneralUtils.*
+
+ @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
+ class ExtractParamNamesTransformation extends AbstractASTTransformation {
+ void visit(ASTNode[] nodes, SourceUnit source) {
+ init(nodes, source)
+ def classNode = nodes[1]
+ assert classNode instanceof ClassNode
+ def result = listX(classNode.abstractMethods.collect{ list2args(it.parameters.name) })
+ classNode.addField(new FieldNode("paramNames", ACC_PUBLIC+ACC_STATIC+ACC_FINAL,
+ ClassHelper.LIST_TYPE.plainNodeReference, classNode, result))
+ }
+ }
''')
}
// ant.project.addBuildListener(debugLogger)
ant.mkdir(dir: 'build')
ant.javac(classpath: '.', destdir: 'build', srcdir: 'src',
- includes: '*.java', includeantruntime: 'false', fork: 'true')
- ['ValueClass', 'MyAnnotation', 'AnnotatedClass'].each { name ->
- ant.mkdir(dir: "build$name")
- ant.copy(file: "build/${name}.class", todir: "build$name")
+ includes: '*.java', includeantruntime: 'false', fork: 'true') {
+ compilerarg(value: '-parameters')
}
+ ant.taskdef(name: 'groovyc', classname: 'org.codehaus.groovy.ant.Groovyc')
+ ant.groovyc(srcdir: 'src', destdir: 'build', parameters: 'true')
ant.taskdef(name: 'groovy', classname: 'org.codehaus.groovy.ant.Groovy')
- ant.groovy(scriptAllOnPath) {
- classpath { pathelement(path: 'buildValueClass') }
- classpath { pathelement(path: 'buildMyAnnotation') }
- classpath { pathelement(path: 'buildAnnotatedClass') }
- }
- ant.groovy(scriptNoValueClass) {
- classpath { pathelement(path: 'buildMyAnnotation') }
- classpath { pathelement(path: 'buildAnnotatedClass') }
- }
- ant.groovy(scriptNoAnnotationOnPath) {
- classpath { pathelement(path: 'buildAnnotatedClass') }
+ ant.groovy(scriptParamNameCheck) {
+ classpath { pathelement(path: 'build') }
}
}
}
[3/3] groovy git commit: GROOVY-8872: Populate the parameter names
from the byte code when available (convert test artifact from list to map)
Posted by pa...@apache.org.
GROOVY-8872: Populate the parameter names from the byte code when available (convert test artifact from list to map)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/eb3494ef
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/eb3494ef
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/eb3494ef
Branch: refs/heads/GROOVY_2_5_X
Commit: eb3494ef73b795288f42efc628771703e5085ca5
Parents: 66c8707
Author: Paul King <pa...@asert.com.au>
Authored: Sat Nov 10 20:10:30 2018 +1000
Committer: Paul King <pa...@asert.com.au>
Committed: Sat Nov 10 20:41:09 2018 +1000
----------------------------------------------------------------------
.../codehaus/groovy/ast/tools/GeneralUtils.java | 10 ++++++++++
.../test/groovy/groovy/ant/Groovy8872Test.groovy | 19 +++++++++----------
2 files changed, 19 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/eb3494ef/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index f0b20e0..d9abc76 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -43,6 +43,8 @@ import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.FieldExpression;
import org.codehaus.groovy.ast.expr.ListExpression;
+import org.codehaus.groovy.ast.expr.MapEntryExpression;
+import org.codehaus.groovy.ast.expr.MapExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.NotExpression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
@@ -649,6 +651,14 @@ public class GeneralUtils {
return new BinaryExpression(lhv, LT, rhv);
}
+ public static MapExpression mapX(List<MapEntryExpression> expressions) {
+ return new MapExpression(expressions);
+ }
+
+ public static MapEntryExpression entryX(Expression key, Expression value) {
+ return new MapEntryExpression(key, value);
+ }
+
/**
* @deprecated use MethodNodeUtils#methodDescriptorWithoutReturnType(MethodNode) instead
*/
http://git-wip-us.apache.org/repos/asf/groovy/blob/eb3494ef/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
index e43714a..7e5db65 100644
--- a/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
+++ b/subprojects/groovy-ant/src/test/groovy/groovy/ant/Groovy8872Test.groovy
@@ -23,11 +23,8 @@ class Groovy8872Test extends AntTestCase {
@ExtractParamNames
abstract class DummyClass implements JavaInterface, GroovyInterface {}
- def paramNames = DummyClass.paramNames
- assert paramNames == [
- ['name', 'dob', 'vip'],
- ['id', 'eventName', 'dateOfEvent']
- ]
+ assert DummyClass.paramNames.addPerson == ['name', 'dob', 'vip']
+ assert DummyClass.paramNames.addEvent == ['id', 'eventName', 'dateOfEvent']
'''
void testParameterNamesSeenInAST() {
@@ -55,8 +52,8 @@ class Groovy8872Test extends AntTestCase {
import java.lang.annotation.*
/**
- * Test transform adds a static method to a class that returns a map from the name
- * for each found method to its parameter names.
+ * Test transform adds a static field to a class that returns a map
+ * from the name for each found method to its parameter names.
*/
@java.lang.annotation.Documented
@Retention(RetentionPolicy.SOURCE)
@@ -78,9 +75,11 @@ class Groovy8872Test extends AntTestCase {
init(nodes, source)
def classNode = nodes[1]
assert classNode instanceof ClassNode
- def result = listX(classNode.abstractMethods.collect{ list2args(it.parameters.name) })
- classNode.addField(new FieldNode("paramNames", ACC_PUBLIC+ACC_STATIC+ACC_FINAL,
- ClassHelper.LIST_TYPE.plainNodeReference, classNode, result))
+ def result = mapX(classNode.allDeclaredMethods.collect{
+ entryX(constX(it.name), list2args(it.parameters.name))
+ })
+ classNode.addField(new FieldNode("paramNames", ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
+ ClassHelper.MAP_TYPE.plainNodeReference, classNode, result))
}
}
''')