CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-palantir-javapoet--javapoet

JavaPoet is a Java API for generating .java source files programmatically with support for modern Java features including records and sealed types

Overview
Eval results
Files

code-blocks.mddocs/

Code Blocks

CodeBlock represents an immutable fragment of code with formatting. It provides a fluent API for building code with proper indentation, control flow structures, and format string placeholders for type-safe code generation.

Capabilities

Creating Code Blocks

Create CodeBlock instances using factory methods.

/**
 * Creates a CodeBlock from a format string
 * @param format - Format string with placeholders ($L, $S, $T, $N)
 * @param args - Arguments for format placeholders
 * @return Immutable CodeBlock
 */
static CodeBlock of(String format, Object... args);

/**
 * Joins multiple code blocks with a separator
 * @param codeBlocks - Iterable of code blocks to join
 * @param separator - Separator string between blocks
 * @return Joined CodeBlock
 */
static CodeBlock join(Iterable<CodeBlock> codeBlocks, String separator);

/**
 * Returns a collector for joining code blocks with separator
 * @param separator - Separator string between blocks
 * @return Collector for Stream operations
 */
static Collector<CodeBlock, ?, CodeBlock> joining(String separator);

/**
 * Returns a collector with prefix, separator, and suffix
 * @param separator - Separator string between blocks
 * @param prefix - String to prepend
 * @param suffix - String to append
 * @return Collector for Stream operations
 */
static Collector<CodeBlock, ?, CodeBlock> joining(String separator, String prefix, String suffix);

/**
 * Creates a new CodeBlock builder
 * @return Builder for constructing a CodeBlock
 */
static CodeBlock.Builder builder();

Usage Examples:

// Simple code block
CodeBlock simple = CodeBlock.of("return $S", "Hello");

// Join multiple blocks
List<CodeBlock> blocks = Arrays.asList(
    CodeBlock.of("$S", "red"),
    CodeBlock.of("$S", "green"),
    CodeBlock.of("$S", "blue")
);
CodeBlock colors = CodeBlock.join(blocks, ", ");

// Using Stream collector
CodeBlock joined = Stream.of("a", "b", "c")
    .map(s -> CodeBlock.of("$S", s))
    .collect(CodeBlock.joining(", ", "[", "]"));

// Build complex code
CodeBlock complex = CodeBlock.builder()
    .addStatement("int total = 0")
    .beginControlFlow("for (int i = 0; i < 10; i++)")
    .addStatement("total += i")
    .endControlFlow()
    .addStatement("return total")
    .build();

Checking if Empty

Check if a CodeBlock contains any code.

/**
 * Checks if this code block is empty
 * @return true if empty, false otherwise
 */
boolean isEmpty();

Modifying CodeBlock

Convert to a builder for modification.

/**
 * Creates a builder initialized with this block's content
 * @return Builder for modifying this CodeBlock
 */
CodeBlock.Builder toBuilder();

CodeBlock.Builder

The builder for constructing CodeBlock instances.

Checking if Builder is Empty

/**
 * Checks if this builder is empty
 * @return true if no code has been added, false otherwise
 */
boolean isEmpty();

Adding Code with Named Arguments

Add code using named argument placeholders.

/**
 * Adds code with named arguments
 * @param format - Format string with named placeholders (e.g., "$name:L")
 * @param args - Map of argument names to values
 * @return This builder for chaining
 */
CodeBlock.Builder addNamed(String format, Map<String, ?> args);

Usage Example:

Map<String, Object> args = new HashMap<>();
args.put("field", "name");
args.put("value", "John");

CodeBlock code = CodeBlock.builder()
    .addNamed("this.$field:N = $value:S", args)
    .build();
// Generates: this.name = "John"

Adding Code

Add code to the block using various methods.

/**
 * Adds a CodeBlock to this builder
 * @param codeBlock - CodeBlock to append
 * @return This builder for chaining
 */
CodeBlock.Builder add(CodeBlock codeBlock);

/**
 * Adds code from a format string
 * @param format - Format string with placeholders
 * @param args - Arguments for format placeholders
 * @return This builder for chaining
 */
CodeBlock.Builder add(String format, Object... args);

Usage Examples:

// Add with format string
CodeBlock code = CodeBlock.builder()
    .add("$T value = ", String.class)
    .add("$S", "hello")
    .build();

// Add existing CodeBlock
CodeBlock existing = CodeBlock.of("$L + $L", 1, 2);
CodeBlock combined = CodeBlock.builder()
    .add("int result = ")
    .add(existing)
    .build();

Adding Statements

