aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorSchuyler Eldridge2019-07-11 16:03:29 -0400
committerSchuyler Eldridge2019-07-11 16:06:53 -0400
commitb10184a77030a3178eb92e9fcc34e24ee1e13831 (patch)
tree00bef3309a65e7f9ae607343feb54f70979c3381 /src/main
parentab87b5a114de1f0e91a4c080d77a99524fada55b (diff)
Change Dependency API to Class[_ <: A]
This changes the Dependency API to specify dependencies in terms of classes subtyping the DependencyAPI trait. Previously, this was invariant which caused a bunch of ugly, unneeded .asInstanceOf jank. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/options/DependencyManager.scala50
-rw-r--r--src/main/scala/firrtl/options/Phase.scala16
2 files changed, 29 insertions, 37 deletions
diff --git a/src/main/scala/firrtl/options/DependencyManager.scala b/src/main/scala/firrtl/options/DependencyManager.scala
index 2afc085d..7b49b074 100644
--- a/src/main/scala/firrtl/options/DependencyManager.scala
+++ b/src/main/scala/firrtl/options/DependencyManager.scala
@@ -22,15 +22,15 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** Requested [[firrtl.options.TransformLike TransformLike]]s that should be run. Internally, this will be converted to
* a set based on the ordering defined here.
*/
- def targets: Seq[Class[B]]
- private lazy val _targets: LinkedHashSet[Class[B]] = targets
- .foldLeft(new LinkedHashSet[Class[B]]()){ case (a, b) => a += b }
+ def targets: Seq[Class[_ <: B]]
+ private lazy val _targets: LinkedHashSet[Class[_ <: B]] = targets
+ .foldLeft(new LinkedHashSet[Class[_ <: B]]()){ case (a, b) => a += b }
/** A sequence of [[firrtl.Transform]]s that have been run. Internally, this will be converted to an ordered set.
*/
- def currentState: Seq[Class[B]]
- private lazy val _currentState: LinkedHashSet[Class[B]] = currentState
- .foldLeft(new LinkedHashSet[Class[B]]()){ case (a, b) => a += b }
+ def currentState: Seq[Class[_ <: B]]
+ private lazy val _currentState: LinkedHashSet[Class[_ <: B]] = currentState
+ .foldLeft(new LinkedHashSet[Class[_ <: B]]()){ case (a, b) => a += b }
/** Existing transform objects that have already been constructed */
def knownObjects: Set[B]
@@ -42,8 +42,8 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** Store of conversions between classes and objects. Objects that do not exist in the map will be lazily constructed.
*/
- protected lazy val classToObject: LinkedHashMap[Class[B], B] = {
- val init = LinkedHashMap[Class[B], B](knownObjects.map(x => x.getClass.asInstanceOf[Class[B]] -> x).toSeq: _*)
+ protected lazy val classToObject: LinkedHashMap[Class[_ <: B], B] = {
+ val init = LinkedHashMap[Class[_ <: B], B](knownObjects.map(x => x.getClass -> x).toSeq: _*)
(_targets ++ _currentState)
.filter(!init.contains(_))
.map(x => init(x) = safeConstruct(x))
@@ -54,33 +54,33 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* requirements. This is used to solve sub-problems arising from invalidations.
*/
protected def copy(
- targets: Seq[Class[B]],
- currentState: Seq[Class[B]],
+ targets: Seq[Class[_ <: B]],
+ currentState: Seq[Class[_ <: B]],
knownObjects: ISet[B] = classToObject.values.toSet): B
/** Implicit conversion from Class[B] to B */
- private implicit def cToO(c: Class[B]): B = classToObject.getOrElseUpdate(c, safeConstruct(c))
+ private implicit def cToO(c: Class[_ <: B]): B = classToObject.getOrElseUpdate(c, safeConstruct(c))
/** Implicit conversion from B to Class[B] */
- private implicit def oToC(b: B): Class[B] = b.getClass.asInstanceOf[Class[B]]
+ private implicit def oToC(b: B): Class[_ <: B] = b.getClass
/** Modified breadth-first search that supports multiple starting nodes and a custom extractor that can be used to
* generate/filter the edges to explore. Additionally, this will include edges to previously discovered nodes.
*/
- private def bfs( start: LinkedHashSet[Class[B]],
- blacklist: LinkedHashSet[Class[B]],
- extractor: B => Set[Class[B]] ): LinkedHashMap[B, LinkedHashSet[B]] = {
+ private def bfs( start: LinkedHashSet[Class[_ <: B]],
+ blacklist: LinkedHashSet[Class[_ <: B]],
+ extractor: B => Set[Class[_ <: B]] ): LinkedHashMap[B, LinkedHashSet[B]] = {
val (queue, edges) = {
- val a: Queue[Class[B]] = Queue(start.toSeq:_*)
+ val a: Queue[Class[_ <: B]] = Queue(start.toSeq:_*)
val b: LinkedHashMap[B, LinkedHashSet[B]] = LinkedHashMap[B, LinkedHashSet[B]](
start.map((cToO(_) -> LinkedHashSet[B]())).toSeq:_*)
(a, b)
}
while (queue.nonEmpty) {
- val u: Class[B] = queue.dequeue
- for (v: Class[B] <- extractor(classToObject(u))) {
+ val u: Class[_ <: B] = queue.dequeue
+ for (v <- extractor(classToObject(u))) {
if (!blacklist.contains(v) && !edges.contains(v)) {
queue.enqueue(v)
}
@@ -107,7 +107,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val edges = bfs(
start = _targets -- _currentState,
blacklist = _currentState,
- extractor = (p: B) => new LinkedHashSet[Class[B]]() ++ p.prerequisites -- _currentState)
+ extractor = (p: B) => new LinkedHashSet[Class[_ <: B]]() ++ p.prerequisites -- _currentState)
DiGraph(edges)
}
@@ -145,7 +145,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
bfs(
start = _targets -- _currentState,
blacklist = _currentState,
- extractor = (p: B) => v.filter(p.invalidates).map(_.asClass).toSet))
+ extractor = (p: B) => v.filter(p.invalidates).map(_.getClass).toSet))
.reverse
}
@@ -158,7 +158,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
}
/** Wrap an [[IllegalAccessException]] due to attempted object construction in a [[DependencyManagerException]] */
- private def safeConstruct[A](a: Class[A]): A = try { a.newInstance } catch {
+ private def safeConstruct[A](a: Class[_ <: A]): A = try { a.newInstance } catch {
case e: IllegalAccessException => throw new DependencyManagerException(
s"Failed to construct '$a'! (Did you try to construct an object?)", e)
case e: InstantiationException => throw new DependencyManagerException(
@@ -230,7 +230,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
final override def transform(annotations: A): A = {
/* A local store of each wrapper to it's underlying class. */
- val wrapperToClass = new HashMap[B, Class[B]]
+ val wrapperToClass = new HashMap[B, Class[_ <: B]]
/* The determined, flat order of transforms is wrapped with surrounding transforms while populating wrapperToClass so
* that each wrapped transform object can be dereferenced to its underlying class. Each wrapped transform is then
@@ -354,10 +354,10 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* @param targets the [[Phase]]s you want to run
*/
class PhaseManager(
- val targets: Seq[Class[Phase]],
- val currentState: Seq[Class[Phase]] = Seq.empty,
+ val targets: Seq[Class[_ <: Phase]],
+ val currentState: Seq[Class[_ <: Phase]] = Seq.empty,
val knownObjects: Set[Phase] = Set.empty) extends Phase with DependencyManager[AnnotationSeq, Phase] {
- protected def copy(a: Seq[Class[Phase]], b: Seq[Class[Phase]], c: ISet[Phase]) = new PhaseManager(a, b, c)
+ protected def copy(a: Seq[Class[_ <: Phase]], b: Seq[Class[_ <: Phase]], c: ISet[Phase]) = new PhaseManager(a, b, c)
}
diff --git a/src/main/scala/firrtl/options/Phase.scala b/src/main/scala/firrtl/options/Phase.scala
index e5aa87ec..66a47f45 100644
--- a/src/main/scala/firrtl/options/Phase.scala
+++ b/src/main/scala/firrtl/options/Phase.scala
@@ -45,8 +45,8 @@ trait DependencyAPI[A <: DependencyAPI[A]] { this: TransformLike[_] =>
/** All transform that must run before this transform
* $seqNote
*/
- def prerequisites: Seq[Class[A]] = Seq.empty
- private[options] lazy val _prerequisites: LinkedHashSet[Class[A]] = new LinkedHashSet() ++ prerequisites.toSet
+ def prerequisites: Seq[Class[_ <: A]] = Seq.empty
+ private[options] lazy val _prerequisites: LinkedHashSet[Class[_ <: A]] = new LinkedHashSet() ++ prerequisites.toSet
/** All transforms that must run ''after'' this transform
*
@@ -67,8 +67,8 @@ trait DependencyAPI[A <: DependencyAPI[A]] { this: TransformLike[_] =>
* @see [[firrtl.passes.CheckTypes]] for an example of an optional checking [[firrtl.Transform]]
* $seqNote
*/
- def dependents: Seq[Class[A]] = Seq.empty
- private[options] lazy val _dependents: LinkedHashSet[Class[A]] = new LinkedHashSet() ++ dependents.toSet
+ def dependents: Seq[Class[_ <: A]] = Seq.empty
+ private[options] lazy val _dependents: LinkedHashSet[Class[_ <: A]] = new LinkedHashSet() ++ dependents.toSet
/** A function that, given a transform will return true if this transform invalidates/undos the effects of the input
* transform
@@ -76,14 +76,6 @@ trait DependencyAPI[A <: DependencyAPI[A]] { this: TransformLike[_] =>
*/
def invalidates(a: A): Boolean = true
- /** Helper method to return the underlying class */
- final def asClass: Class[A] = this.getClass.asInstanceOf[Class[A]]
-
- /** Implicit conversion that allows for terser specification of [[DependencyAPI.prerequisites prerequisites]] and
- * [[DependencyAPI.dependents dependents]].
- */
- implicit def classHelper(a: Class[_ <: A]): Class[A] = a.asInstanceOf[Class[A]]
-
}
/** A trait indicating that no invalidations occur, i.e., all previous transforms are preserved