Skip to content

Cleanup/interface #218

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 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d2670a7
Made LambdaLift capable of having minitransforms run after it.
odersky Oct 28, 2014
ad45e2e
New miniphase: Flatten
odersky Oct 28, 2014
252b6d9
Generalize lift behavior between Flatten and LambdaLift
odersky Oct 28, 2014
936e83f
New phase: RestoreScopes
odersky Oct 29, 2014
d907f26
Bugfix for superaccessors
odersky Oct 30, 2014
250418e
New phase: PrivateToStatic
odersky Oct 30, 2014
3c55ed8
First version of mixin transform.
odersky Oct 31, 2014
0aa670e
Adapt GettersSetters to new Mixin scheme.
odersky Nov 1, 2014
3705a97
Avoid getting confused because of Scala2 local suffixes
odersky Nov 1, 2014
bb17767
Improved version of mixin.
odersky Nov 1, 2014
73f8b43
New option -Ydebug-owners
odersky Nov 3, 2014
d9057ed
Make cloneScope less forcefull.
odersky Nov 3, 2014
6676cf9
Fix problem in changeOwner
odersky Nov 3, 2014
e9eb0c3
Adaptation of Constructors to new mixin scheme.
odersky Nov 3, 2014
3db649f
Adaptation of explicitOuter to trait initializers
odersky Nov 3, 2014
746957d
Take supercalls into account for statement context
odersky Nov 4, 2014
582506e
Fixed redundancy in membersNeedAsSeenFrom
odersky Nov 4, 2014
17f3ac7
Fixed typing of supertypes.
odersky Nov 4, 2014
ddff592
Fix of computeDenot.
odersky Nov 4, 2014
fba1181
Select operations in erasure should fix symbols in types.
odersky Nov 4, 2014
1ff9e63
Superaccessors are methods
odersky Nov 5, 2014
4a753a1
Cleanup of code for ExplicitOuter
odersky Nov 6, 2014
b04854a
Avoid noisy print statement in PrivateToStatic
odersky Nov 7, 2014
afded4a
Methods always shwoDcl as `def`
odersky Nov 7, 2014
63b9179
Fixes to Unit handling in erasure
odersky Nov 8, 2014
1995bf6
More systematic handling of Scala2LocalSuffix.
odersky Nov 8, 2014
a93d955
Accessor methods print as "method", not "val/var".
odersky Nov 8, 2014
82635eb
Small polishings in docs and code.
odersky Nov 8, 2014
d8fa9ff
More robost handling of isSetter/isGetter
odersky Nov 8, 2014
746a256
Adding test for Unit vars.
odersky Nov 8, 2014
56cfa86
New Mixin scheme.
odersky Nov 8, 2014
dbd9393
Retract of optimization in computeDenot
odersky Nov 8, 2014
dc16bad
Fixed handling of ThisTypes in TypeErasure.
odersky Nov 8, 2014
bf45e65
Better error message for adaptations of implicit methods
odersky Nov 8, 2014
da5b427
Reinstantiated full tests.
odersky Nov 8, 2014
8c22e76
Fixed bug in treating Thickets in TreeTransform
odersky Nov 8, 2014
34b7d35
New functionality: changeOwnerAfter
odersky Nov 8, 2014
cab28b2
Merge memoize with miniphases following it into one group.
odersky Nov 8, 2014
033c686
Merge mixin with the group of miniphases following it.
odersky Nov 8, 2014
dc276eb
More docs and removing print statements
odersky Nov 9, 2014
2e8ca84
Remove unused class
odersky Nov 9, 2014
c132cea
Clean up code relating to interfaces.
odersky Nov 9, 2014
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
13 changes: 9 additions & 4 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,21 @@ class Compiler {
new TailRec),
List(new PatternMatcher,
new ExplicitOuter,
// new LazyValTranformContext().transformer, // disabled, awaiting fixes
new Splitter),
List(new ElimByName,
new InterceptedMethods,
new Literalize,
new GettersSetters),
new Getters,
new ResolveSuper),
List(new Erasure),
List(new CapturedVars,
List(new Mixin,
new Memoize, // TODO: Make LazyVals a part of this phase
new CapturedVars,
new Constructors),
List(new LambdaLift)
List(new LambdaLift,
new Flatten,
new RestoreScopes),
List(new PrivateToStatic)
)