Add complete statements (automatically adds semicolon and newline).

/**
 * Adds a statement from a format string
 * @param format - Format string for the statement
 * @param args - Arguments for format placeholders
 * @return This builder for chaining
 */
CodeBlock.Builder addStatement(String format, Object... args);

/**
 * Adds a statement from a CodeBlock
 * @param codeBlock - CodeBlock for the statement
 * @return This builder for chaining
 */
CodeBlock.Builder addStatement(CodeBlock codeBlock);

Usage Examples:

CodeBlock statements = CodeBlock.builder()
    .addStatement("int count = 0")
    .addStatement("$T.out.println($S)", System.class, "Hello")
    .addStatement("return count")
    .build();
// Generates:
// int count = 0;
// System.out.println("Hello");
// return count;

Control Flow Structures

Build control flow structures with proper indentation.

/**
 * Begins a control flow block (if, for, while, etc.)
 * @param controlFlow - Format string for control flow statement
 * @param args - Arguments for format placeholders
 * @return This builder for chaining
 */
CodeBlock.Builder beginControlFlow(String controlFlow, Object... args);

/**
 * Adds next control flow (else if, else, catch, etc.)
 * @param controlFlow - Format string for next control flow
 * @param args - Arguments for format placeholders
 * @return This builder for chaining
 */
CodeBlock.Builder nextControlFlow(String controlFlow, Object... args);

/**
 * Ends the current control flow block
 * @return This builder for chaining
 */
CodeBlock.Builder endControlFlow();

/**
 * Ends control flow with a following statement (e.g., "while" for do-while)
 * @param controlFlow - Format string for ending statement
 * @param args - Arguments for format placeholders
 * @return This builder for chaining
 */
CodeBlock.Builder endControlFlow(String controlFlow, Object... args);

Usage Examples:

// If-else
CodeBlock ifElse = CodeBlock.builder()
    .beginControlFlow("if (value > 0)")
    .addStatement("return true")
    .nextControlFlow("else")
    .addStatement("return false")
    .endControlFlow()
    .build();

// For loop
CodeBlock forLoop = CodeBlock.builder()
    .beginControlFlow("for (int i = 0; i < 10; i++)")
    .addStatement("$T.out.println(i)", System.class)
    .endControlFlow()
    .build();

// While loop
CodeBlock whileLoop = CodeBlock.builder()
    .beginControlFlow("while (iterator.hasNext())")
    .addStatement("process(iterator.next())")
    .endControlFlow()
    .build();

// Try-catch-finally
CodeBlock tryCatch = CodeBlock.builder()
    .beginControlFlow("try")
    .addStatement("riskyOperation()")
    .nextControlFlow("catch ($T e)", IOException.class)
    .addStatement("$T.err.println(e)", System.class)
    .nextControlFlow("finally")
    .addStatement("cleanup()")
    .endControlFlow()
    .build();

// Do-while
CodeBlock doWhile = CodeBlock.builder()
    .beginControlFlow("do")
    .addStatement("process()")
    .endControlFlow("while (hasMore())")
    .build();

// Switch statement
CodeBlock switchStmt = CodeBlock.builder()
    .beginControlFlow("switch (value)")
    .add("case 1:\n")
    .indent()
    .addStatement("handleOne()")
    .addStatement("break")
    .unindent()
    .add("case 2:\n")
    .indent()
    .addStatement("handleTwo()")
    .addStatement("break")
    .unindent()
    .add("default:\n")
    .indent()
    .addStatement("handleDefault()")
    .unindent()
    .endControlFlow()
    .build();

Manual Indentation Control

Manually control indentation levels.

/**
 * Increases indentation level
 * @return This builder for chaining
 */
CodeBlock.Builder indent();

/**
 * Decreases indentation level
 * @return This builder for chaining
 */
CodeBlock.Builder unindent();

Usage Example:

CodeBlock indented = CodeBlock.builder()
    .addStatement("public void method()")
    .indent()
    .addStatement("int x = 1")
    .addStatement("int y = 2")
    .unindent()
    .addStatement("}")
    .build();

Clearing Content

Clear all content from the builder.

/**
 * Clears all content from this builder
 * @return This builder for chaining
 */
CodeBlock.Builder clear();

Building the CodeBlock

Build the final CodeBlock instance.

/**
 * Builds the CodeBlock with configured content
 * @return The built CodeBlock instance
 */
CodeBlock build();

Format String Placeholders

