diff options
Diffstat (limited to 'src/main/scala/firrtl/options/phases')
| -rw-r--r-- | src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala b/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala index 7d857108..ccd08fa4 100644 --- a/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala +++ b/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala @@ -3,11 +3,12 @@ package firrtl.options.phases import firrtl.AnnotationSeq -import firrtl.annotations.{DeletedAnnotation, JsonProtocol} -import firrtl.options.{Phase, StageOptions, Unserializable, Viewer} -import firrtl.options.Dependency +import firrtl.annotations.{Annotation, DeletedAnnotation, JsonProtocol} +import firrtl.options.{CustomFileEmission, Dependency, Phase, PhaseException, StageOptions, Unserializable, Viewer} -import java.io.PrintWriter +import java.io.{BufferedWriter, File, FileWriter, PrintWriter} + +import scala.collection.mutable /** [[firrtl.options.Phase Phase]] that writes an [[AnnotationSeq]] to a file. A file is written if and only if a * [[StageOptions]] view has a non-empty [[StageOptions.annotationFileOut annotationFileOut]]. @@ -27,10 +28,34 @@ class WriteOutputAnnotations extends Phase { /** Write the input [[AnnotationSeq]] to a fie. */ def transform(annotations: AnnotationSeq): AnnotationSeq = { val sopts = Viewer[StageOptions].view(annotations) - val serializable = annotations.filter{ - case _: Unserializable => false - case _: DeletedAnnotation => sopts.writeDeleted - case _ => true + val filesWritten = mutable.HashMap.empty[String, Annotation] + val serializable: AnnotationSeq = annotations.toSeq.flatMap { + case _: Unserializable => None + case a: DeletedAnnotation => if (sopts.writeDeleted) { Some(a) } else { None } + case a: CustomFileEmission => + val filename = a.filename(annotations) + val canonical = filename.getCanonicalPath() + + filesWritten.get(canonical) match { + case None => + val w = new BufferedWriter(new FileWriter(filename)) + a.getBytes.foreach( w.write(_) ) + w.close() + filesWritten(canonical) = a + case Some(first) => + val msg = + s"""|Multiple CustomFileEmission annotations would be serialized to the same file, '$canonical' + | - first writer: + | class: ${first.getClass.getName} + | trimmed serialization: ${first.serialize.take(80)} + | - second writer: + | class: ${a.getClass.getName} + | trimmed serialization: ${a.serialize.take(80)} + |""".stripMargin + throw new PhaseException(msg) + } + a.replacements(filename) + case a => Some(a) } sopts.annotationFileOut match { |
