Skip to content

Make compiler sources invariant under syntax rewritings #7089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,15 @@ class Driver {
MacroClassLoader.init(ctx)
Positioned.updateDebugPos(ctx)

if (!ctx.settings.YdropComments.value(ctx) || ctx.mode.is(Mode.ReadComments)) {
if (!ctx.settings.YdropComments.value(ctx) || ctx.mode.is(Mode.ReadComments))
ctx.setProperty(ContextDoc, new ContextDocstrings)
}

val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
fromTastySetup(fileNames, ctx)
}

/** Setup extra classpath and figure out class names for tasty file inputs */
protected def fromTastySetup(fileNames0: List[String], ctx0: Context): (List[String], Context) = {
protected def fromTastySetup(fileNames0: List[String], ctx0: Context): (List[String], Context) =
if (ctx0.settings.fromTasty.value(ctx0)) {
// Resolve classpath and class names of tasty files
val (classPaths, classNames) = fileNames0.flatMap { name =>
Expand Down Expand Up @@ -98,8 +97,8 @@ class Driver {
val fullClassPath = (classPaths1 :+ ctx1.settings.classpath.value(ctx1)).mkString(java.io.File.pathSeparator)
ctx1.setSetting(ctx1.settings.classpath, fullClassPath)
(classNames, ctx1)
} else (fileNames0, ctx0)
}
}
else (fileNames0, ctx0)

/** Entry point to the compiler that can be conveniently used with Java reflection.
*
Expand Down
18 changes: 10 additions & 8 deletions compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
def compile(fileNames: List[String]): Unit = try {
val sources = fileNames.map(ctx.getSource(_))
compileSources(sources)
} catch {
}
catch {
case NonFatal(ex) =>
ctx.echo(i"exception occurred while compiling $units%, %")
throw ex
Expand All @@ -114,11 +115,12 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
* or we need to assemble phases on each run, and take -Yskip, -Ystop into
* account. I think the latter would be preferable.
*/
def compileSources(sources: List[SourceFile]): Unit =
def compileSources(sources: List[SourceFile]): Unit = {
if (sources forall (_.exists)) {
units = sources.map(CompilationUnit(_))
compileUnits()
}
}

def compileUnits(us: List[CompilationUnit]): Unit = {
units = us
Expand Down Expand Up @@ -150,24 +152,23 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
var lastPrintedTree: PrintedTree = NoPrintedTree
val profiler = ctx.profiler

for (phase <- ctx.base.allPhases)
for (phase <- ctx.base.allPhases) {
if (phase.isRunnable)
Stats.trackTime(s"$phase ms ") {
val start = System.currentTimeMillis
val profileBefore = profiler.beforePhase(phase)
units = phase.runOn(units)
profiler.afterPhase(phase, profileBefore)
if (ctx.settings.Xprint.value.containsPhase(phase)) {
for (unit <- units) {
if (ctx.settings.Xprint.value.containsPhase(phase))
for (unit <- units)
lastPrintedTree =
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
}
}
ctx.informTime(s"$phase ", start)
Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
for (unit <- units)
Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize)
}
}

profiler.finished()
}
Expand All @@ -189,7 +190,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
* If `typeCheck = true`, also run typer on the compilation unit, and set
* `rootTreeOrProvider`.
*/
def lateCompile(file: AbstractFile, typeCheck: Boolean)(implicit ctx: Context): Unit =
def lateCompile(file: AbstractFile, typeCheck: Boolean)(implicit ctx: Context): Unit = {
if (!files.contains(file) && !lateFiles.contains(file)) {
lateFiles += file
val unit = CompilationUnit(ctx.getSource(file.path))
Expand All @@ -208,6 +209,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
}
process()(runContext.fresh.setCompilationUnit(unit))
}
}