JavaPoet supports special placeholders in format strings:

  • $L - Literals (strings, primitives, any object's toString())
  • $S - String literals (automatically escaped and quoted)
  • $T - Types (TypeName, Class<?>, automatically imported)
  • $N - Names (MethodSpec, FieldSpec, ParameterSpec - uses their name)
  • $$ - Escaped dollar sign (produces single $)

Usage Examples:

// $L for literals
CodeBlock literals = CodeBlock.of("int value = $L", 42);
// Generates: int value = 42

// $S for strings (adds quotes and escapes)
CodeBlock strings = CodeBlock.of("String msg = $S", "Hello \"World\"");
// Generates: String msg = "Hello \"World\""

// $T for types (auto-imports)
CodeBlock types = CodeBlock.of("$T list = new $T<>()", List.class, ArrayList.class);
// Generates: List list = new ArrayList<>()
// Auto-imports: java.util.List, java.util.ArrayList

// $N for names
MethodSpec method = MethodSpec.methodBuilder("helper").build();
CodeBlock names = CodeBlock.of("$N()", method);
// Generates: helper()

// $$ for dollar signs
CodeBlock dollars = CodeBlock.of("String pattern = $S", "Price: $$10");
// Generates: String pattern = "Price: $10"

Positional and Named Arguments

// Positional arguments (1-based indexing)
CodeBlock positional = CodeBlock.of("I ate $2L $1L", "tacos", 3);
// Generates: I ate 3 tacos

// Named arguments
Map<String, Object> args = new HashMap<>();
args.put("food", "tacos");
args.put("count", 3);
CodeBlock named = CodeBlock.builder()
    .addNamed("I ate $count:L $food:L", args)
    .build();
// Generates: I ate 3 tacos

Common Patterns

Variable Declaration and Assignment

CodeBlock declaration = CodeBlock.builder()
    .addStatement("$T name = $S", String.class, "John")
    .addStatement("int age = $L", 30)
    .addStatement("$T items = new $T<>()",
        ParameterizedTypeName.get(List.class, String.class),
        ArrayList.class)
    .build();

Method Calls

CodeBlock calls = CodeBlock.builder()
    .addStatement("$T.out.println($S)", System.class, "Hello")
    .addStatement("list.add($S)", "item")
    .addStatement("process(value, $L)", 42)
    .build();

Return Statements

CodeBlock returns = CodeBlock.builder()
    .addStatement("return $S", "result")
    .build();

CodeBlock conditionalReturn = CodeBlock.builder()
    .beginControlFlow("if (value != null)")
    .addStatement("return value")
    .nextControlFlow("else")
    .addStatement("return $S", "default")
    .endControlFlow()
    .build();

Complex Expressions

CodeBlock expression = CodeBlock.builder()
    .add("$T result = stream.filter(x -> x > 0)\n", int.class)
    .indent()
    .add(".map(x -> x * 2)\n")
    .add(".reduce(0, (a, b) -> a + b);\n")
    .unindent()
    .build();

Types

class CodeBlock {
    static CodeBlock of(String format, Object... args);
    static CodeBlock join(Iterable<CodeBlock> codeBlocks, String separator);
    static Collector<CodeBlock, ?, CodeBlock> joining(String separator);
    static Collector<CodeBlock, ?, CodeBlock> joining(String separator, String prefix, String suffix);
    static Builder builder();

    boolean isEmpty();
    Builder toBuilder();
    boolean equals(Object o);
    int hashCode();
    String toString();
}

class CodeBlock.Builder {
    boolean isEmpty();
    CodeBlock.Builder addNamed(String format, Map<String, ?> args);
    CodeBlock.Builder add(CodeBlock codeBlock);
    CodeBlock.Builder add(String format, Object... args);
    CodeBlock.Builder addStatement(String format, Object... args);
    CodeBlock.Builder addStatement(CodeBlock codeBlock);
    CodeBlock.Builder beginControlFlow(String controlFlow, Object... args);
    CodeBlock.Builder nextControlFlow(String controlFlow, Object... args);
    CodeBlock.Builder endControlFlow();
    CodeBlock.Builder endControlFlow(String controlFlow, Object... args);
    CodeBlock.Builder indent();
    CodeBlock.Builder unindent();
    CodeBlock.Builder clear();
    CodeBlock build();
}

Install with Tessl CLI

npx tessl i tessl/maven-com-palantir-javapoet--javapoet@0.11.0

docs

annotation-specifications.md

array-type-names.md

class-names.md

code-blocks.md

field-specifications.md

index.md

java-files.md

method-specifications.md

name-allocator.md

parameter-specifications.md

parameterized-type-names.md

type-names.md

type-specifications.md

type-variable-names.md

wildcard-type-names.md

tile.json