Skip to content

Commit f002133

Browse files
author
Roman Janusz
committed
moving some classes from file to file
1 parent b76cf39 commit f002133

File tree

2 files changed

+83
-75
lines changed

2 files changed

+83
-75
lines changed

commons-core/src/main/scala/com/avsystem/commons/di/Component.scala

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package com.avsystem.commons
22
package di
33

44
import com.avsystem.commons.di.Component.DestroyFunction
5-
import com.avsystem.commons.macros.di.ComponentMacros
65
import com.avsystem.commons.misc.{GraphUtils, SourceInfo}
76

8-
import java.util.concurrent.ConcurrentHashMap
97
import java.util.concurrent.atomic.AtomicReference
108
import scala.annotation.compileTimeOnly
119
import scala.annotation.unchecked.uncheckedVariance
@@ -20,7 +18,7 @@ case class ComponentInfo(
2018
name: String,
2119
filePath: String,
2220
fileName: String,
23-
lineNumber: Int
21+
lineNumber: Int,
2422
) {
2523
override def toString: String = s"$name($fileName:$lineNumber)"
2624
}
@@ -202,7 +200,7 @@ object Component {
202200
onCycle = (node, stack) => {
203201
val cyclePath = node :: (node :: stack.map(_.node).takeWhile(_ != node)).reverse
204202
throw DependencyCycleException(cyclePath)
205-
}
203+
},
206204
)
207205

208206
/**
@@ -225,7 +223,7 @@ object Component {
225223
}
226224
else
227225
terminals += c
228-
}
226+
},
229227
)
230228
val destroyFutures = new MHashMap[Component[_], Future[Unit]]
231229

@@ -246,73 +244,3 @@ object Component {
246244
*/
247245
case class AutoComponent[+T](component: Component[T]) extends AnyVal
248246

