Skip to content

Make tasty inspector receive tasty files directly #10061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ object BootstrappedStdLibTASYyTest:
()
}
val classNames = scalaLibJarTastyClassNames.filterNot(blacklisted)
val hasErrors = inspector.inspect(scalaLibJarPath, classNames)
val hasErrors = inspector.inspectTastyFilesInJar(scalaLibJarPath)
assert(!hasErrors, "Errors reported while loading from TASTy")

def compileFromTasty(blacklisted: String => Boolean): Unit = {
Expand Down
39 changes: 33 additions & 6 deletions tasty-inspector/src/scala/tasty/inspector/TastyInspector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,37 @@ trait TastyInspector:

/** Load and process TASTy files using TASTy reflect
*
* @param classpath Classpath where the classes are located
* @param classes classes to be inspected
* @return if an error was reported
* @param tastyFiles List of paths of `.tasty` files
*/
def inspect(classpath: String, classes: List[String]): Boolean =
def inspectTastyFiles(tastyFiles: List[String]): Boolean =
inspectAllTastyFiles(tastyFiles, Nil, Nil)

/** Load and process TASTy files in a `jar` file using TASTy reflect
*
* @param jars Path of `.jar` file
*/
def inspectTastyFilesInJar(jar: String): Boolean =
inspectAllTastyFiles(Nil, List(jar), Nil)

/** Load and process TASTy files using TASTy reflect
*
* @param tastyFiles List of paths of `.tasty` files
* @param jars List of path of `.jar` files
* @param dependenciesClasspath Classpath with extra dependencies needed to load class in the `.tasty` files
*/
def inspectAllTastyFiles(tastyFiles: List[String], jars: List[String], dependenciesClasspath: List[String]): Boolean =
def checkFile(fileName: String, ext: String): Unit =
val file = dotty.tools.io.Path(fileName)
if file.extension != ext then
throw new IllegalArgumentException(s"File extension is not `.$ext`: $file")
else if !file.exists then
throw new IllegalArgumentException(s"File not found: ${file.toAbsolute}")
tastyFiles.foreach(checkFile(_, "tasty"))
jars.foreach(checkFile(_, "jar"))
val files = tastyFiles ::: jars
files.nonEmpty && inspectFiles(dependenciesClasspath, files)

private def inspectFiles(classpath: List[String], classes: List[String]): Boolean =
if (classes.isEmpty)
throw new IllegalArgumentException("Parameter classes should no be empty")

Expand Down Expand Up @@ -64,11 +90,12 @@ trait TastyInspector:
end TastyInspectorPhase

val currentClasspath = ClasspathFromClassloader(getClass.getClassLoader)
val args = "-from-tasty" :: "-Yretain-trees" :: "-classpath" :: s"$classpath$pathSeparator$currentClasspath" :: classes
val fullClasspath = (classpath :+ currentClasspath).mkString(pathSeparator)
val args = "-from-tasty" :: "-Yretain-trees" :: "-classpath" :: fullClasspath :: classes
val reporter = (new InspectorDriver).process(args.toArray)
reporter.hasErrors

end inspect
end inspectFiles


end TastyInspector
8 changes: 7 additions & 1 deletion tests/run-custom-args/tasty-inspector/i8163.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ case class I8163() {

object Test {
def main(args: Array[String]): Unit = {
new TestInspector().inspect("", List("I8163"))
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
val tastyFiles = allTastyFiles.filter(_.contains("I8163"))

new TestInspector().inspectTastyFiles(tastyFiles)
}
}

Expand Down
41 changes: 0 additions & 41 deletions tests/run-custom-args/tasty-inspector/i8215.scala

This file was deleted.

9 changes: 7 additions & 2 deletions tests/run-custom-args/tasty-inspector/i8364.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import scala.tasty.inspector._
@main def Test = {
val inspector = new TastyInspector {
protected def processCompilationUnit(using QuoteContext)(tree: qctx.reflect.Tree): Unit = {
println(tree.show)
tree.showExtractors // Make sure that tree is loaded and can be traveresed
}
}
inspector.inspect("", List("scala.tasty.Reflection"))

// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val libJarClasspath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(x => x.contains("scala3-library-bootstrapped") && x.endsWith(".jar")).get

inspector.inspectTastyFilesInJar(libJarClasspath)
}
8 changes: 7 additions & 1 deletion tests/run-custom-args/tasty-inspector/i8389.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ import scala.quoted._
import scala.tasty.inspector._

@main def Test = {
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
val tastyFiles = allTastyFiles.filter(_.contains("TraitParams"))

// in dotty-example-project
val inspector = new TastyInspector {
protected def processCompilationUnit(using QuoteContext)(tree: qctx.reflect.Tree): Unit = {
println(tree.show)
}
}
inspector.inspect("", List("TraitParams"))
inspector.inspectTastyFiles(tastyFiles)
}

object TraitParams {
Expand Down
9 changes: 7 additions & 2 deletions tests/run-custom-args/tasty-inspector/i8460.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ case object Bourbon extends Flavor

object Test {
def main(args: Array[String]): Unit = {
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
val tastyFiles = allTastyFiles.filter(_.contains("TraitParams"))

// Tasty Scala Class
val inspect1 = new TestInspector_Children()
inspect1.inspect("", List("Vehicle"))
inspect1.inspectTastyFiles(allTastyFiles.filter(_.contains("Vehicle")))
assert(inspect1.kids == List("Truck","Car","Plane"))

// Java Class
val inspect2 = new TestInspector_Children()
inspect2.inspect("", List("Flavor"))
inspect2.inspectTastyFiles(allTastyFiles.filter(_.contains("Flavor")))
assert(inspect2.kids == List("Vanilla","Chocolate","Bourbon"))
}
}
Expand Down
22 changes: 0 additions & 22 deletions tests/run-custom-args/tasty-inspector/i8558.scala

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import scala.tasty.inspector._

object Test {
def main(args: Array[String]): Unit = {
new DocumentationInspector().inspect("", List("Foo"))
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
val tastyFiles = allTastyFiles.filter(_.contains("Foo"))

new DocumentationInspector().inspectTastyFiles(tastyFiles)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import scala.tasty.inspector._

object Test {
def main(args: Array[String]): Unit = {
new DBInspector().inspect("", List("Foo"))
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
val tastyFiles = allTastyFiles.filter(_.contains("Foo"))

new DBInspector().inspectTastyFiles(tastyFiles)
}
}

Expand Down
17 changes: 13 additions & 4 deletions tests/run-custom-args/tasty-interpreter/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import scala.util.Using
import scala.tasty.interpreter.TastyInterpreter

object Test {

def main(args: Array[String]): Unit = {
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList

val actualOutput = interpret("")("IntepretedMain", "InterpretedBar")
val actualOutput = interpret("")(allTastyFiles.filter(x => x.contains("IntepretedMain") || x.contains("InterpretedBar")))
val expectedOutput =
"""42
|
Expand Down Expand Up @@ -88,7 +93,11 @@ object Test {
val filePath = "tests" + File.separator + "run" + File.separator + testFileName
dotty.tools.dotc.Main.process(Array("-classpath", System.getProperty("java.class.path"), "-d", out.toString, filePath), reproter)

val actualOutput = interpret(out.toString)("Test")
// Artefact of the current test infrastructure
// TODO improve infrastructure to avoid needing this code on each test
val allTastyFiles = dotty.tools.io.Path(out).walkFilter(_.extension == "tasty").map(_.toString).toList

val actualOutput = interpret(out.toString)(allTastyFiles.filter(_.endsWith("Test.tasty")))

val checkFile = java.nio.file.Paths.get("tests/run/" + testFileName.stripSuffix(".scala") + ".check")
if (java.nio.file.Files.exists(checkFile)) {
Expand All @@ -102,10 +111,10 @@ object Test {
}
}

def interpret(classpath: String*)(interpretedClasses: String*): String = {
def interpret(classpath: String*)(interpretedClasses: List[String]): String = {
val ps = new ByteArrayOutputStream()
try scala.Console.withOut(ps) {
new TastyInterpreter().inspect(classpath.mkString(java.io.File.pathSeparatorChar.toString), interpretedClasses.toList)
new TastyInterpreter().inspectAllTastyFiles(interpretedClasses.toList, Nil, classpath.toList)
} catch {
case e: Throwable => throw new Exception(ps.toString, e)
}
Expand Down