|
Groovy example source code file (AstBuilder.groovy)
The Groovy AstBuilder.groovy source code/* * Copyright 2003-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.ast.builder import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.ast.stmt.BlockStatement /** * The AstBuilder provides several ways to build an abstract syntax tree (AST) of Groovy code. * * You can convert a String into AST using the buildFromString method. * You can convert code into AST using the buildFromCode method. * You can use the AST DSL with the buildFromSpec method. * * For more information, see the resources on the Groovy wiki pages. * * @author Hamlet D'Arcy */ public class AstBuilder { /** * Builds AST based on the code within the {@link Closure} parameter. * * This method <strong>must be invoked at compile time and never at runtime, because * an ASTTransformation must be run to support it. If you receive an IllegalStateException then * you most likely need to add stronger typing. For instance, this will not work: * <code> * def builder = new AstBuilder() * builder.buildFromCode { * // some code * } * </code> * While this code will: * <code> * new AstBuilder().buildFromCode { * // some code * } * </code> * * The compiler rewrites buildFromCode invocations into {@link AstBuilder#buildFromString(CompilePhase, boolean, String)} * invocations. An exception raised during AST generation will show a stack trace from {@link AstBuilder#buildFromString(CompilePhase, boolean, String)} * and not from {@link AstBuilder#buildFromCode(CompilePhase, boolean, Closure)} . * * The compiler saves the source code of the closure as a String within the Java class file. The String source * of the closure will be visible and un-obfuscated within the class file. If your Closure parameter contains * sensitive data such as a hard-coded password then that data is free to be seen by anyone with the class file. * Do not store sensitive data within the closure parameter. * * @param phase * the {@link CompilePhase} the AST will be targeted towards. Default is {@link CompilePhase#CLASS_GENERATION} * @param statementsOnly * when true, only the script statements are returned. WHen false, you will * receive back a Script class node also. Default is true. * @param block * the code that will be converted * @returns a List of {@link ASTNode} . * @throws IllegalStateException * this method may not be invoked at runtime. It works via a compile-time transformation * of the closure source code into a String, which is sent to the {@link AstBuilder#buildFromString(CompilePhase, boolean, String)} * method. The buildFromCode() method must be invoked against a strongly typed AstBuilder. */ List<ASTNode> buildFromCode(CompilePhase phase = CompilePhase.CLASS_GENERATION, boolean statementsOnly = true, Closure block) { throw new IllegalStateException("""AstBuilder.build(CompilePhase, boolean, Closure):List<ASTNode> should never be called at runtime. Are you sure you are using it correctly? """) } /** * Builds AST based on the code within the String parameter. * * @param phase * the {@link CompilePhase} the AST will be targeted towards. Default is {@link CompilePhase#CLASS_GENERATION} * @param statementsOnly * when true, only the script statements are returned. WHen false, you will * receive back a Script class node also. Default is true. * @param source * The source code String that will be compiled. * @returns a List of {@link ASTNode} . * @throws IllegalArgumentException * if source is null or empty */ List<ASTNode> buildFromString(CompilePhase phase = CompilePhase.CLASS_GENERATION, boolean statementsOnly = true, String source) { if (!source || "" == source.trim()) throw new IllegalArgumentException("A source must be specified") return new AstStringCompiler().compile(source, phase, statementsOnly); } /** * Builds AST based on the code within the String parameter. The parameter is assumed to be * a code block which is not legal Groovy code. A goto label is affixed to the block, compiled, * and the resulting BlockStatement wrapper is removed before returning a result. * @param phase * the {@link CompilePhase} the AST will be targeted towards. Default is {@link CompilePhase#CLASS_GENERATION} * @param statementsOnly * when true, only the script statements are returned. WHen false, you will * receive back a Script class node also. Default is true. * @param source * The source code String that will be compiled. The string must be a block wrapped in curly braces. * @returns a List of {@link ASTNode} . * @throws IllegalArgumentException * if source is null or empty */ private List<ASTNode> buildFromBlock(CompilePhase phase = CompilePhase.CLASS_GENERATION, boolean statementsOnly = true, String source) { if (!source || "" == source.trim()) throw new IllegalArgumentException("A source must be specified") def labelledSource = "__synthesized__label__${System.currentTimeMillis()}__:" + source List<ASTNode> result = new AstStringCompiler().compile(labelledSource, phase, statementsOnly) // find the block statement from the result, and unwrap it from one level. result.collect { node -> if (node instanceof BlockStatement) { ((BlockStatement)node).statements[0] //unwrap the artifact of pre-pending the goto label } else { node } } } /** * Builds AST based on the DSL data within the Closure parameter. * @param specification * the contents to create */ List<ASTNode> buildFromSpec(Closure specification) { if (specification == null) throw new IllegalArgumentException('Null: specification') def properties = new AstSpecificationCompiler(specification) return properties.expression } } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy AstBuilder.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 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.