249-
/**
250-
* Base trait for classes that define collections of interdependent [[Component]]s.
251-
*/
252-
trait Components extends ComponentsLowPrio {
253-
protected def componentNamePrefix: String = ""
254-
255-
protected def componentInfo(sourceInfo: SourceInfo): ComponentInfo =
256-
ComponentInfo(componentNamePrefix, sourceInfo)
257-
258-
/**
259-
* Creates a [[Component]] based on a definition (i.e. a constructor invocation). The definition may refer to
260-
* other components as dependencies using `.ref`. This macro will transform the definition by extracting dependencies
261-
* in a way that allows them to be initialized in parallel, before initializing the current component itself.
262-
*/
263-
protected def component[T](definition: => T)(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.component[T]
264-
265-
/**
266-
* Asynchronous version of [[component]] macro.
267-
*/
268-
protected def asyncComponent[T](definition: ExecutionContext => Future[T])(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.asyncComponent[T]
269-
270-
/**
271-
* This is the same as [[component]] except that the created [[Component]] is cached inside an outer instance that
272-
* implements [[Components]]. This way you can implement your components using `def`s rather than `val`s
273-
* (`val`s can be problematic in traits) but caching will make sure that your `def` always returns the same,
274-
* cached [[Component]] instance. The cache key is based on source position so overriding a method that returns
275-
* `singleton` will create separate [[Component]] with different cache key.
276-
*/
277-
protected def singleton[T](definition: => T)(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.singleton[T]
278-
279-
/**
280-
* Asynchronous version of [[singleton]] macro.
281-
*/
282-
protected def asyncSingleton[T](definition: ExecutionContext => Future[T])(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.asyncSingleton[T]
283-
284-
private lazy val singletonsCache = new ConcurrentHashMap[ComponentInfo, AtomicReference[Future[_]]]
285-
286-
protected def cached[T](component: Component[T], freshInfo: ComponentInfo): Component[T] = {
287-
val cacheStorage = singletonsCache
288-
.computeIfAbsent(freshInfo, _ => new AtomicReference)
289-
.asInstanceOf[AtomicReference[Future[T]]]
290-
component.cached(cacheStorage, freshInfo)
291-
}
292-
293-
protected def reifyAllSingletons: List[Component[_]] = macro ComponentMacros.reifyAllSingletons
294-
295-
// avoids divergent implicit expansion involving `inject`
296-
// this is not strictly necessary but makes compiler error messages nicer
297-
// i.e. the compiler will emit "could not find implicit value" instead of "divergent implicit expansion"
298-
implicit def ambiguousArbitraryComponent1[T]: Component[T] = null
299-
implicit def ambiguousArbitraryComponent2[T]: Component[T] = null
300-
301-
implicit def autoComponent[T](definition: => T)(implicit sourceInfo: SourceInfo): AutoComponent[T] = macro ComponentMacros.autoComponent[T]
302-
303-
protected def optEmptyComponent: Component[Opt[Nothing]] =
304-
singleton(Opt.Empty)
305-
306-
protected def noneComponent: Component[Option[Nothing]] =
307-
singleton(None)
308-
309-
protected def sequenceOpt[T](componentOpt: Opt[Component[T]]): Component[Opt[T]] =
310-
componentOpt.mapOr(optEmptyComponent, c => component(c.ref.opt))
311-
312-
protected def sequenceOption[T](componentOpt: Option[Component[T]]): Component[Option[T]] =
313-
componentOpt.mapOr(noneComponent, c => component(c.ref.option))
314-
}
315-
trait ComponentsLowPrio {
316-
@compileTimeOnly("implicit Component[T] => implicit T inference only works inside code passed to component/singleton macro")
317-
implicit def inject[T](implicit component: Component[T]): T = sys.error("stub")
318-
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.avsystem.commons
2+
package di
3+
4+
import com.avsystem.commons.macros.di.ComponentMacros
5+
import com.avsystem.commons.misc.SourceInfo
6+
7+
import java.util.concurrent.ConcurrentHashMap
8+
import java.util.concurrent.atomic.AtomicReference
9+
import scala.annotation.compileTimeOnly
10+
11+
/**
12+
* Base trait for classes that define collections of interdependent [[Component]]s.
13+
*/
14+
trait Components extends ComponentsLowPrio {
15+
protected def componentNamePrefix: String = ""
16+
17+
protected def componentInfo(sourceInfo: SourceInfo): ComponentInfo =
18+
ComponentInfo(componentNamePrefix, sourceInfo)
19+
20+
/**
21+
* Creates a [[Component]] based on a definition (i.e. a constructor invocation). The definition may refer to
22+
* other components as dependencies using `.ref`. This macro will transform the definition by extracting dependencies
23+
* in a way that allows them to be initialized in parallel, before initializing the current component itself.
24+
*/
25+
protected def component[T](definition: => T)(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.component[T]
26+
27+
/**
28+
* Asynchronous version of [[component]] macro.
29+
*/
30+
protected def asyncComponent[T](definition: ExecutionContext => Future[T])(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.asyncComponent[T]
31+
32+
/**
33+
* This is the same as [[component]] except that the created [[Component]] is cached inside an outer instance that
34+
* implements [[Components]]. This way you can implement your components using `def`s rather than `val`s
35+
* (`val`s can be problematic in traits) but caching will make sure that your `def` always returns the same,
36+
* cached [[Component]] instance. The cache key is based on source position so overriding a method that returns
37+
* `singleton` will create separate [[Component]] with different cache key.
38+
*/
39+
protected def singleton[T](definition: => T)(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.singleton[T]
40+
41+
/**
42+
* Asynchronous version of [[singleton]] macro.
43+
*/
44+
protected def asyncSingleton[T](definition: ExecutionContext => Future[T])(implicit sourceInfo: SourceInfo): Component[T] = macro ComponentMacros.asyncSingleton[T]
45+
46+
private lazy val singletonsCache = new ConcurrentHashMap[ComponentInfo, AtomicReference[Future[_]]]
47+
48+
protected def cached[T](component: Component[T], freshInfo: ComponentInfo): Component[T] = {
49+
val cacheStorage = singletonsCache
50+
.computeIfAbsent(freshInfo, _ => new AtomicReference)
51+
.asInstanceOf[AtomicReference[Future[T]]]
52+
component.cached(cacheStorage, freshInfo)
53+
}
54+
55+
protected def reifyAllSingletons: List[Component[_]] = macro ComponentMacros.reifyAllSingletons
56+
57+
// avoids divergent implicit expansion involving `inject`
58+
// this is not strictly necessary but makes compiler error messages nicer
59+
// i.e. the compiler will emit "could not find implicit value" instead of "divergent implicit expansion"
60+
implicit def ambiguousArbitraryComponent1[T]: Component[T] = null
61+
implicit def ambiguousArbitraryComponent2[T]: Component[T] = null
62+
63+
implicit def autoComponent[T](definition: => T)(implicit sourceInfo: SourceInfo): AutoComponent[T] = macro ComponentMacros.autoComponent[T]
64+
65+
protected def optEmptyComponent: Component[Opt[Nothing]] =
66+
singleton(Opt.Empty)
67+
68+
protected def noneComponent: Component[Option[Nothing]] =
69+
singleton(None)
70+
71+
protected def sequenceOpt[T](componentOpt: Opt[Component[T]]): Component[Opt[T]] =
72+
componentOpt.mapOr(optEmptyComponent, c => component(c.ref.opt))
73+
74+
protected def sequenceOption[T](componentOpt: Option[Component[T]]): Component[Option[T]] =
75+
componentOpt.mapOr(noneComponent, c => component(c.ref.option))
76+
}
77+
trait ComponentsLowPrio {
78+
@compileTimeOnly("implicit Component[T] => implicit T inference only works inside code passed to component/singleton macro")
79+
implicit def inject[T](implicit component: Component[T]): T = sys.error("stub")
80+
}

0 commit comments

Comments
 (0)