diff --git a/.gitignore b/.gitignore index b8e3c9e0f96e..818b7e549e0f 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,4 @@ compiler/after-pickling.txt *.dotty-ide-version *.decompiled.out +bench/compile.txt diff --git a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala index 41b7e549d2f5..856b3ec5d2b3 100644 --- a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala +++ b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala @@ -67,7 +67,7 @@ object CollectEntryPoints{ def fail(msg: String, pos: Position = sym.pos) = { ctx.warning( sym.name + s" has a main method with parameter type Array[String], but ${toDenot(sym).fullName} will not be a runnable program.\n Reason: $msg", - sourcePos(sym.pos) + sym.pos // TODO: make this next claim true, if possible // by generating valid main methods as static in module classes // not sure what the jvm allows here diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 008c5aab184c..d42da65d7898 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -154,9 +154,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma lazy val Predef_classOf: Symbol = defn.ScalaPredefModule.requiredMethod(nme.classOf) lazy val AnnotationRetentionAttr = ctx.requiredClass("java.lang.annotation.Retention") - lazy val AnnotationRetentionSourceAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") - lazy val AnnotationRetentionClassAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS") - lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") + lazy val AnnotationRetentionSourceAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE".toTermName) + lazy val AnnotationRetentionClassAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS".toTermName) + lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME".toTermName) lazy val JavaAnnotationClass = ctx.requiredClass("java.lang.annotation.Annotation") def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def? @@ -366,7 +366,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] = None - def getRequiredClass(fullname: String): Symbol = ctx.requiredClass(fullname.toTermName) + def getRequiredClass(fullname: String): Symbol = ctx.requiredClass(fullname) def getClassIfDefined(fullname: String): Symbol = NoSymbol // used only for android. todo: implement @@ -376,12 +376,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def requiredClass[T](implicit evidence: ClassTag[T]): Symbol = - ctx.requiredClass(erasureString(evidence.runtimeClass).toTermName) + ctx.requiredClass(erasureString(evidence.runtimeClass)) def requiredModule[T](implicit evidence: ClassTag[T]): Symbol = { val moduleName = erasureString(evidence.runtimeClass) val className = if (moduleName.endsWith("$")) moduleName.dropRight(1) else moduleName - ctx.requiredModule(className.toTermName) + ctx.requiredModule(className) } @@ -498,7 +498,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma // unrelated change. ctx.base.settings.YnoGenericSig.value || sym.is(Flags.Artifact) - || sym.is(Flags.allOf(Flags.Method, Flags.Lifted)) + || sym.isBoth(Flags.Method, and = Flags.Lifted) || sym.is(Flags.Bridge) ) @@ -679,7 +679,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isConstructor: Boolean = toDenot(sym).isConstructor def isAnonymousFunction: Boolean = toDenot(sym).isAnonymousFunction def isMethod: Boolean = sym is Flags.Method - def isPublic: Boolean = sym.flags.is(Flags.EmptyFlags, Flags.Private | Flags.Protected) + def isPublic: Boolean = sym.flags.is(Flags.EmptyFlags, butNot=Flags.Private | Flags.Protected) def isSynthetic: Boolean = sym is Flags.Synthetic def isPackageClass: Boolean = sym is Flags.PackageClass def isModuleClass: Boolean = sym is Flags.ModuleClass @@ -716,7 +716,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isDeprecated: Boolean = false def isMutable: Boolean = sym is Flags.Mutable def hasAbstractFlag: Boolean = - (sym is Flags.Abstract) || (sym is Flags.JavaInterface) || (sym is Flags.Trait) + (sym is Flags.Abstract) || (sym is Flags.Trait) def hasModuleFlag: Boolean = sym is Flags.Module def isSynchronized: Boolean = sym is Flags.Synchronized def isNonBottomSubClass(other: Symbol): Boolean = sym.derivesFrom(other) @@ -808,26 +808,28 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else Nil def annotations: List[Annotation] = toDenot(sym).annotations - def companionModuleMembers: List[Symbol] = { + + def companionModuleMembers: List[Symbol] = { // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, // not local classes of the companion module (E in the exmaple) that were lifted by lambdalift. if (linkedClass.isTopLevelModuleClass) /*exitingPickler*/ linkedClass.memberClasses else Nil } + def fieldSymbols: List[Symbol] = { toDenot(sym).info.decls.filter(p => p.isTerm && !p.is(Flags.Method)) } + def methodSymbols: List[Symbol] = for (f <- toDenot(sym).info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f - def serialVUID: Option[Long] = None + def serialVUID: Option[Long] = None - def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { - ctx.newSymbol(sym, name.toTermName, FlagSet(flags), tpe, NoSymbol, pos) - } + def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = + ctx.newSymbol(sym, name.toTermName, FlagSet(flags), tpe, NoSymbol, pos.toCoord) - def getter(clz: Symbol): Symbol = decorateSymbol(sym).getter - def setter(clz: Symbol): Symbol = decorateSymbol(sym).setter + def getter(clz: Symbol): Symbol = new SymUtilsOps(sym).getter + def setter(clz: Symbol): Symbol = new SymUtilsOps(sym).setter def moduleSuffix: String = "" // todo: validate that names already have $ suffix def outputDirectory: AbstractFile = DottyBackendInterface.this.outputDirectory @@ -840,7 +842,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma * Redundant interfaces are removed unless there is a super call to them. */ def superInterfaces: List[Symbol] = { - val directlyInheritedTraits = decorateSymbol(sym).directlyInheritedTraits + val directlyInheritedTraits = new SymUtilsOps(sym).directlyInheritedTraits val directlyInheritedTraitsSet = directlyInheritedTraits.toSet val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.symbol.asClass.baseClasses.drop(1)).toSet val superCalls = superCallsMap.getOrElse(sym, Set.empty) @@ -1193,8 +1195,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val arity = field.meth.tpe.widenDealias.paramTypes.size - _1.size val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == UnitClass if (returnsUnit) - ctx.requiredClass(("scala.compat.java8.JProcedure" + arity).toTermName) - else ctx.requiredClass(("scala.compat.java8.JFunction" + arity).toTermName) + ctx.requiredClass("scala.compat.java8.JProcedure" + arity) + else ctx.requiredClass("scala.compat.java8.JFunction" + arity) } } } diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index 925890d4ff4c..68f449d32c80 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -43,7 +43,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint */ protected[this] def rootContext(implicit ctx: Context): Context = { ctx.initialize()(ctx) - ctx.setPhasePlan(comp.phases) + ctx.base.setPhasePlan(comp.phases) val rootScope = new MutableScope val bootstrap = ctx.fresh .setPeriod(Period(comp.nextRunId, FirstPhaseId)) @@ -147,7 +147,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint } protected def compileUnits()(implicit ctx: Context) = Stats.maybeMonitored { - ctx.checkSingleThreaded() + ctx.base.checkSingleThreaded() compiling = true // If testing pickler, make sure to stop after pickling phase: @@ -155,15 +155,15 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint if (ctx.settings.YtestPickler.value) List("pickler") else ctx.settings.YstopAfter.value - val phases = ctx.squashPhases(ctx.phasePlan, + val phases = ctx.base.squashPhases(ctx.base.phasePlan, ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value) - ctx.usePhases(phases) + ctx.base.usePhases(phases) def runPhases(implicit ctx: Context) = { var lastPrintedTree: PrintedTree = NoPrintedTree val profiler = ctx.profiler - for (phase <- ctx.allPhases) + for (phase <- ctx.base.allPhases) if (phase.isRunnable) Stats.trackTime(s"$phase ms ") { val start = System.currentTimeMillis @@ -222,7 +222,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint private def printTree(last: PrintedTree)(implicit ctx: Context): PrintedTree = { val unit = ctx.compilationUnit val prevPhase = ctx.phase.prev // can be a mini-phase - val squashedPhase = ctx.squashed(prevPhase) + val squashedPhase = ctx.base.squashed(prevPhase) val treeString = unit.tpdTree.show(ctx.withProperty(XprintMode, Some(()))) ctx.echo(s"result of $unit after $squashedPhase:") @@ -268,4 +268,4 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint myUnits = null myUnitsCached = null } -} \ No newline at end of file +} diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 30dad2f44847..5f69a6f37943 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -126,7 +126,7 @@ object desugar { val ValDef(name, tpt, rhs) = vdef val mods = vdef.mods val setterNeeded = - (mods is Mutable) && ctx.owner.isClass && (!(mods is PrivateLocal) || (ctx.owner is Trait)) + mods.is(Mutable) && ctx.owner.isClass && (!mods.isBoth(Private, and = Local) || ctx.owner.is(Trait)) if (setterNeeded) { // TODO: copy of vdef as getter needed? // val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos? @@ -149,7 +149,7 @@ object desugar { def makeImplicitParameters(tpts: List[Tree], forPrimaryConstructor: Boolean = false)(implicit ctx: Context) = for (tpt <- tpts) yield { - val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param + val paramFlags: FlagSet = if (forPrimaryConstructor) Private | Local | ParamAccessor else Param val epname = EvidenceParamName.fresh() ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit) } @@ -260,9 +260,9 @@ object desugar { @sharable private val synthetic = Modifiers(Synthetic) private def toDefParam(tparam: TypeDef): TypeDef = - tparam.withMods(tparam.rawMods & EmptyFlags | Param) + tparam.withMods(tparam.mods & EmptyFlags | Param) private def toDefParam(vparam: ValDef): ValDef = - vparam.withMods(vparam.rawMods & (Implicit | Erased) | Param) + vparam.withMods(vparam.mods & (Implicit | Erased) | Param) /** The expansion of a class definition. See inline comments for what is involved */ def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = { @@ -314,7 +314,7 @@ object desugar { lazy val derivedEnumParams = enumClass.typeParams.map(derivedTypeParam) val impliedTparams = if (isEnumCase && originalTparams.isEmpty) - derivedEnumParams.map(tdef => tdef.withFlags(tdef.mods.flags | PrivateLocal)) + derivedEnumParams.map(tdef => tdef.withFlags(tdef.mods.flags | Private | Local)) else originalTparams val constrTparams = impliedTparams.map(toDefParam) @@ -729,7 +729,7 @@ object desugar { case _ => val tmpName = UniqueName.fresh() val patMods = - mods & Lazy | Synthetic | (if (ctx.owner.isClass) PrivateLocal else EmptyFlags) + mods & Lazy | Synthetic | (if (ctx.owner.isClass) Private | Local else EmptyFlags) val firstDef = ValDef(tmpName, TypeTree(), matchExpr) .withPos(pat.pos.union(rhs.pos)).withMods(patMods) diff --git a/compiler/src/dotty/tools/dotc/ast/Positioned.scala b/compiler/src/dotty/tools/dotc/ast/Positioned.scala index f8e53f29fb99..66f797c5e334 100644 --- a/compiler/src/dotty/tools/dotc/ast/Positioned.scala +++ b/compiler/src/dotty/tools/dotc/ast/Positioned.scala @@ -16,10 +16,12 @@ abstract class Positioned extends DotClass with Product { setPos(initialPos) - /** The item's position. - */ + /** The item's position. */ def pos: Position = curPos + /** The item's coord. */ + def coord: Coord = curPos.toCoord + /** Destructively update `curPos` to given position. Also, set any missing * positions in children. */ diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 29096e44bc38..08dd9543eb62 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -78,7 +78,7 @@ object Trees { /** The type constructor at the root of the tree */ type ThisTree[T >: Untyped] <: Tree[T] - private[this] var myTpe: T = _ + protected var myTpe: T @uncheckedVariance = _ /** Destructively set the type of the tree. This should be called only when it is known that * it is safe under sharing to do so. One use-case is in the withType method below @@ -91,7 +91,7 @@ object Trees { /** The type of the tree. In case of an untyped tree, * an UnAssignedTypeException is thrown. (Overridden by empty trees) */ - def tpe: T @uncheckedVariance = { + final def tpe: T @uncheckedVariance = { if (myTpe == null) throw new UnAssignedTypeException(this) myTpe @@ -310,7 +310,7 @@ object Trees { private[this] var myMods: untpd.Modifiers = null - private[dotc] def rawMods: untpd.Modifiers = + def mods: untpd.Modifiers = if (myMods == null) untpd.EmptyModifiers else myMods def rawComment: Option[Comment] = getAttachment(DocComment) @@ -338,7 +338,7 @@ object Trees { */ def namePos = if (pos.exists) - if (rawMods.is(Synthetic)) Position(pos.point, pos.point) + if (mods.is(Synthetic)) Position(pos.point, pos.point) else Position(pos.point, pos.point + name.stripModuleClassSuffix.lastPart.length, pos.point) else pos } @@ -727,7 +727,6 @@ object Trees { } trait WithoutTypeOrPos[-T >: Untyped] extends Tree[T] { - override def tpe: T @uncheckedVariance = NoType.asInstanceOf[T] override def withTypeUnchecked(tpe: Type) = this.asInstanceOf[ThisTree[Type]] override def pos = NoPosition override def setPos(pos: Position) = {} @@ -740,6 +739,8 @@ object Trees { */ case class Thicket[-T >: Untyped](trees: List[Tree[T]]) extends Tree[T] with WithoutTypeOrPos[T] { + myTpe = NoType.asInstanceOf[T] + type ThisTree[-T >: Untyped] = Thicket[T] override def isEmpty: Boolean = trees.isEmpty override def toList: List[Tree[T]] = flatten(trees) @@ -758,8 +759,9 @@ object Trees { class EmptyValDef[T >: Untyped] extends ValDef[T]( nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] { + myTpe = NoType.asInstanceOf[T] override def isEmpty: Boolean = true - setMods(untpd.Modifiers(PrivateLocal)) + setMods(untpd.Modifiers(Private | Local)) } @sharable val theEmptyTree: Thicket[Type] = Thicket(Nil) diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index a3be000dbbc2..54a8bf84f35f 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -175,7 +175,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ta.assignType(untpd.ValDef(sym.name, TypeTree(sym.info), rhs), sym) def SyntheticValDef(name: TermName, rhs: Tree)(implicit ctx: Context): ValDef = - ValDef(ctx.newSymbol(ctx.owner, name, Synthetic, rhs.tpe.widen, coord = rhs.pos), rhs) + ValDef(ctx.newSymbol(ctx.owner, name, Synthetic, rhs.tpe.widen, coord = rhs.coord), rhs) def DefDef(sym: TermSymbol, tparams: List[TypeSymbol], vparamss: List[List[TermSymbol]], resultType: Type, rhs: Tree)(implicit ctx: Context): DefDef = @@ -270,7 +270,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { if (parents.head.classSymbol.is(Trait)) parents.head.parents.head :: parents else parents val cls = ctx.newNormalizedClassSymbol(owner, tpnme.ANON_CLASS, Synthetic, parents1, - coord = fns.map(_.pos).reduceLeft(_ union _)) + coord = fns.map(_.pos).reduceLeft(_ union _).toCoord) val constr = ctx.newConstructor(cls, Synthetic, Nil, Nil).entered def forwarder(fn: TermSymbol, name: TermName) = { val fwdMeth = fn.copy(cls, name, Synthetic | Method).entered.asTerm @@ -284,7 +284,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { // {