diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index f65e4870..567afd04 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -15,9 +15,9 @@ abstract class LazyModule()(implicit val p: Parameters) protected[diplomacy] var children = List[LazyModule]() protected[diplomacy] var nodes = List[BaseNode]() protected[diplomacy] var info: SourceInfo = UnlocatableSourceInfo - protected[diplomacy] val parent = LazyModule.stack.headOption + protected[diplomacy] val parent = LazyModule.scope - LazyModule.stack = this :: LazyModule.stack + LazyModule.scope = Some(this) parent.foreach(p => p.children = this :: p.children) private var suggestedName: Option[String] = None @@ -120,16 +120,16 @@ abstract class LazyModule()(implicit val p: Parameters) object LazyModule { - protected[diplomacy] var stack = List[LazyModule]() + protected[diplomacy] var scope: Option[LazyModule] = None private var index = 0 def apply[T <: LazyModule](bc: T)(implicit sourceInfo: SourceInfo): T = { // Make sure the user put LazyModule around modules in the correct order // If this require fails, probably some grandchild was missing a LazyModule // ... or you applied LazyModule twice - require (!stack.isEmpty, s"LazyModule() applied to ${bc.name} twice ${sourceLine(sourceInfo)}") - require (stack.head eq bc, s"LazyModule() applied to ${bc.name} before ${stack.head.name} ${sourceLine(sourceInfo)}") - stack = stack.tail + require (scope.isDefined, s"LazyModule() applied to ${bc.name} twice ${sourceLine(sourceInfo)}") + require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}") + scope = bc.parent bc.info = sourceInfo bc } @@ -142,7 +142,7 @@ sealed trait LazyModuleImpLike extends BaseModule protected[diplomacy] val dangles: Seq[Dangle] // .module had better not be accessed while LazyModules are still being built! - require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}") + require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}") override def desiredName = wrapper.moduleName suggestName(wrapper.instanceName) @@ -191,11 +191,12 @@ trait LazyScope { this: LazyModule => def apply[T](body: => T)(implicit p: Parameters) = { - require (!LazyModule.stack.exists(x => x eq this)) - LazyModule.stack = this :: LazyModule.stack + val saved = LazyModule.scope + LazyModule.scope = Some(this) val out = body - require (LazyModule.stack.head eq this) - LazyModule.stack = LazyModule.stack.tail + require (LazyModule.scope.isDefined, s"LazyScope ${name} tried to exit, but scope was empty!") + require (LazyModule.scope.get eq this, s"LazyScope ${name} exited before LazyModule ${LazyModule.scope.get.name} was closed") + LazyModule.scope = saved out } } diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 626b7b8c..aa858af3 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -84,9 +84,9 @@ abstract class SimpleNodeImp[D, U, E, B <: Data] abstract class BaseNode(implicit val valName: ValName) { - require (!LazyModule.stack.isEmpty, "You cannot create a node outside a LazyModule!") + require (LazyModule.scope.isDefined, "You cannot create a node outside a LazyModule!") - val lazyModule = LazyModule.stack.head + val lazyModule = LazyModule.scope.get val index = lazyModule.nodes.size lazyModule.nodes = this :: lazyModule.nodes @@ -311,7 +311,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( val x = this // x := y val y = h.outward val info = sourceLine(sourceInfo, " at ", "") - require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) val i = x.iPushed val o = y.oPushed y.oPush(i, x, binding match { diff --git a/src/main/scala/diplomacy/Resources.scala b/src/main/scala/diplomacy/Resources.scala index 6a48e667..d62f829e 100644 --- a/src/main/scala/diplomacy/Resources.scala +++ b/src/main/scala/diplomacy/Resources.scala @@ -179,7 +179,7 @@ trait BindingScope private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue]) private lazy val eval: Unit = { - require (LazyModule.stack.isEmpty, "May not evaluate binding while still constructing LazyModules") + require (!LazyModule.scope.isDefined, "May not evaluate binding while still constructing LazyModules") parentScope.foreach { _.eval } resourceBindings = parentScope.map(_.resourceBindings).getOrElse(Nil) BindingScope.active = Some(this) @@ -224,7 +224,7 @@ trait BindingScope object BindingScope { protected[diplomacy] var active: Option[BindingScope] = None - protected[diplomacy] def find(m: Option[LazyModule] = LazyModule.stack.headOption): Option[BindingScope] = m.flatMap { + protected[diplomacy] def find(m: Option[LazyModule] = LazyModule.scope): Option[BindingScope] = m.flatMap { case s: BindingScope => Some(s) case x => find(x.parent) }