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 07:29:10 UTC
[2/2] groovy git commit: GROOVY-8872: Populate the parameter names
from the byte code when available (add test)
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/2193eaf8
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/2193eaf8
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/2193eaf8
Branch: refs/heads/master
Commit: 2193eaf8cc454d0d6e38fa02d32271a24d6b43da
Parents: e1d5c7b
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 17:28:56 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/2193eaf8/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 2e6ebea..06755ee 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -622,6 +622,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/2193eaf8/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') }
}
}
}