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 2016/10/12 10:36:08 UTC
groovy git commit: GROOVY-7967: AstNodeToScriptAdapter should output
source using the recommended modifier order (closes #447)
Repository: groovy
Updated Branches:
refs/heads/master 4ea1207f2 -> 4bca3fea6
GROOVY-7967: AstNodeToScriptAdapter should output source using the recommended modifier order (closes #447)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/4bca3fea
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/4bca3fea
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/4bca3fea
Branch: refs/heads/master
Commit: 4bca3fea67b9ed575725fa850c4f91884747cb61
Parents: 4ea1207
Author: paulk <pa...@asert.com.au>
Authored: Tue Oct 11 20:50:48 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Oct 12 20:34:44 2016 +1000
----------------------------------------------------------------------
.../swingui/AstNodeToScriptAdapter.groovy | 83 ++++--------
.../swingui/AstNodeToScriptAdapterTest.groovy | 133 +++++++++++--------
2 files changed, 100 insertions(+), 116 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/4bca3fea/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstNodeToScriptAdapter.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstNodeToScriptAdapter.groovy b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstNodeToScriptAdapter.groovy
index 533abb4..083adcf 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstNodeToScriptAdapter.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstNodeToScriptAdapter.groovy
@@ -18,7 +18,6 @@
*/
package groovy.inspect.swingui
-
import org.codehaus.groovy.ast.*
import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.ast.stmt.*
@@ -37,10 +36,8 @@ import org.codehaus.groovy.classgen.Verifier
* This class takes Groovy source code, compiles it to a specific compile phase, and then decompiles it
* back to the groovy source. It is used by GroovyConsole's AST Browser, but can also be invoked from
* the command line.
- *
- * @author Hamlet D'Arcy
*/
-class AstNodeToScriptAdapter {
+class AstNodeToScriptAdapter {
/**
* Run this class as a script to compile a groovy file and print out the resulting source.
@@ -68,20 +65,21 @@ and [compilephase] is a valid Integer based org.codehaus.groovy.control.CompileP
}
/**
- * This method takes source code, compiles it, then reverses it back to source.
- * @param script
- * the source code to be compiled. If invalid, a compile error occurs
- * @param compilePhase
- * the CompilePhase. Must be an int mapped in {@link CompilePhase}
- * @param classLoader
- * (optional) the classloader to use. If missing/null then the current is used.
- * This parameter enables things like ASTBrowser to invoke this with the correct classpath
- * @param showScriptFreeForm
- * Whether or not to show the script portion of the source code
- * @param showScriptClass
- * Whether or not to show the Script class from the source code
- * @returns the source code from the AST state
- */
+ * This method takes source code, compiles it, then reverses it back to source.
+ *
+ * @param script
+ * the source code to be compiled. If invalid, a compile error occurs
+ * @param compilePhase
+ * the CompilePhase. Must be an int mapped in {@link CompilePhase}
+ * @param classLoader
+ * (optional) the classloader to use. If missing/null then the current is used.
+ * This parameter enables things like ASTBrowser to invoke this with the correct classpath
+ * @param showScriptFreeForm
+ * Whether or not to show the script portion of the source code
+ * @param showScriptClass
+ * Whether or not to show the Script class from the source code
+ * @returns the source code from the AST state
+ */
String compileToScript(String script, int compilePhase, ClassLoader classLoader = null, boolean showScriptFreeForm = true, boolean showScriptClass = true) {
def writer = new StringWriter()
@@ -113,8 +111,6 @@ and [compilephase] is a valid Integer based org.codehaus.groovy.control.CompileP
/**
* An adapter from ASTNode tree to source code.
- *
- * @author Hamlet D'Arcy
*/
class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements GroovyCodeVisitor, GroovyClassVisitor {
@@ -267,7 +263,8 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
}
visitModifiers(node.modifiers)
- print "class $node.name"
+ if (node.isInterface()) print node.name
+ else print "class $node.name"
visitGenerics node?.genericsTypes
boolean first = true
node.unresolvedInterfaces?.each {
@@ -402,40 +399,10 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
printDoubleBreak()
}
- private def visitModifiers(int modifiers) {
- if (Modifier.isAbstract(modifiers)) {
- print 'abstract '
- }
- if (Modifier.isFinal(modifiers)) {
- print 'final '
- }
- if (Modifier.isInterface(modifiers)) {
- print 'interface '
- }
- if (Modifier.isNative(modifiers)) {
- print 'native '
- }
- if (Modifier.isPrivate(modifiers)) {
- print 'private '
- }
- if (Modifier.isProtected(modifiers)) {
- print 'protected '
- }
- if (Modifier.isPublic(modifiers)) {
- print 'public '
- }
- if (Modifier.isStatic(modifiers)) {
- print 'static '
- }
- if (Modifier.isSynchronized(modifiers)) {
- print 'synchronized '
- }
- if (Modifier.isTransient(modifiers)) {
- print 'transient '
- }
- if (Modifier.isVolatile(modifiers)) {
- print 'volatile '
- }
+ private void visitModifiers(int modifiers) {
+ String mods = Modifier.toString(modifiers)
+ mods = mods ? mods + ' ' : mods
+ print mods
}
@Override
@@ -458,7 +425,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
// GROOVY-5150: final constants may be initialized directly
print ' = '
if (ClassHelper.STRING_TYPE == type) {
- print "'"+node.initialValueExpression.text.replaceAll("'", "\\\\'")+"'"
+ print "'" + node.initialValueExpression.text.replaceAll("'", "\\\\'") + "'"
} else if (ClassHelper.char_TYPE == type) {
print "'${node.initialValueExpression.text}'"
} else {
@@ -635,7 +602,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
if (expression?.arguments instanceof VariableExpression || expression?.arguments instanceof MethodCallExpression) {
print '('
expression?.arguments?.visit this
- print ')'
+ print ')'
} else {
expression?.arguments?.visit this
}
@@ -825,7 +792,6 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
/**
* Prints out the type, safely handling arrays.
* @param classNode
- * classnode
*/
void visitType(ClassNode classNode) {
def name = classNode.name
@@ -866,7 +832,6 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
}
-
@Override
void visitMapExpression(MapExpression expression) {
print '['
http://git-wip-us.apache.org/repos/asf/groovy/blob/4bca3fea/subprojects/groovy-console/src/test/groovy/groovy/inspect/swingui/AstNodeToScriptAdapterTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/test/groovy/groovy/inspect/swingui/AstNodeToScriptAdapterTest.groovy b/subprojects/groovy-console/src/test/groovy/groovy/inspect/swingui/AstNodeToScriptAdapterTest.groovy
index dbb4967..48c0640 100644
--- a/subprojects/groovy-console/src/test/groovy/groovy/inspect/swingui/AstNodeToScriptAdapterTest.groovy
+++ b/subprojects/groovy-console/src/test/groovy/groovy/inspect/swingui/AstNodeToScriptAdapterTest.groovy
@@ -19,10 +19,15 @@
package groovy.inspect.swingui
import org.codehaus.groovy.ast.VariableScope
+import org.codehaus.groovy.ast.expr.BooleanExpression
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.ast.stmt.DoWhileStatement
import org.codehaus.groovy.control.CompilePhase
-import org.codehaus.groovy.ast.expr.*
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX
+import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt
/**
* Unit test for ScriptToTreeNodeAdapter.
@@ -30,8 +35,6 @@ import org.codehaus.groovy.ast.expr.*
* The assertions in this test case often assert against the toString() representation of
* an object. Normally, this is bad form. However, the class under test is meant to display
* toString() forms in a user interface. So in this case it is appropriate.
- *
- * @author Hamlet D'Arcy
*/
class AstNodeToScriptAdapterTest extends GroovyTestCase {
@@ -93,7 +96,7 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
assert result.contains('protected void method4()')
assert result.contains('public java.lang.Object method5(java.lang.Object parm1)')
assert result.contains('public static java.lang.Object method6(java.lang.String parm1)')
- assert result.contains('native public java.lang.Object method7(java.lang.Object parm1, final java.lang.Object parm2)')
+ assert result.contains('public native java.lang.Object method7(java.lang.Object parm1, final java.lang.Object parm2)')
assert result.contains('public synchronized java.lang.Object method8(java.lang.String parm1, final java.lang.String parm2)')
assert result.contains("public java.lang.Object method9(java.lang.String parm1 = this.getValue(), java.lang.String parm2 = 'somevalue')")
assert result.contains('public java.lang.Integer[] method10(java.lang.String[] parm1, java.lang.Object[] parm2)')
@@ -200,7 +203,7 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
String result = compileToScript(script, CompilePhase.CLASS_GENERATION)
assert result.contains('java.lang.String[] x = (([]) as java.lang.String[])')
- assert result.contains('final private java.lang.String[] arr')
+ assert result.contains('private final java.lang.String[] arr')
assert result.contains('arr = new java.lang.String[0]')
}
@@ -214,7 +217,7 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
String result = compileToScript(script, CompilePhase.CLASS_GENERATION)
assert result.contains('java.lang.String[][] x = (([]) as java.lang.String[][])')
assert result.contains('java.lang.String[][][] y = (([]) as java.lang.String[][][])')
- assert result.contains('final private java.lang.String[][] arr')
+ assert result.contains('private final java.lang.String[][] arr')
assert result.contains('arr = new java.lang.String[this.xSize(), 3]')
}
@@ -316,7 +319,7 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
}'''
String result = compileToScript(script, CompilePhase.CLASS_GENERATION)
- assert result.contains('final private static transient java.util.logging.Logger log')
+ assert result.contains('private static final transient java.util.logging.Logger log')
assert result.contains("log = java.util.logging.Logger.getLogger('Event')")
assert result.contains('return log.isLoggable(java.util.logging.Level.FINE) ? log.fine(this.someMethod()) : null')
}
@@ -442,7 +445,7 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
boolean p2() default false;
}
'''
-
+
String result = compileToScript(script)
assert result.contains('@java.lang.SuppressWarnings')
@@ -566,9 +569,9 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}'''
String result = compileToScript(script, CompilePhase.CLASS_GENERATION)
- assert result.contains('final private java.lang.String title')
- assert result.contains('final private java.util.Date when')
- assert result.contains('final private java.awt.Color color')
+ assert result.contains('private final java.lang.String title')
+ assert result.contains('private final java.util.Date when')
+ assert result.contains('private final java.awt.Color color')
// assert hashCode
assert result.contains('public int hashCode()')
@@ -582,15 +585,17 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
void testAnonymousInnerClass() {
- String script = '''new Object() {
- public String toString() { 'foo' }
- }'''
+ String script = '''
+ new Object() {
+ public String toString() { 'foo' }
+ }
+ '''
String result = compileToScript(script, CompilePhase.CANONICALIZATION)
assert result =~ /new script[0-9].*\$1/
assert result =~ /public class script[0-9].*\$1/
- assert result =~ /public java\.lang\.String toString()/
+ assert result =~ /public java\.lang\.String toString\(\)/
}
void testLazyAnnotation() {
@@ -651,14 +656,16 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
void testSuperAndThisCalls() {
- String script = '''class MyClass {
+ String script = '''
+ class MyClass {
MyClass() {
this('foo')
}
MyClass(foo) {
super(foo)
}
- }'''
+ }
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("this ('foo')")
@@ -710,9 +717,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testDoWhileLoop() {
def doWhile = new DoWhileStatement(
- new BooleanExpression(new ConstantExpression(true)),
+ new BooleanExpression(constX(true)),
new BlockStatement(
- [new MethodCallExpression(new VariableExpression('this'), 'println', new ArgumentListExpression(new ConstantExpression('value')))], new VariableScope()
+ [stmt(callThisX('println', args(constX('value'))))],
+ new VariableScope()
))
StringWriter writer = new StringWriter()
@@ -731,18 +739,20 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
void testMethodPointer() {
- String script = '''class Event {
- static def staticMethod(it) { it * it }
- def instanceMethod(it) { it / it }
- }
+ String script = '''
+ class Event {
+ static def staticMethod(it) { it * it }
+ def instanceMethod(it) { it / it }
+ }
- def m1 = Event.&'staticMethod'
- assert 25 == m1(5)
- def m2 = new Event().&'instanceMethod'
- assert 1 == m2(5)
- def e = new Event()
- def m3 = e.&'instanceMethod'
- assert 1 == m3(6) '''
+ def m1 = Event.&'staticMethod'
+ assert 25 == m1(5)
+ def m2 = new Event().&'instanceMethod'
+ assert 1 == m2(5)
+ def e = new Event()
+ def m3 = e.&'instanceMethod'
+ assert 1 == m3(6)
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("java.lang.Object m1 = Event.&'staticMethod'")
@@ -755,8 +765,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
void testAssertRegexExpression() {
- String script = ''' assert "abc.def" =~ /[a-z]b[a-z]\\.def/
- assert "cheesecheese" =~ "cheese" '''
+ String script = '''
+ assert "abc.def" =~ /[a-z]b[a-z]\\.def/
+ assert "cheesecheese" =~ "cheese"
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("assert 'abc.def' =~ '[a-z]b[a-z]\\.def' : null")
@@ -764,8 +776,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
}
void testArrayExpression() {
- String script = '''def x = [4, 5, 6] as String[]
- [1, 2, 3] << new Integer[x.length]'''
+ String script = '''
+ def x = [4, 5, 6] as String[]
+ [1, 2, 3] << new Integer[x.length]
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains('java.lang.Object x = (([4, 5, 6]) as java.lang.String[])')
assert result.contains('[1, 2, 3] << new java.lang.Integer[ x .length]')
@@ -773,9 +787,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadDot() {
String script = '''
- def x = [ ['a':11, 'b':12], ['a':21, 'b':22] ]
- assert x.a == [11, 21] //GPath notation
- assert x*.a == [11, 21] //spread dot notation '''
+ def x = [ ['a':11, 'b':12], ['a':21, 'b':22] ]
+ assert x.a == [11, 21] //GPath notation
+ assert x*.a == [11, 21] //spread dot notation
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("java.lang.Object x = [['a': 11, 'b': 12], ['a': 21, 'b': 22]]")
assert result.contains('assert x .a == [11, 21] : null')
@@ -784,9 +799,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadNotationNullHandling() {
String script = '''
- def x = [ ['a':11, 'b':12], ['a':21, 'b':22], null ]
- assert x*.a == [11, 21, null] //caters for null values
- assert x*.a == x.collect{ it?.a } //equivalent notation '''
+ def x = [ ['a':11, 'b':12], ['a':21, 'b':22], null ]
+ assert x*.a == [11, 21, null] //caters for null values
+ assert x*.a == x.collect{ it?.a } //equivalent notation
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("java.lang.Object x = [['a': 11, 'b': 12], ['a': 21, 'b': 22], null]")
@@ -798,10 +814,10 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadNotationAdvanced() {
String script = '''
- class MyClass{ def getA(){ 'abc' } }
- def x = [ ['a':21, 'b':22], null, new MyClass() ]
- assert x*.a == [21, null, 'abc'] //properties treated like map subscripting
- '''
+ class MyClass{ def getA(){ 'abc' } }
+ def x = [ ['a':21, 'b':22], null, new MyClass() ]
+ assert x*.a == [21, null, 'abc'] //properties treated like map subscripting
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("java.lang.Object x = [['a': 21, 'b': 22], null, new MyClass()]")
assert result.contains("assert x *.a == [21, null, 'abc'] : null")
@@ -809,11 +825,12 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadNotationForMethodsOnLists() {
String script = '''
- class MyClass{ def getA(){ 'abc' } }
- def c1= new MyClass(), c2= new MyClass()
- assert [c1, c2]*.getA() == [c1.getA(), c2.getA()]
- //spread dot also works for method calls
- assert [c1, c2]*.getA() == ['abc', 'abc'] '''
+ class MyClass{ def getA(){ 'abc' } }
+ def c1= new MyClass(), c2= new MyClass()
+ assert [c1, c2]*.getA() == [c1.getA(), c2.getA()]
+ //spread dot also works for method calls
+ assert [c1, c2]*.getA() == ['abc', 'abc']
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains('java.lang.Object c1 = new MyClass()')
assert result.contains('java.lang.Object c2 = new MyClass()')
@@ -829,8 +846,9 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadNotationInMapDefinition() {
String script = '''
- assert ['z':900, *:['a':100, 'b':200], 'a':300] == ['a':300, 'b':200, 'z':900]
- assert [ *:[3:3, *:[5:5] ], 7:7] == [3:3, 5:5, 7:7] '''
+ assert ['z':900, *:['a':100, 'b':200], 'a':300] == ['a':300, 'b':200, 'z':900]
+ assert [ *:[3:3, *:[5:5] ], 7:7] == [3:3, 5:5, 7:7]
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("assert ['z': 900, *: ['a': 100, 'b': 200], 'a': 300] == ['a': 300, 'b': 200, 'z': 900] : null")
assert result.contains('assert [*: [3: 3, *: [5: 5]], 7: 7] == [3: 3, 5: 5, 7: 7] : null')
@@ -838,13 +856,14 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
void testSpreadNotationInClosure() {
String script = '''
- def f(){ [ 1:'u', 2:'v', 3:'w' ] }
- assert [*:f(), 10:'zz'] == [1:'u', 10:'zz', 2:'v', 3:'w']
- def f(m){ m.c }
- assert f(*:['a':10, 'b':20, 'c':30], 'e':50) == 30
+ def f(){ [ 1:'u', 2:'v', 3:'w' ] }
+ assert [*:f(), 10:'zz'] == [1:'u', 10:'zz', 2:'v', 3:'w']
+ def f(m){ m.c }
+ assert f(*:['a':10, 'b':20, 'c':30], 'e':50) == 30
- def f(m, i, j, k){ [m, i, j, k] }
- assert f('e':100, *[4, 5], *:['a':10, 'b':20, 'c':30], 6) == [ ["e":100, "b":20, "c":30, "a":10], 4, 5, 6 ]'''
+ def f(m, i, j, k){ [m, i, j, k] }
+ assert f('e':100, *[4, 5], *:['a':10, 'b':20, 'c':30], 6) == [ ["e":100, "b":20, "c":30, "a":10], 4, 5, 6 ]
+ '''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains("assert [*: this.f(), 10: 'zz'] == [1: 'u', 10: 'zz', 2: 'v', 3: 'w'] : null")
assert result.contains("assert this.f([*: ['a': 10, 'b': 20, 'c': 30], 'e': 50]) == 30 : null")