A fluent API to create abstract syntax trees for Java. Written in Kotlin.

Installation

Fluentast is available for download on Github


Usage

The example below demonstrates how a simple code snippet can be built using JDT Core. It also demonstrates how to create the same snippet using Fluentast.

You can find additional examples in the docs or in the demo project on Github.

// Just a bit of code, how bad could it be?
int i=1;
while (true) {
  System.out.println(i);
  if (i > 99) break;
  i++;
}
// As it turns out, very.
AST ast = AST.newAST(AST.JLS8);
Block block = ast.newBlock();
VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment();
fragment.setName(ast.newSimpleName("i"));
fragment.setInitializer(ast.newNumberLiteral("1"));
VariableDeclarationStatement statement = ast.newVariableDeclarationStatement(fragment);
statement.setType(ast.newPrimitiveType(PrimitiveType.INT));
block.statements().add(statement);
WhileStatement whileStatement = ast.newWhileStatement();
whileStatement.setExpression(ast.newBooleanLiteral(true));
Block whileBody = ast.newBlock();
MethodInvocation methodInvocation = ast.newMethodInvocation();
methodInvocation.setName(ast.newSimpleName("println"));
methodInvocation.setExpression(ast.newName("System.out"));
methodInvocation
    .arguments()
    .add(ast.newSimpleName("i"));
whileBody
    .statements()
    .add(ast.newExpressionStatement(methodInvocation));
IfStatement ifStatement = ast.newIfStatement();
InfixExpression infixExpression = ast.newInfixExpression();
infixExpression.setLeftOperand(ast.newSimpleName("i"));
infixExpression.setOperator(Operator.GREATER);
infixExpression.setRightOperand(ast.newNumberLiteral("99"));
ifStatement.setExpression(infixExpression);
ifStatement.setThenStatement(ast.newBreakStatement());
whileBody
    .statements()
    .add(ifStatement);
PostfixExpression postfixExpression = ast.newPostfixExpression();
postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
postfixExpression.setOperand(ast.newSimpleName("i"));
whileBody
    .statements()
    .add(ast.newExpressionStatement(postfixExpression));
whileStatement.setBody(whileBody);
block.statements().add(whileStatement);
// That's certainly better!
FluentStatement variableDeclaration = stmnt(decl("int",1));
FluentStatement methodInvocation = stmnt(invocation(name("System.out"),
                                                    new ArrayList<FluentType>(),
                                                    "println",
                                                    n("i")));
FluentBlock whileBody = block(methodInvocation,
                              if_(infix(">")
                                      .left(n("i"))
                                      .right(i(99))).then(break_()),
                              stmnt(postfix("++").operand(n("i"))));
block(variableDeclaration,
      while_(b(true))
          .do_(whileBody))
    .build();

Why Fluentast?

There are a number of options out there to programmatically create Java code. Most notably, there is Javapoet.

However, sometimes you just can't help using JDT. Maybe you are developing an Eclipse plugin? Maybe you want to leverage one of the numerous features of JDT?

Either way, if you are stuck with JDT, you will have to be prepared to do lots of typing. Or, you know, just use Fluentast and save you some hassle. I mean, have you looked at the example above?

Supported Elements

The most common syntax elements, such as if-statements, loops, variable assignments and so forth are supported. However, there might still be some missing. For an overview of supported syntax elements please see the supported syntax elements documentation.

Additional Features

Creating an abstract syntax tree is still to cumbersome? You may simple add blocks and statements as strings and mix them with other fluent elements. Have a look at the demo project.

Contributions Welcome

There is still a lot of work to do. Add fluent interfaces for not-yet supported types or even add entirely new capabilities: Your contributions are certainly welcome! Have a look at the repository.