Skip to content

Commit 9ec2464

Browse files
committed
Add an interface for Tasty loaded in the inspector
1 parent 8c2ce79 commit 9ec2464

File tree

16 files changed

+69
-45
lines changed

16 files changed

+69
-45
lines changed

docs/docs/reference/metaprogramming/tasty-inspect.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ libraryDependencies += "org.scala-lang" %% "scala3-tasty-inspector" % scalaVersi
1010
TASTy files contain the full typed tree of a class including source positions
1111
and documentation. This is ideal for tools that analyze or extract semantic
1212
information from the code. To avoid the hassle of working directly with the TASTy
13-
file we provide the `TastyInspector` which loads the contents and exposes it
13+
file we provide the `Inspector` which loads the contents and exposes it
1414
through the TASTy reflect API.
1515

1616
## Inspecting TASTy files
@@ -21,18 +21,22 @@ To inspect the trees of a TASTy file a consumer can be defined in the following
2121
import scala.quoted._
2222
import scala.tasty.inspector._
2323

24-
class MyInspector extends TastyInspector with
25-
protected def processCompilationUnit(using Quotes)(tree: quotes.reflect.Tree): Unit =
24+
class MyInspector extends Inspector with
25+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
2626
import quotes.reflect._
27-
// Do something with the tree
27+
for tasty <- tastys do
28+
val tree = tasty.ast
29+
// Do something with the tree
2830
```
2931

3032
Then the consumer can be instantiated with the following code to get the tree of the `foo/Bar.tasty` file.
3133

3234
```scala
3335
object Test with
3436
def main(args: Array[String]): Unit =
35-
new MyInspector().inspectTastyFiles("foo/Bar.tasty")
37+
val tastyFiles = List("foo/Bar.tasty")
38+
TastyInspector.inspectTastyFiles(tastyFiles)(new MyInspector)
39+
3640
```
3741

3842
Note that if we need to run the main (in the example below defined in an object called `Test`) after compilation we need to make the compiler available to the runtime:

sbt-dotty/sbt-test/sbt-dotty/tasty-inspector-example-project/app/Main.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import java.nio.file.{Path, Files, Paths, FileSystems}
1010
object Main extends App {
1111

1212
val inspector = new Inspector {
13-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
14-
for (_, tree) <- tastys do
15-
val tastyStr = tree.show
13+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
14+
for tasty <- tastys do
15+
val tastyStr = tasty.ast.show
1616
println(tastyStr)
1717

1818
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ object BootstrappedStdLibTASYyTest with
103103

104104
def loadWithTastyInspector(blacklisted: Set[String]): Unit =
105105
val inspector = new scala.tasty.inspector.Inspector {
106-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit =
107-
for (_, tree) <- tastys do
108-
tree.show(using quotes.reflect.Printer.TreeStructure) // Check that we can traverse the full tree
106+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
107+
for tasty <- tastys do
108+
tasty.ast.show(using quotes.reflect.Printer.TreeStructure) // Check that we can traverse the full tree
109109
()
110110
}
111111
val tastyFiles = scalaLibTastyPaths.filterNot(blacklisted)

tasty-inspector/src/scala/tasty/inspector/Inspector.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ trait Inspector:
2323
*
2424
* Note: Within this method `quotes.reflect.SourceFile.current` will not work, hence the explicit source paths.
2525
*
26-
* @param tastys List of tuples containing the path of the `.tasty` and the AST within the file.
26+
* @param tastys List of `Tasty` containing `.tasty`file path and AST
2727
*/
28-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit
28+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit
2929

3030
end Inspector
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package scala.tasty.inspector
2+
3+
import scala.quoted._
4+
5+
/** `.tasty` file representation containing file path and the AST */
6+
trait Tasty[Q <: Quotes & Singleton]:
7+
8+
/** Instance of `Quotes` used to load the AST */
9+
val quotes: Q
10+
11+
/** Path to the `.tasty` file */
12+
def path: String
13+
14+
/** Abstract Syntax Tree contained in the `.tasty` file */
15+
def ast: quotes.reflect.Tree
16+
17+
end Tasty

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ object TastyInspector:
6060

6161
override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
6262
val quotesImpl = QuotesImpl()
63-
val tastys = units.map(unit => (unit.source.path , unit.tpdTree.asInstanceOf[quotesImpl.reflect.Tree]))
63+
class TastyImpl(val path: String, val ast: quotesImpl.reflect.Tree) extends Tasty[quotesImpl.type] {
64+
val quotes = quotesImpl
65+
}
66+
val tastys = units.map(unit => new TastyImpl(unit.source.path , unit.tpdTree.asInstanceOf[quotesImpl.reflect.Tree]))
6467
inspector.inspect(using quotesImpl)(tastys)
6568
units
6669

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ object Test {
3535

3636
class TestInspector() extends Inspector with
3737

38-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit =
38+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
3939
import quotes.reflect._
4040

41-
for (_, root) <- tastys do
42-
val code = root.show
41+
for tasty <- tastys do
42+
val code = tasty.ast.show
4343
assert(code.contains("import Foo.this.g.{given}"), code)
4444
assert(code.contains("import Foo.this.g.{given scala.Int}"), code)
4545

46-
val extractors = root.show(using Printer.TreeStructure)
46+
val extractors = tasty.ast.show(using Printer.TreeStructure)
4747
assert(extractors.contains("GivenSelector"), extractors)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ object Test {
2222

2323
class TestInspector() extends Inspector with
2424

25-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit =
26-
for (_, tree) <- tastys do
27-
inspectClass(tree)
25+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
26+
for tasty <- tastys do
27+
inspectClass(tasty.ast)
2828

2929
private def inspectClass(using Quotes)(tree: quotes.reflect.Tree): Unit =
3030
import quotes.reflect._

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import scala.tasty.inspector._
33

44
@main def Test = {
55
val inspector = new Inspector {
6-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
7-
for (_, tree) <- tastys do
8-
tree.show(using quotes.reflect.Printer.TreeStructure) // Make sure that tree is loaded and can be traveresed
6+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
7+
for tasty <- tastys do
8+
tasty.ast.show(using quotes.reflect.Printer.TreeStructure) // Make sure that tree is loaded and can be traveresed
99
}
1010
}
1111

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import scala.tasty.inspector._
1010

1111
// in dotty-example-project
1212
val inspector = new Inspector {
13-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
14-
for (_, tree) <- tastys do
15-
println(tree.show)
13+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
14+
for tasty <- tastys do
15+
println(tasty.ast.show)
1616
}
1717
}
1818
TastyInspector.inspectTastyFiles(tastyFiles)(inspector)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class TestInspector_Children() extends Inspector with
3737

3838
var kids: List[String] = Nil
3939

40-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
41-
for (_, tree) <- tastys do
42-
inspectClass(tree)
40+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
41+
for tasty <- tastys do
42+
inspectClass(tasty.ast)
4343
}
4444

4545
private def inspectClass(using Quotes)(tree: quotes.reflect.Tree): Unit =

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object Test {
4848

4949
class TestInspector() extends Inspector with
5050

51-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit =
51+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
5252
var foundIOApp: Boolean = false
5353
var foundSimple: Boolean = false
5454

@@ -80,10 +80,10 @@ class TestInspector() extends Inspector with
8080

8181
case _ =>
8282

83-
for (_, tree) <- tastys do
83+
for tasty <- tastys do
8484
foundIOApp = false
8585
foundSimple = false
86-
inspectClass(tree)
86+
inspectClass(tasty.ast)
8787
// Sanity check to make sure that our pattern matches are not simply glossing over the things we want to test
8888
assert(foundIOApp, "the inspector did not encounter IOApp")
8989
assert(foundSimple, "the inspect did not encounter IOApp.Simple")

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Test {
1515

1616
class DocumentationInspector extends Inspector {
1717

18-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
18+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
1919

2020
import quotes.reflect._
2121
object Traverser extends TreeTraverser {
@@ -32,8 +32,8 @@ class DocumentationInspector extends Inspector {
3232
}
3333

3434
}
35-
for (_, tree) <- tastys do
36-
Traverser.traverseTree(tree)
35+
for tasty <- tastys do
36+
Traverser.traverseTree(tasty.ast)
3737
}
3838

3939
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Test {
1515

1616
class DBInspector extends Inspector {
1717

18-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
18+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
1919
import quotes.reflect._
2020
object Traverser extends TreeTraverser {
2121

@@ -28,8 +28,8 @@ class DBInspector extends Inspector {
2828
}
2929

3030
}
31-
for (_, tree) <- tastys do
32-
Traverser.traverseTree(tree)
31+
for tasty <- tastys do
32+
Traverser.traverseTree(tasty.ast)
3333
}
3434

3535
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ object Test {
2222

2323
class TestInspector() extends Inspector:
2424

25-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit =
26-
println(tastys.map(_._1.split("/tasty-inspector/").last))
25+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
26+
println(tastys.map(_.path.split("/tasty-inspector/").last))
2727
try
2828
quotes.reflect.SourceFile.current
2929
assert(false)

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package scala.tasty.interpreter
22

33
import scala.quoted._
4-
import scala.tasty.inspector.Inspector
4+
import scala.tasty.inspector._
55

66
class TastyInterpreter extends Inspector {
77

8-
def inspect(using Quotes)(tastys: List[(String, quotes.reflect.Tree)]): Unit = {
8+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
99
import quotes.reflect._
1010

1111
object Traverser extends TreeTraverser {
@@ -21,8 +21,8 @@ class TastyInterpreter extends Inspector {
2121
}
2222
}
2323

24-
for (_, tree) <- tastys do
25-
Traverser.traverseTree(tree)(Symbol.spliceOwner)
24+
for tasty <- tastys do
25+
Traverser.traverseTree(tasty.ast)(Symbol.spliceOwner)
2626
}
2727

2828
}

0 commit comments

Comments
 (0)