private sealed trait PrintedTree
private /*final*/ case class SomePrintedTree(phase: String, tree: String) extends PrintedTree
Expand Down
32 changes: 19 additions & 13 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,12 @@ object desugar {
* case '{ @patternBindHole def `$a`(...) = ...; ... `$a`() ... } => a
* ```
*/
def transformQuotedPatternName(tree: ValOrDefDef)(implicit ctx: Context): ValOrDefDef = {
def transformQuotedPatternName(tree: ValOrDefDef)(implicit ctx: Context): ValOrDefDef =
if (ctx.mode.is(Mode.QuotedPattern) && !isBackquoted(tree) && tree.name != nme.ANON_FUN && tree.name.startsWith("$")) {
val mods = tree.mods.withAddedAnnotation(New(ref(defn.InternalQuoted_patternBindHoleAnnot.typeRef)).withSpan(tree.span))
tree.withMods(mods)
} else tree
}
}
else tree

/** Add an explicit ascription to the `expectedTpt` to every tail splice.
*
Expand Down Expand Up @@ -926,7 +926,8 @@ object desugar {
val patternBindHoleAnnot = New(ref(defn.InternalQuoted_patternBindHoleAnnot.typeRef)).withSpan(tree.span)
val mods = tree.mods.withAddedAnnotation(patternBindHoleAnnot)
tree.withMods(mods)
} else tree
}
else tree
}

/** The normalized name of `mdef`. This means
Expand All @@ -953,7 +954,8 @@ object desugar {
impl.body.find {
case dd: DefDef if dd.mods.is(Extension) => true
case _ => false
} match {
}
match {
case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) =>
s"${name}_of_${inventTypeName(vparam.tpt)}"
case _ =>
Expand Down Expand Up @@ -1007,7 +1009,7 @@ object desugar {
case id: Ident =>
expandSimpleEnumCase(id.name.asTermName, mods,
Span(id.span.start, id.span.end, id.span.start))
}
}
else {
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
pats1 map (makePatDef(pdef, mods, _, rhs))
Expand Down Expand Up @@ -1068,7 +1070,7 @@ object desugar {
if (tupleOptimizable) // include `_`
pat match {
case Tuple(pats) =>
pats.map { case id: Ident => id -> TypeTree() }
pats.map { case id: Ident => id -> TypeTree() }
}
else getVariables(pat) // no `_`

Expand Down Expand Up @@ -1127,11 +1129,12 @@ object desugar {
case tree: MemberDef =>
var tested: MemberDef = tree
def fail(msg: String) = ctx.error(msg, tree.sourcePos)
def checkApplicable(flag: Flag, test: MemberDefTest): Unit =
def checkApplicable(flag: Flag, test: MemberDefTest): Unit = {
if (tested.mods.is(flag) && !test.applyOrElse(tree, (md: MemberDef) => false)) {
fail(i"modifier `${flag.flagsString}` is not allowed for this definition")
tested = tested.withMods(tested.mods.withoutFlags(flag))
}
}
checkApplicable(Opaque, legalOpaque)
tested
case _ =>
Expand Down Expand Up @@ -1296,7 +1299,7 @@ object desugar {
if (isGenericTuple) Apply(Select(refOfDef(param), nme.apply), Literal(Constant(n)))
else Select(refOfDef(param), nme.selectorName(n))
val vdefs =
params.zipWithIndex.map{
params.zipWithIndex.map {
case (param, idx) =>
DefDef(param.name, Nil, Nil, TypeTree(), selector(idx)).withSpan(param.span)
}
Expand Down Expand Up @@ -1338,7 +1341,7 @@ object desugar {
.withSpan(original.span.withPoint(named.span.start))
val mayNeedSetter = valDef(vdef)
mayNeedSetter
}
}

private def derivedDefDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit src: SourceFile) =
DefDef(named.name.asTermName, Nil, Nil, tpt, rhs)
Expand Down Expand Up @@ -1551,7 +1554,8 @@ object desugar {
RefinedTypeTree(polyFunctionTpt, List(
DefDef(nme.apply, applyTParams, List(applyVParams), res, EmptyTree)
))
} else {
}
else {
// Desugar [T_1, ..., T_M] -> (x_1: P_1, ..., x_N: P_N) => body
// Into new scala.PolyFunction { def apply[T_1, ..., T_M](x_1: P_1, ..., x_N: P_N) = body }

Expand Down Expand Up @@ -1606,7 +1610,8 @@ object desugar {
Annotated(
AppliedTypeTree(ref(seqType), t),
New(ref(defn.RepeatedAnnot.typeRef), Nil :: Nil))
} else {
}
else {
assert(ctx.mode.isExpr || ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive), ctx.mode)
Select(t, op.name)
}
Expand Down Expand Up @@ -1692,8 +1697,9 @@ object desugar {
private def getVariables(tree: Tree)(implicit ctx: Context): List[VarInfo] = {
val buf = ListBuffer[VarInfo]()
def seenName(name: Name) = buf exists (_._1.name == name)
def add(named: NameTree, t: Tree): Unit =
def add(named: NameTree, t: Tree): Unit = {
if (!seenName(named.name) && named.name.isTermName) buf += ((named, t))
}
def collect(tree: Tree): Unit = tree match {
case Bind(nme.WILDCARD, tree1) =>
collect(tree1)
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/ast/MainProxies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object MainProxies {
def pos = mainFun.sourcePos
val argsRef = Ident(nme.args)

def addArgs(call: untpd.Tree, mt: MethodType, idx: Int): untpd.Tree = {
def addArgs(call: untpd.Tree, mt: MethodType, idx: Int): untpd.Tree =
if (mt.isImplicitMethod) {
ctx.error(s"@main method cannot have implicit parameters", pos)
call
Expand All @@ -71,7 +71,6 @@ object MainProxies {
call1
}
}
}

var result: List[TypeDef] = Nil
if (!mainFun.owner.isStaticOwner)
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/NavigateAST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ object NavigateAST {
case _ =>
}
childPath(p.productIterator, p :: path)
} else path
}
else path
singlePath(from, Nil)
}
}
17 changes: 7 additions & 10 deletions compiler/src/dotty/tools/dotc/ast/Positioned.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
/** The span part of the item's position */
def span: Span = mySpan

def span_=(span: Span): Unit = {
def span_=(span: Span): Unit =
mySpan = span
}

uniqueId = src.nextId
span = envelope(src)
Expand All @@ -58,9 +57,8 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
else {
val newpd: this.type =
if (mySpan.isSynthetic) {
if (!mySpan.exists && span.exists) {
if (!mySpan.exists && span.exists)
envelope(source, span.startPos) // fill in children spans
}
this
}
else cloneIn(source)
Expand Down Expand Up @@ -109,12 +107,11 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
else if (span1.start == MaxOffset)
// No positioned child was found
NoSpan
else {
else
///println(s"revisit $uniqueId with $span1")
// We have some children left whose span could not be assigned.
// Go through it again with the known start position.
includeChildren(span1.startPos, 0)
}
span2.toSynthetic
}

Expand Down Expand Up @@ -145,7 +142,7 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
found = isParent(productElement(n))
}
found
}
}
}

/** A hook that can be overridden if overlap checking in `checkPos` should be
Expand Down Expand Up @@ -232,7 +229,8 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
n += 1
}
}
} catch {
}
catch {
case ex: AssertionError =>
println(i"error while checking $this")
throw ex
Expand All @@ -242,7 +240,6 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
object Positioned {
@sharable private[Positioned] var debugId = Int.MinValue

def updateDebugPos(implicit ctx: Context): Unit = {
def updateDebugPos(implicit ctx: Context): Unit =
debugId = ctx.settings.YdebugTreeWithId.value
}
}
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
|| fn.symbol.isPrimaryConstructor && fn.symbol.owner.isNoInitsClass) // TODO: include in isStable?
minOf(exprPurity(fn), args.map(exprPurity)) `min` Pure
else if (fn.symbol.is(Erased)) Pure
else if (fn.symbol.isStableMember /* && fn.symbol.is(Lazy) */)
else if (fn.symbol.isStableMember) /* && fn.symbol.is(Lazy) */
minOf(exprPurity(fn), args.map(exprPurity)) `min` Idempotent
else Impure
case Typed(expr, _) =>
Expand Down Expand Up @@ -686,15 +686,14 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
def defPath(sym: Symbol, root: Tree)(implicit ctx: Context): List[Tree] = trace.onDebug(s"defpath($sym with position ${sym.span}, ${root.show})") {
require(sym.span.exists, sym)
object accum extends TreeAccumulator[List[Tree]] {
def apply(x: List[Tree], tree: Tree)(implicit ctx: Context): List[Tree] = {
def apply(x: List[Tree], tree: Tree)(implicit ctx: Context): List[Tree] =
if (tree.span.contains(sym.span))
if (definedSym(tree) == sym) tree :: x
else {
val x1 = foldOver(x, tree)
if (x1 ne x) tree :: x1 else x1
}
else x
}
}
accum(Nil, root)
}
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class TreeMapWithImplicits extends tpd.TreeMap {

@tailrec def traverse(curStats: List[Tree])(implicit ctx: Context): List[Tree] = {

def recur(stats: List[Tree], changed: Tree, rest: List[Tree])(implicit ctx: Context): List[Tree] = {
def recur(stats: List[Tree], changed: Tree, rest: List[Tree])(implicit ctx: Context): List[Tree] =
if (stats eq curStats) {
val rest1 = transformStats(rest, exprOwner)
changed match {
Expand All @@ -37,7 +37,6 @@ class TreeMapWithImplicits extends tpd.TreeMap {
}
}
else stats.head :: recur(stats.tail, changed, rest)
}

curStats match {
case stat :: rest =>
Expand Down Expand Up @@ -123,5 +122,5 @@ class TreeMapWithImplicits extends tpd.TreeMap {
tree
}
}

}

3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,8 @@ class TreeTypeMap(
val origDcls = cls.info.decls.toList
val mappedDcls = ctx.mapSymbols(origDcls, tmap)
val tmap1 = tmap.withMappedSyms(origDcls, mappedDcls)
if (symsChanged) {
if (symsChanged)
origDcls.lazyZip(mappedDcls).foreach(cls.asClass.replace)
}
tmap1
}
if (symsChanged || (fullMap eq substMap)) fullMap
Expand Down
Loading