Skip to content

Commit

Permalink
Merge branch 'openrewrite:main' into feature/ChangePropertyVersions
Browse files Browse the repository at this point in the history
  • Loading branch information
marcel-gepardec authored Jul 22, 2024
2 parents 826619e + 3de7723 commit 35028b4
Show file tree
Hide file tree
Showing 199 changed files with 1,325 additions and 1,116 deletions.
21 changes: 7 additions & 14 deletions rewrite-core/src/main/java/org/openrewrite/Cursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ public Object next() {
}
}

@Nullable
public <T> T firstEnclosing(Class<T> tClass) {
public <T> @Nullable T firstEnclosing(Class<T> tClass) {
CursorIterator iter = new CursorIterator(this);
while (iter.hasNext()) {
Object value = iter.next();
Expand Down Expand Up @@ -214,17 +213,15 @@ public Cursor dropParentWhile(Predicate<Object> valuePredicate) {
return cursor;
}

@Nullable
public Cursor getParent(int levels) {
public @Nullable Cursor getParent(int levels) {
Cursor cursor = this;
for (int i = 0; i < levels && cursor != null; i++) {
cursor = cursor.parent;
}
return cursor;
}

@Nullable
public Cursor getParent() {
public @Nullable Cursor getParent() {
return getParent(1);
}

Expand Down Expand Up @@ -292,8 +289,7 @@ public <T> T computeMessageIfAbsent(String key, Function<String, ? extends T> ma
* @param <T> The expected value of the message.
* @return The closest message matching the provided key in the cursor stack, or <code>null</code> if none.
*/
@Nullable
public <T> T getNearestMessage(String key) {
public <T> @Nullable T getNearestMessage(String key) {
@SuppressWarnings("unchecked") T t = messages == null ? null : (T) messages.get(key);
return t == null && parent != null ? parent.getNearestMessage(key) : t;
}
Expand All @@ -316,8 +312,7 @@ public <T> T getNearestMessage(String key, T defaultValue) {
* @param <T> The expected value of the message.
* @return The closest message matching the provided key in the cursor stack, or <code>null</code> if none.
*/
@Nullable
public <T> T pollNearestMessage(String key) {
public <T> @Nullable T pollNearestMessage(String key) {
@SuppressWarnings("unchecked") T t = messages == null ? null : (T) messages.remove(key);
return t == null && parent != null ? parent.pollNearestMessage(key) : t;
}
Expand All @@ -329,8 +324,7 @@ public <T> T pollNearestMessage(String key) {
* @param <T> The expected value of the message.
* @return The message matching the provided key, or <code>null</code> if none.
*/
@Nullable
public <T> T getMessage(String key) {
public <T> @Nullable T getMessage(String key) {
//noinspection unchecked
return messages == null ? null : (T) messages.get(key);
}
Expand All @@ -347,8 +341,7 @@ public <T> T getMessage(String key, T defaultValue) {
* @param <T> The expected value of the message.
* @return The message matching the provided key, or <code>null</code> if none.
*/
@Nullable
public <T> T pollMessage(String key) {
public <T> @Nullable T pollMessage(String key) {
//noinspection unchecked
return messages == null ? null : (T) messages.remove(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new TreeVisitor<Tree, ExecutionContext>() {
@Nullable

@Override
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (tree instanceof SourceFile) {
SourceFile sourceFile = (SourceFile) tree;
Path sourcePath = sourceFile.getSourcePath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ default Set<TreeObserver.Subscription> getObservers() {

void putMessage(String key, @Nullable Object value);

@Nullable <T> T getMessage(String key);
<T> @Nullable T getMessage(String key);

default <V, T> T computeMessage(String key, V value, Supplier<T> defaultValue, BiFunction<V, ? super T, ? extends T> remappingFunction) {
T oldMessage = getMessage(key);
Expand Down Expand Up @@ -83,7 +83,7 @@ default <T> T getMessage(String key, @Nullable T defaultValue) {
return t == null ? defaultValue : t;
}

@Nullable <T> T pollMessage(String key);
<T> @Nullable T pollMessage(String key);

@SuppressWarnings("unused")
default <T> T pollMessage(String key, T defaultValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ public class FileAttributes {

long size;

@Nullable
public static FileAttributes fromPath(Path path) {
public static @Nullable FileAttributes fromPath(Path path) {
if (Files.exists(path)) {
try {
BasicFileAttributes basicFileAttributes = Files.readAttributes(path, BasicFileAttributes.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new TreeVisitor<Tree, ExecutionContext>() {
@Nullable

@Override
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (tree instanceof SourceFile) {
SourceFile sourceFile = (SourceFile) tree;
Path sourcePath = sourceFile.getSourcePath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,13 @@ public void putMessage(String key, @Nullable Object value) {
}

@Override
@Nullable
public <T> T getMessage(String key) {
public <T> @Nullable T getMessage(String key) {
//noinspection unchecked
return (T) messages.get(key);
}

@Override
@Nullable
public <T> T pollMessage(String key) {
public <T> @Nullable T pollMessage(String key) {
//noinspection unchecked
return (T) messages.remove(key);
}
Expand Down
90 changes: 87 additions & 3 deletions rewrite-core/src/main/java/org/openrewrite/Recipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import org.intellij.lang.annotations.Language;
import org.openrewrite.config.DataTableDescriptor;
import org.openrewrite.config.OptionDescriptor;
Expand Down Expand Up @@ -195,8 +198,7 @@ public Set<String> getTags() {
/**
* @return An estimated effort were a developer to fix manually instead of using this recipe.
*/
@Nullable
public Duration getEstimatedEffortPerOccurrence() {
public @Nullable Duration getEstimatedEffortPerOccurrence() {
return Duration.ofMinutes(5);
}

Expand Down Expand Up @@ -308,11 +310,40 @@ public boolean causesAnotherCycle() {
* A list of recipes that run, source file by source file,
* after this recipe. This method is guaranteed to be called only once
* per cycle.
* <p>
* When creating a recipe with a fixed recipe list, either override
* this method or {@link #buildRecipeList(RecipeList)} but ideally not
* both, as their default implementations are interconnected.
*
* @return The list of recipes to run.
*/
public List<Recipe> getRecipeList() {
return Collections.emptyList();
RecipeList list = new RecipeList(getName());
buildRecipeList(list);
return list.getRecipes();
}

/**
* Used to build up a recipe list programmatically. Using the
* methods on {@link RecipeList}, the appearance of a recipe
* that chains other recipes with options will be not strikingly
* different from defining it in a recipe.yml.
* <p>
* Building, or at least starting to build, recipes for complex
* migrations with this method is more amenable to AI coding assistants
* since these assistants are primarily optimized for providing completion
* assistance in a single file.
* <p>
* When creating a recipe with a fixed recipe list, either override
* this method or {@link #getRecipeList()} but ideally not
* both, as their default implementations are interconnected.
*
* @param list A recipe list used to build up a series of recipes
* in code in a way that looks fairly declarative and
* therefore is more amenable to AI code completion.
*/
@SuppressWarnings("unused")
public void buildRecipeList(RecipeList list) {
}

/**
Expand Down Expand Up @@ -424,4 +455,57 @@ public Object clone() {
public interface DelegatingRecipe {
Recipe getDelegate();
}

/**
* @return A new recipe builder.
*/
@Incubating(since = "8.31.0")
public static Builder builder(@NlsRewrite.DisplayName @Language("markdown") String displayName,
@NlsRewrite.Description @Language("markdown") String description) {
return new Builder(displayName, description);
}

@Incubating(since = "8.31.0")
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public static class Builder {
@NlsRewrite.DisplayName
@Language("markdown")
final String displayName;

@NlsRewrite.Description
@Language("markdown")
final String description;

TreeVisitor<? extends Tree, ExecutionContext> visitor = TreeVisitor.noop();

public Builder visitor(TreeVisitor<? extends Tree, ExecutionContext> visitor) {
this.visitor = visitor;
return this;
}

public Recipe build(String name) {
return new Recipe() {
@Override
public String getName() {
return name;
}

@Override
public String getDisplayName() {
return displayName;
}

@Override
public String getDescription() {
return description;
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return visitor;
}
};
}
}
}
59 changes: 59 additions & 0 deletions rewrite-core/src/main/java/org/openrewrite/RecipeList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite;

import lombok.RequiredArgsConstructor;
import org.intellij.lang.annotations.Language;

import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.emptyList;

@Incubating(since = "8.31.0")
@RequiredArgsConstructor
public class RecipeList {
private final String parentRecipeName;
private int recipeIndex = 1;

private List<Recipe> recipes;

public RecipeList recipe(Recipe.Builder recipe) {
return addRecipe(recipe.build(parentRecipeName + "$" + recipeIndex++));
}

public RecipeList recipe(@NlsRewrite.DisplayName @Language("markdown") String displayName,
@NlsRewrite.Description @Language("markdown") String description,
TreeVisitor<? extends Tree, ExecutionContext> visitor) {
return recipe(Recipe.builder(displayName, description).visitor(visitor));
}

public RecipeList recipe(org.openrewrite.Recipe recipe) {
return addRecipe(recipe);
}

public List<Recipe> getRecipes() {
return recipes == null ? emptyList() : recipes;
}

private RecipeList addRecipe(Recipe recipe) {
if (recipes == null) {
recipes = new ArrayList<>();
}
recipes.add(recipe);
return this;
}
}
6 changes: 2 additions & 4 deletions rewrite-core/src/main/java/org/openrewrite/RecipeRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ public class RecipeRun {
@With
Map<DataTable<?>, List<?>> dataTables;

@Nullable
public DataTable<?> getDataTable(String name) {
public @Nullable DataTable<?> getDataTable(String name) {
for (DataTable<?> dataTable : dataTables.keySet()) {
if (dataTable.getName().equals(name)) {
return dataTable;
Expand All @@ -52,8 +51,7 @@ public DataTable<?> getDataTable(String name) {
return null;
}

@Nullable
public <E> List<E> getDataTableRows(String name) {
public <E> @Nullable List<E> getDataTableRows(String name) {
for (Map.Entry<DataTable<?>, List<?>> dataTableAndRows : dataTables.entrySet()) {
if (dataTableAndRows.getKey().getName().equals(name)) {
//noinspection unchecked
Expand Down
4 changes: 2 additions & 2 deletions rewrite-core/src/main/java/org/openrewrite/RenameFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new TreeVisitor<Tree, ExecutionContext>() {
@Nullable

@Override
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (tree instanceof SourceFile) {
SourceFile sourceFile = (SourceFile) tree;
Path sourcePath = sourceFile.getSourcePath();
Expand Down
3 changes: 1 addition & 2 deletions rewrite-core/src/main/java/org/openrewrite/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,7 @@ public String diff(@Nullable Path relativeTo, @Nullable PrintOutputCapture.Marke
}
}

@Nullable
public static String diff(String before, String after, Path path) {
public static @Nullable String diff(String before, String after, Path path) {
String diff = null;
try (InMemoryDiffEntry diffEntry = new InMemoryDiffEntry(
path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new TreeVisitor<Tree, ExecutionContext>() {
@Nullable

@Override
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (tree instanceof SourceFile) {
SourceFile sourceFile = (SourceFile) tree;
Path sourcePath = sourceFile.getSourcePath();
Expand Down
3 changes: 1 addition & 2 deletions rewrite-core/src/main/java/org/openrewrite/SourceFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ default boolean printEqualsInput(Parser.Input input, ExecutionContext ctx) {

<T extends SourceFile> T withFileAttributes(@Nullable FileAttributes fileAttributes);

@Nullable
default <S extends Style> S getStyle(Class<S> style) {
default <S extends Style> @Nullable S getStyle(Class<S> style) {
return NamedStyles.merge(style, getMarkers().findAll(NamedStyles.class));
}

Expand Down
Loading

0 comments on commit 35028b4

Please sign in to comment.