Last active
April 23, 2026 08:16
-
-
Save xuwei-k/e3074ef0c558a33a34a0ab29fc017d16 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.File | |
| import scala.quoted.Quotes | |
| import scala.reflect.TypeTest | |
| import scala.tasty.inspector.Inspector | |
| import scala.tasty.inspector.Tasty | |
| import scala.tasty.inspector.TastyInspector | |
| object CoherenceTest { | |
| enum TastyOrJar { | |
| case Tasty(value: File) | |
| case Jar(value: File) | |
| } | |
| private def getTastyFileOrJar(clazz: Class[?]): TastyOrJar = { | |
| val base = new File(clazz.getProtectionDomain.getCodeSource.getLocation.getFile) | |
| println(base) | |
| if (base.isDirectory) { | |
| val name = s"${clazz.getName.replace('.', '/')}.tasty" | |
| TastyOrJar.Tasty(new File(base, name)) | |
| } else if (base.isFile && base.getName.endsWith(".jar")) { | |
| TastyOrJar.Jar(base) | |
| } else { | |
| sys.error(s"not found $clazz") | |
| } | |
| } | |
| private def runInspector(clazz: Class[?], inspector: Inspector): Unit = { | |
| getTastyFileOrJar(clazz) match { | |
| case TastyOrJar.Tasty(tasty) => | |
| TastyInspector.inspectAllTastyFiles( | |
| tastyFiles = tasty.getAbsolutePath :: Nil, | |
| jars = Nil, | |
| dependenciesClasspath = Nil | |
| )(inspector) | |
| case TastyOrJar.Jar(jar) => | |
| TastyInspector.inspectAllTastyFiles( | |
| tastyFiles = Nil, | |
| jars = jar.getAbsolutePath :: Nil, | |
| dependenciesClasspath = Nil | |
| )(inspector) | |
| } | |
| } | |
| val inspector = new Inspector { | |
| override def inspect(using q: Quotes)(tastys: List[Tasty[q.type]]): Unit = { | |
| import q.reflect.* | |
| case class Result(typeString: String, pos: Position) | |
| val accumulator = new TreeAccumulator[List[Result]] { | |
| override def foldTree(result: List[Result], tree: Tree)(owner: Symbol): List[Result] = { | |
| tree match { | |
| case x: ValOrDefDef | |
| if !x.symbol.flags.is(Flags.Param) && (x.symbol.flags.is(Flags.Given) || x.symbol.flags.is(Flags.Implicit)) && summon[ | |
| TypeTest[Tree, Applied] | |
| ].unapply(x.tpt).isDefined => | |
| val r = Result(x.tpt.tpe.dealias.show, x.pos) :: result | |
| x.rhs match { | |
| case Some(body) => | |
| foldTree(r, body)(owner) | |
| case None => | |
| r | |
| } | |
| case _ => | |
| foldOverTree(result, tree)(owner) | |
| } | |
| } | |
| } | |
| val result: List[Result] = tastys.flatMap { | |
| t => | |
| accumulator.foldOverTree(Nil, t.ast)(Symbol.spliceOwner) | |
| } | |
| println(result.size) | |
| val duplicate = result.groupBy(_.typeString).filter(_._2.sizeIs > 1).toList.sortBy(_._2.size) | |
| println(duplicate.size) | |
| duplicate.foreach { | |
| (k, v) => | |
| println(s"${k} ${v.size}") | |
| } | |
| duplicate.filter(_._2.size < 10).foreach { | |
| (k, v) => | |
| v.foreach(x => | |
| report.warning(s"Duplicate ${k} instance", x.pos) | |
| ) | |
| } | |
| } | |
| } | |
| def main(args: Array[String]): Unit = { | |
| runInspector(classOf[ここにクラス], inspector) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment