aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options/phases
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/options/phases')
-rw-r--r--src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala41
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 {