aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
blob: 2b2ccf16b53290045df9f394fc7d3dd089366986 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// SPDX-License-Identifier: Apache-2.0

package firrtl.options.phases

import firrtl.AnnotationSeq
import firrtl.{annoSeqToSeq, seqToAnnoSeq}
import firrtl.annotations.DeletedAnnotation
import firrtl.options.{Phase, Translator}

import scala.collection.mutable

/** Wrap a [[firrtl.options.Phase Phase]] such that any [[firrtl.annotations.Annotation Annotation]] removed by the
  * wrapped [[firrtl.options.Phase Phase]] will be added as [[firrtl.annotations.DeletedAnnotation DeletedAnnotation]]s.
  * @param p a [[firrtl.options.Phase Phase]] to wrap
  */
class DeletedWrapper(p: Phase) extends Phase with Translator[AnnotationSeq, (AnnotationSeq, AnnotationSeq)] {

  override def prerequisites = Seq.empty

  override def optionalPrerequisiteOf = Seq.empty

  override def invalidates(a: Phase) = false

  override lazy val name: String = p.name

  def aToB(a: AnnotationSeq): (AnnotationSeq, AnnotationSeq) = (a, a)

  def bToA(b: (AnnotationSeq, AnnotationSeq)): AnnotationSeq = {
    b._1.diff(b._2).map {
      case DeletedAnnotation(n, a) => DeletedAnnotation(s"$n+$name", a)
      case a                       => DeletedAnnotation(name, a)
    }.toSeq ++ b._2
  }

  def internalTransform(b: (AnnotationSeq, AnnotationSeq)): (AnnotationSeq, AnnotationSeq) = (b._1, p.transform(b._2))

}

object DeletedWrapper {

  /** Wrap a [[firrtl.options.Phase Phase]] in a [[DeletedWrapper]]
    * @param p a [[firrtl.options.Phase Phase]] to wrap
    */
  def apply(p: Phase): DeletedWrapper = new DeletedWrapper(p)

}