var runId = 1
Expand Down
15 changes: 0 additions & 15 deletions src/dotty/tools/dotc/Flatten.scala

This file was deleted.

16 changes: 12 additions & 4 deletions src/dotty/tools/dotc/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package core

import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._, Decorators._, Flags.JavaDefined
import dotc.transform.ExplicitOuter._
import typer.Mode
import util.DotClass

/** Erased types are:
Expand Down Expand Up @@ -89,7 +90,7 @@ object TypeErasure {

/** The current context with a phase no later than erasure */
private def erasureCtx(implicit ctx: Context) =
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase) else ctx
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx

def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)(erasureCtx)
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)(erasureCtx)
Expand All @@ -107,6 +108,8 @@ object TypeErasure {
case tp: TermRef =>
assert(tp.symbol.exists, tp)
TermRef(erasedRef(tp.prefix), tp.symbol.asTerm)
case tp: ThisType =>
tp
case tp =>
erasure(tp)
}
Expand Down Expand Up @@ -141,7 +144,12 @@ object TypeErasure {
if ((sym eq defn.Any_asInstanceOf) || (sym eq defn.Any_isInstanceOf)) eraseParamBounds(sym.info.asInstanceOf[PolyType])
else if (sym.isAbstractType) TypeAlias(WildcardType)
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
else eraseInfo(tp)(erasureCtx)
else eraseInfo(tp)(erasureCtx) match {
case einfo: MethodType if sym.isGetter && einfo.resultType.isRef(defn.UnitClass) =>
defn.BoxedUnitClass.typeRef
case einfo =>
einfo
}
}

def isUnboundedGeneric(tp: Type)(implicit ctx: Context) = !(
Expand Down Expand Up @@ -265,7 +273,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
case tp: TermRef =>
this(tp.widen)
case ThisType(_) =>
tp
this(tp.widen)
case SuperType(thistpe, supertpe) =>
SuperType(this(thistpe), this(supertpe))
case ExprType(rt) =>
Expand Down Expand Up @@ -319,7 +327,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
}

def eraseInfo(tp: Type)(implicit ctx: Context) = tp match {
case ExprType(rt) => MethodType(Nil, Nil, erasure(rt))
case ExprType(rt) => MethodType(Nil, Nil, eraseResult(rt))
case tp => erasure(tp)
}

Expand Down
15 changes: 9 additions & 6 deletions src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>

/** Is tree legal as a member definition of an interface?
*/
def isInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
case EmptyTree => true
case Import(_, _) => true
case TypeDef(_, _, _) => true
case DefDef(mods, _, _, _, _, __) => mods.flags is Deferred
case ValDef(mods, _, _, _) => mods is Deferred
def isPureInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
case EmptyTree | Import(_, _) | TypeDef(_, _, _) => true
case DefDef(_, _, _, _, _, rhs) => rhs.isEmpty
case ValDef(mods, _, _, rhs) => rhs.isEmpty
case _ => false
}

/** Is tree legal as a member definition of a no-init trait?
*/
def isNoInitMember(tree: Tree): Boolean =
isPureInterfaceMember(tree) || unsplice(tree).isInstanceOf[DefDef]

