Skip to content

Commit d70b8f4

Browse files
authored
Merge pull request #2991 from dotty-staging/topic/new-repl
Add native Dotty REPL
2 parents bb2f409 + 331892e commit d70b8f4

File tree

106 files changed

+2382
-2255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+2382
-2255
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`
1818
val `scala-library` = Build.`scala-library`
1919
val `scala-compiler` = Build.`scala-compiler`
2020
val `scala-reflect` = Build.`scala-reflect`
21+
val `dotty-repl` = Build.`dotty-repl`
2122
val scalap = Build.scalap
2223
val dist = Build.dist
2324
val `dist-bootstrapped` = Build.`dist-bootstrapped`

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ object Bench extends Driver {
1616

1717
@sharable private var numRuns = 1
1818

19-
def newCompiler(implicit ctx: Context): Compiler = new Compiler
20-
2119
private def ntimes(n: Int)(op: => Reporter): Reporter =
2220
(emptyReporter /: (0 until n)) ((_, _) => op)
2321

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

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -116,41 +116,13 @@ class Compiler {
116116
runId += 1; runId
117117
}
118118

119-
/** Produces the following contexts, from outermost to innermost
120-
*
121-
* bootStrap: A context with next available runId and a scope consisting of
122-
* the RootPackage _root_
123-
* start A context with RootClass as owner and the necessary initializations
124-
* for type checking.
125-
* imports For each element of RootImports, an import context
126-
*/
127-
def rootContext(implicit ctx: Context): Context = {
128-
ctx.initialize()(ctx)
129-
ctx.setPhasePlan(phases)
130-
val rootScope = new MutableScope
131-
val bootstrap = ctx.fresh
132-
.setPeriod(Period(nextRunId, FirstPhaseId))
133-
.setScope(rootScope)
134-
rootScope.enter(ctx.definitions.RootPackage)(bootstrap)
135-
val start = bootstrap.fresh
136-
.setOwner(defn.RootClass)
137-
.setTyper(new Typer)
138-
.addMode(Mode.ImplicitsEnabled)
139-
.setTyperState(new MutableTyperState(ctx.typerState, ctx.typerState.reporter, isCommittable = true))
140-
.setFreshNames(new FreshNameCreator.Default)
141-
ctx.initialize()(start) // re-initialize the base context with start
142-
def addImport(ctx: Context, refFn: () => TermRef) =
143-
ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx))
144-
(start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)
145-
}
146-
147119
def reset()(implicit ctx: Context): Unit = {
148120
ctx.base.reset()
149121
ctx.runInfo.clear()
150122
}
151123

152124
def newRun(implicit ctx: Context): Run = {
153125
reset()
154-
new Run(this)(rootContext)
126+
new Run(this, ctx)
155127
}
156128
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import scala.util.control.NonFatal
1313
* process, but in most cases you only need to call [[process]] on the
1414
* existing object [[Main]].
1515
*/
16-
abstract class Driver extends DotClass {
16+
class Driver extends DotClass {
1717

18-
protected def newCompiler(implicit ctx: Context): Compiler
18+
protected def newCompiler(implicit ctx: Context): Compiler = new Compiler
1919

2020
protected def emptyReporter: Reporter = new StoreReporter(null)
2121

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ object FromTasty extends Driver {
4545

4646
override def newRun(implicit ctx: Context): Run = {
4747
reset()
48-
new TASTYRun(this)(rootContext)
48+
new TASTYRun(this, ctx)
4949
}
5050
}
5151

52-
class TASTYRun(comp: Compiler)(implicit ctx: Context) extends Run(comp) {
52+
class TASTYRun(comp: Compiler, ictx: Context) extends Run(comp, ictx) {
5353
override def compile(classNames: List[String]) = {
5454
units = classNames.map(new TASTYCompilationUnit(_))
5555
compileUnits()

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ package dotc
44
import core.Contexts.Context
55

66
/** Main class of the `dotc` batch compiler. */
7-
object Main extends Driver {
8-
override def newCompiler(implicit ctx: Context): Compiler = new Compiler
9-
}
7+
object Main extends Driver

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ class Resident extends Driver {
2727

2828
object residentCompiler extends Compiler
2929

30-
override def newCompiler(implicit ctx: Context): Compiler = ???
31-
3230
override def sourcesRequired = false
3331

3432
private val quit = ":q"

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

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import Contexts._
66
import Periods._
77
import Symbols._
88
import Phases._
9+
import Types._
10+
import Scopes._
11+
import typer.{FrontEnd, Typer, ImportInfo, RefChecks}
912
import Decorators._
1013
import dotty.tools.dotc.transform.TreeTransforms.TreeTransformer
1114
import io.PlainFile
@@ -22,12 +25,41 @@ import dotty.tools.io.VirtualFile
2225
import scala.util.control.NonFatal
2326

2427
/** A compiler run. Exports various methods to compile source files */
25-
class Run(comp: Compiler)(implicit ctx: Context) {
26-
27-
assert(ctx.runId <= Periods.MaxPossibleRunId)
28+
class Run(comp: Compiler, ictx: Context) {
2829

2930
var units: List[CompilationUnit] = _
3031

32+
/** Produces the following contexts, from outermost to innermost
33+
*
34+
* bootStrap: A context with next available runId and a scope consisting of
35+
* the RootPackage _root_
36+
* start A context with RootClass as owner and the necessary initializations
37+
* for type checking.
38+
* imports For each element of RootImports, an import context
39+
*/
40+
protected[this] def rootContext(implicit ctx: Context): Context = {
41+
ctx.initialize()(ctx)
42+
ctx.setPhasePlan(comp.phases)
43+
val rootScope = new MutableScope
44+
val bootstrap = ctx.fresh
45+
.setPeriod(Period(comp.nextRunId, FirstPhaseId))
46+
.setScope(rootScope)
47+
rootScope.enter(ctx.definitions.RootPackage)(bootstrap)
48+
val start = bootstrap.fresh
49+
.setOwner(defn.RootClass)
50+
.setTyper(new Typer)
51+
.addMode(Mode.ImplicitsEnabled)
52+
.setTyperState(new MutableTyperState(ctx.typerState, ctx.typerState.reporter, isCommittable = true))
53+
.setFreshNames(new FreshNameCreator.Default)
54+
ctx.initialize()(start) // re-initialize the base context with start
55+
def addImport(ctx: Context, refFn: () => TermRef) =
56+
ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx))
57+
(start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)
58+
}
59+
60+
protected[this] implicit val ctx: Context = rootContext(ictx)
61+
assert(ctx.runId <= Periods.MaxPossibleRunId)
62+
3163
def getSource(fileName: String): SourceFile = {
3264
val f = new PlainFile(fileName)
3365
if (f.isDirectory) {
@@ -63,7 +95,17 @@ class Run(comp: Compiler)(implicit ctx: Context) {
6395
compileUnits()
6496
}
6597

66-
protected def compileUnits() = Stats.monitorHeartBeat {
98+
def compileUnits(us: List[CompilationUnit]): Unit = {
99+
units = us
100+
compileUnits()
101+
}
102+
103+
def compileUnits(us: List[CompilationUnit], ctx: Context): Unit = {
104+
units = us
105+
compileUnits()(ctx)
106+
}
107+
108+
protected def compileUnits()(implicit ctx: Context) = Stats.monitorHeartBeat {
67109
ctx.checkSingleThreaded()
68110

69111
// If testing pickler, make sure to stop after pickling phase:
@@ -76,7 +118,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
76118
ctx.usePhases(phases)
77119
var lastPrintedTree: PrintedTree = NoPrintedTree
78120
for (phase <- ctx.allPhases)
79-
if (!ctx.reporter.hasErrors) {
121+
if (phase.isRunnable) {
80122
val start = System.currentTimeMillis
81123
units = phase.runOn(units)
82124
if (ctx.settings.Xprint.value.containsPhase(phase)) {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class Definitions {
251251
lazy val Any_getClass = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
252252
lazy val Any_isInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
253253
lazy val Any_asInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, TypeParamRef(_, 0), Final)
254-
lazy val Any_typeTest = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final)
254+
lazy val Any_typeTest = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic)
255255
// generated by pattern matcher, eliminated by erasure
256256

257257
def AnyMethods = List(Any_==, Any_!=, Any_equals, Any_hashCode,
@@ -863,8 +863,8 @@ class Definitions {
863863
)
864864

865865
val PredefImportFns = List[() => TermRef](
866-
() => ScalaPredefModuleRef,
867-
() => DottyPredefModuleRef
866+
() => ScalaPredefModuleRef,
867+
() => DottyPredefModuleRef
868868
)
869869

870870
lazy val RootImportFns =

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ object NameOps {
6464
def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR
6565
def isStaticConstructorName = name == STATIC_CONSTRUCTOR
6666
def isLocalDummyName = name startsWith str.LOCALDUMMY_PREFIX
67-
def isReplWrapperName = name.toString contains str.INTERPRETER_IMPORT_WRAPPER
67+
def isReplWrapperName = name.toString contains str.REPL_SESSION_LINE
68+
def isReplAssignName = name.toString contains str.REPL_ASSIGN_SUFFIX
6869
def isSetterName = name endsWith str.SETTER_SUFFIX
6970
def isScala2LocalSuffix = testSimple(_.endsWith(" "))
7071
def isSelectorName = testSimple(n => n.startsWith("_") && n.drop(1).forall(_.isDigit))

0 commit comments

Comments
 (0)