diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/Planner.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/Planner.scala index 8ce0596896..41640337ea 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/Planner.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/Planner.scala @@ -9,12 +9,13 @@ import izumi.fundamentals.collections.nonempty.NEList trait Planner { def plan(input: PlannerInput): Either[NEList[DIError], Plan] - @inline final def plan(bindings: ModuleBase, activation: Activation, roots: Roots, locatorPrivacy: LocatorPrivacy): Either[NEList[DIError], Plan] = { - plan(PlannerInput(bindings, activation, roots, locatorPrivacy)) - } - - @inline final def plan(bindings: ModuleBase, roots: Roots): Either[NEList[DIError], Plan] = { - plan(bindings, Activation.empty, roots, LocatorPrivacy.PublicByDefault) + @inline final def plan( + bindings: ModuleBase, + roots: Roots, + activation: Activation = Activation.empty, + locatorPrivacy: LocatorPrivacy = LocatorPrivacy.PublicByDefault, + ): Either[NEList[DIError], Plan] = { + plan(PlannerInput(bindings, roots, activation, locatorPrivacy)) } /** diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/PlannerInput.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/PlannerInput.scala index 96c41df9aa..bc7fcfe2ce 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/PlannerInput.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/PlannerInput.scala @@ -21,59 +21,64 @@ import izumi.reflect.Tag * On [[izumi.distage.model.plan.Roots.Everything]] garbage collection will not be performed – that would be equivalent to * designating _all_ DIKeys as roots. */ -final case class PlannerInput( - bindings: ModuleBase, - activation: Activation, - roots: Roots, - locatorPrivacy: LocatorPrivacy, -) +final case class PlannerInput(bindings: ModuleBase, roots: Roots, activation: Activation, locatorPrivacy: LocatorPrivacy) object PlannerInput { + private val DefaultPrivacy = LocatorPrivacy.PublicByDefault + implicit class PlannerInputSyntax(private val input: PlannerInput) extends AnyVal { - def privateByDefault: PlannerInput = input.copy(locatorPrivacy = LocatorPrivacy.PrivateByDefault) - def publicByDefault: PlannerInput = input.copy(locatorPrivacy = LocatorPrivacy.PublicByDefault) def withLocatorPrivacy(privacy: LocatorPrivacy): PlannerInput = input.copy(locatorPrivacy = privacy) + def privateByDefault: PlannerInput = withLocatorPrivacy(LocatorPrivacy.PrivateByDefault) + def publicByDefault: PlannerInput = withLocatorPrivacy(LocatorPrivacy.PublicByDefault) + + def withActivation(activation: Activation): PlannerInput = input.copy(activation = activation) + def emptyActivation: PlannerInput = withActivation(Activation.empty) } - def apply(bindings: ModuleBase, activation: Activation, roots: Roots): PlannerInput = PlannerInput(bindings, activation, roots, LocatorPrivacy.PublicByDefault) - /** - * Instantiate `roots` and the dependencies of `roots`, discarding bindings that are unrelated. + def apply(bindings: ModuleBase, roots: Roots, activation: Activation = Activation.empty, locatorPrivacy: LocatorPrivacy = DefaultPrivacy): PlannerInput = + new PlannerInput(bindings, roots, activation, locatorPrivacy) + + /** Instantiate `T` and the dependencies of `T`, discarding bindings that are unrelated. * * Effectively, this selects and creates a *sub-graph* of the largest possible object graph that can be described by `bindings` */ - def apply(bindings: ModuleBase, activation: Activation, roots: NESet[? <: DIKey]): PlannerInput = - PlannerInput(bindings, activation, Roots(roots), LocatorPrivacy.PublicByDefault) + def target[T: Tag](bindings: ModuleBase): PlannerInput = + PlannerInput(bindings, Roots.target[T], Activation.empty, DefaultPrivacy) - /** - * Instantiate `roots` and the dependencies of `roots`, discarding bindings that are unrelated. + /** Instantiate `T @Id(name)` and the dependencies of `T @Id(name)`, discarding bindings that are unrelated. * * Effectively, this selects and creates a *sub-graph* of the largest possible object graph that can be described by `bindings` + * + * @see [[izumi.distage.model.definition.Id @Id annotation]] */ - def apply(bindings: ModuleBase, activation: Activation, roots: Set[? <: DIKey])(implicit d: DummyImplicit): PlannerInput = - PlannerInput(bindings, activation, Roots(roots), LocatorPrivacy.PublicByDefault) + def target[T: Tag](name: String)(bindings: ModuleBase): PlannerInput = + PlannerInput(bindings, Roots.target[T](name), Activation.empty, DefaultPrivacy) - /** Instantiate `root`, `roots` and their dependencies, discarding bindings that are unrelated. + /** Disable all dependency pruning. Every binding in `bindings` will be instantiated, without selection of the root components. There's almost always a better way to model things though. */ + def everything(bindings: ModuleBase, activation: Activation = Activation.empty, locatorPrivacy: LocatorPrivacy = DefaultPrivacy): PlannerInput = + PlannerInput(bindings, Roots.Everything, activation, locatorPrivacy) + + /** + * Instantiate `roots` and the dependencies of `roots`, discarding bindings that are unrelated. * * Effectively, this selects and creates a *sub-graph* of the largest possible object graph that can be described by `bindings` */ - def apply(bindings: ModuleBase, activation: Activation, root: DIKey, roots: DIKey*): PlannerInput = - PlannerInput(bindings, activation, Roots(root, roots*), LocatorPrivacy.PublicByDefault) + def apply(bindings: ModuleBase, roots: NESet[? <: DIKey], activation: Activation): PlannerInput = + PlannerInput(bindings, Roots(roots), activation, DefaultPrivacy) - /** Instantiate `T` and the dependencies of `T`, discarding bindings that are unrelated. + /** + * Instantiate `roots` and the dependencies of `roots`, discarding bindings that are unrelated. * * Effectively, this selects and creates a *sub-graph* of the largest possible object graph that can be described by `bindings` */ - def target[T: Tag](bindings: ModuleBase, activation: Activation): PlannerInput = PlannerInput(bindings, activation, DIKey.get[T]) + def apply(bindings: ModuleBase, roots: Set[? <: DIKey], activation: Activation)(implicit d: DummyImplicit): PlannerInput = + PlannerInput(bindings, Roots(roots), activation, DefaultPrivacy) - /** Instantiate `T @Id(name)` and the dependencies of `T @Id(name)`, discarding bindings that are unrelated. + /** Instantiate `root`, `roots` and their dependencies, discarding bindings that are unrelated. * * Effectively, this selects and creates a *sub-graph* of the largest possible object graph that can be described by `bindings` - * - * @see [[izumi.distage.model.definition.Id @Id annotation]] */ - def target[T: Tag](name: String)(bindings: ModuleBase, activation: Activation): PlannerInput = PlannerInput(bindings, activation, DIKey.get[T].named(name)) + def apply(bindings: ModuleBase, activation: Activation, root: DIKey, roots: DIKey*): PlannerInput = + PlannerInput(bindings, Roots(root, roots*), activation, DefaultPrivacy) - /** Disable all dependency pruning. Every binding in `bindings` will be instantiated, without selection of the root components. There's almost always a better way to model things though. */ - def everything(bindings: ModuleBase, activation: Activation = Activation.empty): PlannerInput = - PlannerInput(bindings, activation, Roots.Everything, LocatorPrivacy.PublicByDefault) } diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/LocatorDef.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/LocatorDef.scala index f04802b3f2..6bf1011924 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/LocatorDef.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/LocatorDef.scala @@ -59,7 +59,7 @@ trait LocatorDef extends AbstractLocator with AbstractBindingDefDSL[LocatorDef.B val nodes = ops.map(op => (op._1.target, op._1)) Plan( DG(s, s.transposed, GraphMeta(nodes.toMap)), - PlannerInput(Module.make(ops.map(_._2).toSet), Activation.empty, Roots.Everything, LocatorPrivacy.PublicByDefault), + PlannerInput(Module.make(ops.map(_._2).toSet), Roots.Everything, Activation.empty, LocatorPrivacy.PublicByDefault), ) } diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala index d6aab34e71..24968d5e06 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala @@ -5,12 +5,11 @@ import izumi.distage.model.definition.* import izumi.distage.model.definition.Binding.{EmptySetBinding, ImplBinding, SetElementBinding, SingletonBinding} import izumi.distage.model.definition.dsl.AbstractBindingDefDSL.* import izumi.distage.model.definition.dsl.AbstractBindingDefDSL.SetElementInstruction.ElementAddTags -import izumi.distage.model.definition.dsl.AbstractBindingDefDSL.SetInstruction.{AddTagsAll, SetIdAll} +import izumi.distage.model.definition.dsl.AbstractBindingDefDSL.SetInstruction.{AddTagOntoSet, SetIdAll} import izumi.distage.model.definition.dsl.AbstractBindingDefDSL.SingletonInstruction.* import izumi.distage.model.exceptions.dsl.InvalidFunctoidModifier import izumi.distage.model.providers.Functoid -import izumi.distage.model.reflection.{DIKey, MultiSetImplId} -import izumi.distage.model.reflection.SetKeyMeta +import izumi.distage.model.reflection.{DIKey, MultiSetImplId, SetKeyMeta} import izumi.fundamentals.platform.language.{CodePositionMaterializer, SourceFilePosition} import izumi.reflect.Tag @@ -448,7 +447,7 @@ object AbstractBindingDefDSL { val emptySetBinding = setOps.foldLeft(initial: EmptySetBinding[DIKey.BasicKey]) { (b, instr) => instr match { - case AddTagsAll(tags) => b.addTags(tags) + case AddTagOntoSet(tags) => b.addTags(tags) case SetIdAll(id) => b.withTarget(DIKey.TypeKey(b.key.tpe).named(id)) } } @@ -564,7 +563,7 @@ object AbstractBindingDefDSL { sealed trait SetInstruction object SetInstruction { - final case class AddTagsAll(tags: Set[BindingTag]) extends SetInstruction + final case class AddTagOntoSet(tags: Set[BindingTag]) extends SetInstruction final case class SetIdAll(id: Identifier) extends SetInstruction } diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala index ebc480b130..ab4771db1c 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala @@ -682,6 +682,8 @@ object ModuleDefDSL { "modifyBy", "addDependency", "addDependencies", + "exposed", + "confined", ) final class MakeDSL[T]( @@ -785,8 +787,11 @@ object ModuleDefDSL { final class SetDSL[T]( protected val mutableState: SetRef - ) extends SetDSLMutBase[T] { - + ) extends SetDSLMutBase[T] + with Tagging[SetDSL[T]] { + def tagged(tags: BindingTag*): SetDSL[T] = { + addOp(SetInstruction.AddTagOntoSet(tags.toSet))(new SetDSL[T](_)) + } def named(name: Identifier): SetNamedDSL[T] = { addOp(SetInstruction.SetIdAll(name))(new SetNamedDSL[T](_)) } @@ -796,6 +801,11 @@ object ModuleDefDSL { final class SetNamedDSL[T]( override protected val mutableState: SetRef ) extends SetDSLMutBase[T] + with Tagging[SetNamedDSL[T]] { + def tagged(tags: BindingTag*): SetNamedDSL[T] = { + addOp(SetInstruction.AddTagOntoSet(tags.toSet))(new SetNamedDSL[T](_)) + } + } final class SetElementDSL[T]( override protected val mutableState: SetRef, diff --git a/distage/distage-core/.jvm/src/test/scala/izumi/distage/gc/GcBasicTestsJvm.scala b/distage/distage-core/.jvm/src/test/scala/izumi/distage/gc/GcBasicTestsJvm.scala index c154fa6fec..812a698b08 100644 --- a/distage/distage-core/.jvm/src/test/scala/izumi/distage/gc/GcBasicTestsJvm.scala +++ b/distage/distage-core/.jvm/src/test/scala/izumi/distage/gc/GcBasicTestsJvm.scala @@ -16,17 +16,13 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - make[Circular3] - make[Circular4] - make[Trash] - }, - Activation.empty, - Roots(DIKey.get[Circular2]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + make[Circular3] + make[Circular4] + make[Trash] + }, Roots(DIKey.get[Circular2]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -52,15 +48,11 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[MkS3Client].from[Impl] - make[S3Component] - make[App] - }, - Activation.empty, - Roots(DIKey.get[App]), - ) + PlannerInput(new ModuleDef { + make[MkS3Client].from[Impl] + make[S3Component] + make[App] + }, Roots(DIKey.get[App]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -72,18 +64,14 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - many[IntegrationComponent].add[S3Component] - - make[MkS3Client].from[Impl] - make[S3Upload] - make[Ctx] - make[S3Component] - }, - Activation.empty, - Roots(DIKey.get[Ctx]), - ) + PlannerInput(new ModuleDef { + many[IntegrationComponent].add[S3Component] + + make[MkS3Client].from[Impl] + make[S3Upload] + make[Ctx] + make[S3Component] + }, Roots(DIKey.get[Ctx]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -98,18 +86,14 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[MkS3Client] - make[S3Upload] - make[Ctx] - make[S3Component] - many[IntegrationComponent].add[S3Component] - make[Initiator] - }, - Activation.empty, - Roots(DIKey.get[Ctx], DIKey.get[Initiator]), - ) + PlannerInput(new ModuleDef { + make[MkS3Client] + make[S3Upload] + make[Ctx] + make[S3Component] + many[IntegrationComponent].add[S3Component] + make[Initiator] + }, Roots(DIKey.get[Ctx], DIKey.get[Initiator]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -121,16 +105,12 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - make[T1].using[Circular1] - make[T2].using[Circular2] - }, - Activation.empty, - Roots(DIKey.get[Circular2]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + make[T1].using[Circular1] + make[T2].using[Circular2] + }, Roots(DIKey.get[Circular2]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -145,14 +125,10 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[T1].from[Circular1] - make[T2].from[Circular2] - }, - Activation.empty, - Roots(DIKey.get[T1]), - ) + PlannerInput(new ModuleDef { + make[T1].from[Circular1] + make[T2].from[Circular2] + }, Roots(DIKey.get[T1]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -165,33 +141,29 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1].from { - (t1: Circular1, t2: Circular2) => - new Circular1 { - override def c1: Circular1 = t1 - - override def c2: Circular2 = t2 - - override def nothing: Int = 1 - } - } - make[Circular2].from { - (t1: Circular1, t2: Circular2) => - new Circular2 { - - override def c1: Circular1 = t1 - - override def c2: Circular2 = t2 - - override def nothing: Int = 2 - } - } - }, - Activation.empty, - Roots(DIKey.get[Circular2]), - ) + PlannerInput(new ModuleDef { + make[Circular1].from { + (t1: Circular1, t2: Circular2) => + new Circular1 { + override def c1: Circular1 = t1 + + override def c2: Circular2 = t2 + + override def nothing: Int = 1 + } + } + make[Circular2].from { + (t1: Circular1, t2: Circular2) => + new Circular2 { + + override def c1: Circular1 = t1 + + override def c2: Circular2 = t2 + + override def nothing: Int = 2 + } + } + }, Roots(DIKey.get[Circular2]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() assert(result.get[Circular1].nothing == 1) @@ -205,14 +177,10 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - }, - Activation.empty, - Roots(DIKey.get[Circular2]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + }, Roots(DIKey.get[Circular2]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -227,14 +195,10 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - }, - Activation.empty, - Roots(DIKey.get[Circular2]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + }, Roots(DIKey.get[Circular2]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -248,14 +212,10 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - }, - Activation.empty, - Roots(DIKey.get[Circular2], DIKey.get[Set[AutoCloseable]]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + }, Roots(DIKey.get[Circular2], DIKey.get[Set[AutoCloseable]]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() @@ -269,19 +229,15 @@ class GcBasicTestsJvm extends AnyWordSpec with MkGcInjector { val injector = mkInjector() val plan = injector.planUnsafe( - PlannerInput( - new ModuleDef { - make[Circular1] - make[Circular2] - make[Circular3] - make[Circular4] - many[T1] - .ref[Circular1] - .ref[Circular2] - }, - Activation.empty, - Roots(DIKey.get[Circular4], DIKey.get[immutable.Set[T1]], DIKey.get[Circular3]), - ) + PlannerInput(new ModuleDef { + make[Circular1] + make[Circular2] + make[Circular3] + make[Circular4] + many[T1] + .ref[Circular1] + .ref[Circular2] + }, Roots(DIKey.get[Circular4], DIKey.get[immutable.Set[T1]], DIKey.get[Circular3]), Activation.empty) ) val result = injector.produce(plan).unsafeGet() diff --git a/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/AnimalModelTestJvm.scala b/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/AnimalModelTestJvm.scala index 1457ccd4ba..e48e1d2eb6 100644 --- a/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/AnimalModelTestJvm.scala +++ b/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/AnimalModelTestJvm.scala @@ -11,21 +11,17 @@ class AnimalModelTestJvm extends AnyWordSpec with MkInjector { "animal model" must { "produce valid plans" in { import AnimalModelTestJvm._ - val definition = PlannerInput( - new ModuleDef { - make[Cluster] - make[UserRepo].from[UserRepoImpl] - make[AccountsRepo].from[AccountsRepoImpl] - make[UsersService].from[UserServiceImpl] - make[AccountingService].from[AccountingServiceImpl] - make[UsersApiImpl] - make[AccountsApiImpl] - make[UnrequiredDep] - make[App] - }, - Activation.empty, - Roots(DIKey.get[App]), - ) + val definition = PlannerInput(new ModuleDef { + make[Cluster] + make[UserRepo].from[UserRepoImpl] + make[AccountsRepo].from[AccountsRepoImpl] + make[UsersService].from[UserServiceImpl] + make[AccountingService].from[AccountingServiceImpl] + make[UsersApiImpl] + make[AccountsApiImpl] + make[UnrequiredDep] + make[App] + }, Roots(DIKey.get[App]), Activation.empty) val debug = false diff --git a/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/CglibProxiesTestJvm.scala b/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/CglibProxiesTestJvm.scala index e30fd2d536..62b8a61a86 100644 --- a/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/CglibProxiesTestJvm.scala +++ b/distage/distage-core/.jvm/src/test/scala/izumi/distage/injector/CglibProxiesTestJvm.scala @@ -228,8 +228,8 @@ class CglibProxiesTestJvm extends AnyWordSpec with MkInjector with ScalatestGuar make[ComponentHolder] make[Root] }, - Activation.empty, Roots(DIKey.get[Root]), + Activation.empty, ) val injector = mkInjector() @@ -368,8 +368,8 @@ class CglibProxiesTestJvm extends AnyWordSpec with MkInjector with ScalatestGuar make[S3Component].fromResource(s3ComponentResource[Fn] _) make[S3Client].fromResource(s3clientResource[Fn] _) }, - Activation.empty, Roots(DIKey.get[S3Client]), + Activation.empty, ) val injector = mkInjector() diff --git a/distage/distage-core/src/main/scala/distage/Injector.scala b/distage/distage-core/src/main/scala/distage/Injector.scala index 34548c24e1..7da1884d5b 100644 --- a/distage/distage-core/src/main/scala/distage/Injector.scala +++ b/distage/distage-core/src/main/scala/distage/Injector.scala @@ -21,7 +21,7 @@ object Injector extends InjectorFactory { override def apply[F[_]: QuasiIO: TagK: DefaultModule]( overrides: BootstrapModule* ): Injector[F] = { - bootstrap(this, defaultBootstrap, defaultBootstrapActivation, None, overrides, LocatorPrivacy.PublicByDefault) + bootstrap(this, defaultBootstrap, defaultBootstrapActivation, None, overrides, defaultBootstrapLocatorPrivacy) } /** @@ -48,9 +48,9 @@ object Injector extends InjectorFactory { bootstrapActivation: Activation = defaultBootstrapActivation, parent: Option[Locator] = None, overrides: Seq[BootstrapModule] = Nil, - locatorPrivacy: LocatorPrivacy = LocatorPrivacy.PublicByDefault, + bootstrapLocatorPrivacy: LocatorPrivacy = defaultBootstrapLocatorPrivacy, ): Injector[F] = { - bootstrap(this, bootstrapBase, defaultBootstrapActivation ++ bootstrapActivation, parent, overrides, locatorPrivacy) + bootstrap(this, bootstrapBase, defaultBootstrapActivation ++ bootstrapActivation, parent, overrides, bootstrapLocatorPrivacy) } /** @@ -120,7 +120,7 @@ object Injector extends InjectorFactory { cycleChoice: Cycles.AxisChoiceDef ) extends InjectorFactory { override final def apply[F[_]: QuasiIO: TagK: DefaultModule](overrides: BootstrapModule*): Injector[F] = { - bootstrap(this, defaultBootstrap, defaultBootstrapActivation, None, overrides, LocatorPrivacy.PublicByDefault) + bootstrap(this, defaultBootstrap, defaultBootstrapActivation, None, overrides, BootstrapLocator.defaultBoostrapPrivacy) } override final def apply[F[_]: QuasiIO: TagK: DefaultModule]( @@ -153,6 +153,7 @@ object Injector extends InjectorFactory { override protected final def defaultBootstrap: BootstrapContextModule = BootstrapLocator.defaultBootstrap override protected final def defaultBootstrapActivation: Activation = definition.Activation(Cycles -> cycleChoice) + override protected def defaultBootstrapLocatorPrivacy: LocatorPrivacy = BootstrapLocator.defaultBoostrapPrivacy } private def bootstrap[F[_]: QuasiIO: TagK: DefaultModule]( @@ -178,5 +179,5 @@ object Injector extends InjectorFactory { @inline override protected def defaultBootstrap: BootstrapContextModule = BootstrapLocator.defaultBootstrap @inline override protected def defaultBootstrapActivation: Activation = BootstrapLocator.defaultBootstrapActivation - + @inline override protected def defaultBootstrapLocatorPrivacy: LocatorPrivacy = BootstrapLocator.defaultBoostrapPrivacy } diff --git a/distage/distage-core/src/main/scala/izumi/distage/InjectorDefaultImpl.scala b/distage/distage-core/src/main/scala/izumi/distage/InjectorDefaultImpl.scala index 2b1ed45be0..5980432f7f 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/InjectorDefaultImpl.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/InjectorDefaultImpl.scala @@ -57,18 +57,16 @@ final class InjectorDefaultImpl[F[_]]( private def addSelfInfo(input: PlannerInput): PlannerInput = { val selfReflectionModule = InjectorDefaultImpl.selfReflectionModule(parentFactory, bsModule, defaultModule, input.activation, input) - input.copy( - bindings = ModuleBase.make( - ModuleBase - .overrideImpl( - ModuleBase.overrideImpl( - defaultModule.iterator, - input.bindings.iterator, - ), - selfReflectionModule.iterator, - ).toSet - ) - ) + input.copy(bindings = ModuleBase.make( + ModuleBase + .overrideImpl( + ModuleBase.overrideImpl( + defaultModule.iterator, + input.bindings.iterator, + ), + selfReflectionModule.iterator, + ).toSet + )) } override def providedEnvironment: InjectorProvidedEnv = { diff --git a/distage/distage-core/src/main/scala/izumi/distage/InjectorFactory.scala b/distage/distage-core/src/main/scala/izumi/distage/InjectorFactory.scala index 02df12fd96..b0f26b80ab 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/InjectorFactory.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/InjectorFactory.scala @@ -42,11 +42,11 @@ trait InjectorFactory { * They can be used to customize the Injector, e.g. by adding members to [[izumi.distage.model.planning.PlanningHook]] Set. */ def apply[F[_]: QuasiIO: TagK: DefaultModule]( - bootstrapBase: BootstrapContextModule = defaultBootstrap, - bootstrapActivation: Activation = defaultBootstrapActivation, - parent: Option[Locator] = None, - overrides: Seq[BootstrapModule] = Nil, - locatorPrivacy: LocatorPrivacy, + bootstrapBase: BootstrapContextModule = defaultBootstrap, + bootstrapActivation: Activation = defaultBootstrapActivation, + parent: Option[Locator] = None, + overrides: Seq[BootstrapModule] = Nil, + locatorPrivacy: LocatorPrivacy = defaultBootstrapLocatorPrivacy, ): Injector[F] /** @@ -95,4 +95,5 @@ trait InjectorFactory { protected def defaultBootstrap: BootstrapContextModule protected def defaultBootstrapActivation: Activation + protected def defaultBootstrapLocatorPrivacy: LocatorPrivacy } diff --git a/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapLocator.scala b/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapLocator.scala index 87796375cc..c468d73011 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapLocator.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapLocator.scala @@ -19,6 +19,7 @@ import izumi.distage.planning.solver.SemigraphSolver.SemigraphSolverImpl import izumi.distage.planning.solver.{GraphQueries, PlanSolver, SemigraphSolver} import izumi.distage.provisioning.* import izumi.distage.provisioning.strategies.* +import izumi.fundamentals.collections.nonempty.NESet import izumi.fundamentals.platform.functional.Identity object BootstrapLocator { @@ -48,9 +49,18 @@ object BootstrapLocator { // Please open an issue if you need the ability to override Activation using BootstrapModule val bindings = bindings0 ++ BootstrapLocator.selfReflectionModule(bindings0, bootstrapActivation) + val primaryRoots: NESet[DIKey] = NESet(DIKey.get[Planner], DIKey.get[PlanInterpreter], DIKey.get[BootstrapModule], DIKey.get[Activation].named("bootstrapActivation")) + val customRoots = bindings.bindings.filter(_.tags.contains(BindingTag.Exposed)).map(_.key) + val allRoots = primaryRoots ++ customRoots + val plan = BootstrapLocator.bootstrapPlanner - .plan(bindings, bootstrapActivation, Roots.Everything, locatorPrivacy).getOrThrow() + .plan( + bindings, + Roots(allRoots), + bootstrapActivation, + locatorPrivacy, + ).getOrThrow() val resource = BootstrapLocator.bootstrapProducer @@ -152,6 +162,8 @@ object BootstrapLocator { Cycles -> Cycles.Proxy ) + final val defaultBoostrapPrivacy: LocatorPrivacy = LocatorPrivacy.PublicRoots + private def selfReflectionModule(bindings0: BootstrapContextModule, bootstrapActivation: Activation): BootstrapModuleDef = { new BootstrapModuleDef { make[Activation].named("bootstrapActivation").fromValue(bootstrapActivation) diff --git a/distage/distage-core/src/main/scala/izumi/distage/model/Injector.scala b/distage/distage-core/src/main/scala/izumi/distage/model/Injector.scala index 236bb2addd..76713efaae 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/model/Injector.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/model/Injector.scala @@ -60,7 +60,7 @@ trait Injector[F[_]] extends Planner with Producer { activation: Activation = Activation.empty, )(function: Functoid[F[A]] ): F[A] = { - produce(PlannerInput(bindings, activation, function.get.diKeys.toSet)) + produce(PlannerInput(bindings, function.get.diKeys.toSet, activation)) .use(_.run(function)) } @@ -109,7 +109,7 @@ trait Injector[F[_]] extends Planner with Producer { activation: Activation = Activation.empty, )(function: Functoid[F[A]] ): Lifecycle[F, A] = { - produce(PlannerInput(bindings, activation, function.get.diKeys.toSet)) + produce(PlannerInput(bindings, function.get.diKeys.toSet, activation)) .evalMap(_.run(function)) } @@ -195,7 +195,7 @@ trait Injector[F[_]] extends Planner with Producer { activation: Activation = Activation.empty, locatorPrivacy: LocatorPrivacy = LocatorPrivacy.PublicByDefault, ): Lifecycle[F, Locator] = { - produce(PlannerInput(bindings, activation, roots, locatorPrivacy)) + produce(PlannerInput(bindings, roots, activation, locatorPrivacy)) } /** diff --git a/distage/distage-core/src/main/scala/izumi/distage/model/recursive/Bootloader.scala b/distage/distage-core/src/main/scala/izumi/distage/model/recursive/Bootloader.scala index 16387a41d9..b0a1eccfc1 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/model/recursive/Bootloader.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/model/recursive/Bootloader.scala @@ -51,7 +51,7 @@ class Bootloader( val roots = config.roots(input.roots) for { - plan <- injector.plan(PlannerInput(module, activation, roots, locatorPrivacy)) + plan <- injector.plan(PlannerInput(module, roots, activation, locatorPrivacy)) } yield { BootstrappedApp(injector, module, plan) } diff --git a/distage/distage-core/src/main/scala/izumi/distage/planning/AutoSetModule.scala b/distage/distage-core/src/main/scala/izumi/distage/planning/AutoSetModule.scala index 8ebe5d740f..d847007a74 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/planning/AutoSetModule.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/planning/AutoSetModule.scala @@ -20,11 +20,11 @@ abstract class AutoSetModule(name: Option[String]) extends BootstrapModuleDef { def registerOnly[T: Tag](filter: InclusionPredicate): AutoSetModule = { name match { case Some(id) => - many[T].named(id) + many[T].named(id).exposed many[PlanningHook].addValue(AutoSetHook[T](filter, name = id, weak = false)) case None => - many[T] + many[T].exposed many[PlanningHook].addValue(AutoSetHook[T](filter, weak = false)) } this diff --git a/distage/distage-core/src/main/scala/izumi/distage/planning/SubcontextHandler.scala b/distage/distage-core/src/main/scala/izumi/distage/planning/SubcontextHandler.scala index e4eaf45245..0b0f6e809c 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/planning/SubcontextHandler.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/planning/SubcontextHandler.scala @@ -24,7 +24,7 @@ object SubcontextHandler { val roots = c.extractingFunction.diKeys.toSet for { subplan <- planner - .plan(PlannerInput(c.module, input.activation, roots)) + .plan(PlannerInput(c.module, roots, input.activation)) .left.map(errors => LocalContextPlanningFailure(binding, c, errors)) } yield { val allImported = subplan.importedKeys diff --git a/distage/distage-core/src/main/scala/izumi/distage/provisioning/PlanInterpreterNonSequentialRuntimeImpl.scala b/distage/distage-core/src/main/scala/izumi/distage/provisioning/PlanInterpreterNonSequentialRuntimeImpl.scala index 1b2e6100ee..29833d517d 100644 --- a/distage/distage-core/src/main/scala/izumi/distage/provisioning/PlanInterpreterNonSequentialRuntimeImpl.scala +++ b/distage/distage-core/src/main/scala/izumi/distage/provisioning/PlanInterpreterNonSequentialRuntimeImpl.scala @@ -122,12 +122,12 @@ class PlanInterpreterNonSequentialRuntimeImpl( } private def computePrivateBindings(plan: Plan): Set[DIKey] = { - def isPrivateRoot(target: DIKey): Boolean = { + def isRoot(target: DIKey): Boolean = { plan.input.roots match { case Roots.Of(roots) => - !roots.contains(target) + roots.contains(target) case Roots.Everything => - false + true } } @@ -138,7 +138,7 @@ class PlanInterpreterNonSequentialRuntimeImpl( case LocatorPrivacy.PrivateByDefault => !binding.tags.contains(BindingTag.Exposed) case LocatorPrivacy.PublicRoots => - isPrivateRoot(target) + !isRoot(target) && !binding.tags.contains(BindingTag.Exposed) } } @@ -155,7 +155,7 @@ class PlanInterpreterNonSequentialRuntimeImpl( case LocatorPrivacy.PrivateByDefault => true case LocatorPrivacy.PublicRoots => - isPrivateRoot(op.target) + isRoot(op.target) } } } diff --git a/distage/distage-core/src/test/scala-2/izumi/distage/injector/InnerClassesTest.scala b/distage/distage-core/src/test/scala-2/izumi/distage/injector/InnerClassesTest.scala index 997cc53ce6..1bc6fb8546 100644 --- a/distage/distage-core/src/test/scala-2/izumi/distage/injector/InnerClassesTest.scala +++ b/distage/distage-core/src/test/scala-2/izumi/distage/injector/InnerClassesTest.scala @@ -3,12 +3,12 @@ package izumi.distage.injector import izumi.distage.constructors.FactoryConstructor import izumi.distage.fixtures.InnerClassCases.* import izumi.distage.model.PlannerInput -import izumi.distage.model.definition.{Activation, ModuleDef} +import izumi.distage.model.definition.ModuleDef import org.scalatest.wordspec.AnyWordSpec class InnerClassesTest extends AnyWordSpec with MkInjector { "can instantiate inner classes from stable objects where the classes are inherited from a trait" in { - import InnerClassStablePathsCase._ + import InnerClassStablePathsCase.* val definition = PlannerInput.everything(new ModuleDef { make[StableObjectInheritingTrait.TestDependency] @@ -23,8 +23,8 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { } "can instantiate inner classes from stable objects where the classes are inherited from a trait and depend on types defined inside trait" in { - import InnerClassStablePathsCase._ - import StableObjectInheritingTrait._ + import InnerClassStablePathsCase.* + import StableObjectInheritingTrait.* val definition = PlannerInput.everything(new ModuleDef { make[TestDependency] @@ -37,7 +37,7 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { } "can support path-dependant injections with injector lookup" in { - import InnerClassUnstablePathsCase._ + import InnerClassUnstablePathsCase.* val testProviderModule = new TestModule @@ -56,7 +56,7 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { "can handle function local path-dependent injections" in { def someFunction() = { - import InnerClassUnstablePathsCase._ + import InnerClassUnstablePathsCase.* val testProviderModule = new TestModule @@ -98,7 +98,7 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { } "support path-dependent by-name injections" in { - import InnerClassByNameCase._ + import InnerClassByNameCase.* val testProviderModule = new TestModule @@ -149,8 +149,8 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { } "can now find proper constructor for by-name circular dependencies inside stable objects that contain inner classes from inherited traits that depend on types defined inside trait" in { - import InnerClassStablePathsCase._ - import StableObjectInheritingTrait._ + import InnerClassStablePathsCase.* + import StableObjectInheritingTrait.* val definition = PlannerInput.everything(new ModuleDef { make[ByNameCircular1] @@ -164,7 +164,7 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { } "can now handle path-dependent factories" in { - import InnerClassUnstablePathsCase._ + import InnerClassUnstablePathsCase.* val testProviderModule = new TestModule FactoryConstructor[testProviderModule.TestFactory] @@ -173,8 +173,7 @@ class InnerClassesTest extends AnyWordSpec with MkInjector { new ModuleDef { make[testProviderModule.type].from[testProviderModule.type](testProviderModule: testProviderModule.type) makeFactory[testProviderModule.TestFactory] - }, - Activation.empty, + } ) val context = mkInjector().produce(definition).unsafeGet() diff --git a/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala b/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala index c8fb00dfc5..32135deb2f 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala @@ -104,7 +104,7 @@ class DSLTest extends AnyWordSpec with MkInjector with should.Matchers { } val injector = mkInjector() - val definitionAnnotated = PlannerInput(ModuleAnnotated, Activation(), Roots.Everything) + val definitionAnnotated = PlannerInput(ModuleAnnotated, Roots.Everything, Activation()) val planAnnotated = injector.planUnsafe(definitionAnnotated) assert(planAnnotated.definition.bindings.nonEmpty) diff --git a/distage/distage-core/src/test/scala/izumi/distage/gc/GcBasicTests.scala b/distage/distage-core/src/test/scala/izumi/distage/gc/GcBasicTests.scala index 611aa49d8d..0449361e57 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/gc/GcBasicTests.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/gc/GcBasicTests.scala @@ -22,8 +22,8 @@ class GcBasicTests extends AnyWordSpec with MkGcInjector { make[Circular1] make[Circular2] }, - Activation.empty, Roots(DIKey.get[Circular2]), + Activation.empty, ) ) } @@ -43,8 +43,8 @@ class GcBasicTests extends AnyWordSpec with MkGcInjector { make[T1] make[Box[T1]].from(new Box(new T1)) }, - Activation.empty, Roots(DIKey.get[Circular1], DIKey.get[Circular2]), + Activation.empty, ) ) @@ -61,7 +61,7 @@ class GcBasicTests extends AnyWordSpec with MkGcInjector { val roots = Set[DIKey](DIKey.get[Set[Elem]]) - val objects = mkInjector().produce(PlannerInput(module, Activation.empty, roots)).unsafeGet() + val objects = mkInjector().produce(PlannerInput(module, roots, Activation.empty)).unsafeGet() assert(objects.find[Strong].nonEmpty) assert(objects.find[Weak].isEmpty) diff --git a/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala b/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala index 7c93d30392..03fc28915a 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala @@ -22,13 +22,13 @@ class AxisTest extends AnyWordSpec with MkInjector { } val injector1 = mkInjector() - val context1 = injector1.produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots(DIKey.get[JustTrait]))).unsafeGet() + val context1 = injector1.produce(PlannerInput(definition, Roots(DIKey.get[JustTrait]), Activation(Repo -> Repo.Prod))).unsafeGet() assert(context1.get[JustTrait].isInstanceOf[Impl1]) assert(!context1.get[JustTrait].isInstanceOf[Impl0]) val injector2 = mkInjector() - val context2 = injector2.produce(PlannerInput(definition, Activation(Repo -> Repo.Dummy), Roots(DIKey.get[JustTrait]))).unsafeGet() + val context2 = injector2.produce(PlannerInput(definition, Roots(DIKey.get[JustTrait]), Activation(Repo -> Repo.Dummy))).unsafeGet() assert(context2.get[JustTrait].isInstanceOf[Impl0]) assert(!context2.get[JustTrait].isInstanceOf[Impl1]) @@ -38,19 +38,19 @@ class AxisTest extends AnyWordSpec with MkInjector { import BasicCase1._ val bsDefinition = new BootstrapModuleDef { - make[JustTrait].tagged(Repo.Dummy).from[Impl0] - make[JustTrait].tagged(Repo.Prod).from[Impl1] + make[JustTrait].tagged(Repo.Dummy).from[Impl0].exposed + make[JustTrait].tagged(Repo.Prod).from[Impl1].exposed } val appDefinition = Module.empty val injector1 = Injector[Identity](bootstrapActivation = Activation(Repo -> Repo.Prod), overrides = Seq(bsDefinition)) - val context1 = injector1.produce(PlannerInput(appDefinition, Activation.empty, Roots.Everything)).unsafeGet() + val context1 = injector1.produce(PlannerInput(appDefinition, Roots.Everything, Activation.empty)).unsafeGet() assert(context1.get[JustTrait].isInstanceOf[Impl1]) assert(!context1.get[JustTrait].isInstanceOf[Impl0]) val injector2 = Injector[Identity](bootstrapActivation = Activation(Repo -> Repo.Dummy), overrides = Seq(bsDefinition)) - val context2 = injector2.produce(PlannerInput(appDefinition, Activation.empty, Roots.Everything)).unsafeGet() + val context2 = injector2.produce(PlannerInput(appDefinition, Roots.Everything, Activation.empty)).unsafeGet() assert(context2.get[JustTrait].isInstanceOf[Impl0]) assert(!context2.get[JustTrait].isInstanceOf[Impl1]) @@ -64,7 +64,7 @@ class AxisTest extends AnyWordSpec with MkInjector { } val context = mkInjector() - .produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots.Everything)) + .produce(PlannerInput(definition, Roots.Everything, Activation(Repo -> Repo.Prod))) .unsafeGet() assert(context.find[JustTrait].isEmpty) @@ -167,7 +167,7 @@ class AxisTest extends AnyWordSpec with MkInjector { } val instance = mkInjector() - .produce(PlannerInput(definition, Activation(Repo -> Repo.Dummy), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[SetTrait]]), Activation(Repo -> Repo.Dummy))) .unsafeGet() .get[Set[SetTrait]] @@ -188,7 +188,7 @@ class AxisTest extends AnyWordSpec with MkInjector { intercept[InjectorFailed] { mkInjector() - .produce(PlannerInput(definition, Activation(), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[SetTrait]]), Activation())) .unsafeGet() .get[Set[SetTrait]] } @@ -207,7 +207,7 @@ class AxisTest extends AnyWordSpec with MkInjector { intercept[InjectorFailed] { mkInjector() - .produce(PlannerInput(definition, Activation(), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[SetTrait]]), Activation())) .unsafeGet() .get[Set[SetTrait]] } @@ -223,7 +223,7 @@ class AxisTest extends AnyWordSpec with MkInjector { } val set = mkInjector() - .produce(PlannerInput(definition, Activation(Repo.Dummy), Roots(DIKey[Set[Service]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[Service]]), Activation(Repo.Dummy))) .unsafeGet() .get[Set[Service]] assert(set.size == 1) @@ -240,7 +240,7 @@ class AxisTest extends AnyWordSpec with MkInjector { intercept[InjectorFailed] { mkInjector() - .produce(PlannerInput(definition, Activation(Repo.Dummy), Roots(DIKey[Set[Service]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[Service]]), Activation(Repo.Dummy))) .unsafeGet() .get[Set[Service]] } @@ -256,7 +256,7 @@ class AxisTest extends AnyWordSpec with MkInjector { } val set = mkInjector() - .produce(PlannerInput(definition, Activation(Repo.Dummy), Roots(DIKey[Set[Service]]))) + .produce(PlannerInput(definition, Roots(DIKey[Set[Service]]), Activation(Repo.Dummy))) .unsafeGet() .get[Set[Service]] assert(set.size == 1) @@ -275,28 +275,28 @@ class AxisTest extends AnyWordSpec with MkInjector { } val instance1 = mkInjector() - .produce(PlannerInput(definitionTodo, Activation(Repo.Dummy), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(definitionTodo, Roots(DIKey[Set[SetTrait]]), Activation(Repo.Dummy))) .unsafeGet() .get[Set[SetTrait]] assert(instance1.isEmpty) val instance2 = mkInjector() - .produce(PlannerInput(definitionTodo, Activation(Repo.Prod), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(definitionTodo, Roots(DIKey[Set[SetTrait]]), Activation(Repo.Prod))) .unsafeGet() .get[Set[SetTrait]] assert(instance2.size == 1) val instance3 = mkInjector() - .produce(PlannerInput(baseDef, Activation(Repo.Prod), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(baseDef, Roots(DIKey[Set[SetTrait]]), Activation(Repo.Prod))) .unsafeGet() .get[Set[SetTrait]] assert(instance3.size == 1) val instance4 = mkInjector() - .produce(PlannerInput(baseDef, Activation(Repo.Dummy), Roots(DIKey[Set[SetTrait]]))) + .produce(PlannerInput(baseDef, Roots(DIKey[Set[SetTrait]]), Activation(Repo.Dummy))) .unsafeGet() .get[Set[SetTrait]] @@ -313,7 +313,7 @@ class AxisTest extends AnyWordSpec with MkInjector { } val instance = mkInjector() - .produce(PlannerInput(definition, Activation(Repo -> Repo.Dummy), Roots(DIKey[X]))) + .produce(PlannerInput(definition, Roots(DIKey[X]), Activation(Repo -> Repo.Dummy))) .unsafeGet() .get[X] diff --git a/distage/distage-core/src/test/scala/izumi/distage/injector/PlanOperationsTest.scala b/distage/distage-core/src/test/scala/izumi/distage/injector/PlanOperationsTest.scala index 2d325d5d8e..f6e09c197b 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/injector/PlanOperationsTest.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/injector/PlanOperationsTest.scala @@ -29,8 +29,8 @@ class PlanOperationsTest extends AnyWordSpec with MkInjector { make[SharedComponent1] make[SharedComponent2] }, - Activation.empty, primary ++ sub, + Activation.empty, ) val srcPlan = injector.planUnsafe(definition) diff --git a/distage/distage-core/src/test/scala/izumi/distage/injector/PrivateBindingsTest.scala b/distage/distage-core/src/test/scala/izumi/distage/injector/PrivateBindingsTest.scala index 32b77e281a..46dc48e461 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/injector/PrivateBindingsTest.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/injector/PrivateBindingsTest.scala @@ -1,10 +1,9 @@ package izumi.distage.injector -import distage.{Activation, Injector, LocatorPrivacy, ModuleDef} -import izumi.distage.fixtures.BasicCases.BasicCase1 +import distage.{Injector, LocatorPrivacy, ModuleDef} +import izumi.distage.fixtures.BasicCases.BasicCase1.* import izumi.distage.model.PlannerInput import org.scalatest.wordspec.AnyWordSpec -import BasicCase1.* class PrivateBindingsTest extends AnyWordSpec with MkInjector { "Support private bindings in public-by-default mode" in { @@ -68,8 +67,7 @@ class PrivateBindingsTest extends AnyWordSpec with MkInjector { new ModuleDef { make[TestInstanceBinding].fromValue(TestInstanceBinding()) make[TestCaseClass2] - }, - Activation.empty, + } ) .withLocatorPrivacy(LocatorPrivacy.PublicRoots) diff --git a/distage/distage-core/src/test/scala/izumi/distage/injector/ResourceEffectBindingsTest.scala b/distage/distage-core/src/test/scala/izumi/distage/injector/ResourceEffectBindingsTest.scala index ca3866ae60..1b44b4eeb3 100644 --- a/distage/distage-core/src/test/scala/izumi/distage/injector/ResourceEffectBindingsTest.scala +++ b/distage/distage-core/src/test/scala/izumi/distage/injector/ResourceEffectBindingsTest.scala @@ -34,8 +34,8 @@ class ResourceEffectBindingsTest extends AnyWordSpec with MkInjector with GivenW (i: Int @Id("2")) => 10 + i } }, - Activation.empty, Roots(DIKey.get[Int]), + Activation.empty, ) val injector = mkInjector() @@ -53,8 +53,8 @@ class ResourceEffectBindingsTest extends AnyWordSpec with MkInjector with GivenW (i: Int @Id("2")) => Suspend2(10 + i) } }, - Activation.empty, Roots(DIKey.get[Int]), + Activation.empty, ) val injector = mkInjector() @@ -95,8 +95,8 @@ class ResourceEffectBindingsTest extends AnyWordSpec with MkInjector with GivenW (i: Int @Id("2")) => 10 + i } }, - Activation.empty, Roots(DIKey.get[Int]), + Activation.empty, ) val injector = mkInjector() diff --git a/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala b/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala index fa53920bb2..7524000f4a 100644 --- a/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala +++ b/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala @@ -17,8 +17,7 @@ final class ConfigTest extends AnyWordSpec { def mkConfigModule(path: String)(p: PlannerInput): PlannerInput = { p.copy(bindings = p.bindings ++ - mkModule(ConfigFactory.load(path, ConfigParseOptions.defaults().setAllowMissing(false), ConfigResolveOptions.noSystem())) - ) + mkModule(ConfigFactory.load(path, ConfigParseOptions.defaults().setAllowMissing(false), ConfigResolveOptions.noSystem()))) } def mkModule(config: Config): AppConfigModule = { diff --git a/distage/distage-extension-config/src/main/scala/izumi/distage/config/AppConfigModule.scala b/distage/distage-extension-config/src/main/scala/izumi/distage/config/AppConfigModule.scala index 8f6bd3e44a..03202d93c4 100644 --- a/distage/distage-extension-config/src/main/scala/izumi/distage/config/AppConfigModule.scala +++ b/distage/distage-extension-config/src/main/scala/izumi/distage/config/AppConfigModule.scala @@ -4,7 +4,7 @@ import izumi.distage.config.model.AppConfig import izumi.distage.model.definition.ModuleDef class AppConfigModule(appConfig: AppConfig) extends ModuleDef { - make[AppConfig].fromValue(appConfig) + make[AppConfig].fromValue(appConfig).exposed } object AppConfigModule { diff --git a/distage/distage-extension-logstage/src/main/scala/izumi/logstage/distage/LogstageModule.scala b/distage/distage-extension-logstage/src/main/scala/izumi/logstage/distage/LogstageModule.scala index 05bf045e03..d1d4f065dc 100644 --- a/distage/distage-extension-logstage/src/main/scala/izumi/logstage/distage/LogstageModule.scala +++ b/distage/distage-extension-logstage/src/main/scala/izumi/logstage/distage/LogstageModule.scala @@ -14,6 +14,7 @@ class LogstageModule(router: LogRouter, setupStaticLogRouter: Boolean) extends B make[IzLogger] .aliased[RoutingLogger] .aliased[AbstractLogger] + .exposed make[LogRouter].fromValue(router) make[CustomContext].fromValue(CustomContext.empty) diff --git a/distage/distage-framework/.jvm/src/test/scala/com/github/pshirshov/test3/bootstrap/BootstrapFixture3.scala b/distage/distage-framework/.jvm/src/test/scala/com/github/pshirshov/test3/bootstrap/BootstrapFixture3.scala index 67cb369db5..615a0b78dc 100644 --- a/distage/distage-framework/.jvm/src/test/scala/com/github/pshirshov/test3/bootstrap/BootstrapFixture3.scala +++ b/distage/distage-framework/.jvm/src/test/scala/com/github/pshirshov/test3/bootstrap/BootstrapFixture3.scala @@ -11,8 +11,8 @@ object BootstrapFixture3 { final case class BasicConfig(a: Boolean, b: Int) object BootstrapPlugin extends BootstrapPluginDef() with ConfigModuleDef { - makeConfig[BasicConfig]("basicConfig") - make[BootstrapComponent] + makeConfig[BasicConfig]("basicConfig").exposed + make[BootstrapComponent].exposed } final class UnsatisfiedDep diff --git a/distage/distage-framework/.jvm/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala b/distage/distage-framework/.jvm/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala index 383d1591f9..3993c1bab4 100644 --- a/distage/distage-framework/.jvm/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala +++ b/distage/distage-framework/.jvm/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala @@ -176,7 +176,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties { options = PlanningOptions(), activation = Activation.empty, bsModule = BootstrapModule.empty, - bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, Activation.empty, roots)), + bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, roots, Activation.empty)), logger = logger, ) @@ -213,7 +213,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties { options = PlanningOptions(), activation = Activation.empty, bsModule = BootstrapModule.empty, - bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, Activation.empty, roots)), + bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, roots, Activation.empty)), logger = logger, ) @@ -254,7 +254,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties { options = PlanningOptions(), activation = Activation.empty, bsModule = BootstrapModule.empty, - bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, Activation.empty, roots)), + bootloader = Injector.bootloader[Identity](BootstrapModule.empty, Activation.empty, DefaultModule.empty, PlannerInput(definition, roots, Activation.empty)), logger = logger, ) diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala index 288c0fba00..b029e3f57c 100644 --- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala +++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala @@ -74,10 +74,10 @@ object ModuleProvider { def bootstrapModules(): Seq[BootstrapModule] = { val roleInfoModule = new BootstrapModuleDef { - make[RolesInfo].fromValue(roles) - make[RawAppArgs].fromValue(args) - make[ActivationInfo].fromValue(activationInfo) - make[AppShutdownInitiator].fromValue(shutdownInitiator) + make[RolesInfo].fromValue(roles).exposed + make[RawAppArgs].fromValue(args).exposed + make[ActivationInfo].fromValue(activationInfo).exposed + make[AppShutdownInitiator].fromValue(shutdownInitiator).exposed } val loggerModule = new LogstageModule(logRouter, true) diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala index 5e0a729bba..e40a662cfd 100644 --- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala +++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala @@ -14,8 +14,6 @@ import izumi.reflect.TagK trait RoleAppPlanner { def bootloader: Bootloader - -// def reboot(bsModule: BootstrapModule, config: Option[AppConfig]): RoleAppPlanner def makePlan(appMainRoots: Set[DIKey]): AppStartupPlans } @@ -33,11 +31,7 @@ object RoleAppPlanner { bsModule: BootstrapModule @Id("roleapp"), val bootloader: Bootloader @Id("roleapp"), logger: IzLogger, -// parser: ActivationParser, - ) /*(implicit - defaultModule: DefaultModule[F] - )*/ - extends RoleAppPlanner { self => + ) extends RoleAppPlanner { self => private val runtimeGcRoots: Set[DIKey] = Set( DIKey.get[QuasiIORunner[F]], @@ -45,17 +39,6 @@ object RoleAppPlanner { DIKey.get[QuasiAsync[F]], ) -// override def reboot(bsOverride: BootstrapModule, config: Option[AppConfig]): RoleAppPlanner = { -// val configOverride = new BootstrapModuleDef { -// config.foreach(cfg => include(AppConfigModule(cfg))) -// } -// val updatedBsModule = bsModule overriddenBy bsOverride overriddenBy configOverride -// -// val activation = config.map(parser.parseActivation).getOrElse(this.activation) -// -// new RoleAppPlanner.Impl[F](options, activation, updatedBsModule, bootloader, logger, parser) -// } - override def makePlan(appMainRoots: Set[DIKey]): AppStartupPlans = { logger.trace(s"Application will use: ${appMainRoots -> "app roots"} and $activation") @@ -76,7 +59,7 @@ object RoleAppPlanner { logger.trace(s"Bootstrap plan:\n${bootstrapped.plan.render() -> "bootstrap dump" -> null}") logger.trace(s"App module: ${(bootstrapped.module: ModuleBase) -> "app module" -> null}") } - appPlan <- bootstrapped.injector.plan(PlannerInput(bootstrapped.module.drop(runtimeKeys), activation, appMainRoots)) + appPlan <- bootstrapped.injector.plan(PlannerInput(bootstrapped.module.drop(runtimeKeys), appMainRoots, activation)) } yield { val check = new PlanCircularDependencyCheck(options, logger) diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppBootModule.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppBootModule.scala index a088f92951..763c6e3d16 100644 --- a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppBootModule.scala +++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppBootModule.scala @@ -157,7 +157,7 @@ class RoleAppBootModule[F[_]: TagK: DefaultModule]( roots: Set[DIKey] @Id("distage.roles.roots"), defaultModule: DefaultModule[F], ) => - injectorFactory.bootloader(bsModule, bsActivation, defaultModule, PlannerInput(appModule, activation, roots)) + injectorFactory.bootloader(bsModule, bsActivation, defaultModule, PlannerInput(appModule, roots, activation)) } make[RoleAppPlanner].from[RoleAppPlanner.Impl[F]] diff --git a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestPlanner.scala b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestPlanner.scala index b173ee11af..6aac01ed81 100644 --- a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestPlanner.scala +++ b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestPlanner.scala @@ -269,8 +269,8 @@ class TestPlanner[F[_]: TagK: DefaultModule]( runtimePlan <- injector.plan( PlannerInput( appModule ++ new TestRuntimeModule(envExecutionParams), - fullActivation, runtimeGcRoots, + fullActivation, ) ) _ <- Right(planChecker.showProxyWarnings(runtimePlan)) @@ -291,7 +291,7 @@ class TestPlanner[F[_]: TagK: DefaultModule]( .map { case (testRoots, distageTests) => for { - plan <- if (testRoots.nonEmpty) injector.plan(PlannerInput(reducedAppModule, fullActivation, testRoots)) else Right(Plan.empty) + plan <- if (testRoots.nonEmpty) injector.plan(PlannerInput(reducedAppModule, testRoots, fullActivation)) else Right(Plan.empty) _ <- Right(planChecker.showProxyWarnings(plan)) } yield { distageTests.map(AlmostPreparedTest(_, reducedAppModule, plan.keys, fullActivation)) @@ -364,7 +364,7 @@ class TestPlanner[F[_]: TagK: DefaultModule]( for { plan <- if (sharedKeys.nonEmpty) { - injector.plan(PlannerInput(appModule, activation, sharedKeys)) + injector.plan(PlannerInput(appModule, sharedKeys, activation)) } else { Right(Plan.empty) } diff --git a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestTreeBuilder.scala b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestTreeBuilder.scala index becaab320d..21253a37a7 100644 --- a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestTreeBuilder.scala +++ b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/runner/impl/TestTreeBuilder.scala @@ -58,7 +58,7 @@ object TestTreeBuilder { /** (1) It's important to remember that .plan() would always return the same result regardless of the parent locator! * (2) The planner here must preserve customizations (bootstrap modules) hence be the same as instantiated in TestPlanner */ - planner.plan(PlannerInput(newAppModule, t.activation, newRoots)) + planner.plan(PlannerInput(newAppModule, newRoots, t.activation)) } else { Right(Plan.empty) } diff --git a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/spec/DistageTestEnv.scala b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/spec/DistageTestEnv.scala index 5dfc5f0659..a91e6a3c80 100644 --- a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/spec/DistageTestEnv.scala +++ b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/spec/DistageTestEnv.scala @@ -92,7 +92,7 @@ object DistageTestEnv { private[distage] def testkitBootstrapReflectiveModule(availableActivations: ActivationInfo): BootstrapModuleDef = new BootstrapModuleDef { // Update `testkitBootstrapReflectiveKeys` if you add anything here - make[ActivationInfo].fromValue(availableActivations) + make[ActivationInfo].fromValue(availableActivations).exposed } lazy val testkitBootstrapReflectiveKeys: Set[DIKey] = {