Skip to content

Commit c050b14

Browse files
authored
Migrate Micronaut Nullability annotations to JSpecify nullability annotations (#950)
1 parent fadd76b commit c050b14

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ dependencies {
9090
testRuntimeOnly("org.jboss.logging:jboss-logging:3.6.0.Final")
9191
testRuntimeOnly("jakarta.annotation:jakarta.annotation-api:2.1.1")
9292
testRuntimeOnly("org.springframework:spring-core:6.1.13")
93+
testRuntimeOnly("io.micronaut:micronaut-core:4.10.8")
9394
testRuntimeOnly("com.google.code.findbugs:jsr305:3.0.2")
9495
testRuntimeOnly("javax.mail:mail:1.4.7")
9596
testRuntimeOnly("javax.mail:javax.mail-api:1.6.2")

src/main/resources/META-INF/rewrite/jspecify.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ recipeList:
4141
- org.openrewrite.java.jspecify.MigrateFromJakartaAnnotationApi
4242
- org.openrewrite.java.jspecify.MigrateFromJetbrainsAnnotations
4343
- org.openrewrite.java.jspecify.MigrateFromMicrometerAnnotations
44+
- org.openrewrite.java.jspecify.MigrateFromMicronautAnnotations
4445
# Running the following recipe on current versions of Spring can cause Spring to misunderstand a nullable field.
4546
# For instance, a custom Prometheus scrape endpoint with @Nullable Set<String> includedNames will fail if
4647
# includedNames is null and if @Nullable is @org.jspecify.annotations.Nullable.
@@ -160,3 +161,25 @@ recipeList:
160161
ignoreDefinition: true
161162
- org.openrewrite.staticanalysis.java.MoveFieldAnnotationToType:
162163
annotationType: org.jspecify.annotations.*
164+
---
165+
type: specs.openrewrite.org/v1beta/recipe
166+
name: org.openrewrite.java.jspecify.MigrateFromMicronautAnnotations
167+
displayName: Migrate from Micronaut Framework annotations to JSpecify
168+
description: Migrate from Micronaut Framework annotations to JSpecify.
169+
recipeList:
170+
- org.openrewrite.java.dependencies.AddDependency:
171+
groupId: org.jspecify
172+
artifactId: jspecify
173+
version: 1.0.0
174+
onlyIfUsing: io.micronaut.core.annotation.*ull*
175+
acceptTransitive: true
176+
- org.openrewrite.java.ChangeType:
177+
oldFullyQualifiedTypeName: io.micronaut.core.annotation.Nullable
178+
newFullyQualifiedTypeName: org.jspecify.annotations.Nullable
179+
ignoreDefinition: true
180+
- org.openrewrite.java.ChangeType:
181+
oldFullyQualifiedTypeName: io.micronaut.core.annotation.NonNull
182+
newFullyQualifiedTypeName: org.jspecify.annotations.NonNull
183+
ignoreDefinition: true
184+
- org.openrewrite.staticanalysis.java.MoveFieldAnnotationToType:
185+
annotationType: org.jspecify.annotations.*

src/test/java/org/openrewrite/java/migrate/jspecify/JSpecifyBestPracticesTest.java

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class JSpecifyBestPracticesTest implements RewriteTest {
3232
public void defaults(RecipeSpec spec) {
3333
spec
3434
.recipeFromResource("/META-INF/rewrite/jspecify.yml", "org.openrewrite.java.jspecify.JSpecifyBestPractices")
35-
.parser(JavaParser.fromJavaVersion().classpath("jsr305", "jakarta.annotation-api", "annotations", "spring-core"));
35+
.parser(JavaParser.fromJavaVersion().classpath("jsr305", "jakarta.annotation-api", "annotations", "spring-core", "micronaut-core"));
3636
}
3737

3838
@DocumentExample
@@ -420,4 +420,96 @@ class Bar {
420420
)
421421
);
422422
}
423+
424+
@Test
425+
void migrateFromMicronautAnnotationToJspecify() {
426+
rewriteRun(
427+
mavenProject("foo",
428+
//language=java
429+
srcMainJava(
430+
java(
431+
"""
432+
import io.micronaut.core.annotation.NonNull;
433+
import io.micronaut.core.annotation.Nullable;
434+
435+
public class Test {
436+
@NonNull
437+
public String field1;
438+
@Nullable
439+
public String field2;
440+
@Nullable
441+
public Foo.Bar foobar;
442+
}
443+
444+
interface Foo {
445+
class Bar {
446+
@NonNull
447+
public String barField;
448+
}
449+
}
450+
""",
451+
"""
452+
import org.jspecify.annotations.NonNull;
453+
import org.jspecify.annotations.Nullable;
454+
455+
public class Test {
456+
@NonNull
457+
public String field1;
458+
@Nullable
459+
public String field2;
460+
461+
public Foo.@Nullable Bar foobar;
462+
}
463+
464+
interface Foo {
465+
class Bar {
466+
@NonNull
467+
public String barField;
468+
}
469+
}
470+
"""
471+
)
472+
)
473+
,
474+
//language=xml
475+
pomXml(
476+
"""
477+
<project>
478+
<modelVersion>4.0.0</modelVersion>
479+
<groupId>com.example.foobar</groupId>
480+
<artifactId>foobar-core</artifactId>
481+
<version>1.0.0</version>
482+
<dependencies>
483+
<dependency>
484+
<groupId>io.micronaut</groupId>
485+
<artifactId>micronaut-core</artifactId>
486+
<version>4.10.8</version>
487+
</dependency>
488+
</dependencies>
489+
</project>
490+
""",
491+
"""
492+
<project>
493+
<modelVersion>4.0.0</modelVersion>
494+
<groupId>com.example.foobar</groupId>
495+
<artifactId>foobar-core</artifactId>
496+
<version>1.0.0</version>
497+
<dependencies>
498+
<dependency>
499+
<groupId>io.micronaut</groupId>
500+
<artifactId>micronaut-core</artifactId>
501+
<version>4.10.8</version>
502+
</dependency>
503+
<dependency>
504+
<groupId>org.jspecify</groupId>
505+
<artifactId>jspecify</artifactId>
506+
<version>1.0.0</version>
507+
</dependency>
508+
</dependencies>
509+
</project>
510+
"""
511+
)
512+
)
513+
);
514+
}
423515
}

0 commit comments

Comments
 (0)