Skip to content

Commit 611d65f

Browse files
committed
Expose AbstractFile only in Run
1 parent 3b6d351 commit 611d65f

File tree

17 files changed

+155
-129
lines changed

17 files changed

+155
-129
lines changed

bench/src/main/scala/Benchmarks.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ class CompilerOptions {
9393

9494
class Worker extends Driver {
9595
// override to avoid printing summary information
96-
override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
96+
override def doCompile(compiler: Compiler, files: List[AbstractFile])(implicit ctx: Context): Reporter =
9797
if (fileNames.nonEmpty)
9898
try {
9999
val run = compiler.newRun
100-
run.compile(fileNames)
100+
run.compile(files)
101101
ctx.reporter
102102
}
103103
catch {

compiler/src/dotty/tools/dotc/Bench.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dotc
33

44
import core.Contexts._
55
import reporting.Reporter
6+
import io.AbstractFile
67

78
import scala.annotation.internal.sharable
89

@@ -19,12 +20,12 @@ object Bench extends Driver:
1920

2021
@sharable private var times: Array[Int] = _
2122

22-
override def doCompile(compiler: Compiler, fileNames: List[String])(using Context): Reporter =
23+
override def doCompile(compiler: Compiler, files: List[AbstractFile])(using Context): Reporter =
2324
times = new Array[Int](numRuns)
2425
var reporter: Reporter = emptyReporter
2526
for i <- 0 until numRuns do
2627
val start = System.nanoTime()
27-
reporter = super.doCompile(compiler, fileNames)
28+
reporter = super.doCompile(compiler, files)
2829
times(i) = ((System.nanoTime - start) / 1000000).toInt
2930
println(s"time elapsed: ${times(i)}ms")
3031
if ctx.settings.Xprompt.value then

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 31 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import core.Contexts._
99
import core.{MacroClassLoader, Mode, TypeError}
1010
import core.StdNames.nme
1111
import dotty.tools.dotc.ast.Positioned
12-
import dotty.tools.io.{File, AbstractFile}
12+
import dotty.tools.io.AbstractFile
1313
import reporting._
1414
import core.Decorators._
1515
import config.Feature
@@ -32,28 +32,11 @@ class Driver {
3232

3333
protected def emptyReporter: Reporter = new StoreReporter(null)
3434

35-
protected def doCompile(compiler: Compiler, fileNames: List[String])(using ctx: Context): Reporter =
36-
if fileNames.nonEmpty then
37-
try
38-
val run = compiler.newRun
39-
run.compile(fileNames)
40-
finish(compiler, run)
41-
catch
42-
case ex: FatalError =>
43-
report.error(ex.getMessage) // signals that we should fail compilation.
44-
case ex: TypeError =>
45-
println(s"${ex.toMessage} while compiling ${fileNames.mkString(", ")}")
46-
throw ex
47-
case ex: Throwable =>
48-
println(s"$ex while compiling ${fileNames.mkString(", ")}")
49-
throw ex
50-
ctx.reporter
51-
52-
protected def doCompileFiles(compiler: Compiler, files: List[AbstractFile])(using Context): Reporter =
35+
protected def doCompile(compiler: Compiler, files: List[AbstractFile])(using Context): Reporter =
5336
if files.nonEmpty then
5437
try
5538
val run = compiler.newRun
56-
run.compileFiles(files)
39+
run.compile(files)
5740
finish(compiler, run)
5841
catch
5942
case ex: FatalError =>
@@ -81,7 +64,7 @@ class Driver {
8164

8265
protected def sourcesRequired: Boolean = true
8366

84-
def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
67+
def setup(args: Array[String], rootCtx: Context): (List[AbstractFile], Context) = {
8568
val ictx = rootCtx.fresh
8669
val summary = CompilerCommand.distill(args)(using ictx)
8770
ictx.setSettings(summary.sstate)
@@ -92,43 +75,35 @@ class Driver {
9275
if !ctx.settings.YdropComments.value || ctx.mode.is(Mode.ReadComments) then
9376
ictx.setProperty(ContextDoc, new ContextDocstrings)
9477
val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)
95-
fromTastySetup(fileNames, ctx)
78+
val files = fileNames.map(ctx.getFile)
79+
(files, fromTastySetup(files))
9680
}
9781
}
9882

99-
/** Setup extra classpath and figure out class names for tasty file inputs */
100-
protected def fromTastySetup(fileNames0: List[String], ctx0: Context): (List[String], Context) =
101-
given Context = ctx0
102-
if (ctx0.settings.fromTasty.value) {
103-
val fromTastyIgnoreList = ctx0.settings.YfromTastyIgnoreList.value.toSet
104-
// Resolve classpath and class names of tasty files
105-
val (classPaths, classNames) = fileNames0.flatMap { name =>
106-
val path = Paths.get(name)
107-
if !Files.exists(path) then
108-
report.error(s"File does not exist: $name")
109-
Nil
110-
else if name.endsWith(".jar") then
111-
new dotty.tools.io.Jar(File(name)).toList.collect {
112-
case e if e.getName.endsWith(".tasty") && !fromTastyIgnoreList(e.getName) =>
113-
(name, e.getName.stripSuffix(".tasty").replace("/", "."))
114-
}
115-
else if name.endsWith(".tasty") then
116-
TastyFileUtil.getClassName(path) match
117-
case Some(res) => res :: Nil
83+
/** Setup extra classpath of tasty and jar files */
84+
protected def fromTastySetup(files: List[AbstractFile])(using Context): Context =
85+
if ctx.settings.fromTasty.value then
86+
val newEntries: List[String] = files
87+
.filter(_.exists)
88+
.flatMap { file =>
89+
file.extension match
90+
case "jar" => Some(file.path)
91+
case "tasty" =>
92+
TastyFileUtil.getClassPath(file) match
93+
case Some(classpath) => Some(classpath)
94+
case _ =>
95+
report.error(s"Could not load classname from: ${file.path}")
96+
None
11897
case _ =>
119-
report.error(s"Could not load classname from: $name")
120-
Nil
121-
else
122-
report.error(s"File extension is not `tasty` or `jar`: $name")
123-
Nil
124-
}.unzip
125-
val ctx1 = ctx0.fresh
126-
val classPaths1 = classPaths.distinct.filter(_ != "")
127-
val fullClassPath = (classPaths1 :+ ctx1.settings.classpath.value(using ctx1)).mkString(java.io.File.pathSeparator)
98+
report.error(s"File extension is not `tasty` or `jar`: ${file.path}")
99+
None
100+
}
101+
.distinct
102+
val ctx1 = ctx.fresh
103+
val fullClassPath =
104+
(newEntries :+ ctx.settings.classpath.value).mkString(java.io.File.pathSeparator)
128105
ctx1.setSetting(ctx1.settings.classpath, fullClassPath)
129-
(classNames, ctx1)
130-
}
131-
else (fileNames0, ctx0)
106+
else ctx
132107

133108
/** Entry point to the compiler that can be conveniently used with Java reflection.
134109
*
@@ -205,8 +180,9 @@ class Driver {
205180
* if compilation succeeded.
206181
*/
207182
def process(args: Array[String], rootCtx: Context): Reporter = {
208-
val (fileNames, compileCtx) = setup(args, rootCtx)
209-
doCompile(newCompiler(using compileCtx), fileNames)(using compileCtx)
183+
println(getClass.getName)
184+
val (files, compileCtx) = setup(args, rootCtx)
185+
doCompile(newCompiler(using compileCtx), files)(using compileCtx)
210186
}
211187

212188
def main(args: Array[String]): Unit = {

compiler/src/dotty/tools/dotc/Resident.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class Resident extends Driver {
4040

4141
final override def process(args: Array[String], rootCtx: Context): Reporter = {
4242
@tailrec def loop(args: Array[String], prevCtx: Context): Reporter = {
43-
var (fileNames, ctx) = setup(args, prevCtx)
44-
inContext(ctx){doCompile(residentCompiler, fileNames)}
43+
var (files, ctx) = setup(args, prevCtx)
44+
inContext(ctx) { doCompile(residentCompiler, files) }
4545
var nextCtx = ctx
4646
var line = getLine()
4747
while (line == reset) {

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,15 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
124124
/** Actions that need to be performed at the end of the current compilation run */
125125
private var finalizeActions = mutable.ListBuffer[() => Unit]()
126126

127-
def compile(fileNames: List[String]): Unit =
128-
val sources = fileNames.map(runContext.getSource(_))
129-
compileSources(sources)
130-
131-
def compileFiles(files: List[AbstractFile]): Unit =
132-
val sources = files.map(runContext.getSource(_))
133-
compileSources(sources)
127+
def compile(files: List[AbstractFile]): Unit =
128+
try
129+
val sources = files.map(runContext.getSource(_))
130+
compileSources(sources)
131+
catch
132+
case NonFatal(ex) =>
133+
if units != null then report.echo(i"exception occurred while compiling $units%, %")
134+
else report.echo(s"exception occurred while compiling ${files.map(_.name).mkString(", ")}")
135+
throw ex
134136

135137
/** TODO: There's a fundamental design problem here: We assemble phases using `fusePhases`
136138
* when we first build the compiler. But we modify them with -Yskip, -Ystop
@@ -139,15 +141,11 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
139141
* account. I think the latter would be preferable.
140142
*/
141143
def compileSources(sources: List[SourceFile]): Unit =
142-
try
143-
if sources forall (_.exists) then
144-
units = sources.map(CompilationUnit(_))
145-
compileUnits()
146-
catch
147-
case NonFatal(ex) =>
148-
if units != null then report.echo(i"exception occurred while compiling $units%, %")
149-
else report.echo(s"exception occurred while compiling ${sources.map(_.name).mkString(", ")}")
150-
throw ex
144+
if (sources forall (_.exists)) {
145+
units = sources.map(CompilationUnit(_))
146+
compileUnits()
147+
}
148+
151149

152150
def compileUnits(us: List[CompilationUnit]): Unit = {
153151
units = us

compiler/src/dotty/tools/dotc/config/CompilerCommand.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object CompilerCommand {
3333

3434
def versionMsg: String = s"Scala compiler $versionString -- $copyrightString"
3535

36-
def shouldStopWithInfo(using ctx: Context) = {
36+
def shouldStopWithInfo(using Context): Boolean = {
3737
val settings = ctx.settings
3838
import settings._
3939
Set(help, Xhelp, Yhelp, showPlugins, XshowPhases) exists (_.value)

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -266,25 +266,36 @@ object Contexts {
266266
base.sources.getOrElseUpdate(file, new SourceFile(file, codec))
267267
}
268268

269-
/** Sourcefile with given path name, memoized */
270-
def getSource(path: TermName): SourceFile = base.sourceNamed.get(path) match {
269+
/** SourceFile with given path name, memoized */
270+
def getSource(path: TermName): SourceFile = base.sourceNamed.get(path) match
271271
case Some(source) =>
272272
source
273-
case None => try {
274-
val f = new PlainFile(Path(path.toString))
275-
val src = getSource(f)
276-
base.sourceNamed(path) = src
277-
src
278-
} catch {
279-
case ex: InvalidPathException =>
280-
report.error(s"invalid file path: ${ex.getMessage}")
281-
NoSource
282-
}
283-
}
273+
case None =>
274+
getFile(path) match
275+
case NoAbstractFile => NoSource
276+
case file => getSource(file)
284277

285-
/** Sourcefile with given path, memoized */
278+
/** SourceFile with given path, memoized */
286279
def getSource(path: String): SourceFile = getSource(path.toTermName)
287280

281+
/** AbstraFile with given path name, memoized */
282+
def getFile(name: TermName): AbstractFile = base.files.get(name) match
283+
case Some(file) =>
284+
file
285+
case None =>
286+
try
287+
val file = new PlainFile(Path(name.toString))
288+
base.files(name) = file
289+
file
290+
catch
291+
case ex: InvalidPathException =>
292+
report.error(s"invalid file path: ${ex.getMessage}")
293+
NoAbstractFile
294+
295+
/** AbstractFile with given path, memoized */
296+
def getFile(name: String): AbstractFile = getFile(name.toTermName)
297+
298+
288299
private var related: SimpleIdentityMap[Phase | SourceFile, Context] = null
289300

290301
private def lookup(key: Phase | SourceFile): Context =
@@ -842,9 +853,10 @@ object Contexts {
842853
private var _nextSymId: Int = 0
843854
def nextSymId: Int = { _nextSymId += 1; _nextSymId }
844855

845-
/** Sources that were loaded */
856+
/** Sources and Files that were loaded */
846857
val sources: util.HashMap[AbstractFile, SourceFile] = util.HashMap[AbstractFile, SourceFile]()
847858
val sourceNamed: util.HashMap[TermName, SourceFile] = util.HashMap[TermName, SourceFile]()
859+
val files: util.HashMap[TermName, AbstractFile] = util.HashMap()
848860

849861
// Types state
850862
/** A table for hash consing unique types */
@@ -929,6 +941,7 @@ object Contexts {
929941
errorTypeMsg.clear()
930942
sources.clear()
931943
sourceNamed.clear()
944+
files.clear()
932945
comparers.clear() // forces re-evaluation of top and bottom classes in TypeComparer
933946

934947
// Test that access is single threaded

compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import dotty.tools.dotc.core.Contexts._
66
import dotty.tools.dotc.core._
77
import dotty.tools.dotc.core.tasty.TastyHTMLPrinter
88
import dotty.tools.dotc.reporting._
9+
import dotty.tools.io.AbstractFile
910

1011
import scala.quoted.runtime.impl.QuotesImpl
1112

@@ -25,13 +26,13 @@ class IDEDecompilerDriver(val settings: List[String]) extends dotc.Driver {
2526

2627
private val decompiler = new PartialTASTYDecompiler
2728

28-
def run(className: String): (String, String) = {
29+
def run(tastyFile: AbstractFile): (String, String) = {
2930
val reporter = new StoreReporter(null) with HideNonSensicalMessages
3031

3132
val run = decompiler.newRun(using myInitCtx.fresh.setReporter(reporter))
3233

3334
inContext(run.runContext) {
34-
run.compile(List(className))
35+
run.compile(List(tastyFile))
3536
run.printSummary()
3637
val unit = ctx.run.units.head
3738

compiler/src/dotty/tools/dotc/decompiler/Main.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.nio.file.Files
44

55
import dotty.tools.dotc
66
import dotty.tools.dotc.core.Contexts._
7+
import dotty.tools.io.AbstractFile
78

89
/** Main class of the `dotc -decompiler` decompiler.
910
*
@@ -17,7 +18,7 @@ object Main extends dotc.Driver {
1718
new TASTYDecompiler
1819
}
1920

20-
override def setup(args0: Array[String], rootCtx: Context): (List[String], Context) = {
21+
override def setup(args0: Array[String], rootCtx: Context): (List[AbstractFile], Context) = {
2122
var args = args0.filter(a => a != "-decompile")
2223
if (!args.contains("-from-tasty")) args = "-from-tasty" +: args
2324
if (args.contains("-d")) args = "-color:never" +: args

compiler/src/dotty/tools/dotc/fromtasty/TASTYRun.scala

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,29 @@ package dotty.tools
22
package dotc
33
package fromtasty
44

5+
import io.{JarArchive, AbstractFile, Path}
56
import core.Contexts._
67

78
class TASTYRun(comp: Compiler, ictx: Context) extends Run(comp, ictx) {
8-
override def compile(classNames: List[String]): Unit = {
9-
val units = classNames.map(new TASTYCompilationUnit(_))
9+
override def compile(files: List[AbstractFile]): Unit = {
10+
val units = tastyUnits(files)
1011
compileUnits(units)
1112
}
13+
14+
private def tastyUnits(files: List[AbstractFile]): List[TASTYCompilationUnit] =
15+
val fromTastyIgnoreList = ctx.settings.YfromTastyIgnoreList.value.toSet
16+
// Resolve class names of tasty and jar files
17+
val classNames = files.flatMap { file =>
18+
file.extension match
19+
case "jar" =>
20+
JarArchive.open(Path(file.path), create = false).iterator()
21+
.filter(e => e.extension == "tasty" && !fromTastyIgnoreList(e.name))
22+
.map(e => e.name.stripSuffix(".tasty").replace("/", "."))
23+
.toList
24+
case "tasty" => TastyFileUtil.getClassName(file)
25+
case _ =>
26+
report.error(s"File extension is not `tasty` or `jar`: ${file.path}")
27+
Nil
28+
}
29+
classNames.map(new TASTYCompilationUnit(_))
1230
}

0 commit comments

Comments
 (0)