diff options
author | Martin Odersky <odersky@gmail.com> | 2014-02-06 18:40:09 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-02-06 18:42:54 +0100 |
commit | ab62ca99a31ccd1984b875f7040b430bfccc2724 (patch) | |
tree | 202e07d6d74068767d40ec958dd434d5e34bd8ce /src | |
parent | 56a11807feaa00f81504925a5b95ebf7b8dab689 (diff) | |
download | dotty-ab62ca99a31ccd1984b875f7040b430bfccc2724.tar.gz dotty-ab62ca99a31ccd1984b875f7040b430bfccc2724.tar.bz2 dotty-ab62ca99a31ccd1984b875f7040b430bfccc2724.zip |
Checking for already existing symbols before creating new ones.
Otherwise we get spurious "compiled twice" errors on every symbol defined in a run after the first one.
Also, fixed a bug so that now run ids are correctly incremented.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Driver.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Phases.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 28 |
4 files changed, 25 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index a4226eec2..1172143cd 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -12,11 +12,14 @@ class Compiler { def phases = List(new FrontEnd) + var runId = 1 + def nextRunId = { runId += 1; runId } + def rootContext(implicit ctx: Context): Context = { ctx.definitions.init() ctx.usePhases(phases) val start = ctx.fresh - .withPeriod(Period(ctx.runId + 1, FirstPhaseId)) + .withPeriod(Period(nextRunId, FirstPhaseId)) .withOwner(defn.RootClass) .withTyper(new Typer) .withNewMode(Mode.ImplicitsEnabled) diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 49e93e220..fd2b776f8 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -24,7 +24,7 @@ abstract class Driver extends DotClass { def process(args: Array[String]): Reporter = { val summary = CompilerCommand.distill(args)(initCtx) - implicit val ctx = initCtx.fresh.withSettings(summary.sstate) + implicit val ctx: Context = initCtx.fresh.withSettings(summary.sstate) val fileNames = CompilerCommand.checkUsage(summary) try { doCompile(newCompiler(), fileNames) diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 7979d3c58..72ebc7129 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -12,7 +12,7 @@ trait Phases { self: Context => if ((this eq NoContext) || !phase.exists) Nil else phase :: outersIterator.dropWhile(_.phase == phase).next.phasesStack - /** Execute `op` at given phase id */ + /** Execute `op` at given phase */ def atPhase[T](phase: Phase)(op: Context => T): T = atPhase(phase.id)(op) @@ -92,7 +92,7 @@ object Phases { } } - final def <= (that: Phase)(implicit ctx: Context) = + final def <= (that: Phase)(implicit ctx: Context) = exists && id <= that.id final def prev(implicit ctx: Context): Phase = diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index d67579408..6583b4c0b 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -182,19 +182,35 @@ class Namer { typer: Typer => else completer typr.println(i"creating symbol for $tree") + + def checkNoConflict(name: Name): Unit = { + def preExisting = ctx.effectiveScope.lookup(name) + if (ctx.owner is PackageClass) { + if (preExisting.isDefinedInCurrentRun) + ctx.error(s"${preExisting.showLocated} is compiled twice, runid = ${ctx.runId}", tree.pos) + } + else if ((!ctx.owner.isClass || name.isTypeName) && preExisting.exists) { + ctx.error(i"$name is already defined as $preExisting") + } + } + tree match { case tree: TypeDef if tree.isClassDef => + val name = tree.name.encode.asTypeName + checkNoConflict(name) val cls = record(ctx.newClassSymbol( - ctx.owner, tree.name.encode.asTypeName, tree.mods.flags, + ctx.owner, name, tree.mods.flags, cls => adjustIfModule(new ClassCompleter(cls, tree)(ctx), tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) cls.completer.asInstanceOf[ClassCompleter].init() cls case tree: MemberDef => + val name = tree.name.encode + checkNoConflict(name) val deferred = if (lacksDefinition(tree)) Deferred else EmptyFlags val method = if (tree.isInstanceOf[DefDef]) Method else EmptyFlags record(ctx.newSymbol( - ctx.owner, tree.name.encode, tree.mods.flags | deferred | method, + ctx.owner, name, tree.mods.flags | deferred | method, adjustIfModule(new Completer(tree), tree), privateWithinClass(tree.mods), tree.pos)) case tree: Import => @@ -211,14 +227,6 @@ class Namer { typer: Typer => def enterSymbol(sym: Symbol)(implicit ctx: Context) = { if (sym.exists) { typr.println(s"entered: $sym in ${ctx.owner} and ${ctx.effectiveScope}") - def preExisting = ctx.effectiveScope.lookup(sym.name) - if (sym.owner is PackageClass) { - if (preExisting.isDefinedInCurrentRun) - ctx.error(s"${sym.showLocated} is compiled twice", sym.pos) - } - else if (!sym.owner.isClass && preExisting.exists) { - ctx.error(i"${sym.name} is already defined as $preExisting") - } ctx.enter(sym) } sym |