From b7cb6f44ccdf69fc82e819845e1df26149678796 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Fri, 24 Apr 2026 17:05:31 -0300 Subject: [PATCH 1/9] feat: add FormatSqlTextBlockRecipe for SQL Text Blocks marked with // language=sql Add a new recipe that formats SQL in Java Text Blocks preceded by the `// language=sql` comment (case-insensitive). This is the same language injection comment recognized by IntelliJ IDEA for SQL syntax highlighting. - Extract shared Text Block utilities to TextBlockFormatter (isTextBlock, formatTextBlockSql, getFileIndent) - Refactor AnnotationOnlyOneArgumentProcessor to use TextBlockFormatter - Add FormatSqlTextBlockRecipe with FormatSqlTextBlockVisitor - Add FormatSqlTextBlockRecipeTest with 10 test scenarios (including multiple variables in a single declaration) - Update README.md with documentation for the new recipe --- README.md | 37 +- .../mhagnumdw/FormatSqlTextBlockRecipe.java | 54 +++ .../mhagnumdw/FormatSqlTextBlockVisitor.java | 93 +++++ .../io/github/mhagnumdw/TextBlockUtil.java | 136 ++++++++ .../resources/META-INF/rewrite/examples.yml | 37 ++ .../FormatSqlTextBlockRecipeTest.java | 317 ++++++++++++++++++ 6 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java create mode 100644 src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java create mode 100644 src/main/java/io/github/mhagnumdw/TextBlockUtil.java create mode 100644 src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java diff --git a/README.md b/README.md index 19f21b3..6725776 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,12 @@ A set of [OpenRewrite](https://docs.openrewrite.org/) recipes for formatting SQL - [Recipes](#recipes) - [FormatSqlBlockRecipe](#formatsqlblockrecipe) + - [FormatSqlTextBlockRecipe](#formatsqltextblockrecipe) - [FormatSqlFileRecipe](#formatsqlfilerecipe) - [Configurable Options](#configurable-options) - [Examples](#examples) - [FormatSqlBlockRecipe Example](#formatsqlblockrecipe-example) + - [FormatSqlTextBlockRecipe Example](#formatsqltextblockrecipe-example) - [FormatSqlFileRecipe Example](#formatsqlfilerecipe-example) - [Usage](#usage) - [Configuring in `pom.xml`](#configuring-in-pomxml) @@ -33,13 +35,19 @@ The `io.github.mhagnumdw.FormatSqlBlockRecipe` recipe automatically formats SQL > Future enhancements may allow configuration of custom annotations. Please open an issue. +### FormatSqlTextBlockRecipe + +The `io.github.mhagnumdw.FormatSqlTextBlockRecipe` recipe formats SQL code in Java [Text Blocks](https://docs.oracle.com/en/java/javase/13/text_blocks/index.html) that are preceded by a `// language=sql` comment (case-insensitive). + +This is the same [language injection comment](https://www.jetbrains.com/help/idea/language-injections.html) recognized by IntelliJ IDEA for SQL syntax highlighting. + ### FormatSqlFileRecipe The `io.github.mhagnumdw.FormatSqlFileRecipe` recipe automatically formats the content of SQL files. ## Configurable Options -The following options are applicable to both `FormatSqlBlockRecipe` and `FormatSqlFileRecipe`: +The following options are applicable to `FormatSqlBlockRecipe`, `FormatSqlTextBlockRecipe`, and `FormatSqlFileRecipe`: | Type | Name | Description | Example | Default Value | | :------ | :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------- | @@ -91,6 +99,33 @@ public interface HolidayRepository { } ``` +### FormatSqlTextBlockRecipe Example + +Before + +```java +// language=sql +private static final String QUERY = """ + select * from users u inner join orders o on u.id = o.user_id where u.active = true order by u.name + """; +``` + +After + +```java +// language=sql +private static final String QUERY = """ + select + * + from + users u + inner join orders o on u.id = o.user_id + where + u.active = true + order by + u.name"""; +``` + ### FormatSqlFileRecipe Example Consider the following `example.sql` file: diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java new file mode 100644 index 0000000..512627f --- /dev/null +++ b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java @@ -0,0 +1,54 @@ +package io.github.mhagnumdw; + +import org.jspecify.annotations.Nullable; +import org.openrewrite.ExecutionContext; +import org.openrewrite.FindSourceFiles; +import org.openrewrite.Preconditions; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.search.UsesJavaVersion; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = false) +public class FormatSqlTextBlockRecipe extends FormatSqlRecipeAbstract { + + private static final String DEFAULT_FILE_PATH = "**/*.java"; + + @JsonCreator + public FormatSqlTextBlockRecipe( + @Nullable @JsonProperty("filePath") String filePath, + @Nullable @JsonProperty("sqlDialect") String sqlDialect, + @Nullable @JsonProperty("indent") String indent, + @Nullable @JsonProperty("maxColumnLength") Integer maxColumnLength, + @Nullable @JsonProperty("uppercase") Boolean uppercase) { + super(filePath == null ? DEFAULT_FILE_PATH : filePath, sqlDialect, indent, maxColumnLength, uppercase); + } + + @Override + public String getDisplayName() { + return "Format SQL Text Blocks marked with language injection comment"; + } + + @Override + public String getDescription() { + return "Formats SQL code in Java Text Blocks that are preceded by " + + "a '// language=sql' comment (case-insensitive)."; + } + + @Override + TreeVisitor getFormattingVisitor( + Dialect dialect, FormatConfig formatConfig) { + TreeVisitor check = Preconditions.and( + new FindSourceFiles(getFilePath()).getVisitor(), + new UsesJavaVersion<>(13) // Text blocks were introduced as a preview feature in Java 13 and became a standard feature in Java 15 + ); + return Preconditions.check(check, new FormatSqlTextBlockVisitor(dialect, formatConfig)); + } +} diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java new file mode 100644 index 0000000..ba63084 --- /dev/null +++ b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java @@ -0,0 +1,93 @@ +package io.github.mhagnumdw; + +import static org.openrewrite.java.tree.J.Literal; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.tree.Comment; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.TextComment; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + +public class FormatSqlTextBlockVisitor extends JavaIsoVisitor { + + private static final Pattern LANGUAGE_SQL_PATTERN = Pattern.compile( + "\\s*language\\s*=\\s*sql\\s*", Pattern.CASE_INSENSITIVE + ); + + private final Dialect dialect; + private final FormatConfig formatConfig; + + FormatSqlTextBlockVisitor(Dialect dialect, FormatConfig formatConfig) { + this.dialect = dialect; + this.formatConfig = formatConfig; + } + + @Override + public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations varDecls, ExecutionContext ctx) { + + if (!hasLanguageSqlComment(varDecls)) { + return varDecls; + } + + List variables = varDecls.getVariables(); + boolean changed = false; + + for (int i = 0; i < variables.size(); i++) { + J.VariableDeclarations.NamedVariable var = variables.get(i); + Expression initializer = var.getInitializer(); + + if (initializer == null || !TextBlockUtil.isTextBlock(initializer)) { + continue; + } + + String indentation = getParentIndentation(varDecls) + + TextBlockUtil.getFileIndent(getCursor()); + + Literal newLiteral = TextBlockUtil.formatTextBlock( + (Literal) initializer, indentation, dialect, formatConfig); + + if (newLiteral != null) { + var = var.withInitializer(newLiteral); + List newVariables = new ArrayList<>(variables); + newVariables.set(i, var); + variables = newVariables; + changed = true; + } + } + + if (!changed) { + return varDecls; + } + + return varDecls.withVariables(variables); + } + + private static boolean hasLanguageSqlComment(J.VariableDeclarations varDecls) { + List comments = varDecls.getPrefix().getComments(); + if (comments == null) { + return false; + } + + for (Comment comment : comments) { + if (comment instanceof TextComment) { + TextComment tc = (TextComment) comment; + if (!tc.isMultiline() && LANGUAGE_SQL_PATTERN.matcher(tc.getText()).matches()) { + return true; + } + } + } + return false; + } + + private static String getParentIndentation(J.VariableDeclarations varDecls) { + return varDecls.getPrefix().getIndent(); + } +} diff --git a/src/main/java/io/github/mhagnumdw/TextBlockUtil.java b/src/main/java/io/github/mhagnumdw/TextBlockUtil.java new file mode 100644 index 0000000..bebc0b4 --- /dev/null +++ b/src/main/java/io/github/mhagnumdw/TextBlockUtil.java @@ -0,0 +1,136 @@ +package io.github.mhagnumdw; + +import static org.openrewrite.Tree.randomId; + +import org.jspecify.annotations.Nullable; +import org.openrewrite.Cursor; +import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.style.IntelliJ; +import org.openrewrite.java.style.TabsAndIndentsStyle; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.JavaSourceFile; +import org.openrewrite.java.tree.JavaType; +import org.openrewrite.java.tree.TypeUtils; +import org.openrewrite.marker.Markers; +import org.openrewrite.style.Style; + +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + +/** + * Utility class for formatting SQL in Java Text Blocks. + * Provides shared methods used by both annotation processors and the Text Block visitor. + */ +public final class TextBlockUtil { + + private TextBlockUtil() {} + + /** + * Checks if the given expression is a Java Text Block ("""..."""). + * + * @param expr The expression to check + * @return true if the expression is a text block, false otherwise + * @see UseTextBlocks.java + */ + public static boolean isTextBlock(Expression expr) { + if (expr instanceof J.Literal) { + J.Literal l = (J.Literal) expr; + return TypeUtils.isString(l.getType()) && + l.getValueSource() != null && + l.getValueSource().startsWith("\"\"\""); + } + return false; + } + + /** + * Formats SQL in a text block literal and returns the new literal, + * or null if nothing changed. + * + * @param literal The text block literal containing SQL + * @param indentation The indentation string to apply to formatted SQL + * @param dialect The SQL dialect to use for formatting + * @param formatConfig The format configuration + * @return The new formatted literal, or null if nothing changed + */ + public static J.@Nullable Literal formatTextBlock( + J.Literal literal, + String indentation, + Dialect dialect, + FormatConfig formatConfig) { + + String sql = (String) literal.getValue(); + if (sql == null) { + return null; + } + + String sqlFormattedRaw = SqlFormatter.of(dialect).format(sql, formatConfig); + + if (sqlFormattedRaw.equals(sql)) { + return null; + } + + String sqlFormatted = sqlFormattedRaw.replace("\n", "\n" + indentation); + sqlFormatted = "\n" + indentation + sqlFormatted; + + if (sqlFormatted.equals(literal.getValue())) { + return null; + } + + return new J.Literal( + randomId(), + literal.getPrefix(), + Markers.EMPTY, + sqlFormatted, + String.format("\"\"\"%s\"\"\"", sqlFormatted), + null, + JavaType.Primitive.String + ); + } + + /** + * Retrieves the file indentation from the cursor context. + * + * @param cursor The cursor to extract indentation from + * @return The indentation string (spaces or tab) + */ + public static String getFileIndent(Cursor cursor) { + JavaSourceFile sf = cursor.firstEnclosingOrThrow(JavaSourceFile.class); + TabsAndIndentsStyle style = Style.from(TabsAndIndentsStyle.class, sf); + if (style == null) { + style = IntelliJ.tabsAndIndents(); + } + + boolean useTab = style.getUseTabCharacter(); + int tabSize = style.getTabSize(); + + if (useTab) { + return "\t"; + } + return StringUtils.repeat(" ", tabSize); + } + + /** + * Retrieves the indentation of the parent node from the cursor context. + * + * @param cursor The cursor to extract indentation from + * @return The indentation string (spaces or tab) + */ + public static String getParentIndentation(Cursor cursor) { + Cursor parentCursor = cursor.getParent(); + + while (parentCursor != null) { + Object parent = parentCursor.getValue(); + + if (parent instanceof J.MethodDeclaration) { + J.MethodDeclaration lstNode = (J.MethodDeclaration) parent; + return lstNode.getPrefix().getIndent(); + } + + parentCursor = parentCursor.getParent(); + } + + return ""; + } +} diff --git a/src/main/resources/META-INF/rewrite/examples.yml b/src/main/resources/META-INF/rewrite/examples.yml index 849af9c..0e51fc4 100644 --- a/src/main/resources/META-INF/rewrite/examples.yml +++ b/src/main/resources/META-INF/rewrite/examples.yml @@ -43,3 +43,40 @@ examples: void select(); } language: java +--- +type: specs.openrewrite.org/v1beta/example +recipeName: io.github.mhagnumdw.FormatSqlTextBlockRecipe +examples: +- description: '' + parameters: + - io/github/mhagnumdw/test/*.java + - sql + - 'null' + - 'null' + - 'null' + sources: + - before: | + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = """ + select * from users u inner join orders o on u.id = o.user_id where u.active = true order by u.name"""; + } + after: | + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = """ + select + * + from + users u + inner join orders o on u.id = o.user_id + where + u.active = true + order by + u.name"""; + } + language: java diff --git a/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java new file mode 100644 index 0000000..c5acb1b --- /dev/null +++ b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java @@ -0,0 +1,317 @@ +package io.github.mhagnumdw; + +import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.java.Assertions.javaVersion; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +class FormatSqlTextBlockRecipeTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe( + new FormatSqlTextBlockRecipe( + "io/github/mhagnumdw/test/*.java", + "sql", + null, + null, + null + ) + ) + .allSources(s -> s.markers( + // https://docs.openrewrite.org/authoring-recipes/recipe-testing#specifying-java-versions + javaVersion(13) // Text blocks were introduced as a preview feature in Java 13 and became a standard feature in Java 15 + )); + } + + @DocumentExample + @Test + void shouldFormatFieldWithLanguageSqlComment() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = \""" + select * from users u inner join orders o on u.id = o.user_id where u.active = true order by u.name\"""; + } + """, + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = \""" + select + * + from + users u + inner join orders o on u.id = o.user_id + where + u.active = true + order by + u.name\"""; + } + """ + ) + ); + } + + @Test + void shouldFormatLocalVariableWithLanguageSqlComment() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + public void test() { + // language=sql + String query = \""" + select * from users where active = true\"""; + } + } + """, + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + public void test() { + // language=sql + String query = \""" + select + * + from + users + where + active = true\"""; + } + } + """ + ) + ); + } + + @Test + void shouldBeCaseInsensitive() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // LANGUAGE=SQL + private static final String Q1 = \""" + select * from users\"""; + // Language=Sql + private static final String Q2 = \""" + select * from orders\"""; + //language=sql + private static final String Q3 = \""" + select * from products\"""; + } + """, + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // LANGUAGE=SQL + private static final String Q1 = \""" + select + * + from + users\"""; + // Language=Sql + private static final String Q2 = \""" + select + * + from + orders\"""; + //language=sql + private static final String Q3 = \""" + select + * + from + products\"""; + } + """ + ) + ); + } + + // Text Block without comment — does not change + @Test + void shouldNotFormatWithoutComment() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + private static final String QUERY = \""" + select * from users\"""; + } + """ + ) + ); + } + + // Normal string with // language=sql — does not change + @Test + void shouldNotFormatNonTextBlockWithComment() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = "select * from users"; + } + """ + ) + ); + } + + // Because we only support `language=sql` comment for both sql and hql, + // shouldn't do anything with `language=hql` comment + @Test + void shouldNotFormatWithLanguageHqlComment() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=hql + private static final String QUERY = \""" + select * from users\"""; + } + """ + ) + ); + } + + @Test + void shouldPreserveTextBlockIndentation() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + public class Inner { + // language=sql + private static final String QUERY = \""" + select * from users\"""; + } + } + """, + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + public class Inner { + // language=sql + private static final String QUERY = \""" + select + * + from + users\"""; + } + } + """ + ) + ); + } + + // Block already formatted — no diff + @Test + void shouldNotChangeAlreadyFormatted() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String QUERY = \""" + select + * + from + users\"""; + } + """ + ) + ); + } + + // Block with multiple variables in the same declaration, like + // String q1 = """...""", q2 = """..."""; + @Test + void shouldFormatMultipleVariablesInSameDeclaration() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String Q1 = \""" + select * from users\""", + Q2 = \""" + select * from orders\""", + Q3 = \""" + select * from products\"""; + } + """, + """ + package io.github.mhagnumdw.test; + + public class MyQuery { + // language=sql + private static final String Q1 = \""" + select + * + from + users\""", + Q2 = \""" + select + * + from + orders\""", + Q3 = \""" + select + * + from + products\"""; + } + """ + ) + ); + } + + // Class outside the filePath — does not change + @Test + void shouldNotChangeUnrelatedClasses() { + rewriteRun( + java( + """ + package io.github.mhagnumdw.other; + + public class OtherQuery { + // language=sql + private static final String QUERY = \""" + select * from users ORDER by name\"""; + } + """ + ) + ); + } + +} From 3147aa16f5bcd5c1d1e08f325ff44c493521d0c9 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Fri, 24 Apr 2026 18:39:21 -0300 Subject: [PATCH 2/9] fix sonar --- .vscode/settings.json | 6 +++++- .../github/mhagnumdw/FormatSqlTextBlockVisitor.java | 11 ++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2e6f00d..706a886 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,9 @@ "jakarta", "openrewrite", "plsql" - ] + ], + "sonarlint.connectedMode.project": { + "connectionId": "SonarQube for IDE - Visual Studio Code", + "projectKey": "mhagnumdw_rewrite-format-sql" + } } diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java index ba63084..487da59 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java @@ -41,8 +41,8 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v boolean changed = false; for (int i = 0; i < variables.size(); i++) { - J.VariableDeclarations.NamedVariable var = variables.get(i); - Expression initializer = var.getInitializer(); + J.VariableDeclarations.NamedVariable variable = variables.get(i); + Expression initializer = variable.getInitializer(); if (initializer == null || !TextBlockUtil.isTextBlock(initializer)) { continue; @@ -55,9 +55,9 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v (Literal) initializer, indentation, dialect, formatConfig); if (newLiteral != null) { - var = var.withInitializer(newLiteral); + variable = variable.withInitializer(newLiteral); List newVariables = new ArrayList<>(variables); - newVariables.set(i, var); + newVariables.set(i, variable); variables = newVariables; changed = true; } @@ -72,9 +72,6 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v private static boolean hasLanguageSqlComment(J.VariableDeclarations varDecls) { List comments = varDecls.getPrefix().getComments(); - if (comments == null) { - return false; - } for (Comment comment : comments) { if (comment instanceof TextComment) { From 8373fee9164345de6ef1c9056733074c825bdf2a Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Fri, 24 Apr 2026 18:46:15 -0300 Subject: [PATCH 3/9] Ignora java:S2699 --- .../java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java index c5acb1b..d82e4dd 100644 --- a/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java +++ b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java @@ -8,6 +8,8 @@ import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +// SonarQube doesn't recognize internal assertions in rewriteRun() +@SuppressWarnings("java:S2699") class FormatSqlTextBlockRecipeTest implements RewriteTest { @Override From 42eb956cb647fa675cee88b9d080cea6b7b0fe25 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sat, 25 Apr 2026 17:27:45 -0300 Subject: [PATCH 4/9] Improve AnnotationOnlyOneArgumentProcessor --- pom.xml | 10 ++ .../mhagnumdw/FormatSqlTextBlockRecipe.java | 26 ++---- .../AnnotationOnlyOneArgumentProcessor.java | 92 +++---------------- .../resources/META-INF/rewrite/examples.yml | 2 +- 4 files changed, 31 insertions(+), 99 deletions(-) diff --git a/pom.xml b/pom.xml index 4c6a9a4..a097a62 100644 --- a/pom.xml +++ b/pom.xml @@ -94,11 +94,21 @@ junit-jupiter-api test + + org.junit.jupiter + junit-jupiter-engine + test + org.junit.jupiter junit-jupiter-params test + + org.junit.platform + junit-platform-launcher + test + org.openrewrite rewrite-java-17 diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java index 512627f..d50565f 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockRecipe.java @@ -1,19 +1,17 @@ package io.github.mhagnumdw; -import org.jspecify.annotations.Nullable; -import org.openrewrite.ExecutionContext; -import org.openrewrite.FindSourceFiles; -import org.openrewrite.Preconditions; -import org.openrewrite.TreeVisitor; -import org.openrewrite.java.search.UsesJavaVersion; - import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.vertical_blank.sqlformatter.core.FormatConfig; import com.github.vertical_blank.sqlformatter.languages.Dialect; - import lombok.EqualsAndHashCode; import lombok.Value; +import org.jspecify.annotations.Nullable; +import org.openrewrite.ExecutionContext; +import org.openrewrite.FindSourceFiles; +import org.openrewrite.Preconditions; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.search.UsesJavaVersion; @Value @EqualsAndHashCode(callSuper = false) @@ -31,16 +29,10 @@ public FormatSqlTextBlockRecipe( super(filePath == null ? DEFAULT_FILE_PATH : filePath, sqlDialect, indent, maxColumnLength, uppercase); } - @Override - public String getDisplayName() { - return "Format SQL Text Blocks marked with language injection comment"; - } + String displayName = "Format SQL Text Blocks marked with language injection comment"; - @Override - public String getDescription() { - return "Formats SQL code in Java Text Blocks that are preceded by " + - "a '// language=sql' comment (case-insensitive)."; - } + String description = "Formats SQL code in Java Text Blocks that are preceded by " + + "a '// language=sql' comment (case-insensitive)."; @Override TreeVisitor getFormattingVisitor( diff --git a/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java b/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java index 5f4bc02..579a208 100644 --- a/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java +++ b/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java @@ -1,26 +1,14 @@ package io.github.mhagnumdw.processors; import static java.util.Collections.singletonList; -import static org.openrewrite.Tree.randomId; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; +import io.github.mhagnumdw.TextBlockUtil; +import java.util.List; import org.openrewrite.Cursor; -import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.style.IntelliJ; -import org.openrewrite.java.style.TabsAndIndentsStyle; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.J.Literal; -import org.openrewrite.java.tree.JavaSourceFile; -import org.openrewrite.java.tree.JavaType; -import org.openrewrite.java.tree.TypeUtils; -import org.openrewrite.marker.Markers; -import org.openrewrite.style.Style; - -import java.util.List; - -import com.github.vertical_blank.sqlformatter.SqlFormatter; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; /** * This abstract class provides a common tasks for processing annotations that contain an annotation with single SQL/HQL @@ -34,12 +22,11 @@ abstract class AnnotationOnlyOneArgumentProcessor implements AnnotationProcessor @Override public final J.Annotation process(J.Annotation annotation, Cursor cursor, Dialect dialect, FormatConfig formatConfig) { - JavaType type = annotation.getType(); - if (type == null) { + if (annotation.getType() == null) { return annotation; } - if (!getFQN().equals(type.toString())) { + if (!getFQN().equals(annotation.getType().toString())) { return annotation; } @@ -51,78 +38,21 @@ public final J.Annotation process(J.Annotation annotation, Cursor cursor, Dialec Expression arg = args.get(0); - if (!isTextBlock(arg)) { + if (!TextBlockUtil.isTextBlock(arg)) { return annotation; } - J.Literal literal = (Literal) arg; - String sql = (String) literal.getValue(); - - String sqlFormatted = SqlFormatter.of(dialect).format(sql, formatConfig); - - String indentation = getParentIndentation(cursor) + getFileIndent(cursor); - - // handle preceding indentation - sqlFormatted = sqlFormatted.replace("\n", "\n" + indentation); + J.Literal literal = (J.Literal) arg; + String indentation = TextBlockUtil.getParentIndentation(cursor) + TextBlockUtil.getFileIndent(cursor); - // add first line - sqlFormatted = "\n" + indentation + sqlFormatted; + J.Literal newLiteral = TextBlockUtil.formatTextBlock(literal, indentation, dialect, formatConfig); - if (sqlFormatted.equals(sql)) { + if (newLiteral == null) { // nothing has changed return annotation; } - J.Literal newLiteral = new J.Literal(randomId(), literal.getPrefix(), Markers.EMPTY, sqlFormatted, - String.format("\"\"\"%s\"\"\"", sqlFormatted), null, JavaType.Primitive.String); - return annotation.withArguments(singletonList(newLiteral)); } - // Retrieve the file indentation based on the style of the file - private String getFileIndent(Cursor cursor) { - JavaSourceFile sf = cursor.firstEnclosingOrThrow(JavaSourceFile.class); - TabsAndIndentsStyle style = Style.from(TabsAndIndentsStyle.class, sf); - if (style == null) { - style = IntelliJ.tabsAndIndents(); - } - - boolean useTab = style.getUseTabCharacter(); - int tabSize = style.getTabSize(); - - if (useTab) { - return "\t"; - } - return StringUtils.repeat(" ", tabSize); - } - - // From: https://github.com/openrewrite/rewrite-migrate-java/blob/main/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java - private static boolean isTextBlock(Expression expr) { - if (expr instanceof J.Literal) { - J.Literal l = (J.Literal) expr; - return TypeUtils.isString(l.getType()) && - l.getValueSource() != null && - l.getValueSource().startsWith("\"\"\""); - } - return false; - } - - // Retrieve the indentation of the parent method declaration - private static String getParentIndentation(Cursor cursor) { - Cursor parentCursor = cursor.getParent(); - - while (parentCursor != null) { - Object parent = parentCursor.getValue(); - - if (parent instanceof J.MethodDeclaration) { - J.MethodDeclaration lstNode = (J.MethodDeclaration) parent; - return lstNode.getPrefix().getIndent(); - } - - parentCursor = parentCursor.getParent(); - } - - return ""; - } - } diff --git a/src/main/resources/META-INF/rewrite/examples.yml b/src/main/resources/META-INF/rewrite/examples.yml index 0e51fc4..215aa43 100644 --- a/src/main/resources/META-INF/rewrite/examples.yml +++ b/src/main/resources/META-INF/rewrite/examples.yml @@ -47,7 +47,7 @@ examples: type: specs.openrewrite.org/v1beta/example recipeName: io.github.mhagnumdw.FormatSqlTextBlockRecipe examples: -- description: '' +- description: '`FormatSqlTextBlockRecipeTest#shouldFormatFieldWithLanguageSqlComment`' parameters: - io/github/mhagnumdw/test/*.java - sql From 6068a50fda344a555db8833a42d33c1203867345 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sat, 25 Apr 2026 17:33:02 -0300 Subject: [PATCH 5/9] fix openrewrite --- .../java/io/github/mhagnumdw/FormatSqlBlockRecipe.java | 5 ++--- .../java/io/github/mhagnumdw/FormatSqlBlockVisitor.java | 5 ++--- src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java | 5 ++--- .../java/io/github/mhagnumdw/FormatSqlFileVisitor.java | 7 +++---- .../java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java | 5 ++--- .../io/github/mhagnumdw/FormatSqlTextBlockVisitor.java | 5 ++--- src/main/java/io/github/mhagnumdw/TextBlockUtil.java | 7 +++---- .../processors/AnnotationOnlyOneArgumentProcessor.java | 3 ++- .../github/mhagnumdw/processors/AnnotationProcessor.java | 5 ++--- 9 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java index 3cde71c..6ccf2af 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -11,9 +13,6 @@ import org.openrewrite.TreeVisitor; import org.openrewrite.java.search.UsesJavaVersion; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * A recipe that formats SQL/HQL in Text Blocks within Java source files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java index 2c299cd..05e3913 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java @@ -1,14 +1,13 @@ package io.github.mhagnumdw; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import io.github.mhagnumdw.processors.Annotations; import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - public class FormatSqlBlockVisitor extends JavaIsoVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java index 27c0207..82f9fea 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -10,9 +12,6 @@ import org.openrewrite.Preconditions; import org.openrewrite.TreeVisitor; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * A recipe that formats SQL text files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java index ef3a2b5..716ddcc 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java @@ -1,5 +1,8 @@ package io.github.mhagnumdw; +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.jspecify.annotations.Nullable; import org.openrewrite.ExecutionContext; import org.openrewrite.SourceFile; @@ -9,10 +12,6 @@ import java.util.Objects; -import com.github.vertical_blank.sqlformatter.SqlFormatter; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - public class FormatSqlFileVisitor extends TreeVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java index 0130924..45878c8 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java @@ -1,6 +1,8 @@ package io.github.mhagnumdw; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Getter; import org.jspecify.annotations.Nullable; @@ -9,9 +11,6 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * Abstract base class for SQL formatting recipes. * Provides common configuration options and methods for SQL formatting. diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java index 487da59..11008bb 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlTextBlockVisitor.java @@ -2,6 +2,8 @@ import static org.openrewrite.java.tree.J.Literal; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.Comment; @@ -13,9 +15,6 @@ import java.util.List; import java.util.regex.Pattern; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - public class FormatSqlTextBlockVisitor extends JavaIsoVisitor { private static final Pattern LANGUAGE_SQL_PATTERN = Pattern.compile( diff --git a/src/main/java/io/github/mhagnumdw/TextBlockUtil.java b/src/main/java/io/github/mhagnumdw/TextBlockUtil.java index bebc0b4..5e7ed78 100644 --- a/src/main/java/io/github/mhagnumdw/TextBlockUtil.java +++ b/src/main/java/io/github/mhagnumdw/TextBlockUtil.java @@ -2,6 +2,9 @@ import static org.openrewrite.Tree.randomId; +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.jspecify.annotations.Nullable; import org.openrewrite.Cursor; import org.openrewrite.internal.StringUtils; @@ -15,10 +18,6 @@ import org.openrewrite.marker.Markers; import org.openrewrite.style.Style; -import com.github.vertical_blank.sqlformatter.SqlFormatter; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * Utility class for formatting SQL in Java Text Blocks. * Provides shared methods used by both annotation processors and the Text Block visitor. diff --git a/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java b/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java index 579a208..c4cef40 100644 --- a/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java +++ b/src/main/java/io/github/mhagnumdw/processors/AnnotationOnlyOneArgumentProcessor.java @@ -5,11 +5,12 @@ import com.github.vertical_blank.sqlformatter.core.FormatConfig; import com.github.vertical_blank.sqlformatter.languages.Dialect; import io.github.mhagnumdw.TextBlockUtil; -import java.util.List; import org.openrewrite.Cursor; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; +import java.util.List; + /** * This abstract class provides a common tasks for processing annotations that contain an annotation with single SQL/HQL * string as their argument. It handles the extraction of the query, formatting it, and updating the annotation with diff --git a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java index 17d3c40..d2e5efc 100644 --- a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java +++ b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java @@ -1,10 +1,9 @@ package io.github.mhagnumdw.processors; -import org.openrewrite.Cursor; -import org.openrewrite.java.tree.J; - import com.github.vertical_blank.sqlformatter.core.FormatConfig; import com.github.vertical_blank.sqlformatter.languages.Dialect; +import org.openrewrite.Cursor; +import org.openrewrite.java.tree.J; /** * This interface defines the contract for processing annotations that contain an annotation with SQL/HQL. From 27446d57c19028503e2733867cf4158d95cbb38b Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sat, 25 Apr 2026 17:44:13 -0300 Subject: [PATCH 6/9] Remove only the import changes that OpenRewrite is making --- .../java/io/github/mhagnumdw/FormatSqlBlockRecipe.java | 5 +++-- .../java/io/github/mhagnumdw/FormatSqlBlockVisitor.java | 5 +++-- src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java | 5 +++-- .../java/io/github/mhagnumdw/FormatSqlFileVisitor.java | 7 ++++--- .../java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java | 5 +++-- .../github/mhagnumdw/processors/AnnotationProcessor.java | 5 +++-- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java index 6ccf2af..3cde71c 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -13,6 +11,9 @@ import org.openrewrite.TreeVisitor; import org.openrewrite.java.search.UsesJavaVersion; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + /** * A recipe that formats SQL/HQL in Text Blocks within Java source files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java index 05e3913..2c299cd 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java @@ -1,13 +1,14 @@ package io.github.mhagnumdw; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import io.github.mhagnumdw.processors.Annotations; import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + public class FormatSqlBlockVisitor extends JavaIsoVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java index 82f9fea..27c0207 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -12,6 +10,9 @@ import org.openrewrite.Preconditions; import org.openrewrite.TreeVisitor; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + /** * A recipe that formats SQL text files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java index 716ddcc..ef3a2b5 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java @@ -1,8 +1,5 @@ package io.github.mhagnumdw; -import com.github.vertical_blank.sqlformatter.SqlFormatter; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.jspecify.annotations.Nullable; import org.openrewrite.ExecutionContext; import org.openrewrite.SourceFile; @@ -12,6 +9,10 @@ import java.util.Objects; +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + public class FormatSqlFileVisitor extends TreeVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java index 45878c8..0130924 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java @@ -1,8 +1,6 @@ package io.github.mhagnumdw; import com.fasterxml.jackson.annotation.JsonProperty; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Getter; import org.jspecify.annotations.Nullable; @@ -11,6 +9,9 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + /** * Abstract base class for SQL formatting recipes. * Provides common configuration options and methods for SQL formatting. diff --git a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java index d2e5efc..17d3c40 100644 --- a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java +++ b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java @@ -1,10 +1,11 @@ package io.github.mhagnumdw.processors; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.openrewrite.Cursor; import org.openrewrite.java.tree.J; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; + /** * This interface defines the contract for processing annotations that contain an annotation with SQL/HQL. * Implementations of this interface are responsible for extracting the query from the annotation, From d4fa8c32327565e551f922453d04d3a99e7c89a1 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sat, 25 Apr 2026 18:16:48 -0300 Subject: [PATCH 7/9] Revert "Remove only the import changes that OpenRewrite is making" This reverts commit 27446d57c19028503e2733867cf4158d95cbb38b. --- .../java/io/github/mhagnumdw/FormatSqlBlockRecipe.java | 5 ++--- .../java/io/github/mhagnumdw/FormatSqlBlockVisitor.java | 5 ++--- src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java | 5 ++--- .../java/io/github/mhagnumdw/FormatSqlFileVisitor.java | 7 +++---- .../java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java | 5 ++--- .../github/mhagnumdw/processors/AnnotationProcessor.java | 5 ++--- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java index 3cde71c..6ccf2af 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockRecipe.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -11,9 +13,6 @@ import org.openrewrite.TreeVisitor; import org.openrewrite.java.search.UsesJavaVersion; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * A recipe that formats SQL/HQL in Text Blocks within Java source files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java index 2c299cd..05e3913 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlBlockVisitor.java @@ -1,14 +1,13 @@ package io.github.mhagnumdw; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import io.github.mhagnumdw.processors.Annotations; import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - public class FormatSqlBlockVisitor extends JavaIsoVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java index 27c0207..82f9fea 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileRecipe.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -10,9 +12,6 @@ import org.openrewrite.Preconditions; import org.openrewrite.TreeVisitor; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * A recipe that formats SQL text files. */ diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java index ef3a2b5..716ddcc 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlFileVisitor.java @@ -1,5 +1,8 @@ package io.github.mhagnumdw; +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import org.jspecify.annotations.Nullable; import org.openrewrite.ExecutionContext; import org.openrewrite.SourceFile; @@ -9,10 +12,6 @@ import java.util.Objects; -import com.github.vertical_blank.sqlformatter.SqlFormatter; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - public class FormatSqlFileVisitor extends TreeVisitor { private final Dialect dialect; diff --git a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java index 0130924..45878c8 100644 --- a/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java +++ b/src/main/java/io/github/mhagnumdw/FormatSqlRecipeAbstract.java @@ -1,6 +1,8 @@ package io.github.mhagnumdw; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.vertical_blank.sqlformatter.core.FormatConfig; +import com.github.vertical_blank.sqlformatter.languages.Dialect; import lombok.EqualsAndHashCode; import lombok.Getter; import org.jspecify.annotations.Nullable; @@ -9,9 +11,6 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; -import com.github.vertical_blank.sqlformatter.core.FormatConfig; -import com.github.vertical_blank.sqlformatter.languages.Dialect; - /** * Abstract base class for SQL formatting recipes. * Provides common configuration options and methods for SQL formatting. diff --git a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java index 17d3c40..d2e5efc 100644 --- a/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java +++ b/src/main/java/io/github/mhagnumdw/processors/AnnotationProcessor.java @@ -1,10 +1,9 @@ package io.github.mhagnumdw.processors; -import org.openrewrite.Cursor; -import org.openrewrite.java.tree.J; - import com.github.vertical_blank.sqlformatter.core.FormatConfig; import com.github.vertical_blank.sqlformatter.languages.Dialect; +import org.openrewrite.Cursor; +import org.openrewrite.java.tree.J; /** * This interface defines the contract for processing annotations that contain an annotation with SQL/HQL. From 7c21a61ed8f2479a0c43a0c868710931a542ed0d Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sun, 26 Apr 2026 12:22:41 -0300 Subject: [PATCH 8/9] Update README for FormatSqlTextBlockRecipe --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6725776..7b20227 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ The following options are applicable to `FormatSqlBlockRecipe`, `FormatSqlTextBl | Type | Name | Description | Example | Default Value | | :------ | :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------- | -| String | `filePath` | Optional. The path to the files that the Recipe should process. Accepts a glob expression; multiple patterns can be specified, separated by a semicolon `;`. If omitted, processes all matching files. | `**/*DAO.java`
`**/*.sql` | FormatSqlBlockRecipe: `**/*.java`
FormatSqlFileRecipe: `**/*.sql` | +| String | `filePath` | Optional. The path to the files that the Recipe should process. Accepts a glob expression; multiple patterns can be specified, separated by a semicolon `;`. If omitted, processes all matching files. | `**/*DAO.java`
`**/*.sql` | FormatSqlBlockRecipe: `**/*.java`
FormatSqlTextBlockRecipe: `**/*.java`
FormatSqlFileRecipe: `**/*.sql` | | String | `sqlDialect` | Optional. The SQL dialect to be used for formatting. Valid options: `sql` (StandardSql), `mysql`, `postgresql`, `db2`, `plsql` (Oracle PL/SQL), `n1ql` (Couchbase N1QL), `redshift`, `spark`, `tsql` (SQL Server Transact-SQL). Details [here](https://github.com/vertical-blank/sql-formatter). | `plsql` | `sql` | | String | `indent` | Optional. The string to be used for indentation. | `" "` for 2 spaces
`"\t"` for a tab | 4 spaces `" "` | | Integer | `maxColumnLength` | Optional. The maximum length of a line before the formatter tries to break it. | `100` | `120` | @@ -175,6 +175,7 @@ Inside the plugins section, add: io.github.mhagnumdw.FormatSqlBlockRecipe + io.github.mhagnumdw.FormatSqlTextBlockRecipe io.github.mhagnumdw.FormatSqlFileRecipe false @@ -205,6 +206,8 @@ recipeList: # Add the Recipes you want to use here - io.github.mhagnumdw.FormatSqlBlockRecipe: sqlDialect: "plsql" + - io.github.mhagnumdw.FormatSqlTextBlockRecipe: + sqlDialect: "plsql" - io.github.mhagnumdw.FormatSqlFileRecipe: sqlDialect: "mysql" ``` @@ -220,7 +223,7 @@ And change the `` tag in `pom.xml` to: io.github.mhagnumdw.FormatSqlCustomConfig ``` -> As in this example the `FormatSqlCustomConfig` recipe includes both `FormatSqlBlockRecipe` and `FormatSqlFileRecipe` recipes, in `pom.xml` it is only necessary to define the `FormatSqlCustomConfig` recipe. +> As in this example the `FormatSqlCustomConfig` recipe includes both `FormatSqlBlockRecipe`, `FormatSqlTextBlockRecipe` and `FormatSqlFileRecipe` recipes, in `pom.xml` it is only necessary to define the `FormatSqlCustomConfig` recipe. Then run: @@ -236,7 +239,7 @@ This mode is indicated if your intention is to run the recipe only once. ```bash ./mvnw org.openrewrite.maven:rewrite-maven-plugin:run \ - -Drewrite.activeRecipes=io.github.mhagnumdw.FormatSqlBlockRecipe,io.github.mhagnumdw.FormatSqlFileRecipe \ + -Drewrite.activeRecipes=io.github.mhagnumdw.FormatSqlBlockRecipe,io.github.mhagnumdw.FormatSqlTextBlockRecipe,io.github.mhagnumdw.FormatSqlFileRecipe \ -Drewrite.recipeArtifactCoordinates=io.github.mhagnumdw:rewrite-format-sql:1.0.0 ``` From 6e93b85a1f09f96c0d04ee21bdee7f97ca969304 Mon Sep 17 00:00:00 2001 From: Dwouglas Mhagnum Date: Sun, 26 Apr 2026 12:22:49 -0300 Subject: [PATCH 9/9] fix sonar --- .../java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java index d82e4dd..1b117b7 100644 --- a/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java +++ b/src/test/java/io/github/mhagnumdw/FormatSqlTextBlockRecipeTest.java @@ -253,8 +253,7 @@ public class MyQuery { ); } - // Block with multiple variables in the same declaration, like - // String q1 = """...""", q2 = """..."""; + // Block with multiple variables in the same declaration @Test void shouldFormatMultipleVariablesInSameDeclaration() { rewriteRun(