blob: d50b2c6fb37afa5f6483a279b64277e0c684a8b5 (
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
// SPDX-License-Identifier: Apache-2.0
package firrtl.options.phases
import firrtl.AnnotationSeq
import firrtl.annotations.{AnnotationFileNotFoundException, JsonProtocol}
import firrtl.options.{InputAnnotationFileAnnotation, Phase, StageUtils}
import firrtl.FileUtils
import firrtl.stage.AllowUnrecognizedAnnotations
import java.io.File
import scala.collection.mutable
import scala.util.{Failure, Try}
/** Recursively expand all [[InputAnnotationFileAnnotation]]s in an [[AnnotationSeq]] */
class GetIncludes extends Phase {
override def prerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq.empty
override def invalidates(a: Phase) = false
/** Read all [[annotations.Annotation]] from a file in JSON or YAML format
* @param filename a JSON or YAML file of [[annotations.Annotation]]
* @throws annotations.AnnotationFileNotFoundException if the file does not exist
*/
private def readAnnotationsFromFile(
filename: String,
allowUnrecognizedAnnotations: Boolean = false
): AnnotationSeq = {
val file = new File(filename).getCanonicalFile
if (!file.exists) { throw new AnnotationFileNotFoundException(file) }
JsonProtocol.deserialize(file, allowUnrecognizedAnnotations)
}
/** Recursively read all [[Annotation]]s from any [[InputAnnotationFileAnnotation]]s while making sure that each file is
* only read once
* @param includeGuard filenames that have already been read
* @param annos a sequence of annotations
* @return the original annotation sequence with any discovered annotations added
*/
private def getIncludes(includeGuard: mutable.Set[String] = mutable.Set())(annos: AnnotationSeq): AnnotationSeq = {
val allowUnrecognizedAnnotations = annos.contains(AllowUnrecognizedAnnotations)
annos.flatMap {
case a @ InputAnnotationFileAnnotation(value) =>
if (includeGuard.contains(value)) {
StageUtils.dramaticWarning(s"Annotation file ($value) already included! (Did you include it more than once?)")
None
} else {
includeGuard += value
getIncludes(includeGuard)(readAnnotationsFromFile(value, allowUnrecognizedAnnotations))
}
case x => Seq(x)
}
}
def transform(annotations: AnnotationSeq): AnnotationSeq = getIncludes()(annotations)
}
|