def isOpAssign(tree: Tree) = unsplice(tree) match {
case Apply(fn, _ :: Nil) =>
unsplice(fn) match {
Expand Down
7 changes: 7 additions & 0 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ object Trees {
s
}

/** If this is a thicket, gerform `op` on each of its trees
* otherwise, perform `op` ion tree itself.
*/
def foreachInThicket(op: Tree[T] => Unit): Unit = op(this)

override def toText(printer: Printer) = printer.toText(this)

override def hashCode(): Int = System.identityHashCode(this)
Expand Down Expand Up @@ -809,6 +814,8 @@ object Trees {
val newTrees = trees.map(_.withPos(pos))
new Thicket[T](newTrees).asInstanceOf[this.type]
}
override def foreachInThicket(op: Tree[T] => Unit): Unit =
trees foreach (_.foreachInThicket(op))
}

class EmptyValDef[T >: Untyped] extends ValDef[T](
Expand Down
31 changes: 26 additions & 5 deletions src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import transform.SymUtils._
import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Symbols._
import Denotations._, Decorators._
import Denotations._, Decorators._, DenotTransformers._
import config.Printers._
import typer.Mode
import collection.mutable
Expand Down Expand Up @@ -39,8 +39,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def This(cls: ClassSymbol)(implicit ctx: Context): This =
untpd.This(cls.name).withType(cls.thisType)

def Super(qual: Tree, mix: TypeName, inConstrCall: Boolean)(implicit ctx: Context): Super =
ta.assignType(untpd.Super(qual, mix), qual, inConstrCall)
def Super(qual: Tree, mix: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
ta.assignType(untpd.Super(qual, mix), qual, inConstrCall, mixinClass)

def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply =
ta.assignType(untpd.Apply(fn, args), fn, args)
Expand Down Expand Up @@ -263,7 +263,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case _ =>
false
}
try test
try test || tp.symbol.is(JavaStatic)
catch { // See remark in SymDenotations#accessWithin
case ex: NotDefinedHere => test(ctx.addMode(Mode.FutureDefsOK))
}
Expand Down Expand Up @@ -527,7 +527,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
*/
def changeOwner(from: Symbol, to: Symbol)(implicit ctx: Context): ThisTree = {
def loop(from: Symbol, froms: List[Symbol], tos: List[Symbol]): ThisTree = {
if (from.isWeakOwner) loop(from.owner, from :: froms, to :: tos)
if (from.isWeakOwner && !from.owner.isClass)
loop(from.owner, from :: froms, to :: tos)
else {
//println(i"change owner ${from :: froms}%, % ==> $tos of $tree")
new TreeTypeMap(oldOwners = from :: froms, newOwners = tos).apply(tree)
Expand All @@ -536,6 +537,26 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
loop(from, Nil, to :: Nil)
}

/** After phase `trans`, set the owner of every definition in this tree that was formerly
* owner by `from` to `to`.
*/
def changeOwnerAfter(from: Symbol, to: Symbol, trans: DenotTransformer)(implicit ctx: Context): ThisTree = {
assert(ctx.phase == trans.next)
val traverser = new TreeTraverser {
def traverse(tree: Tree) = tree match {
case tree: DefTree =>
val sym = tree.symbol
if (sym.denot(ctx.withPhase(trans)).owner == from)
sym.copySymDenotation(owner = to).installAfter(trans)
if (sym.isWeakOwner) traverseChildren(tree)
case _ =>
traverseChildren(tree)
}
}
traverser.traverse(tree)
tree
}

def select(name: Name)(implicit ctx: Context): Select =
Select(tree, name)

Expand Down
5 changes: 3 additions & 2 deletions src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ class ScalaSettings extends Settings.SettingGroup {
val Xdce = BooleanSetting("-Ydead-code", "Perform dead code elimination.")
val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
val debugNames = BooleanSetting("-YdebugNames", "Show name-space indicators when printing names")
val debugTrace = BooleanSetting("-YdebugTrace", "Trace core operations")
val debugFlags = BooleanSetting("-YdebugFlags", "Print all flags of definitions")
val debugTrace = BooleanSetting("-Ydebug-trace", "Trace core operations")
val debugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
val debugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
//val doc = BooleanSetting ("-Ydoc", "Generate documentation")
val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
val inline = BooleanSetting("-Yinline", "Perform inlining when possible.")
Expand Down
13 changes: 9 additions & 4 deletions src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,21 @@ object Contexts {
def thisCallArgContext: Context = {
assert(owner.isClassConstructor)
val constrCtx = outersIterator.dropWhile(_.outer.owner == owner).next
var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next
classCtx.superOrThisCallContext(owner, constrCtx.scope).setTyperState(typerState)
superOrThisCallContext(owner, constrCtx.scope).setTyperState(typerState)
}

/** The super= or this-call context with given owner and locals. */
private def superOrThisCallContext(owner: Symbol, locals: Scope): FreshContext = {
assert(isClassDefContext)
outer.fresh.setOwner(owner).setScope(locals).setMode(ctx.mode | Mode.InSuperCall)
var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next
classCtx.outer.fresh.setOwner(owner).setScope(locals).setMode(classCtx.mode | Mode.InSuperCall)
}

/** The context of expression `expr` seen as a member of a statement sequence */
def exprContext(stat: Tree[_ >: Untyped], exprOwner: Symbol) =
if (exprOwner == this.owner) this
else if (untpd.isSuperConstrCall(stat) && this.owner.isClass) superCallContext
else ctx.fresh.setOwner(exprOwner)

/** The current source file; will be derived from current
* compilation unit.
*/
Expand Down
6 changes: 3 additions & 3 deletions src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class Definitions {
lazy val ScalaStaticsClass = ScalaStaticsModule.moduleClass.asClass

def staticsMethod(name: PreName) = ctx.requiredMethod(ScalaStaticsClass, name)

lazy val DottyPredefModule = ctx.requiredModule("dotty.DottyPredef")
lazy val NilModule = ctx.requiredModule("scala.collection.immutable.Nil")
lazy val PredefConformsClass = ctx.requiredClass("scala.Predef." + tpnme.Conforms)
Expand All @@ -201,7 +201,7 @@ class Definitions {
// needed as a synthetic class because Scala 2.x refers to it in classfiles
// but does not define it as an explicit class.
newCompleteClassSymbol(
ScalaPackageClass, tpnme.Singleton, Trait | Interface | Final,
ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final,
List(AnyClass.typeRef), EmptyScope)
lazy val SeqClass: ClassSymbol = ctx.requiredClass("scala.collection.Seq")
lazy val Seq_apply = ctx.requiredMethod(SeqClass, nme.apply)
Expand Down Expand Up @@ -506,7 +506,7 @@ class Definitions {
val cls = newClassSymbol(
ScalaPackageClass,
traitName,
Trait | Interface | Synthetic,
PureInterfaceCreationFlags | Synthetic,
completer)
myLambdaTraits += cls
cls
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ object Denotations {
def requiredClass(name: PreName)(implicit ctx: Context): ClassSymbol =
info.member(name.toTypeName).requiredSymbol(_.isClass).asClass

/** The denotation that has a type matching `targetType` when seen
/** The alternative of this denotation that has a type matching `targetType` when seen
* as a member of type `site`, `NoDenotation` if none exists.
*/
def matchingDenotation(site: Type, targetType: Type)(implicit ctx: Context): SingleDenotation =
Expand Down
21 changes: 15 additions & 6 deletions src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ object Flags {
/** A trait that has only abstract methods as members
* (and therefore can be represented by a Java interface
*/
final val Interface = typeFlag(22, "interface")
final val PureInterface = typeFlag(22, "interface")

/** Labeled with of abstract & override */
final val AbsOverride = termFlag(22, "abstract override")
Expand Down Expand Up @@ -335,6 +335,9 @@ object Flags {
final val JavaStaticTerm = JavaStatic.toTermFlags
final val JavaStaticType = JavaStatic.toTypeFlags

/** Trait is not an interface, but does not have fields or intialization code */
final val NoInits = typeFlag(32, "<noInits>")

/** Variable is accessed from nested function. */
final val Captured = termFlag(32, "<captured>")

Expand All @@ -353,9 +356,6 @@ object Flags {
/** Symbol is a Java-style varargs method */
final val JavaVarargs = termFlag(37, "<varargs>")

/** Symbol is a Java default method */
final val DefaultMethod = termFlag(38, "<defaultmethod>")

// Flags following this one are not pickled

/** Symbol always defines a fresh named type */
Expand Down Expand Up @@ -464,6 +464,9 @@ object Flags {
/** Accessors always have these flags set */
final val AccessorCreationFlags = Method | Accessor

/** Pure interfaces always have these flags */
final val PureInterfaceCreationFlags = Trait | NoInits | PureInterface

/** The flags of the self symbol */
final val SelfSymFlags = Private | Local | Deferred

Expand Down Expand Up @@ -512,6 +515,9 @@ object Flags {
/** Labeled `private` or `final` */
final val PrivateOrFinal = Private | Final

/** A private method */
final val PrivateMethod = allOf(Private, Method)

/** A type parameter with synthesized name */
final val ExpandedTypeParam = allOf(ExpandedName, TypeParam)

Expand All @@ -536,8 +542,11 @@ object Flags {
/** Is a default parameter in Scala 2*/
final val DefaultParameter = allOf(Param, DefaultParameterized)

/** A Java interface */
final val JavaInterface = allOf(JavaDefined, Trait)
/** A trait that does not need to be initialized */
final val NoInitsTrait = allOf(Trait, NoInits)

/** A Java interface, potentially with default methods */
final val JavaTrait = allOf(JavaDefined, Trait, NoInits)

/** A Java companion object */
final val JavaModule = allOf(JavaDefined, Module)
Expand Down
Loading