Skip to content

Commit c8bd97c

Browse files
committed
Extract parser into its own phase
1 parent 2a7edab commit c8bd97c

File tree

9 files changed

+64
-62
lines changed

9 files changed

+64
-62
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import transform._
99
import dotty.tools.backend.jvm.{CollectSuperCalls, GenBCode}
1010
import dotty.tools.backend.sjs
1111
import dotty.tools.dotc.transform.localopt.StringInterpolatorOpt
12+
import dotty.tools.dotc.parsing.Parsing
1213

1314
/** The central class of the dotc compiler. The job of a compiler is to create
1415
* runs, which process given `phases` in a given `rootContext`.
@@ -36,6 +37,7 @@ class Compiler {
3637

3738
/** Phases dealing with the frontend up to trees ready for TASTY pickling */
3839
protected def frontendPhases: List[List[Phase]] =
40+
List(new Parsing) ::
3941
List(new FrontEnd) :: // Compiler frontend: scanner, parser, namer, typer
4042
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
4143
List(new PostTyper) :: // Additional checks and cleanups after type checking

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
155155
Stats.trackTime(s"$phase ms ") {
156156
val start = System.currentTimeMillis
157157
val profileBefore = profiler.beforePhase(phase)
158-
units = phase.runOn(units)
158+
units = phase.runOn(units)(ctx.fresh.setPhase(phase.start))
159159
profiler.afterPhase(phase, profileBefore)
160160
if (ctx.settings.Xprint.value.containsPhase(phase)) {
161161
for (unit <- units) {
@@ -217,7 +217,10 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
217217
val unit = ctx.compilationUnit
218218
val prevPhase = ctx.phase.prev // can be a mini-phase
219219
val squashedPhase = ctx.base.squashed(prevPhase)
220-
val treeString = unit.tpdTree.show(ctx.withProperty(XprintMode, Some(())))
220+
val tree =
221+
if (ctx.isAfterTyper) unit.tpdTree
222+
else unit.untpdTree
223+
val treeString = tree.show(ctx.withProperty(XprintMode, Some(())))
221224

222225
ctx.echo(s"result of $unit after $squashedPhase:")
223226

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Denotations._
1010
import Decorators._
1111
import config.Printers.config
1212
import scala.collection.mutable.ListBuffer
13+
import scala.util.control.NonFatal
1314
import dotty.tools.dotc.transform.MegaPhase._
1415
import dotty.tools.dotc.transform._
1516
import Periods._
@@ -305,7 +306,7 @@ object Phases {
305306
/** @pre `isRunnable` returns true */
306307
def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] =
307308
units.map { unit =>
308-
val unitCtx = ctx.fresh.setPhase(this.start).setCompilationUnit(unit)
309+
val unitCtx = ctx.fresh.setCompilationUnit(unit)
309310
run(unitCtx)
310311
unitCtx.compilationUnit
311312
}
@@ -320,7 +321,7 @@ object Phases {
320321
def checkPostCondition(tree: tpd.Tree)(implicit ctx: Context): Unit = ()
321322

322323
/** Is this phase the standard typerphase? True for FrontEnd, but
323-
* not for other first phases (such as FromTasty). The predicate
324+
* not for other first phases (such as ReadTasty). The predicate
324325
* is tested in some places that perform checks and corrections. It's
325326
* different from isAfterTyper (and cheaper to test).
326327
*/
@@ -402,6 +403,14 @@ object Phases {
402403
final def iterator: Iterator[Phase] =
403404
Iterator.iterate(this)(_.next) takeWhile (_.hasNext)
404405

406+
final def monitor(doing: String)(body: => Unit)(implicit ctx: Context): Unit =
407+
try body
408+
catch {
409+
case NonFatal(ex) =>
410+
ctx.echo(s"exception occurred while $doing ${ctx.compilationUnit}")
411+
throw ex
412+
}
413+
405414
override def toString: String = phaseName
406415
}
407416

compiler/src/dotty/tools/dotc/interactive/InteractiveCompiler.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ package interactive
55
import core._
66
import Phases._
77
import typer._
8+
import parsing.Parsing
89

910
class InteractiveCompiler extends Compiler {
1011
// TODO: Figure out what phases should be run in IDEs
1112
// More phases increase latency but allow us to report more errors.
1213
// This could be improved by reporting errors back to the IDE
1314
// after each phase group instead of waiting for the pipeline to finish.
1415
override def phases: List[List[Phase]] = List(
16+
List(new Parsing),
1517
List(new FrontEnd),
1618
List(new transform.SetRootTree),
1719
List(new transform.CookComments)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dotty.tools.dotc.parsing
2+
3+
import dotty.tools.dotc.config.Config
4+
import dotty.tools.dotc.core.Contexts.Context
5+
import dotty.tools.dotc.core.Phases.Phase
6+
import dotty.tools.dotc.parsing.JavaParsers.JavaParser
7+
import dotty.tools.dotc.parsing.Parsers.Parser
8+
9+
class Parsing extends Phase {
10+
11+
override def phaseName: String = "parsing"
12+
13+
// We run TreeChecker only after type checking
14+
override def isCheckable: Boolean = false
15+
16+
override def isRunnable(implicit ctx: Context): Boolean =
17+
!ctx.settings.fromTasty.value
18+
19+
override def run(implicit ctx: Context): Unit = monitor("parsing") {
20+
val unit = ctx.compilationUnit
21+
unit.untpdTree =
22+
if (unit.isJava) new JavaParser(unit.source).parse()
23+
else new Parser(unit.source).parse()
24+
25+
if (Config.checkPositions)
26+
unit.untpdTree.checkPos(nonOverlapping = !unit.isJava && !ctx.reporter.hasErrors)
27+
}
28+
}

compiler/src/dotty/tools/dotc/typer/FrontEnd.scala

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ import core._
66
import Phases._
77
import Contexts._
88
import Symbols._
9-
import dotty.tools.dotc.parsing.JavaParsers.JavaParser
10-
import parsing.Parsers.Parser
119
import config.Config
1210
import config.Printers.{typr, default}
1311
import util.Stats._
14-
import scala.util.control.NonFatal
15-
import ast.Trees._
12+
import ast.{tpd, Trees}
13+
import Trees._
1614

1715
class FrontEnd extends Phase {
16+
import tpd._
1817

1918
override def phaseName: String = FrontEnd.name
2019
override def isTyper: Boolean = true
21-
import ast.tpd
20+
21+
// Run regardless of parsing errors
22+
override def isRunnable(implicit ctx: Context): Boolean = true
2223

2324
override def allowsImplicitSearch: Boolean = true
2425

@@ -31,40 +32,21 @@ class FrontEnd extends Phase {
3132
def stillToBeEntered(name: String): Boolean =
3233
remaining.exists(_.compilationUnit.toString.endsWith(name + ".scala"))
3334

34-
def monitor(doing: String)(body: => Unit)(implicit ctx: Context): Unit =
35-
try body
36-
catch {
37-
case NonFatal(ex) =>
38-
ctx.echo(s"exception occurred while $doing ${ctx.compilationUnit}")
39-
throw ex
40-
}
41-
42-
def parse(implicit ctx: Context): Unit = monitor("parsing") {
43-
val unit = ctx.compilationUnit
44-
unit.untpdTree =
45-
if (unit.isJava) new JavaParser(unit.source).parse()
46-
else new Parser(unit.source).parse()
47-
val printer = if (ctx.settings.Xprint.value.contains("parser")) default else typr
48-
printer.println("parsed:\n" + unit.untpdTree.show)
49-
if (Config.checkPositions)
50-
unit.untpdTree.checkPos(nonOverlapping = !unit.isJava && !ctx.reporter.hasErrors)
51-
}
52-
53-
def enterSyms(implicit ctx: Context): Unit = monitor("indexing") {
35+
private def enterSyms(implicit ctx: Context): Unit = monitor("indexing") {
5436
val unit = ctx.compilationUnit
5537
ctx.typer.index(unit.untpdTree)
5638
typr.println("entered: " + unit.source)
5739
}
5840

59-
def typeCheck(implicit ctx: Context): Unit = monitor("typechecking") {
41+
private def typeCheck(implicit ctx: Context): Unit = monitor("typechecking") {
6042
val unit = ctx.compilationUnit
6143
unit.tpdTree = ctx.typer.typedExpr(unit.untpdTree)
6244
typr.println("typed: " + unit.source)
6345
record("retained untyped trees", unit.untpdTree.treeSize)
6446
record("retained typed trees after typer", unit.tpdTree.treeSize)
6547
}
6648

67-
private def firstTopLevelDef(trees: List[tpd.Tree])(implicit ctx: Context): Symbol = trees match {
49+
private def firstTopLevelDef(trees: List[Tree])(implicit ctx: Context): Symbol = trees match {
6850
case PackageDef(_, defs) :: _ => firstTopLevelDef(defs)
6951
case Import(_, _, _) :: defs => firstTopLevelDef(defs)
7052
case (tree @ TypeDef(_, _)) :: _ => tree.symbol
@@ -79,15 +61,15 @@ class FrontEnd extends Phase {
7961
ctx.inform(s"compiling ${unit.source}")
8062
ctx.fresh.setCompilationUnit(unit)
8163
}
82-
unitContexts foreach (parse(_))
83-
record("parsedTrees", ast.Trees.ntrees)
64+
65+
record("parsedTrees", Trees.ntrees)
8466
remaining = unitContexts
8567
while (remaining.nonEmpty) {
8668
enterSyms(remaining.head)
8769
remaining = remaining.tail
8870
}
8971
unitContexts.foreach(typeCheck(_))
90-
record("total trees after typer", ast.Trees.ntrees)
72+
record("total trees after typer", Trees.ntrees)
9173
unitContexts.map(_.compilationUnit).filterNot(discardAfterTyper)
9274
}
9375

compiler/src/dotty/tools/repl/ReplCompiler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import dotty.tools.dotc.core.StdNames._
1313
import dotty.tools.dotc.core.Symbols._
1414
import dotty.tools.dotc.reporting.diagnostic.messages
1515
import dotty.tools.dotc.transform.PostTyper
16-
import dotty.tools.dotc.typer.ImportInfo
16+
import dotty.tools.dotc.typer.{FrontEnd, ImportInfo}
1717
import dotty.tools.dotc.util.Spans._
1818
import dotty.tools.dotc.util.{ParsedComment, SourceFile}
1919
import dotty.tools.dotc.{CompilationUnit, Compiler, Run}
@@ -32,7 +32,7 @@ import scala.collection.mutable
3232
class ReplCompiler extends Compiler {
3333

3434
override protected def frontendPhases: List[List[Phase]] = List(
35-
List(new REPLFrontEnd),
35+
List(new FrontEnd),
3636
List(new CollectTopLevelImports),
3737
List(new PostTyper)
3838
)

compiler/src/dotty/tools/repl/ReplFrontEnd.scala

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

doc-tool/src/dotty/tools/dottydoc/DocCompiler.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import dotc.typer.FrontEnd
1111

1212
import dotty.tools.dotc.fromtasty.{ReadTasty, TASTYRun}
1313
import dotty.tools.dotc.transform.CookComments
14+
import dotty.tools.dotc.parsing.Parsing
1415

1516
/** Custom Compiler with phases for the documentation tool
1617
*
@@ -53,6 +54,7 @@ class DocCompiler extends Compiler {
5354
}
5455

5556
override def phases: List[List[Phase]] = List(
57+
List(new Parsing),
5658
List(new DocFrontEnd),
5759
List(new ReadTasty),
5860
List(new CookComments),

0 commit comments

Comments
 (0)