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 c37a05c74e..2a1247f261 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 @@ -327,7 +327,8 @@ class DSLTest extends WordSpec with MkInjector { "support binding to multiple interfaces" in { import BasicCase6._ - val implXYZ = new ImplXYZ + val implXYZ: Identity[ImplXYZ] = new ImplXYZ + val implXYZResource = DIResource.make(implXYZ)(_ => ()) val definition = new ModuleDef { bind[ImplXYZ] @@ -346,7 +347,7 @@ class DSLTest extends WordSpec with MkInjector { )) val definitionEffect = new ModuleDef { - bindEffect[Identity, ImplXYZ](implXYZ).to[TraitX].to[TraitY].to[TraitZ] + bindEffect(implXYZ).to[TraitX].to[TraitY].to[TraitZ] } assert(definitionEffect === Module.make( @@ -360,13 +361,29 @@ class DSLTest extends WordSpec with MkInjector { )) val definitionResource = new ModuleDef { - bindResource[DIResource.Simple[ImplXYZ], ImplXYZ].to[TraitX].to[TraitY].to[TraitZ] + bindResource[DIResource.Simple[ImplXYZ]].to[TraitX].to[TraitY].to[TraitZ] } assert(definitionResource === Module.make( Set( - SingletonBinding(DIKey.get[ImplXYZ], ImplDef.ResourceImpl(SafeType.get[ImplXYZ], SafeType.getK[Identity], - ImplDef.TypeImpl(SafeType.get[DIResource.Simple[ImplXYZ]])), Set.empty, SourceFilePosition.unknown) + SingletonBinding(DIKey.get[ImplXYZ] + , ImplDef.ResourceImpl(SafeType.get[ImplXYZ], SafeType.getK[Identity], ImplDef.TypeImpl(SafeType.get[DIResource.Simple[ImplXYZ]])) + , Set.empty, SourceFilePosition.unknown) + , Bindings.reference[TraitX, ImplXYZ] + , Bindings.reference[TraitY, ImplXYZ] + , Bindings.reference[TraitZ, ImplXYZ] + ) + )) + + val definitionResourceFn = new ModuleDef { + bindResource(implXYZResource).to[TraitX].to[TraitY].to[TraitZ] + } + + assert(definitionResourceFn === Module.make( + Set( + SingletonBinding(DIKey.get[ImplXYZ] + , ImplDef.ResourceImpl(SafeType.get[ImplXYZ], SafeType.getK[Identity], ImplDef.InstanceImpl(SafeType.get[DIResource[Identity, ImplXYZ]], implXYZResource)) + , Set.empty, SourceFilePosition.unknown) , Bindings.reference[TraitX, ImplXYZ] , Bindings.reference[TraitY, ImplXYZ] , Bindings.reference[TraitZ, ImplXYZ] diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala b/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala index bb1d8ad701..560cc204c3 100644 --- a/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala +++ b/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/AbstractBindingDefDSL.scala @@ -96,6 +96,16 @@ trait AbstractBindingDefDSL[BindDSL[_], MultipleDSL[_], SetDSL[_]] { _setDSL(setRef) } + /** Same as `make[T].from(implicitly[T])` **/ + final protected def addImplicit[T: Tag](implicit instance: T, pos: CodePositionMaterializer): Unit = { + registered(new SingletonRef(Bindings.binding(instance))).discard() + } + + /** Same as `make[T].named(name).from(implicitly[T])` **/ + final protected def addImplicit[T: Tag](name: String)(implicit instance: T, pos: CodePositionMaterializer): Unit = { + registered(new SingletonRef(Bindings.binding(instance), mutable.Queue(SingletonInstruction.SetId(name)))).discard() + } + final protected def bind[T: Tag](implicit pos: CodePositionMaterializer): MultipleDSL[T] = { bindImpl[T](ImplDef.TypeImpl(SafeType.get[T])) } @@ -124,41 +134,30 @@ trait AbstractBindingDefDSL[BindDSL[_], MultipleDSL[_], SetDSL[_]] { bindImpl[T](ImplDef.EffectImpl(SafeType.get[T], SafeType.getK[F], ImplDef.ProviderImpl(SafeType.get[F[T]], function.get))) } - final protected def bindResource[R <: DIResourceBase[Any, T], T](implicit tag: ResourceTag[R] {type A = T}, pos: CodePositionMaterializer): MultipleDSL[T] = { + final protected def bindResource[R <: DIResourceBase[Any, Any]](implicit tag: ResourceTag[R], pos: CodePositionMaterializer): MultipleDSL[tag.A] = { import tag._ - bindImpl[T](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.TypeImpl(SafeType.get[R]))) + bindImpl[A](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.TypeImpl(SafeType.get[R]))) } - final protected def bindResource[R <: DIResourceBase[Any, T], T](instance: R with DIResourceBase[Any, T])(implicit tag: ResourceTag[R] {type A = T}, pos: CodePositionMaterializer): MultipleDSL[T] = { + final protected def bindResource[R <: DIResourceBase[Any, Any]](instance: R with DIResourceBase[Any, Any])(implicit tag: ResourceTag[R], pos: CodePositionMaterializer): MultipleDSL[tag.A] = { import tag._ - bindImpl[T](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.InstanceImpl(SafeType.get[R], instance))) + bindImpl[A](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.InstanceImpl(SafeType.get[R], instance))) } - final protected def bindResource[R <: DIResourceBase[Any, T], T](function: ProviderMagnet[R with DIResourceBase[Any, T]])(implicit tag: ResourceTag[R] {type A = T}, pos: CodePositionMaterializer): MultipleDSL[T] = { + final protected def bindResource[R <: DIResourceBase[Any, Any]](function: ProviderMagnet[R with DIResourceBase[Any, Any]])(implicit tag: ResourceTag[R], pos: CodePositionMaterializer): MultipleDSL[tag.A] = { import tag._ - bindImpl[T](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.ProviderImpl(SafeType.get[R], function.get))) + bindImpl[A](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.ProviderImpl(SafeType.get[R], function.get))) } - final protected def bindResource[R0, R <: DIResourceBase[Any, T], T] - (function: ProviderMagnet[R0])(implicit adapt: ProviderMagnet[R0] => ProviderMagnet[R with DIResourceBase[Any, T]], tag: ResourceTag[R] {type A = T}, pos: CodePositionMaterializer): MultipleDSL[T] = { + final protected def bindResource[R0, R <: DIResourceBase[Any, Any]](function: ProviderMagnet[R0])(implicit + adapt: ProviderMagnet[R0] => ProviderMagnet[R with DIResourceBase[Any, Any]], + tag: ResourceTag[R], + pos: CodePositionMaterializer): MultipleDSL[tag.A] = { import tag._ - bindImpl[T](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.ProviderImpl(SafeType.get[R], adapt(function).get))) - } - - // @deprecated("use .setOf", "14.03.2019") - // final protected def many[T: Tag](implicit pos: CodePositionMaterializer): SetDSL[T] = setOf[T] - - /** Same as `make[T].from(implicitly[T])` **/ - final protected def addImplicit[T: Tag](implicit instance: T, pos: CodePositionMaterializer): Unit = { - registered(new SingletonRef(Bindings.binding(instance))).discard() + bindImpl[A](ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.ProviderImpl(SafeType.get[R], adapt(function).get))) } - /** Same as `make[T].named(name).from(implicitly[T])` **/ - final protected def addImplicit[T: Tag](name: String)(implicit instance: T, pos: CodePositionMaterializer): Unit = { - registered(new SingletonRef(Bindings.binding(instance), mutable.Queue(SingletonInstruction.SetId(name)))).discard() - } - - private[distage] def bindImpl[T: Tag](implDef: ImplDef)(implicit pos: CodePositionMaterializer): MultipleDSL[T] = { + private[this] def bindImpl[T: Tag](implDef: ImplDef)(implicit pos: CodePositionMaterializer): MultipleDSL[T] = { val ref = registered(new MultipleRef(SingletonBinding(DIKey.get[T], implDef, Set.empty, pos.get.position), pos.get.position)) _multipleDSL[T](ref) } @@ -216,10 +215,6 @@ object AbstractBindingDefDSL { } } - private final class MultiSetHackId(private val long: Long) extends AnyVal { - override def toString: String = s"multi.${long.toString}" - } - final class SetRef ( initial: EmptySetBinding[DIKey.TypeKey], @@ -304,55 +299,34 @@ object AbstractBindingDefDSL { } sealed trait SingletonInstruction - object SingletonInstruction { - final case class SetImpl(implDef: ImplDef) extends SingletonInstruction - final case class AddTags(tags: Set[BindingTag]) extends SingletonInstruction - final case class SetId[I](id: I)(implicit val idContract: IdContract[I]) extends SingletonInstruction - final case class SetIdFromImplName() extends SingletonInstruction - } sealed trait MultipleInstruction - object MultipleInstruction { - final case class AddTags(tags: Set[BindingTag]) extends MultipleInstruction - final case class SetId[I](id: I)(implicit val idContract: IdContract[I]) extends MultipleInstruction - final case class ImplWithReference(key: DIKey) extends MultipleInstruction - } sealed trait SetInstruction - object SetInstruction { - final case class AddTagsAll(tags: Set[BindingTag]) extends SetInstruction - final case class SetIdAll[I](id: I)(implicit val idContract: IdContract[I]) extends SetInstruction - } sealed trait SetElementInstruction - object SetElementInstruction { - final case class ElementAddTags(tags: Set[BindingTag]) extends SetElementInstruction - } sealed trait MultiSetElementInstruction - object MultiSetElementInstruction { - final case class MultiAddTags(tags: Set[BindingTag]) extends MultiSetElementInstruction - } } diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala b/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala index 29619775a7..f6daa47531 100644 --- a/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala +++ b/distage/distage-model/src/main/scala/izumi/distage/model/definition/dsl/ModuleDefDSL.scala @@ -68,7 +68,7 @@ trait ModuleDefDSL import AbstractBindingDefDSL._ - override def bindings: Set[Binding] = freeze + override final def bindings: Set[Binding] = freeze private[this] final def freeze: Set[Binding] = { ModuleBase.tagwiseMerge(retaggedIncludes ++ frozenState) @@ -76,13 +76,13 @@ trait ModuleDefDSL .++(asIsIncludes) } - override private[definition] def _bindDSL[T: Tag](ref: SingletonRef): ModuleDefDSL.BindDSL[T] = + override private[definition] final def _bindDSL[T: Tag](ref: SingletonRef): ModuleDefDSL.BindDSL[T] = new ModuleDefDSL.BindDSL[T](ref, ref.key) - override private[definition] def _multipleDSL[T: Tag](ref: MultipleRef): ModuleDefDSL.MultipleDSL[T] = + override private[definition] final def _multipleDSL[T: Tag](ref: MultipleRef): ModuleDefDSL.MultipleDSL[T] = new ModuleDefDSL.MultipleDSL[T](ref, ref.key) - override private[definition] def _setDSL[T: Tag](ref: SetRef): ModuleDefDSL.SetDSL[T] = + override private[definition] final def _setDSL[T: Tag](ref: SetRef): ModuleDefDSL.SetDSL[T] = new ModuleDefDSL.SetDSL[T](ref) /** @@ -642,7 +642,6 @@ object ModuleDefDSL { appendElement(ImplDef.ResourceImpl(SafeType.get[A], SafeType.getK[F], ImplDef.ReferenceImpl(SafeType.get[R], DIKey.get[R].named(name), weak = true)), pos) } - protected def multiSetAdd(newImpl: ImplDef, pos: CodePositionMaterializer): AfterMultiAdd protected def appendElement(newImpl: ImplDef, pos: CodePositionMaterializer): AfterAdd }