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:09 UTC
[1/2] groovy git commit: GROOVY-8872: Populate the parameter names
from the byte code when available (closes #820)
Repository: groovy
Updated Branches:
refs/heads/master 603d6e711 -> 2193eaf8c
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/e1d5c7b6
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/e1d5c7b6
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/e1d5c7b6
Branch: refs/heads/master
Commit: e1d5c7b6de5ea24d0cea3fbebba18cabd0292a12
Parents: 603d6e7
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 17:26:27 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/e1d5c7b6/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/e1d5c7b6/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/e1d5c7b6/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/e1d5c7b6/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/2] 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/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') }
}
}
}