Klassisch
String query =
"SELECT * \n" +
"FROM my_table\n" +
"WHERE something = 1;";
Merlin Bögershausen / @mboegie
Refactoring is a controlled technique for improving the design of an existing code base. Its essence is applying a series of small behavior-preserving transformations, each of which "too small to be worth doing".
Klassisch
String query =
"SELECT * \n" +
"FROM my_table\n" +
"WHERE something = 1;";
Java 15+
String query = """
SELECT *
FROM my_table
WHERE something = 1;
""";
➜ |
@Before /*->*/ @BeforeEach
@AfterClass /*->*/ @AfterAll
@Test(expected = IndexOutOfBoundsException.class)
/*->*/ assertThrows(IndexOutOfBoundsException.class, () -> {})
Assert.assertEquals("One is one", 1, 1);
/*->*/ Assertions.assertEquals(1, 1, "One is one");
@Test(timeout = 500) /*->*/ @Test @Timeout(500)
Commonhaus Foundation |
class T {
java.util.List<String> list;
}
import java.util.List;
class T {
List<String> list;
}
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
-Drewrite.activeRecipes=org.openrewrite.java.\
ShortenFullyQualifiedTypeReferences
rewrite-maven-plugin:5.20.0:run (default-cli) @ spring-petclinic
Using active recipe(s) [o.o.h.ShortenFullyQualifiedTypeReferences]
Using active styles(s) []
Validating active recipes...
Project [petclinic] Resolving Poms...
Project [petclinic] Parsing source files
Running recipe(s)...
Changes have been made to o/s/e/petclinic/vet/Vet.java by:
o.o.j.ShortenFullyQualifiedTypeReferences
Please review and commit the results.
<!-- project/build/plugins -->
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.17.1</version> <!-- keep this up to date 😉 -->
<configuration>
<activeRecipes>
<recipe>
org.openrewrite.java.ShortenFullyQualifiedTypeReferences
</recipe>
</activeRecipes>
</configuration>
</plugin>
Migrate to Spring Boot 3.2 (from 2.0 😱🤯)
📝 Recipe UpgradeSpringBoot_3_2
-Drewrite.recipeArtifactCoordinates=\
org.openrewrite.recipe:rewrite-spring:RELEASE \
-Drewrite.activeRecipes=\
org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2
Changes have been made to src/main/java/o/s/s/p/v/Vet.java by:
o.o.j.spring.boot3.UpgradeSpringBoot_3_2
o.o.j.spring.boot3.UpgradeSpringBoot_3_1
o.o.j.spring.boot3.UpgradeSpringBoot_3_0
o.o.j.migrate.UpgradeToJava17
o.o.j.migrate.Java8toJava11
o.o.j.migrate.JavaVersion11
o.o.j.migrate.UpgradeJavaVersion: {version=11}
o.o.j.migrate.JavaVersion17
o.o.j.migrate.UpgradeJavaVersion: {version=17}
o.o.j.migrate.jakarta.JavaxMigrationToJakarta
If it can be declarative,
do it declarative!
class SomeCallee {
@java.lang.SuppressWarnings("deprecation") // 🤡
void doIllegalStuff() {
someService.oldOperation(); // ok..
}
}
class SomeService {
@java.lang.Deprecated
void oldOperation(){/*..*/}
}
---
type: specs.openrewrite.org/v1beta/recipe
name: io.github.mboegers.RemoveDeprecationSuppression
displayName: Remove SuppressWarnings for deprecation
recipeList:
- org.openrewrite.java.RemoveAnnotation:
annotationPattern: \
'@java.lang.SuppressWarnings("deprecation")'
class SomeCallee {
void doIllegalStuff() {
someService.oldOperation();
}
}
class SomeService { /*...*/ }
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.`
class SomeCallee {
void doIllegalStuff() {
someService.oldOperation(); // ⚠️
}
}
class SomeService {
@java.lang.Deprecated
void oldOperation(){/*..*/}
void betterOperation(){/*..*/}
}
@RecipeDescriptor(
name = "Replace oldOperation with betterOperation",
description = "Replace deprecated ´oldOperation´ " +
"with surrogate ´betterOperation´")
public static class ReplaceOldOperation {
@BeforeTemplate
public void oldOperation(SomeService s) {
s.oldOperation();
}
@AfterTemplate
public void newOperation(SomeService s) {
s.betterOperation();
}
}
class SomeCallee {
void doIllegalStuff() {
someService.betterOperation(); // 👌
}
}
class SomeService {
@java.lang.Deprecated
void oldOperation(){/*..*/}
void betterOperation(){/*..*/}
}
class A {
void test() {
int a;
a = 0;
}
}
-J.CompilationUnit
\-J.ClassDeclaration
|-J.Identifier | "A"
\-J.Block
\-J.MethodDeclaration | "MethodDeclaration{A{name=test,return=void,parameters=[]}}"
|---J.Primitive | "void"
|---J.Identifier | "test"
public class MakePublic extends Recipe {
@Override
protected JavaVisitor<ExecutionContext> getVisitor() {
return new ChangeTypeVisitor();
}
public String getDisplayName() {
return "Make Class Public";
}
private class MakePublicVisitor
extends JavaVisitor<ExecutionContext> {}
}
Bearbeite den LST mit Visitors
class JavaVisitor<P> extends TreeVisitor<J, P> {
J visitStatement(Statement statement) {}
J visitAnnotatedType(J.AnnotatedType annotatedType) {}
J visitAnnotation(J.Annotation annotation) {}
J visitAssert(J.Assert azzert) {}
J visitAssignment(J.Assignment assign) {}
J visitAssignmentOperation(J.AssignmentOperation assignOp) {}
//...
}
new JavaIsoVisitor<ExecutionContext> {
public J.ClassDeclaration visitClassDeclaration(
J.ClassDeclaration cd, ExecutionContext ctx) {
cd = super.visitClassDeclaration(cd, ctx);
List<J.Modifier> modifiers = cd.getModifiers();
modifiers.removeIf(
m -> J.Modifier.Type.Private.equals(m.getType()));
// and Protected & Public
modifiers.add(PUBLIC_MODIFIER);
return cd.withModifiers(modifiers);
}
}
type: specs.openrewrite.org/v1beta/style
name: io.moderne.spring.style
styleConfigs:
- org.openrewrite.java.style.NeedBracesStyle:
allowSingleLineStatement: false
allowEmptyLoopBody: true
for(int i = 0; i < 10; i++);
if(success()) return false;
for(int i = 0; i < 10; i++);
if(success()){
return false;
}
Declarative
Refaster Templates
Imperative
Always test driven, see you in a few minutes!
Project Logos from respective Project Page
Migration Types from Moderne Prove of Value
Moderne UI Screenshot by Author
IKEA instruction from justinzhuang.com
DIY Titelbild Bild von Freepik
Schüler Bild von Freepik
Commonhaus Logo from https://github.com/commonhaus/foundation
Modernes Commonhaus Statement from Twitter/X