groovy git commit: GROOVY-8072: AstBrowser source view does not generate labels for statements (closes #490)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

groovy git commit: GROOVY-8072: AstBrowser source view does not generate labels for statements (closes #490)

jwagenleitner-2
Repository: groovy
Updated Branches:
  refs/heads/master d40a6400c -> 1f6c48cc7


GROOVY-8072: AstBrowser source view does not generate labels for statements (closes #490)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/1f6c48cc
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/1f6c48cc
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/1f6c48cc

Branch: refs/heads/master
Commit: 1f6c48cc7e1c72e6d5352cc4de57ed987ce1e16f
Parents: d40a640
Author: John Wagenleitner <[hidden email]>
Authored: Sun Feb 12 13:42:27 2017 -0800
Committer: John Wagenleitner <[hidden email]>
Committed: Sun Feb 12 14:07:35 2017 -0800

----------------------------------------------------------------------
 .../swingui/AstNodeToScriptAdapter.groovy       | 51 ++++++++++-
 .../swingui/AstNodeToScriptAdapterTest.groovy   | 92 ++++++++++++++++++++
 2 files changed, 140 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1f6c48cc/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 554b953..2a90ed7 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
@@ -476,9 +476,22 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitBlockStatement(BlockStatement block) {
-        block?.statements?.each {
-            it.visit(this)
+        if (printStatementLabels(block)) {
+            print '{'
+            printLineBreak()
+            indented {
+                block?.statements?.each {
+                    it.visit(this)
+                    printLineBreak()
+                }
+            }
+            print '}'
             printLineBreak()
+        } else {
+            block?.statements?.each {
+                it.visit(this)
+                printLineBreak()
+            }
         }
         if (!_out.toString().endsWith('\n')) {
             printLineBreak()
@@ -487,7 +500,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitForLoop(ForStatement statement) {
-
+        printStatementLabels(statement)
         print 'for ('
         if (statement?.variable != ForStatement.FOR_LOOP_DUMMY) {
             visitParameters([statement.variable])
@@ -510,6 +523,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitIfElse(IfStatement ifElse) {
+        printStatementLabels(ifElse)
         print 'if ('
         ifElse?.booleanExpression?.visit this
         print ') {'
@@ -545,6 +559,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitSwitch(SwitchStatement statement) {
+        printStatementLabels(statement)
         print 'switch ('
         statement?.expression?.visit this
         print ') {'
@@ -577,12 +592,18 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
     @Override
     void visitBreakStatement(BreakStatement statement) {
         print 'break'
+        if (statement?.label) {
+            print ' ' + statement.label
+        }
         printLineBreak()
     }
 
     @Override
     void visitContinueStatement(ContinueStatement statement) {
         print 'continue'
+        if (statement?.label) {
+            print ' ' + statement.label
+        }
         printLineBreak()
     }
 
@@ -878,6 +899,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitTryCatchFinally(TryCatchStatement statement) {
+        printStatementLabels(statement)
         print 'try {'
         printLineBreak()
         indented {
@@ -907,6 +929,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitSynchronizedStatement(SynchronizedStatement statement) {
+        printStatementLabels(statement)
         print 'synchronized ('
         statement?.expression?.visit this
         print ') {'
@@ -938,6 +961,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitWhileLoop(WhileStatement statement) {
+        printStatementLabels(statement)
         print 'while ('
         statement?.booleanExpression?.visit this
         print ') {'
@@ -952,6 +976,7 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
 
     @Override
     void visitDoWhileLoop(DoWhileStatement statement) {
+        printStatementLabels(statement)
         print 'do {'
         printLineBreak()
         indented {
@@ -1035,4 +1060,24 @@ class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements Groovy
         print '*:'
         expression?.expression?.visit this
     }
+
+    /**
+     * Prints all labels for the given statement.  The labels will be printed on a single
+     * line and line break will be added.
+     *
+     * @param statement for which to print labels
+     * @return {@code true} if the statement had labels to print, else {@code false}
+     */
+    private boolean printStatementLabels(Statement statement) {
+        List<String> labels = statement?.statementLabels
+        if (labels == null || labels.isEmpty()) {
+            return false
+        }
+        for (String label : labels) {
+            print label + ':'
+            printLineBreak()
+        }
+        return true
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/1f6c48cc/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 c526f17..1884feb 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
@@ -887,4 +887,96 @@ class AstNodeToScriptAdapterTest extends GroovyTestCase {
         result = compileToScript(script, CompilePhase.CLASS_GENERATION)
         assert result =~ /(?s)public A\(\) \{.*?v = 2\s*v = 1\s*\}/
     }
+
+    void testStatementLabels() {
+        String script = '''
+            label1:
+            label1a:
+            for (int x : (1..10)) {
+                if (x == 5) {
+                    break label1
+                }
+                if (x == 6) {
+                    continue label1a
+                }
+                println x
+            }
+
+            label2:
+            while (true) {
+                switch(hashCode()) {
+                    case 0: break label2
+                    case 1: break
+                }
+                break
+            }
+
+            label3:
+            if (hashCode() > 0) {
+                for (x in [1,2,3]) {
+                    if (x > 2) {
+                        break label3
+                    }
+                }
+            }
+
+            label4:
+            switch (hashCode()) { }
+
+            label5:
+            try { } catch (any) { }
+
+            label6:
+            synchronized (this) { }
+        '''
+
+        String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
+        assert result.contains('label1a:\nlabel1:\nfor (int x : (1..10)) {')
+        assert result.contains('break label1')
+        assert result.contains('continue label1a')
+        assert result.contains('label2:\nwhile (true)')
+        assert result.contains('break label2')
+        assert result.contains('label3:\nif (this.hashCode() > 0)')
+        assert result.contains('label4:\nswitch (this.hashCode())')
+        assert result.contains('label5:\ntry {')
+        assert result.contains('label6:\nsynchronized')
+    }
+
+    void testStatementLabelsForDoWhileLoop() {
+        def doWhile = new DoWhileStatement(
+                new BooleanExpression(constX(true)),
+                new BlockStatement(
+                        [stmt(callThisX('println', args(constX('value'))))],
+                        new VariableScope()
+                ))
+        doWhile.addStatementLabel('label1')
+
+        StringWriter writer = new StringWriter()
+        new AstNodeToScriptVisitor(writer).visitDoWhileLoop doWhile
+        String result = writer.toString()
+        assert result.contains('label1:\ndo {')
+        assert result.contains('} while (true)')
+    }
+
+    void testNestedObjectInitializers() {
+        String script = '''
+            class A {
+                def v
+                A() { v = 1 }
+                {
+                    v = 2
+                    // nested block must be labeled to avoid appearing as a closure
+                    oi:
+                    {
+                        v += 2
+                    }
+                }
+            }
+        '''
+
+        String result = compileToScript(script)
+        assert result =~ /\{\s*v = 2/
+        assert result =~ /(?s)oi:.*?\{.*?v \+= 2.*?\}/
+    }
+
 }