3232import static org .openrewrite .Validated .invalid ;
3333
3434@ RequiredArgsConstructor
35- public class DeclarativeRecipe extends ScanningRecipe <DeclarativeRecipe .Accumulator > {
35+ public class DeclarativeRecipe extends ScanningRecipe <DeclarativeRecipe .Accumulator > implements RecipePreconditions {
3636 @ Getter
3737 private final String name ;
3838
@@ -161,17 +161,16 @@ private void initializeDeclarativeRecipe(DeclarativeRecipe declarativeRecipe, St
161161 }
162162 }
163163
164- @ SuppressWarnings ("NotNullFieldNotInitialized" )
165164 @ JsonIgnore
166- private transient Accumulator accumulator ;
165+ private transient ThreadLocal < Accumulator > accumulator = new ThreadLocal <>() ;
167166
168167 @ Override
169168 public Accumulator getInitialValue (ExecutionContext ctx ) {
170169 Accumulator acc = new Accumulator ();
171170 for (Recipe precondition : preconditions ) {
172171 registerNestedScanningRecipes (precondition , acc , ctx );
173172 }
174- accumulator = acc ;
173+ accumulator . set ( acc ) ;
175174 return acc ;
176175 }
177176
@@ -187,7 +186,6 @@ private void registerNestedScanningRecipes(Recipe recipe, Accumulator acc, Execu
187186 @ Override
188187 public TreeVisitor <?, ExecutionContext > getScanner (Accumulator acc ) {
189188 return new TreeVisitor <Tree , ExecutionContext >() {
190- @ SuppressWarnings ({"rawtypes" , "unchecked" })
191189 @ Override
192190 public @ Nullable Tree visit (@ Nullable Tree tree , ExecutionContext ctx ) {
193191 for (Recipe precondition : preconditions ) {
@@ -251,7 +249,7 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) {
251249
252250 @ EqualsAndHashCode (callSuper = false )
253251 @ Value
254- static class BellwetherDecoratedRecipe extends Recipe implements DelegatingRecipe {
252+ static class BellwetherDecoratedRecipe extends Recipe implements DelegatingRecipe , RecipePreconditions {
255253
256254 DeclarativeRecipe .PreconditionBellwether bellwether ;
257255 Recipe delegate ;
@@ -350,11 +348,19 @@ public Validated<Object> validate(ExecutionContext ctx) {
350348 public Collection <Validated <Object >> validateAll (ExecutionContext ctx , Collection <Validated <Object >> acc ) {
351349 return delegate .validateAll (ctx , acc );
352350 }
351+
352+ @ Override
353+ public List <Recipe > getPreconditions () {
354+ if (delegate instanceof RecipePreconditions ) {
355+ return ((RecipePreconditions ) delegate ).getPreconditions ();
356+ }
357+ return emptyList ();
358+ }
353359 }
354360
355361 @ Value
356362 @ EqualsAndHashCode (callSuper = false )
357- static class BellwetherDecoratedScanningRecipe <T > extends ScanningRecipe <T > implements DelegatingRecipe {
363+ static class BellwetherDecoratedScanningRecipe <T > extends ScanningRecipe <T > implements DelegatingRecipe , RecipePreconditions {
358364
359365 DeclarativeRecipe .PreconditionBellwether bellwether ;
360366 ScanningRecipe <T > delegate ;
@@ -468,6 +474,14 @@ public Validated<Object> validate(ExecutionContext ctx) {
468474 public Collection <Validated <Object >> validateAll (ExecutionContext ctx , Collection <Validated <Object >> acc ) {
469475 return delegate .validateAll (ctx , acc );
470476 }
477+
478+ @ Override
479+ public List <Recipe > getPreconditions () {
480+ if (delegate instanceof RecipePreconditions ) {
481+ return ((RecipePreconditions ) delegate ).getPreconditions ();
482+ }
483+ return emptyList ();
484+ }
471485 }
472486
473487 @ Override
@@ -494,7 +508,8 @@ private TreeVisitor<?, ExecutionContext> orVisitors(Recipe recipe) {
494508 //noinspection rawtypes
495509 ScanningRecipe scanning = (ScanningRecipe ) recipe ;
496510 //noinspection unchecked
497- conditions .add (scanning .getVisitor (accumulator .recipeToAccumulator .get (scanning )));
511+ Accumulator acc = accumulator .get ();
512+ conditions .add (scanning .getVisitor (acc != null ? acc .recipeToAccumulator .get (scanning ) : null ));
498513 } else {
499514 conditions .add (recipe .getVisitor ());
500515 }
@@ -587,15 +602,31 @@ private static class LazyLoadedRecipe extends Recipe {
587602 String description = "Recipe that is loaded lazily." ;
588603 }
589604
605+ @ Override
606+ public void onComplete (ExecutionContext ctx ) {
607+ accumulator .remove ();
608+ }
609+
610+ @ Override
611+ public DeclarativeRecipe clone () {
612+ DeclarativeRecipe cloned = (DeclarativeRecipe ) super .clone ();
613+ cloned .accumulator = new ThreadLocal <>();
614+ return cloned ;
615+ }
616+
590617 @ Override
591618 protected RecipeDescriptor createRecipeDescriptor () {
592- List <RecipeDescriptor > recipeList = new ArrayList <>();
593- for (Recipe childRecipe : getRecipeList ()) {
594- recipeList .add (childRecipe .getDescriptor ());
619+ List <RecipeDescriptor > preconditionDescriptors = new ArrayList <>();
620+ for (Recipe childRecipe : preconditions ) {
621+ preconditionDescriptors .add (childRecipe .getDescriptor ());
622+ }
623+ List <RecipeDescriptor > recipeDescriptors = new ArrayList <>();
624+ for (Recipe childRecipe : recipeList ) {
625+ recipeDescriptors .add (childRecipe .getDescriptor ());
595626 }
596627 return new RecipeDescriptor (getName (), getDisplayName (), getInstanceName (), getDescription () != null ? getDescription () : "" ,
597628 getTags (), getEstimatedEffortPerOccurrence (),
598- emptyList (), recipeList , getDataTableDescriptors (), getMaintainers (), getContributors (),
629+ emptyList (), preconditionDescriptors , recipeDescriptors , getDataTableDescriptors (), getMaintainers (), getContributors (),
599630 getExamples (), source );
600631 }
601632
0 commit comments