From 03cd8c56a28b3b8f41b0a45c84b4611a77fef4d4 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Thu, 22 Sep 2022 13:27:56 -0700 Subject: [PATCH] Fix serialization of whens with empty blocks Also get rid of whitespace-only lines that were emitted after every when block. --- src/main/scala/firrtl/ir/Serializer.scala | 16 ++++++++++------ src/test/scala/firrtlTests/SerializerSpec.scala | 5 +++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/scala/firrtl/ir/Serializer.scala b/src/main/scala/firrtl/ir/Serializer.scala index 21b08b655e..2d77546507 100644 --- a/src/main/scala/firrtl/ir/Serializer.scala +++ b/src/main/scala/firrtl/ir/Serializer.scala @@ -157,6 +157,8 @@ object Serializer { while (next == null && hasNextStmt) { val head = underlying head.next() match { + case b: Block if b.stmts.isEmpty => + next = EmptyStmt case b: Block => val first = b.stmts.iterator val last = underlying @@ -200,21 +202,22 @@ object Serializer { def consumeStmt(stmt: Statement): Unit = { stmt match { case wb: WhenBegin => - newLineAndIndent() + doIndent() b ++= "when "; s(wb.pred); b ++= " :"; s(wb.info) indent += 1 case AltBegin => indent -= 1 - newLineAndIndent() + doIndent() b ++= "else :" indent += 1 case WhenEnd => indent -= 1 case other => + doIndent() s(other) } - if (this.hasNext) { - newLineAndIndent() + if (this.hasNext && stmt != WhenEnd) { + newLineNoIndent() } } b.clear() @@ -238,6 +241,7 @@ object Serializer { case cond: Conditionally => new StmtsSerializer(Seq(cond), indent) case other => implicit val b = new StringBuilder + doIndent() s(other) Iterator(b.toString) } @@ -383,7 +387,7 @@ object Serializer { doIndent(0); b ++= "module "; b ++= name; b ++= " :"; s(info) ports.foreach { p => newLineAndIndent(1); s(p) } newLineNoIndent() // add a blank line between port declaration and body - newLineAndIndent(1) // also indent before body + newLineNoIndent() // newline for body, sIt will indent b.toString } Iterator(start) ++ sIt(body)(indent + 1) @@ -434,7 +438,7 @@ object Serializer { private def newLineNoIndent()(implicit b: StringBuilder): Unit = b += NewLine /** create indent, inc allows for a temporary increment */ - private def doIndent(inc: Int)(implicit b: StringBuilder, indent: Int): Unit = { + private def doIndent(inc: Int = 0)(implicit b: StringBuilder, indent: Int): Unit = { (0 until (indent + inc)).foreach { _ => b ++= Indent } } diff --git a/src/test/scala/firrtlTests/SerializerSpec.scala b/src/test/scala/firrtlTests/SerializerSpec.scala index 797a6045e5..9a984d6055 100644 --- a/src/test/scala/firrtlTests/SerializerSpec.scala +++ b/src/test/scala/firrtlTests/SerializerSpec.scala @@ -116,4 +116,9 @@ class SerializerSpec extends AnyFlatSpec with Matchers { serialized should be(childModuleTabbed) } + it should "emit whens with empty Blocks correctly" in { + val when = Conditionally(NoInfo, Reference("cond"), Block(Seq()), EmptyStmt) + val serialized = Serializer.serialize(when, 1) + serialized should be(" when cond :\n skip\n") + } }