Skip to content

Commit 31d5120

Browse files
committed
Make tasty inspector receive tasty files directly
We add ways to load a list of tasty files and all tasty files in a jar. This change is aligned with the changes in progress on the `-from-tasty` compilation. We remove the old way to load tasty file by passing the class name. Loading by name had some unintended consecuences that made this API fragile. - Loaded Scala 2 classes by mistake (no tasty) - Loaded java classes by mistake (no tasty) - Load the wrong version of the tasty file because the classpath contains an older/newer version of that class (different tasty)
1 parent 489c12f commit 31d5120

File tree

11 files changed

+89
-82
lines changed

11 files changed

+89
-82
lines changed

stdlib-bootstrapped-tasty-tests/test/BootstrappedStdLibTASYyTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ object BootstrappedStdLibTASYyTest:
108108
()
109109
}
110110
val classNames = scalaLibJarTastyClassNames.filterNot(blacklisted)
111-
val hasErrors = inspector.inspect(scalaLibJarPath, classNames)
111+
val hasErrors = inspector.inspectTastyFilesInJar(scalaLibJarPath)
112112
assert(!hasErrors, "Errors reported while loading from TASTy")
113113

114114
def compileFromTasty(blacklisted: String => Boolean): Unit = {

tasty-inspector/src/scala/tasty/inspector/TastyInspector.scala

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,37 @@ trait TastyInspector:
2222

2323
/** Load and process TASTy files using TASTy reflect
2424
*
25-
* @param classpath Classpath where the classes are located
26-
* @param classes classes to be inspected
27-
* @return if an error was reported
25+
* @param tastyFiles List of paths of `.tasty` files
2826
*/
29-
def inspect(classpath: String, classes: List[String]): Boolean =
27+
def inspectTastyFiles(tastyFiles: List[String]): Boolean =
28+
inspectAllTastyFiles(tastyFiles, Nil, Nil)
29+
30+
/** Load and process TASTy files in a `jar` file using TASTy reflect
31+
*
32+
* @param jars Path of `.jar` file
33+
*/
34+
def inspectTastyFilesInJar(jar: String): Boolean =
35+
inspectAllTastyFiles(Nil, List(jar), Nil)
36+
37+
/** Load and process TASTy files using TASTy reflect
38+
*
39+
* @param tastyFiles List of paths of `.tasty` files
40+
* @param jars List of path of `.jar` files
41+
* @param dependenciesClasspath Classpath with extra dependencies needed to load class in the `.tasty` files
42+
*/
43+
def inspectAllTastyFiles(tastyFiles: List[String], jars: List[String], dependenciesClasspath: List[String]): Boolean =
44+
def checkFile(fileName: String, ext: String): Unit =
45+
val file = dotty.tools.io.Path(fileName)
46+
if file.extension != ext then
47+
throw new IllegalArgumentException(s"File extension is not `.$ext`: $file")
48+
else if !file.exists then
49+
throw new IllegalArgumentException(s"File not found: ${file.toAbsolute}")
50+
tastyFiles.foreach(checkFile(_, "tasty"))
51+
jars.foreach(checkFile(_, "jar"))
52+
val files = tastyFiles ::: jars
53+
files.nonEmpty && inspectFiles(dependenciesClasspath, files)
54+
55+
private def inspectFiles(classpath: List[String], classes: List[String]): Boolean =
3056
if (classes.isEmpty)
3157
throw new IllegalArgumentException("Parameter classes should no be empty")
3258

@@ -64,11 +90,12 @@ trait TastyInspector:
6490
end TastyInspectorPhase
6591

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

71-
end inspect
98+
end inspectFiles
7299

73100

74101
end TastyInspector

tests/run-custom-args/tasty-inspector/i8163.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ case class I8163() {
1010

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

tests/run-custom-args/tasty-inspector/i8215.scala

Lines changed: 0 additions & 41 deletions
This file was deleted.

tests/run-custom-args/tasty-inspector/i8364.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ import scala.tasty.inspector._
44
@main def Test = {
55
val inspector = new TastyInspector {
66
protected def processCompilationUnit(using QuoteContext)(tree: qctx.reflect.Tree): Unit = {
7-
println(tree.show)
7+
tree.showExtractors // Make sure that tree is loaded and can be traveresed
88
}
99
}
10-
inspector.inspect("", List("scala.tasty.Reflection"))
10+
11+
// Artefact of the current test infrastructure
12+
// TODO improve infrastructure to avoid needing this code on each test
13+
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
14+
15+
inspector.inspectTastyFilesInJar(libJarClasspath)
1116
}

tests/run-custom-args/tasty-inspector/i8389.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ import scala.quoted._
22
import scala.tasty.inspector._
33

44
@main def Test = {
5+
// Artefact of the current test infrastructure
6+
// TODO improve infrastructure to avoid needing this code on each test
7+
val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get
8+
val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList
9+
val tastyFiles = allTastyFiles.filter(_.contains("TraitParams"))
10+
511
// in dotty-example-project
612
val inspector = new TastyInspector {
713
protected def processCompilationUnit(using QuoteContext)(tree: qctx.reflect.Tree): Unit = {
814
println(tree.show)
915
}
1016
}
11-
inspector.inspect("", List("TraitParams"))
17+
inspector.inspectTastyFiles(tastyFiles)
1218
}
1319

1420
object TraitParams {

tests/run-custom-args/tasty-inspector/i8460.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@ case object Bourbon extends Flavor
1515

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

1924
// Tasty Scala Class
2025
val inspect1 = new TestInspector_Children()
21-
inspect1.inspect("", List("Vehicle"))
26+
inspect1.inspectTastyFiles(allTastyFiles.filter(_.contains("Vehicle")))
2227
assert(inspect1.kids == List("Truck","Car","Plane"))
2328

2429
// Java Class
2530
val inspect2 = new TestInspector_Children()
26-
inspect2.inspect("", List("Flavor"))
31+
inspect2.inspectTastyFiles(allTastyFiles.filter(_.contains("Flavor")))
2732
assert(inspect2.kids == List("Vanilla","Chocolate","Bourbon"))
2833
}
2934
}

tests/run-custom-args/tasty-inspector/i8558.scala

Lines changed: 0 additions & 22 deletions
This file was deleted.

tests/run-custom-args/tasty-inspector/tasty-documentation-inspector/Test.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import scala.tasty.inspector._
33

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

tests/run-custom-args/tasty-inspector/tasty-inspector/Test.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import scala.tasty.inspector._
33

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

tests/run-custom-args/tasty-interpreter/Test.scala

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ import scala.util.Using
1111
import scala.tasty.interpreter.TastyInterpreter
1212

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

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

91-
val actualOutput = interpret(out.toString)("Test")
96+
// Artefact of the current test infrastructure
97+
// TODO improve infrastructure to avoid needing this code on each test
98+
val allTastyFiles = dotty.tools.io.Path(out).walkFilter(_.extension == "tasty").map(_.toString).toList
99+
100+
val actualOutput = interpret(out.toString)(allTastyFiles.filter(_.endsWith("Test.tasty")))
92101

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

105-
def interpret(classpath: String*)(interpretedClasses: String*): String = {
114+
def interpret(classpath: String*)(interpretedClasses: List[String]): String = {
106115
val ps = new ByteArrayOutputStream()
107116
try scala.Console.withOut(ps) {
108-
new TastyInterpreter().inspect(classpath.mkString(java.io.File.pathSeparatorChar.toString), interpretedClasses.toList)
117+
new TastyInterpreter().inspectAllTastyFiles(interpretedClasses.toList, Nil, classpath.toList)
109118
} catch {
110119
case e: Throwable => throw new Exception(ps.toString, e)
111120
}

0 commit comments

Comments
 (0)