summaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/main/scala/chisel3/internal/InstantiableMacro.scala77
-rw-r--r--macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala30
2 files changed, 107 insertions, 0 deletions
diff --git a/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
new file mode 100644
index 00000000..1d374198
--- /dev/null
+++ b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.internal
+
+import scala.language.experimental.macros
+import scala.annotation.StaticAnnotation
+import scala.reflect.macros.whitebox
+
+
+private[chisel3] object instantiableMacro {
+
+ def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
+ import c.universe._
+ def processBody(stats: Seq[Tree]): (Seq[Tree], Iterable[Tree]) = {
+ val extensions = scala.collection.mutable.ArrayBuffer.empty[Tree]
+ extensions += q"implicit val mg = new chisel3.internal.MacroGenerated{}"
+ val resultStats = stats.flatMap {
+ case x @ q"@public val $tpname: $tpe = $name" if tpname.toString() == name.toString() =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Nil
+ case x @ q"@public val $tpname: $tpe = $_" =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Seq(x)
+ case x @ q"@public lazy val $tpname: $tpe = $_" =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Seq(x)
+ case other => Seq(other)
+ }
+ (resultStats, extensions)
+ }
+ val result = {
+ val (clz, objOpt) = annottees.map(_.tree).toList match {
+ case Seq(c, o) => (c, Some(o))
+ case Seq(c) => (c, None)
+ }
+ val (newClz, implicitClzs, tpname) = clz match {
+ case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
+ val defname = TypeName(tpname + c.freshName())
+ val instname = TypeName(tpname + c.freshName())
+ val (newStats, extensions) = processBody(stats)
+ (q""" $mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats } """,
+ Seq(q"""implicit class $defname(module: chisel3.experimental.hierarchy.Definition[$tpname]) { ..$extensions }""",
+ q"""implicit class $instname(module: chisel3.experimental.hierarchy.Instance[$tpname]) { ..$extensions } """),
+ tpname)
+ case q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
+ val defname = TypeName(tpname + c.freshName())
+ val instname = TypeName(tpname + c.freshName())
+ val (newStats, extensions) = processBody(stats)
+ (q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats }",
+ Seq(q"""implicit class $defname(module: chisel3.experimental.hierarchy.Definition[$tpname]) { ..$extensions }""",
+ q"""implicit class $instname(module: chisel3.experimental.hierarchy.Instance[$tpname]) { ..$extensions } """),
+ tpname)
+ }
+ val newObj = objOpt match {
+ case None => q"""object ${tpname.toTermName} { ..$implicitClzs } """
+ case Some(obj @ q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }") =>
+ q"""
+ $mods object $tname extends { ..$earlydefns } with ..$parents { $self =>
+ ..$implicitClzs
+ ..$body
+ }
+ """
+ }
+ q"""
+ $newClz
+
+ $newObj
+ """
+ }
+ c.Expr[Any](result)
+ }
+}
+
+private[chisel3] class instantiable extends StaticAnnotation {
+ def macroTransform(annottees: Any*): Any = macro instantiableMacro.impl
+}
+private[chisel3] class public extends StaticAnnotation
diff --git a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
index 6121bc1e..a8a7e8d5 100644
--- a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
+++ b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
@@ -47,6 +47,36 @@ class InstTransform(val c: Context) extends SourceInfoTransformMacro {
}
// Workaround for https://github.com/sbt/sbt/issues/3966
+object DefinitionTransform
+// Module instantiation transform
+class DefinitionTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def apply[T: c.WeakTypeTag](proto: c.Tree): c.Tree = {
+ q"$thisObj.do_apply($proto)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+}
+
+object DefinitionWrapTransform
+// Module instantiation transform
+class DefinitionWrapTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def wrap[T: c.WeakTypeTag](proto: c.Tree): c.Tree = {
+ q"$thisObj.do_wrap($proto)($implicitSourceInfo)"
+ }
+}
+
+
+// Workaround for https://github.com/sbt/sbt/issues/3966
+object InstanceTransform
+// Module instantiation transform
+class InstanceTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def apply[T: c.WeakTypeTag](definition: c.Tree): c.Tree = {
+ q"$thisObj.do_apply($definition)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+}
+
+// Workaround for https://github.com/sbt/sbt/issues/3966
object MemTransform
class MemTransform(val c: Context) extends SourceInfoTransformMacro {
import c.universe._