Skip to content

Commit f36c302

Browse files
committed
Copy TastyInspector into scaladoc
1 parent 931e9f2 commit f36c302

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copy of tasty-inspector/src/scala/tasty/inspector/Inspector.scala
2+
// FIXME remove this copy of the file
3+
4+
package scala.tasty.inspector
5+
6+
import scala.quoted._
7+
import scala.quoted.runtime.impl.QuotesImpl
8+
9+
import dotty.tools.dotc.Compiler
10+
import dotty.tools.dotc.Driver
11+
import dotty.tools.dotc.Run
12+
import dotty.tools.dotc.core.Contexts.Context
13+
import dotty.tools.dotc.core.Mode
14+
import dotty.tools.dotc.core.Phases.Phase
15+
import dotty.tools.dotc.fromtasty._
16+
import dotty.tools.dotc.util.ClasspathFromClassloader
17+
import dotty.tools.dotc.CompilationUnit
18+
import dotty.tools.unsupported
19+
import dotty.tools.dotc.report
20+
21+
import java.io.File.pathSeparator
22+
23+
trait Inspector:
24+
25+
/** Inspect all TASTy files using `Quotes` reflect API.
26+
*
27+
* Note: Within this method `quotes.reflect.SourceFile.current` will not work, hence the explicit source paths.
28+
*
29+
* @param tastys List of `Tasty` containing `.tasty`file path and AST
30+
*/
31+
def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit
32+
33+
end Inspector
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copy of tasty-inspector/src/scala/tasty/inspector/Tasty.scala
2+
// FIXME remove this copy of the file
3+
4+
package scala.tasty.inspector
5+
6+
import scala.quoted._
7+
8+
/** `.tasty` file representation containing file path and the AST */
9+
trait Tasty[Q <: Quotes & Singleton]:
10+
11+
/** Instance of `Quotes` used to load the AST */
12+
val quotes: Q
13+
14+
/** Path to the `.tasty` file */
15+
def path: String
16+
17+
/** Abstract Syntax Tree contained in the `.tasty` file */
18+
def ast: quotes.reflect.Tree
19+
20+
end Tasty
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copy of tasty-inspector/src/scala/tasty/inspector/TastyInspector.scala
2+
// FIXME remove this copy of the file
3+
4+
package scala.tasty.inspector
5+
6+
import scala.quoted._
7+
import scala.quoted.runtime.impl.QuotesImpl
8+
9+
import dotty.tools.dotc.Compiler
10+
import dotty.tools.dotc.Driver
11+
import dotty.tools.dotc.Run
12+
import dotty.tools.dotc.core.Contexts.Context
13+
import dotty.tools.dotc.core.Mode
14+
import dotty.tools.dotc.core.Phases.Phase
15+
import dotty.tools.dotc.fromtasty._
16+
import dotty.tools.dotc.quoted.QuotesCache
17+
import dotty.tools.dotc.util.ClasspathFromClassloader
18+
import dotty.tools.dotc.CompilationUnit
19+
import dotty.tools.unsupported
20+
import dotty.tools.dotc.report
21+
22+
import java.io.File.pathSeparator
23+
24+
object TastyInspector:
25+
26+
/** Load and process TASTy files using TASTy reflect
27+
*
28+
* @param tastyFiles List of paths of `.tasty` files
29+
*
30+
* @return boolean value indicating whether the process succeeded
31+
*/
32+
def inspectTastyFiles(tastyFiles: List[String])(inspector: Inspector): Boolean =
33+
inspectAllTastyFiles(tastyFiles, Nil, Nil)(inspector)
34+
35+
/** Load and process TASTy files in a `jar` file using TASTy reflect
36+
*
37+
* @param jars Path of `.jar` file
38+
*
39+
* @return boolean value indicating whether the process succeeded
40+
*/
41+
def inspectTastyFilesInJar(jar: String)(inspector: Inspector): Boolean =
42+
inspectAllTastyFiles(Nil, List(jar), Nil)(inspector)
43+
44+
/** Load and process TASTy files using TASTy reflect
45+
*
46+
* @param tastyFiles List of paths of `.tasty` files
47+
* @param jars List of path of `.jar` files
48+
* @param dependenciesClasspath Classpath with extra dependencies needed to load class in the `.tasty` files
49+
*
50+
* @return boolean value indicating whether the process succeeded
51+
*/
52+
def inspectAllTastyFiles(tastyFiles: List[String], jars: List[String], dependenciesClasspath: List[String])(inspector: Inspector): Boolean =
53+
def checkFile(fileName: String, ext: String): Unit =
54+
val file = dotty.tools.io.Path(fileName)
55+
if file.extension != ext then
56+
throw new IllegalArgumentException(s"File extension is not `.$ext`: $file")
57+
else if !file.exists then
58+
throw new IllegalArgumentException(s"File not found: ${file.toAbsolute}")
59+
tastyFiles.foreach(checkFile(_, "tasty"))
60+
jars.foreach(checkFile(_, "jar"))
61+
val files = tastyFiles ::: jars
62+
inspectFiles(dependenciesClasspath, files)(inspector)
63+
64+
private def inspectorDriver(inspector: Inspector) =
65+
class InspectorDriver extends Driver:
66+
override protected def newCompiler(implicit ctx: Context): Compiler = new TastyFromClass
67+
68+
class TastyInspectorPhase extends Phase:
69+
override def phaseName: String = "tastyInspector"
70+
71+
override def runOn(units: List[CompilationUnit])(using ctx0: Context): List[CompilationUnit] =
72+
val ctx = QuotesCache.init(ctx0.fresh)
73+
runOnImpl(units)(using ctx)
74+
75+
private def runOnImpl(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
76+
val quotesImpl = QuotesImpl()
77+
class TastyImpl(val path: String, val ast: quotesImpl.reflect.Tree) extends Tasty[quotesImpl.type] {
78+
val quotes = quotesImpl
79+
}
80+
val tastys = units.map(unit => new TastyImpl(unit.source.path , unit.tpdTree.asInstanceOf[quotesImpl.reflect.Tree]))
81+
inspector.inspect(using quotesImpl)(tastys)
82+
units
83+
84+
override def run(implicit ctx: Context): Unit = unsupported("run")
85+
end TastyInspectorPhase
86+
87+
class TastyFromClass extends TASTYCompiler:
88+
89+
override protected def frontendPhases: List[List[Phase]] =
90+
List(new ReadTasty) :: // Load classes from tasty
91+
Nil
92+
93+
override protected def picklerPhases: List[List[Phase]] = Nil
94+
95+
override protected def transformPhases: List[List[Phase]] = Nil
96+
97+
override protected def backendPhases: List[List[Phase]] =
98+
List(new TastyInspectorPhase) :: // Perform a callback for each compilation unit
99+
Nil
100+
101+
override def newRun(implicit ctx: Context): Run =
102+
reset()
103+
val ctx2 = ctx.fresh
104+
.addMode(Mode.ReadPositions)
105+
.setSetting(ctx.settings.YreadComments, true)
106+
new TASTYRun(this, ctx2)
107+
108+
new InspectorDriver
109+
110+
private def inspectorArgs(classpath: List[String], classes: List[String]): Array[String] =
111+
val currentClasspath = ClasspathFromClassloader(getClass.getClassLoader)
112+
val fullClasspath = (classpath :+ currentClasspath).mkString(pathSeparator)
113+
("-from-tasty" :: "-Yretain-trees" :: "-classpath" :: fullClasspath :: classes).toArray
114+
115+
116+
private def inspectFiles(classpath: List[String], classes: List[String])(inspector: Inspector): Boolean =
117+
classes match
118+
case Nil => true
119+
case _ =>
120+
val reporter = inspectorDriver(inspector).process(inspectorArgs(classpath, classes))
121+
!reporter.hasErrors
122+
123+
end inspectFiles
124+
125+
126+
end TastyInspector

0 commit comments

Comments
 (0)