You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/11/14 19:29:01 UTC
[groovy] branch master updated: improve `getText()` and `toString()` of method and closure
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new cf2f77f improve `getText()` and `toString()` of method and closure
cf2f77f is described below
commit cf2f77fb033a10d36c4db3a7ff07a2b04631afcf
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Nov 14 13:11:01 2021 -0600
improve `getText()` and `toString()` of method and closure
---
.../apache/groovy/ast/tools/MethodNodeUtils.java | 11 +--
.../org/codehaus/groovy/ast/AstToTextHelper.java | 81 ++++++++++------------
.../java/org/codehaus/groovy/ast/MethodNode.java | 31 +++++----
.../groovy/ast/expr/ClosureExpression.java | 53 +++++++-------
.../org/codehaus/groovy/ast/MethodNodeTest.groovy | 73 ++++++++++---------
.../groovy/ast/expr/ClosureExpressionTest.groovy | 38 ++++++----
.../{Groovy6650Bug.groovy => Groovy6650.groovy} | 43 ++++++------
7 files changed, 175 insertions(+), 155 deletions(-)
diff --git a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
index 5b4b346..00b639d 100644
--- a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
@@ -59,17 +59,18 @@ public class MethodNodeUtils {
* @return the method node's descriptor
*/
public static String methodDescriptor(final MethodNode mNode) {
- StringBuilder sb = new StringBuilder(mNode.getName().length() + mNode.getParameters().length * 10);
+ Parameter[] parameters = mNode.getParameters();
+ int nParameters = parameters == null ? 0 : parameters.length;
+ StringBuilder sb = new StringBuilder(mNode.getName().length() * 2 + nParameters * 10);
sb.append(mNode.getReturnType().getName());
sb.append(' ');
sb.append(mNode.getName());
sb.append('(');
- for (int i = 0; i < mNode.getParameters().length; i++) {
+ for (int i = 0; i < nParameters; i += 1) {
if (i > 0) {
sb.append(", ");
}
- Parameter p = mNode.getParameters()[i];
- sb.append(ClassNodeUtils.formatTypeName(p.getType()));
+ sb.append(parameters[i].getType().getName());
}
sb.append(')');
return sb.toString();
@@ -140,7 +141,7 @@ public class MethodNodeUtils {
public static boolean isGetterCandidate(MethodNode m) {
Parameter[] parameters = m.getParameters();
return m.isPublic() && !m.isStatic() && !m.isAbstract()
- && (null == parameters || 0 == parameters.length)
+ && (parameters == null || parameters.length == 0)
&& !ClassHelper.VOID_TYPE.equals(m.getReturnType());
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/AstToTextHelper.java b/src/main/java/org/codehaus/groovy/ast/AstToTextHelper.java
index 80dde3f..601166f 100644
--- a/src/main/java/org/codehaus/groovy/ast/AstToTextHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/AstToTextHelper.java
@@ -19,92 +19,85 @@
package org.codehaus.groovy.ast;
import java.lang.reflect.Modifier;
+import java.util.StringJoiner;
/**
* Helper class for converting AST into text.
*/
public class AstToTextHelper {
- public static String getClassText(ClassNode node) {
+ public static String getClassText(final ClassNode node) {
if (node == null) return "<unknown>";
- if (node.getName() == null) return "<unknown>";
- return node.getName();
+ return node.toString(false);
}
- public static String getParameterText(Parameter node) {
+ public static String getParameterText(final Parameter node) {
if (node == null) return "<unknown>";
- String name = node.getName() == null ? "<unknown>" : node.getName();
+ String name = node.getName();
+ if (name == null) name = "<unknown>";
String type = getClassText(node.getType());
- if (node.getInitialExpression() != null) {
- return type + " " + name + " = " + node.getInitialExpression().getText();
+
+ String text = type + " " + name;
+ if (node.hasInitialExpression()) {
+ text += " = " + node.getInitialExpression().getText();
}
- return type + " " + name;
+ return text;
}
- public static String getParametersText(Parameter[] parameters) {
- if (parameters == null) return "";
- if (parameters.length == 0) return "";
- StringBuilder result = new StringBuilder();
- int max = parameters.length;
- for (int x = 0; x < max; x++) {
- result.append(getParameterText(parameters[x]));
- if (x < (max - 1)) {
- result.append(", ");
- }
+ public static String getParametersText(final Parameter[] parameters) {
+ if (parameters == null || parameters.length == 0) return "";
+ StringJoiner result = new StringJoiner(", ");
+ for (Parameter parameter : parameters) {
+ result.add(getParameterText(parameter));
}
return result.toString();
}
- public static String getThrowsClauseText(ClassNode[] exceptions) {
- if (exceptions == null) return "";
- if (exceptions.length == 0) return "";
- StringBuilder result = new StringBuilder("throws ");
- int max = exceptions.length;
- for (int x = 0; x < max; x++) {
- result.append(getClassText(exceptions[x]));
- if (x < (max - 1)) {
- result.append(", ");
- }
+ public static String getThrowsClauseText(final ClassNode[] exceptions) {
+ if (exceptions == null || exceptions.length == 0) return "";
+ StringJoiner result = new StringJoiner(", ");
+ for (ClassNode exception : exceptions) {
+ result.add(getClassText(exception));
}
- return result.toString();
+ return " throws " + result.toString();
}
- public static String getModifiersText(int modifiers) {
- StringBuilder result = new StringBuilder();
+ public static String getModifiersText(final int modifiers) {
+ StringJoiner result = new StringJoiner(" ");
if (Modifier.isPrivate(modifiers)) {
- result.append("private ");
+ result.add("private");
}
if (Modifier.isProtected(modifiers)) {
- result.append("protected ");
+ result.add("protected");
}
if (Modifier.isPublic(modifiers)) {
- result.append("public ");
+ result.add("public");
}
if (Modifier.isStatic(modifiers)) {
- result.append("static ");
+ result.add("static");
}
if (Modifier.isAbstract(modifiers)) {
- result.append("abstract ");
+ result.add("abstract");
}
if (Modifier.isFinal(modifiers)) {
- result.append("final ");
+ result.add("final");
}
if (Modifier.isInterface(modifiers)) {
- result.append("interface ");
+ result.add("interface");
}
if (Modifier.isNative(modifiers)) {
- result.append("native ");
+ result.add("native");
}
if (Modifier.isSynchronized(modifiers)) {
- result.append("synchronized ");
+ result.add("synchronized");
}
if (Modifier.isTransient(modifiers)) {
- result.append("transient ");
+ result.add("transient");
}
if (Modifier.isVolatile(modifiers)) {
- result.append("volatile ");
+ result.add("volatile");
}
- return result.toString().trim();
+ return result.toString();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/codehaus/groovy/ast/MethodNode.java b/src/main/java/org/codehaus/groovy/ast/MethodNode.java
index af4a26e..844dede 100644
--- a/src/main/java/org/codehaus/groovy/ast/MethodNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/MethodNode.java
@@ -18,7 +18,6 @@
*/
package org.codehaus.groovy.ast;
-import org.apache.groovy.ast.tools.MethodNodeUtils;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.Statement;
@@ -26,6 +25,9 @@ import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Optional;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.formatTypeName;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptor;
+import static org.codehaus.groovy.ast.tools.GenericsUtils.toGenericTypesString;
import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
@@ -79,7 +81,7 @@ public class MethodNode extends AnnotatedNode {
*/
public String getTypeDescriptor() {
if (typeDescriptor == null) {
- typeDescriptor = MethodNodeUtils.methodDescriptor(this);
+ typeDescriptor = methodDescriptor(this);
}
return typeDescriptor;
}
@@ -276,23 +278,26 @@ public class MethodNode extends AnnotatedNode {
this.syntheticPublic = syntheticPublic;
}
- /**
- * Provides a nicely formatted string of the method definition. For simplicity, generic types on some of the elements
- * are not displayed.
- *
- * @return string form of node with some generic elements suppressed
- */
@Override
public String getText() {
- String retType = AstToTextHelper.getClassText(returnType);
- String exceptionTypes = AstToTextHelper.getThrowsClauseText(exceptions);
- String params = AstToTextHelper.getParametersText(parameters);
int mask = this instanceof ConstructorNode ? Modifier.constructorModifiers() : Modifier.methodModifiers();
- return AstToTextHelper.getModifiersText(modifiers & mask) + " " + retType + " " + name + "(" + params + ") " + exceptionTypes + " { ... }";
+ return new StringBuilder(AstToTextHelper.getModifiersText(getModifiers() & mask))
+ .append(' ')
+ .append(toGenericTypesString(getGenericsTypes()))
+ .append(AstToTextHelper.getClassText(getReturnType()))
+ .append(' ')
+ .append(getName())
+ .append('(')
+ .append(AstToTextHelper.getParametersText(getParameters()))
+ .append(')')
+ .append(AstToTextHelper.getThrowsClauseText(getExceptions()))
+ .append(" { ... }")
+ .toString();
}
@Override
public String toString() {
- return super.toString() + "[" + getDeclaringClass().getName() + "#" + getTypeDescriptor() + "]";
+ ClassNode declaringClass = getDeclaringClass();
+ return super.toString() + "[" + getTypeDescriptor() + (declaringClass == null ? "" : " from " + formatTypeName(declaringClass)) + "]";
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
index d47d07a..00842b4 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
@@ -18,13 +18,14 @@
*/
package org.codehaus.groovy.ast.expr;
-import org.codehaus.groovy.ast.AstToTextHelper;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.GroovyCodeVisitor;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.VariableScope;
import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.runtime.InvokerHelper;
+
+import static org.codehaus.groovy.ast.AstToTextHelper.getParametersText;
+import static org.codehaus.groovy.ast.tools.ClosureUtils.hasImplicitParameter;
/**
* Represents a closure expression such as <pre>{ statement }</pre>
@@ -36,27 +37,12 @@ public class ClosureExpression extends Expression {
private Statement code;
private VariableScope variableScope;
- public ClosureExpression(Parameter[] parameters, Statement code) {
+ public ClosureExpression(final Parameter[] parameters, final Statement code) {
this.parameters = parameters;
this.code = code;
setType(ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
}
- @Override
- public void visit(GroovyCodeVisitor visitor) {
- visitor.visitClosureExpression(this);
- }
-
- @Override
- public Expression transformExpression(ExpressionTransformer transformer) {
- return this;
- }
-
- @Override
- public String toString() {
- return super.toString() + InvokerHelper.toString(parameters) + "{ " + code + " }";
- }
-
/**
* This gets the code statement of the closure. You can read this method to find out what actions
* the closure is going to perform.
@@ -73,7 +59,7 @@ public class ClosureExpression extends Expression {
*
* @param code the new Statement
*/
- public void setCode(Statement code) {
+ public void setCode(final Statement code) {
this.code = code;
}
@@ -95,17 +81,32 @@ public class ClosureExpression extends Expression {
return variableScope;
}
- public void setVariableScope(VariableScope variableScope) {
+ public void setVariableScope(final VariableScope variableScope) {
this.variableScope = variableScope;
}
@Override
public String getText() {
- String paramText = AstToTextHelper.getParametersText(parameters);
- if (paramText.length() > 0) {
- return "{ " + paramText + " -> ... }";
- } else {
- return "{ -> ... }";
- }
+ return toString("...");
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + this.toString(code == null ? "<null>" : code.toString());
+ }
+
+ private String toString(final String bodyText) {
+ if (hasImplicitParameter(this)) return "{ " + bodyText + " }";
+ return "{ " + getParametersText(parameters) + " -> " + bodyText + " }";
+ }
+
+ @Override
+ public Expression transformExpression(final ExpressionTransformer transformer) {
+ return this;
+ }
+
+ @Override
+ public void visit(final GroovyCodeVisitor visitor) {
+ visitor.visitClosureExpression(this);
}
}
diff --git a/src/test/org/codehaus/groovy/ast/MethodNodeTest.groovy b/src/test/org/codehaus/groovy/ast/MethodNodeTest.groovy
index 0abbbab..d7bbade 100644
--- a/src/test/org/codehaus/groovy/ast/MethodNodeTest.groovy
+++ b/src/test/org/codehaus/groovy/ast/MethodNodeTest.groovy
@@ -19,55 +19,64 @@
package org.codehaus.groovy.ast
import org.codehaus.groovy.ast.builder.AstBuilder
-import org.codehaus.groovy.ast.stmt.BlockStatement
-import org.objectweb.asm.Opcodes
-
-import junit.framework.TestCase
import org.codehaus.groovy.control.CompilePhase
+import org.junit.Test
-/**
- * Tests the VariableExpressionNode
- */
-class MethodNodeTest extends TestCase implements Opcodes {
+final class MethodNodeTest {
- void testGetTextSimple() {
- def ast = new AstBuilder().buildFromString CompilePhase.SEMANTIC_ANALYSIS, false, '''
+ private static ClassNode fromString(String source) {
+ new AstBuilder().buildFromString(CompilePhase.SEMANTIC_ANALYSIS, false, source)[1]
+ }
- def myMethod() {
- }
-'''
- assert ast[1].@methods.get('myMethod')[0].text ==
- 'public java.lang.Object myMethod() { ... }'
+ @Test
+ void testGetText1() {
+ String result = fromString('def method(){}').getMethod('method').text
+ assert result == 'public java.lang.Object method() { ... }'
+ }
+
+ @Test
+ void testGetText2() {
+ def script = fromString '''
+ private static final <T extends Number> T method(String p1, int p2 = 1) throws Exception, IOException { }
+ '''
+ String result = script.getMethods('method')[0].text
+ assert result == 'private static final <T extends java.lang.Number> T method(java.lang.String p1, int p2 = 1) throws java.lang.Exception, java.io.IOException { ... }'
}
- void testGetTextAdvanced() {
- def ast = new AstBuilder().buildFromString CompilePhase.SEMANTIC_ANALYSIS, false, '''
+ @Test
+ void testToString() {
+ String result = new MethodNode('foo', 0, null, null, null, null)
+ assert result.endsWith('[java.lang.Object foo()]')
- private static final <T> T myMethod(String p1, int p2 = 1) throws Exception, IOException {
+ Parameter[] params = [new Parameter(ClassHelper.int_TYPE, 'i'), new Parameter(ClassHelper.int_TYPE.makeArray(), 'j')]
+ result = new MethodNode('foo', 0, ClassHelper.STRING_TYPE.makeArray(), params, null, null).tap {
+ declaringClass = ClassHelper.OBJECT_TYPE
}
-'''
- assert ast[1].@methods.get('myMethod')[0].text ==
- 'private static final java.lang.Object myMethod(java.lang.String p1, int p2 = 1) throws java.lang.Exception, java.io.IOException { ... }'
+ assert result.endsWith('[Ljava.lang.String; foo(int, [I) from java.lang.Object]')
}
- void testIsDynamicReturnTypeExplicitObject() {
- def methodNode = new MethodNode('foo', ACC_PUBLIC, new ClassNode(Object.class), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement())
- assert !methodNode.isDynamicReturnType()
+ @Test
+ void testIsDynamicReturnType1() {
+ def methodNode = new MethodNode('foo', 0, ClassHelper.dynamicType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)
+ assert methodNode.isDynamicReturnType()
}
- void testIsDynamicReturnTypeDYNAMIC_TYPE() {
- MethodNode methodNode = new MethodNode('foo', ACC_PUBLIC, ClassHelper.dynamicType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement())
- assert methodNode.isDynamicReturnType()
+ @Test
+ void testIsDynamicReturnType2() {
+ def methodNode = new MethodNode('foo', 0, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)
+ assert !methodNode.isDynamicReturnType()
}
- void testIsDynamicReturnTypeVoid() {
- MethodNode methodNode = new MethodNode('foo', ACC_PUBLIC, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement())
+ @Test
+ void testIsDynamicReturnType3() {
+ def methodNode = new MethodNode('foo', 0, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)
assert !methodNode.isDynamicReturnType()
}
- void testIsDynamicReturnTypeNull() {
- MethodNode methodNode = new MethodNode('foo', ACC_PUBLIC, null, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement())
+ @Test
+ void testIsDynamicReturnType4() {
+ def methodNode = new MethodNode('foo', 0, null, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)
assert !methodNode.isDynamicReturnType()
- assertNotNull(methodNode.getReturnType())
+ assert methodNode.returnType != null
}
}
diff --git a/src/test/org/codehaus/groovy/ast/expr/ClosureExpressionTest.groovy b/src/test/org/codehaus/groovy/ast/expr/ClosureExpressionTest.groovy
index ba3a8d5..17efbea 100644
--- a/src/test/org/codehaus/groovy/ast/expr/ClosureExpressionTest.groovy
+++ b/src/test/org/codehaus/groovy/ast/expr/ClosureExpressionTest.groovy
@@ -18,38 +18,50 @@
*/
package org.codehaus.groovy.ast.expr
-import groovy.test.GroovyTestCase
import org.codehaus.groovy.ast.builder.AstBuilder
+import org.codehaus.groovy.control.CompilePhase
+import org.junit.Test
-class ClosureExpressionTest extends GroovyTestCase {
+final class ClosureExpressionTest {
+ private static Expression fromString(String source) {
+ List nodes = new AstBuilder().buildFromString(CompilePhase.SEMANTIC_ANALYSIS, source)
+ nodes[0].statements[0].expression
+ }
+
+ @Test
void testGetText_Simple() {
- def expression = buildFromString 'return { it * it }'
- assert expression.text == '{ -> ... }'
+ def expression = fromString 'return { it * it }'
+ assert expression.text == '{ ... }'
}
+ @Test
void testGetText_Parameter() {
- def expression = buildFromString 'return { x -> x * x }'
+ def expression = fromString 'return { x -> x * x }'
assert expression.text == '{ java.lang.Object x -> ... }'
}
- void testGetText_MultipleParameters() {
- def expression = buildFromString 'return { x, y -> x * y }'
+ @Test
+ void testGetText_Parameters() {
+ def expression = fromString 'return { x, y -> x * y }'
assert expression.text == '{ java.lang.Object x, java.lang.Object y -> ... }'
}
+ @Test
void testGetText_TypedParameter() {
- def expression = buildFromString 'return { String x -> x * x }'
+ def expression = fromString 'return { String x -> x * x }'
assert expression.text == '{ java.lang.String x -> ... }'
}
- void testGetText_MultipleTypedParameters() {
- def expression = buildFromString 'return { String x, Integer y -> x * y }'
+ @Test
+ void testGetText_TypedParameters() {
+ def expression = fromString 'return { String x, Integer y -> x * y }'
assert expression.text == '{ java.lang.String x, java.lang.Integer y -> ... }'
}
- private Expression buildFromString(String source) {
- def ast = new AstBuilder().buildFromString(source)
- ast[0].statements[0].expression
+ @Test
+ void testGetText_ParameterizedType() {
+ def expression = fromString 'return { List<String> x -> }'
+ assert expression.text == '{ java.util.List<java.lang.String> x -> ... }'
}
}
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650.groovy
similarity index 51%
rename from src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650Bug.groovy
rename to src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650.groovy
index 4e08e40..7b9e3c1 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650Bug.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6650.groovy
@@ -22,33 +22,32 @@ package org.codehaus.groovy.classgen.asm.sc.bugs
import groovy.transform.stc.StaticTypeCheckingTestCase
import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
-class Groovy6650Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
- void testShouldChooseVargsMethod() {
- assertScript '''import org.codehaus.groovy.transform.stc.ExtensionMethodNode
+final class Groovy6650 extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
-def x = 'a,b,c'.split(',')
-def y = 'd,e,f'.split(',')
+ void testShouldChooseVargsMethod() {
+ assertScript '''
+ import org.codehaus.groovy.ast.MethodNode
-@ASTTest(phase=INSTRUCTION_SELECTION,value={
- def call = node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
- assert call instanceof ExtensionMethodNode
- def emn = call.extensionMethodNode
- def typeDesc = emn.typeDescriptor
- assert typeDesc == '[Ljava.lang.Object; plus(java.lang.Object[], java.lang.Object[])'
- println emn.typeDescriptor
-})
-String[] result = x + y
-assert result as List == ['a', 'b', 'c', 'd', 'e', 'f']
-'''
+ def x = 'a,b,c'.split(',')
+ def y = 'd,e,f'.split(',')
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ MethodNode target = node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+ assert target instanceof org.codehaus.groovy.transform.stc.ExtensionMethodNode
+ assert target.parameters[0].type == OBJECT_TYPE.makeArray()
+ })
+ String[] result = x + y
+ assert result.toList() == ['a','b','c','d','e','f']
+ '''
}
void testShouldNotThrowAmbiguousSelectionError() {
- assertScript '''import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.MethodNode
+ assertScript '''
+ import org.codehaus.groovy.ast.ClassNode
+ import org.codehaus.groovy.ast.MethodNode
-MethodNode methodNode = null
-ClassNode annotation = null
-List annots = methodNode?.getAnnotations(annotation)
-return (annots != null && annots.size() > 0);'''
+ MethodNode methodNode = null; ClassNode annotation = null
+ List annos = methodNode?.getAnnotations(annotation)
+ return (annos != null && !annos.isEmpty())
+ '''
}
}