|
Groovy example source code file (AstBuilderFromCodeTest.groovy)
The Groovy AstBuilderFromCodeTest.groovy source code
package org.codehaus.groovy.ast.builder
import org.codehaus.groovy.ast.builder.AstBuilder as FactoryAlias
import org.codehaus.groovy.ast.builder.AstBuilder
import org.codehaus.groovy.ast.builder.*
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.runtime.MethodClosure
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.Parameter
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.ast.VariableScope
import org.codehaus.groovy.ast.AnnotationNode
import org.codehaus.groovy.ast.expr.ConstantExpression
import static org.objectweb.asm.Opcodes.*
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.expr.BinaryExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.DynamicVariable
import org.codehaus.groovy.syntax.Token
import org.codehaus.groovy.syntax.Types
import org.codehaus.groovy.ast.expr.ConstructorCallExpression
import org.codehaus.groovy.ast.expr.TupleExpression
import org.codehaus.groovy.ast.expr.NamedArgumentListExpression
import org.codehaus.groovy.ast.expr.MapEntryExpression
import org.codehaus.groovy.ast.stmt.ReturnStatement
import org.codehaus.groovy.ast.expr.ElvisOperatorExpression
import org.codehaus.groovy.ast.expr.BooleanExpression
import org.codehaus.groovy.ast.stmt.WhileStatement
import org.codehaus.groovy.ast.expr.PostfixExpression
import org.codehaus.groovy.ast.stmt.ContinueStatement
import org.codehaus.groovy.ast.expr.TernaryExpression
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.SpreadMapExpression
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.stmt.ForStatement
import org.codehaus.groovy.ast.expr.ClosureListExpression
import org.codehaus.groovy.ast.expr.DeclarationExpression
import org.codehaus.groovy.ast.stmt.TryCatchStatement
import org.codehaus.groovy.ast.stmt.SynchronizedStatement
import org.codehaus.groovy.ast.stmt.AssertStatement
import org.codehaus.groovy.ast.stmt.BreakStatement
import org.codehaus.groovy.ast.stmt.SwitchStatement
import org.codehaus.groovy.ast.stmt.CaseStatement
import org.codehaus.groovy.ast.stmt.EmptyStatement
import org.codehaus.groovy.ast.expr.RangeExpression
import org.codehaus.groovy.ast.expr.MethodPointerExpression
import org.codehaus.groovy.ast.expr.ClassExpression
import org.codehaus.groovy.ast.expr.GStringExpression
import org.codehaus.groovy.ast.expr.MapExpression
import org.codehaus.groovy.ast.expr.UnaryPlusExpression
import org.codehaus.groovy.ast.expr.UnaryMinusExpression
import org.codehaus.groovy.ast.expr.PrefixExpression
import org.codehaus.groovy.ast.expr.NotExpression
import org.codehaus.groovy.ast.expr.ClosureExpression
import org.codehaus.groovy.ast.expr.CastExpression
import org.codehaus.groovy.ast.expr.ListExpression
import org.codehaus.groovy.ast.stmt.IfStatement
import org.codehaus.groovy.ast.ClassHelper
/**
* Test case to show an ASTBuilder working off of a code block.
*
* The field declarations, static initializers, instance initializers,
* and most of the comments are all meaningful and tested.
*
* @author Hamlet D'Arcy
*/
@WithAstBuilder
public class AstBuilderFromCodeTest extends GroovyTestCase {
List<ASTNode> normalField = new AstBuilder().buildFromCode { "constant#1" }
static List<ASTNode> staticInitializedField
static {
staticInitializedField = new AstBuilder().buildFromCode { "constant#3" }
}
List<ASTNode> constructorInializedField
AstBuilderFromCodeTest() {
constructorInializedField = new AstBuilder().buildFromCode { "constant#4" }
}
List<ASTNode> normalProperty = new AstBuilder().buildFromCode { "constant#5" }
public void testImportedClassName() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testFullyQualifiedClassName() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
// it is important for this to remain a method invocation on a fully qualified class name
def result = new org.codehaus.groovy.ast.builder.AstBuilder().buildFromCode {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testAliasedClassName() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new FactoryAlias().buildFromCode {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testVariableInvocation() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
AstBuilder factory = new AstBuilder() //temporary variable is important to test
def result = factory.buildFromCode {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testMethodReturnTypeInvocation() {
shouldFail(IllegalStateException) {
//todo: is there any way to make this work?
makeAstFactory().buildFromCode { // typed as Object in AST :(
println "Hello World"
}
}
}
/**
* Factory method used in testing.
*/
private AstBuilder makeAstFactory() {
return new AstBuilder()
}
public void testPhase_SemanticAnalysis() {
def expected = new AstBuilder().buildFromString(CompilePhase.SEMANTIC_ANALYSIS, """ println "Hello World" """)
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testPhase_Conversion() {
def expected = new AstBuilder().buildFromString(CompilePhase.CONVERSION, """ println "Hello World" """)
def result = new AstBuilder().buildFromCode(CompilePhase.CONVERSION) {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testStatementsOnly_ReturnsScriptClass() {
def expected = new AstBuilder().buildFromString(CompilePhase.CONVERSION, false, """ println "Hello World" """)
def result = new AstBuilder().buildFromCode(CompilePhase.CONVERSION, false) {
println "Hello World"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testSingleLineClosure() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {println "Hello World"}
AstAssert.assertSyntaxTree(expected, result)
}
public void testSingleLineClosure_WithComment() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {println "Hello World"} // a comment DO NOT REMOVE
AstAssert.assertSyntaxTree(expected, result)
}
public void testSingleLineClosure_MultipleStatements() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {println "Hello World"};4+5
AstAssert.assertSyntaxTree(expected, result)
}
public void testMultilineClosure_WithComments() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {//comment1
println "Hello World"//comment2
}//comment3
AstAssert.assertSyntaxTree(expected, result)
}
public void testSingleLineClosure_WithCStyleComment() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder().buildFromCode {println "Hello World"} /* a comment DO NOT REMOVE */
AstAssert.assertSyntaxTree(expected, result)
}
public void testSingleLineClosure_WithMultipleCStyleComments() {
def expected = new AstBuilder().buildFromString(""" println "Hello World" """)
def result = new AstBuilder()./*comment1*/buildFromCode/*comment2*/{/*comment3*/println/*comment4*/"Hello World"/*comment5*/}/*comment6*/
AstAssert.assertSyntaxTree(expected, result)
}
public void testThreeLineClosure() {
def expected = new AstBuilder().buildFromString(""" println "I"; println "Love"; println "Groovy" """)
def result = new AstBuilder().buildFromCode {
println "I"
println "Love"
println "Groovy"
}
AstAssert.assertSyntaxTree(expected, result)
}
public void testInitializationInFieldDeclaration() {
def expected = new AstBuilder().buildFromString(""" "constant#1" """)
AstAssert.assertSyntaxTree(expected, normalField)
}
public void testInitializationInstaticInialization() {
def expected = new AstBuilder().buildFromString(""" "constant#3" """)
AstAssert.assertSyntaxTree(expected, staticInitializedField)
}
public void testInitializationInConstructor() {
def expected = new AstBuilder().buildFromString(""" "constant#4" """)
AstAssert.assertSyntaxTree(expected, constructorInializedField)
}
public void testInitializationInPropertyDeclaration() {
def expected = new AstBuilder().buildFromString(""" "constant#5" """)
AstAssert.assertSyntaxTree(expected, normalProperty)
}
public void testNamedArgumentListExpression() {
def result = new AstBuilder().buildFromCode {
new String(foo: 'bar')
}
def expected = new BlockStatement(
[new ReturnStatement(
new ConstructorCallExpression(
new ClassNode(String),
new TupleExpression(
new NamedArgumentListExpression(
[
new MapEntryExpression(
new ConstantExpression('foo'),
new ConstantExpression('bar'),
)
]
)
)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testElvisOperatorExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
name ?: 'Anonymous'
}
def expected = new BlockStatement(
[new ExpressionStatement(
new ElvisOperatorExpression(
new VariableExpression('name'),
new ConstantExpression('Anonymous')
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testWhileStatementAndContinue() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
while (true) {
x++;
continue
}
}
def expected = new BlockStatement(
[new WhileStatement(
new BooleanExpression(
new ConstantExpression(true)
),
new BlockStatement(
[
new ExpressionStatement(
new PostfixExpression(
new VariableExpression("x"),
new Token(Types.PLUS_PLUS, "++", -1, -1),
)
),
new ContinueStatement()
],
new VariableScope()
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testTernaryExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
true ? 'male' : 'female'
}
def expected = new BlockStatement(
[new ExpressionStatement(
new TernaryExpression(
new BooleanExpression(
new ConstantExpression(true)
),
new ConstantExpression('male'),
new ConstantExpression('female')
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testSpreadMapExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
func(*: m)
}
def expected = new BlockStatement(
[new ExpressionStatement(
new MethodCallExpression(
new VariableExpression('this', ClassHelper.OBJECT_TYPE),
'func',
new NamedArgumentListExpression(
[new MapEntryExpression(
new SpreadMapExpression(
new VariableExpression('m', ClassHelper.OBJECT_TYPE)
),
new VariableExpression('m', ClassHelper.OBJECT_TYPE)
)]
)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testForStatementAndClosureListExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
for (int x = 0; x < 10; x++) {
println x
}
}
def expected = new BlockStatement([new ForStatement(
new Parameter(ClassHelper.OBJECT_TYPE, "forLoopDummyParameter"),
new ClosureListExpression(
[
new DeclarationExpression(
new VariableExpression("x"),
new Token(Types.EQUALS, "=", -1, -1),
new ConstantExpression(0)
),
new BinaryExpression(
new VariableExpression("x"),
new Token(Types.COMPARE_LESS_THAN, "<", -1, -1),
new ConstantExpression(10)
),
new PostfixExpression(
new VariableExpression("x"),
new Token(Types.PLUS_PLUS, "++", -1, -1)
)
]
),
new BlockStatement(
[
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new VariableExpression("x"),
)
)
)
],
new VariableScope()
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testFinallyStatement() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
try {
return 1
} finally {
x.close()
}
}
def expected = new BlockStatement(
[new TryCatchStatement(
new BlockStatement(
[new ReturnStatement(
new ConstantExpression(1)
)],
new VariableScope()
),
new BlockStatement(
[
new BlockStatement(
[
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression('x'),
'close',
new ArgumentListExpression()
)
)
],
new VariableScope())
],
new VariableScope()
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testReturnAndSynchronizedStatement() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
synchronized (this) {
return 1
}
}
def expected = new BlockStatement(
[new SynchronizedStatement(
new VariableExpression("this"),
new BlockStatement(
[new ReturnStatement(
new ConstantExpression(1)
)],
new VariableScope()
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testAssertStatement() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
assert true: "should always be true"
assert 1 == 2
}
def expected = new BlockStatement(
[
new AssertStatement(
new BooleanExpression(
new ConstantExpression(true)
),
new ConstantExpression("should always be true")
),
new AssertStatement(
new BooleanExpression(
new BinaryExpression(
new ConstantExpression(1),
new Token(Types.COMPARE_EQUAL, "==", -1, -1),
new ConstantExpression(2)
)
)
),
],
new VariableScope()
)
AstAssert.assertSyntaxTree([expected], result)
}
public void testSwitchAndCaseAndBreakStatements() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
switch (foo) {
case 0:
break
case 1:
case 2:
println "<3"
break
default:
println ">2"
}
}
def expected = new BlockStatement(
[new SwitchStatement(
new VariableExpression("foo"),
[
new CaseStatement(
new ConstantExpression(0),
new BlockStatement(
[new BreakStatement()], new VariableScope())
),
new CaseStatement(
new ConstantExpression(1),
new EmptyStatement()
),
new CaseStatement(
new ConstantExpression(2),
new BlockStatement(
[
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
[new ConstantExpression("<3")]
)
)
),
new BreakStatement()
], new VariableScope()
)
)
],
new BlockStatement(
[new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
[new ConstantExpression(">2")]
)
)
)],
new VariableScope()
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testRangeExpression_SimpleForm() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
(0..10)
}
def expected = new BlockStatement(
[new ExpressionStatement(
new RangeExpression(
new ConstantExpression(0),
new ConstantExpression(10),
true
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testMethodPointerExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
Integer.&toString
}
def expected = new BlockStatement(
[new ExpressionStatement(
new MethodPointerExpression(
new ClassExpression(ClassHelper.Integer_TYPE),
new ConstantExpression("toString")
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testGStringExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
"$foo"
}
def expected = new BlockStatement(
[new ExpressionStatement(
new GStringExpression('$foo',
[new ConstantExpression(''), new ConstantExpression('')],
[new VariableExpression('foo')])
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testMapAndMapEntryExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
[foo: 'bar', baz: 'buz']
}
def expected = new BlockStatement(
[new ExpressionStatement(
new MapExpression(
[
new MapEntryExpression(
new ConstantExpression('foo'),
new ConstantExpression('bar')
),
new MapEntryExpression(
new ConstantExpression('baz'),
new ConstantExpression('buz')
),
]
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testClassExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
def foo = String
}
def expected = new BlockStatement(
[new ExpressionStatement(
new DeclarationExpression(
new VariableExpression("foo"),
new Token(Types.EQUALS, "=", -1, -1),
new ClassExpression(ClassHelper.STRING_TYPE)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testUnaryPlusExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
(+foo)
}
def expected = new BlockStatement(
[new ExpressionStatement(
new UnaryPlusExpression(
new VariableExpression("foo")
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testUnaryMinusExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
(-foo)
}
def expected = new BlockStatement(
[new ExpressionStatement(
new UnaryMinusExpression(
new VariableExpression("foo")
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testPrefixExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
++1
}
def expected = new BlockStatement(
[new ExpressionStatement(
new PrefixExpression(
new Token(Types.PLUS_PLUS, "++", -1, -1),
new ConstantExpression(1)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testPostfixExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
1++
}
def expected = new BlockStatement(
[new ExpressionStatement(
new PostfixExpression(
new ConstantExpression(1),
new Token(Types.PLUS_PLUS, "++", -1, -1)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testNotExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
!true
}
def expected = new BlockStatement(
[new ExpressionStatement(
new NotExpression(
new ConstantExpression(true)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testConstructorCallExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
new Integer(4)
}
def expected = new BlockStatement(
[new ExpressionStatement(
new ConstructorCallExpression(
new ClassNode(Integer),
new ArgumentListExpression(
new ConstantExpression(4)
)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testClosureExpression_MultipleParameters() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
{x, y, z -> println z }
}
def expected = new BlockStatement(
[new ExpressionStatement(
new ClosureExpression(
[
new Parameter(ClassHelper.OBJECT_TYPE, "x"),
new Parameter(ClassHelper.OBJECT_TYPE, "y"),
new Parameter(ClassHelper.OBJECT_TYPE, "z")] as Parameter[],
new BlockStatement(
[new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new VariableExpression("z")
)
)
)],
new VariableScope()
)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testCastExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
(Integer) ""
}
def expected = new BlockStatement(
[new ExpressionStatement(
new CastExpression(
new ClassNode(Integer),
new ConstantExpression("")
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testDeclarationAndListExpression() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
def foo = [1, 2, 3]
}
def expected = new BlockStatement(
[new ExpressionStatement(
new DeclarationExpression(
new VariableExpression("foo"),
new Token(Types.EQUALS, "=", -1, -1),
new ListExpression(
[new ConstantExpression(1),
new ConstantExpression(2),
new ConstantExpression(3),]
)
))], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
public void testIfStatement() {
def result = new AstBuilder().buildFromCode(CompilePhase.SEMANTIC_ANALYSIS) {
if (foo == bar) println "Hello" else println "World"
}
def expected = new BlockStatement(
[new IfStatement(
new BooleanExpression(
new BinaryExpression(
new VariableExpression("foo"),
new Token(Types.COMPARE_EQUAL, "==", -1, -1),
new VariableExpression("bar")
)
),
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
[new ConstantExpression("Hello")]
)
)
),
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
[new ConstantExpression("World")]
)
)
)
)], new VariableScope())
AstAssert.assertSyntaxTree([expected], result)
}
}
Other Groovy examples (source code examples)Here is a short list of links related to this Groovy AstBuilderFromCodeTest.groovy source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.