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")