summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/experimental
diff options
context:
space:
mode:
authorAdam Izraelevitz2021-10-27 15:51:21 -0700
committerGitHub2021-10-27 22:51:21 +0000
commit2a68cc0636580db1a5fa98e87727bb3ec870e0bc (patch)
treec316b53e452667a18ac41a4346e9d163e28250e3 /core/src/main/scala/chisel3/experimental
parent5024b706f0638cf3ebbe634b658fa016941e72ac (diff)
Add java reflection to hierarchy (#2209)
* Add Hierarchy trait * Add Hierarchy trait * Add Hierarchy scaladoc * Add license * Add isA and tests * Add back isA * Make calculate via lazy val * Apply suggestions from code review Co-authored-by: Megan Wachs <megan@sifive.com> * Add shouldNot compile * Update src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala Co-authored-by: Jack Koenig <koenig@sifive.com> * Made protected vals private Co-authored-by: Megan Wachs <megan@sifive.com> Co-authored-by: Jack Koenig <koenig@sifive.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'core/src/main/scala/chisel3/experimental')
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala31
1 files changed, 29 insertions, 2 deletions
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
index 8dbc5a54..d1ccfb1b 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
@@ -4,7 +4,7 @@ package chisel3.experimental.hierarchy
import chisel3._
import scala.collection.mutable.{HashMap, HashSet}
-import scala.reflect.runtime.universe.WeakTypeTag
+import scala.reflect.runtime.universe.TypeTag
import chisel3.internal.BaseModule.IsClone
import chisel3.experimental.BaseModule
import _root_.firrtl.annotations.IsModule
@@ -25,12 +25,39 @@ sealed trait Hierarchy[+A] {
private[chisel3] val cache = HashMap[Data, Data]()
private[chisel3] def getInnerDataContext: Option[BaseModule]
+ /** Determine whether underlying proto is of type provided.
+ *
+ * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class.
+ * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure.
+ * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type
+ *
+ * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String]
+ * @return Whether underlying proto is of provided type (with caveats outlined above)
+ */
+ def isA[B : TypeTag]: Boolean = {
+ val tptag = implicitly[TypeTag[B]]
+ val name = tptag.tpe.toString
+ inBaseClasses(name)
+ }
+
+ private lazy val superClasses = calculateSuperClasses(proto.getClass())
+ private def calculateSuperClasses(clz: Class[_]): Set[String] = {
+ if(clz != null) {
+ Set(clz.getCanonicalName()) ++
+ clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++
+ calculateSuperClasses(clz.getSuperclass())
+ } else {
+ Set.empty[String]
+ }
+ }
+ private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz)
+
/** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
* Instead, mark the field you are accessing with [[@public]]
*
* Given a selector function (that) which selects a member from the original, return the
- * corresponding member from the hierarhcy.
+ * corresponding member from the hierarchy.
*
* Our @instantiable and @public macros generate the calls to this apply method
*