Skip to content

Refactor/super accessors #495

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

Merged
merged 16 commits into from
Apr 28, 2015
Merged
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
10 changes: 4 additions & 6 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Contexts._
import Periods._
import Symbols._
import Scopes._
import typer.{FrontEnd, Typer, Mode, ImportInfo, RefChecks, InstChecks}
import typer.{FrontEnd, Typer, Mode, ImportInfo, RefChecks}
import reporting.ConsoleReporter
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.transform._
Expand Down Expand Up @@ -38,11 +38,9 @@ class Compiler {
def phases: List[List[Phase]] =
List(
List(new FrontEnd),
List(new InstChecks),
List(new FirstTransform,
new SyntheticMethods),
List(new SuperAccessors),
List(new Pickler), // Pickler needs to come last in a group since it should not pickle trees generated later
List(new PostTyper),
List(new Pickler),
List(new FirstTransform),
List(new RefChecks,
new ElimRepeated,
new NormalizeFlags,
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

def Import(expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import =
ta.assignType(untpd.Import(expr, selectors), ctx.newImportSymbol(expr))
ta.assignType(untpd.Import(expr, selectors), ctx.newImportSymbol(ctx.owner, expr))

def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef =
ta.assignType(untpd.PackageDef(pid, stats), pid)
Expand Down
4 changes: 4 additions & 0 deletions src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ object SymDenotations {
final def hasAnnotation(cls: Symbol)(implicit ctx: Context) =
dropOtherAnnotations(annotations, cls).nonEmpty

/** Apply transform `f` to all annotations of this denotation */
final def transformAnnotations(f: Annotation => Annotation)(implicit ctx: Context): Unit =
annotations = annotations.mapConserve(f)

/** Optionally, the annotation matching the given class symbol */
final def getAnnotation(cls: Symbol)(implicit ctx: Context): Option[Annotation] =
dropOtherAnnotations(annotations, cls) match {
Expand Down
12 changes: 8 additions & 4 deletions src/dotty/tools/dotc/core/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ trait Symbols { this: Context =>
newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType)

/** Create an import symbol pointing back to given qualifier `expr`. */
def newImportSymbol(expr: Tree, coord: Coord = NoCoord) =
newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord)
def newImportSymbol(owner: Symbol, expr: Tree, coord: Coord = NoCoord) =
newSymbol(owner, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord)

/** Create a class constructor symbol for given class `cls`. */
def newConstructor(cls: ClassSymbol, flags: FlagSet, paramNames: List[TermName], paramTypes: List[Type], privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) =
Expand Down Expand Up @@ -552,13 +552,17 @@ object Symbols {
ctx.newSymbol(owner, name, flags, info, privateWithin, coord)
}

implicit def defn(implicit ctx: Context): Definitions = ctx.definitions

/** Makes all denotation operations available on symbols */
implicit def toDenot(sym: Symbol)(implicit ctx: Context): SymDenotation = sym.denot

/** Makes all class denotations available on class symbols */
implicit def toClassDenot(cls: ClassSymbol)(implicit ctx: Context): ClassDenotation = cls.classDenot

/** The Definitions object */
def defn(implicit ctx: Context): Definitions = ctx.definitions

/** The current class */
def currentClass(implicit ctx: Context): ClassSymbol = ctx.owner.enclosingClass.asClass

var stubs: List[Symbol] = Nil // diagnostic
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/TypeApplications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class TypeApplications(val self: Type) extends AnyVal {
default
}
}

/** Translate a type of the form From[T] to To[T], keep other types as they are.
* `from` and `to` must be static classes, both with one type parameter, and the same variance.
*/
Expand Down
8 changes: 4 additions & 4 deletions src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1788,12 +1788,12 @@ object Types {
if (false) RefinedType(parent, refinedName, refinedInfo)
else RefinedType(parent, refinedName, rt => refinedInfo.substSkolem(this, SkolemType(rt)))
}

/** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */
def wrapIfMember(parent: Type)(implicit ctx: Context): Type =
if (parent.member(refinedName).exists) derivedRefinedType(parent, refinedName, refinedInfo)
else parent

override def equals(that: Any) = that match {
case that: RefinedType =>
this.parent == that.parent &&
Expand Down Expand Up @@ -2414,7 +2414,7 @@ object Types {
selfTypeCache = {
def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
val given = givenSelfType
val raw =
val raw =
if (!given.exists) fullRef
else if (cls is Module) given
else if (ctx.erasedTypes) fullRef
Expand All @@ -2423,7 +2423,7 @@ object Types {
}
selfTypeCache
}

/** The explicitly given self type (self types of modules are assumed to be
* explcitly given here).
*/
Expand Down
22 changes: 20 additions & 2 deletions src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -657,10 +657,10 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
}

def readIndexedStat(exprOwner: Symbol)(implicit ctx: Context): Tree = nextByte match {
case TYPEDEF | VALDEF | DEFDEF | IMPORT =>
case TYPEDEF | VALDEF | DEFDEF =>
readIndexedDef()
case IMPORT =>
???
readImport()
case PACKAGE =>
val start = currentAddr
processPackage { (pid, end) => implicit ctx =>
Expand All @@ -670,6 +670,24 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
readTerm()(ctx.withOwner(exprOwner))
}

def readImport()(implicit ctx: Context): Tree = {
readByte()
readEnd()
val expr = readTerm()
def readSelectors(): List[untpd.Tree] = nextByte match {
case RENAMED =>
readByte()
readEnd()
untpd.Pair(untpd.Ident(readName()), untpd.Ident(readName())) :: readSelectors()
case IMPORTED =>
readByte()
untpd.Ident(readName()) :: readSelectors()
case _ =>
Nil
}
Import(expr, readSelectors())
}

def readIndexedStats(exprOwner: Symbol, end: Addr)(implicit ctx: Context): List[Tree] =
until(end)(readIndexedStat(exprOwner))

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
homogenize(tp) match {
case tp: TypeType =>
toTextRHS(tp)
case tp: TermRef if !tp.denotationIsCurrent || tp.symbol.is(Module) =>
case tp: TermRef if !tp.denotationIsCurrent || tp.symbol.is(Module) || tp.symbol.name.isImportName =>
toTextRef(tp) ~ ".type"
case tp: TermRef if tp.denot.isOverloaded =>
"<overloaded " ~ toTextRef(tp) ~ ">"
Expand Down
2 changes: 2 additions & 0 deletions src/dotty/tools/dotc/transform/ExtensionMethods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful

override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[ElimRepeated])

override def runsAfterGroupsOf = Set(classOf[FirstTransform]) // need companion objects to exist

override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
case ref: ClassDenotation if ref is ModuleClass =>
ref.linkedClass match {
Expand Down
54 changes: 3 additions & 51 deletions src/dotty/tools/dotc/transform/FirstTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,13 @@ import StdNames._

/** The first tree transform
* - ensures there are companion objects for all classes except module classes
* - eliminates some kinds of trees: Imports, NamedArgs, all TypTrees other than TypeTree
* - converts Select/Ident/SelectFromTypeTree nodes that refer to types to TypeTrees.
* - inserts `.package` for selections of package object members
* - checks the bounds of AppliedTypeTrees
* - eliminates some kinds of trees: Imports, NamedArgs
* - stubs out native methods
* - removes java-defined ASTs
*/
class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer with AnnotationTransformer { thisTransformer =>
import ast.tpd._

override def phaseName = "firstTransform"

override def runsAfter = Set(classOf[typer.InstChecks])
// This phase makes annotations disappear in types, so InstChecks should
// run before so that it can get at all annotations.

def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp

Expand Down Expand Up @@ -101,10 +93,7 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
case stat => stat
}

def skipJava(stats: List[Tree]): List[Tree] = // packages get a JavaDefined flag. Dont skip them
stats.filter(t => !(t.symbol is(Flags.JavaDefined, Flags.Package)))

addMissingCompanions(reorder(skipJava(stats)))
addMissingCompanions(reorder(stats))
}

override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
Expand All @@ -119,47 +108,10 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] =
ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisTransformer.next)))

private def normalizeType(tree: Tree)(implicit ctx: Context) =
if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree

override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = tree.tpe match {
case tpe: ThisType =>
/*
A this reference hide in a self ident, and be subsequently missed
when deciding on whether outer accessors are needed and computing outer paths.
We do this normalization directly after Typer, because during typer the
ident should rest available for hyperlinking.*/
This(tpe.cls).withPos(tree.pos)
case _ => normalizeType(tree)
}



override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
normalizeType {
val qual = tree.qualifier
qual.symbol.moduleClass.denot match {
case pkg: PackageClassDenotation if !tree.symbol.maybeOwner.is(Package) =>
cpy.Select(tree)(qual select pkg.packageObj.symbol, tree.name)
case _ =>
tree
}
}

override def transformSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context, info: TransformerInfo) =
normalizeType(tree)

override def transformOther(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
case tree: Import => EmptyTree
case tree: NamedArg => transform(tree.arg)
case AppliedTypeTree(tycon, args) =>
val tparams = tycon.tpe.typeSymbol.typeParams
val bounds = tparams.map(tparam =>
tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds)
Checking.checkBounds(args, bounds, _.substDealias(tparams, _))
normalizeType(tree)
case tree =>
normalizeType(tree)
case tree => tree
}

// invariants: all modules have companion objects
Expand Down
11 changes: 3 additions & 8 deletions src/dotty/tools/dotc/transform/FullParameterization.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Types._
import Contexts._
import Symbols._
import Decorators._
import TypeUtils._
import StdNames.nme
import NameOps._
import ast._
Expand Down Expand Up @@ -128,14 +129,8 @@ trait FullParameterization {
*/
def memberSignature(info: Type)(implicit ctx: Context): Signature = info match {
case info: PolyType => memberSignature(info.resultType)
case info @ MethodType(nme.SELF :: Nil, _) =>
val normalizedResultType = info.resultType match {
case rtp: MethodType => rtp
case rtp => ExprType(rtp)
}
normalizedResultType.signature
case _ =>
Signature.NotAMethod
case info @ MethodType(nme.SELF :: Nil, _) => info.resultType.ensureMethodic.signature
case _ => Signature.NotAMethod
}

/** The type parameters (skolems) of the method definition `originalDef`,
Expand Down
22 changes: 11 additions & 11 deletions src/dotty/tools/dotc/transform/LambdaLift.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,18 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
* in `enclosure` or there is an intermediate class properly containing `enclosure`
* in which `sym` is also free. Also, update `liftedOwner` of `enclosure` so
* that `enclosure` can access `sym`, or its proxy in an intermediate class.
* This means:
*
* This means:
*
* 1. If there is an intermediate class in which `sym` is free, `enclosure`
* must be contained in that class (in order to access the `sym proxy stored
* must be contained in that class (in order to access the `sym proxy stored
* in the class).
*
*
* 2. If there is no intermediate class, `enclosure` must be contained
* in the class enclosing `sym`.
*
*
* Return the closest enclosing intermediate class between `enclosure` and
* the owner of sym, or NoSymbol if none exists.
*
*
* pre: sym.owner.isTerm, (enclosure.isMethod || enclosure.isClass)
*
* The idea of `markFree` is illustrated with an example:
Expand Down Expand Up @@ -150,10 +150,10 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
else {
ctx.log(i"mark free: ${sym.showLocated} with owner ${sym.maybeOwner} marked free in $enclosure")
ctx.debuglog(i"$enclosure != ${sym.enclosure}")
val intermediate =
val intermediate =
if (enclosure.is(PackageClass)) enclosure
else markFree(sym, enclosure.skipConstructor.enclosure)
// `enclosure` might be a constructor, in which case we want the enclosure
else markFree(sym, enclosure.skipConstructor.enclosure)
// `enclosure` might be a constructor, in which case we want the enclosure
// of the enclosing class, so skipConstructor is needed here.
if (intermediate.exists) {
narrowLiftedOwner(enclosure, intermediate)
Expand Down Expand Up @@ -394,12 +394,12 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
val sym = tree.symbol
tree.tpe match {
case tpe @ TermRef(prefix, _) =>
if (prefix eq NoPrefix)
if (prefix eq NoPrefix)
if (sym.enclosure != currentEnclosure && !sym.isStatic)
(if (sym is Method) memberRef(sym) else proxyRef(sym)).withPos(tree.pos)
else if (sym.owner.isClass) // sym was lifted out
ref(sym).withPos(tree.pos)
else
else
tree
else if (!prefixIsElidable(tpe)) ref(tpe)
else tree
Expand Down
5 changes: 0 additions & 5 deletions src/dotty/tools/dotc/transform/MacroTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ abstract class MacroTransform extends Phase {
ctx.fresh.setTree(tree).setOwner(owner)
}

/** The current enclosing class
* @pre We must be inside a class
*/
def currentClass(implicit ctx: Context): ClassSymbol = ctx.owner.enclosingClass.asClass

def transformStats(trees: List[Tree], exprOwner: Symbol)(implicit ctx: Context): List[Tree] = {
def transformStat(stat: Tree): Tree = stat match {
case _: Import | _: DefTree => transform(stat)
Expand Down
Loading