Skip to content

constructors & getters-setters #187

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 58 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
00175e1
Replace call to unimplemented method runtimeCall
odersky Sep 17, 2014
7008782
Facturing out EnclosingMethodTraverser from CapturedVars
odersky Sep 17, 2014
8918bd9
Make enteredAfter, installAfter more forgiving as to when they are ca…
odersky Sep 17, 2014
02ab2e8
Add isProperlyContainedIn method
odersky Sep 17, 2014
117b643
Fix lifting of application:
odersky Sep 18, 2014
12a624a
Replace tree.withName with {tpd|untpd}.rename.tree
odersky Sep 18, 2014
14b539e
Take receiver into account when selecting default getters.
odersky Sep 18, 2014
59ae5e6
Treat @static as a source flag.
odersky Sep 18, 2014
8f18250
Allow relaxed typing of applications
odersky Sep 18, 2014
67e0313
Take environment into account when typing a closure.
odersky Sep 18, 2014
c93f545
Erasure should keep prefix in termrefs.
odersky Sep 18, 2014
8975b85
Drop type declarations from erased ClassInfo
odersky Sep 21, 2014
d9a911c
Uncurry also in DefDef trees, not just in infos.
odersky Sep 21, 2014
ce81244
Fix handling of type params in secondary constructors
odersky Sep 21, 2014
d288981
Fix tree typing to account for trees after constructors is run.
odersky Sep 21, 2014
d32ff05
New utility methods in SymUtils
odersky Sep 21, 2014
3f542aa
Account for PolyProto and IgnoredProto types in expectedTypeStr
odersky Sep 21, 2014
3307736
Fix to primaryConstructor
odersky Sep 21, 2014
96f754c
Add constructors phase
odersky Sep 21, 2014
88d11fa
Combine captured vars and constructors into one macro phase.
odersky Sep 21, 2014
478b97a
Fix rewriting of by-name class parameter accessors.
odersky Sep 23, 2014
8ec91d4
Completed constructors phase
odersky Sep 23, 2014
a64e0a2
Made TypeVars uncahable keys
odersky Sep 23, 2014
5289a37
Fix caching logic in baseTypeRef
odersky Sep 23, 2014
0617380
Added method to help traversing children in a TreeTraverser
odersky Sep 24, 2014
103d167
Move private fields into constructor
odersky Sep 24, 2014
9ab1568
Fix errors in SymDenotations.isCachable.
DarkDimius Oct 11, 2014
c0da421
After-rebase fix: weaken owner-chain restriction.
DarkDimius Oct 11, 2014
550ac13
Avoid creating ConstantTypes by TypeAssigner after erasure.
odersky Oct 11, 2014
f3d42cd
Add possibility to compile all files in a directory and all subdirect…
odersky Oct 11, 2014
35f46b4
ElimByName now handles casts to by-name-parameter TermRefs
odersky Oct 11, 2014
33113aa
Fix tree typing to account for trees after constructors is run.
odersky Sep 21, 2014
f244287
Fix to primaryConstructor
odersky Oct 11, 2014
2ca36a9
Create setters also for private vars
odersky Oct 6, 2014
5de2556
Fixes to TermRefs and others in TypeErasure.
odersky Oct 7, 2014
afd9a66
rename AddGetters -> GettersSetters
odersky Oct 7, 2014
f0578aa
Two fixes to TypeComparer
odersky Oct 7, 2014
0e6e7be
Re-usable method to determine self-ness.
odersky Oct 7, 2014
dfeff38
More robust printing or trees
odersky Oct 7, 2014
939bdf4
SymUtil methods to navigate between setters, getters and fields.
odersky Oct 7, 2014
8800746
Avoid caching NoDenotations in NamedTypes
odersky Oct 7, 2014
c72d404
Replace typed with typedUnadapted.
odersky Oct 7, 2014
6efccf9
Don't adapt to FunProto in TreeChecker.
odersky Oct 7, 2014
fa44d5c
Enabled GettersSetters phase.
odersky Oct 11, 2014
fd81127
New tests
odersky Oct 7, 2014
b371bae
Bring back lost AccessorCreationFlags
odersky Oct 11, 2014
41211c5
Fix typing of _* patterns.
odersky Oct 10, 2014
73e7da5
Make widening ops more systematic & complete
odersky Oct 10, 2014
4e89716
Fix bug in varianceInType
odersky Oct 11, 2014
74fa107
Moved caseAccessors to SymUtils
odersky Oct 11, 2014
3c6cf39
TypeTestCasts should test and cast wrt erased types
odersky Oct 11, 2014
ce826ee
Avoid generating Any in erasedLubs
odersky Oct 11, 2014
1f0b25b
Make Scala2Existentials valid forever
odersky Oct 11, 2014
8e9404b
Avoid capturing an old context in Classfile#typeParamCompleter
odersky Oct 11, 2014
765960f
Rename explicitOuter to explicitOuterPhase in Phases
DarkDimius Oct 12, 2014
cf5999c
Remove appliedIfMethod use ensureApplied instead
DarkDimius Oct 12, 2014
e9be067
move caseAccessors from TypeUtils
DarkDimius Oct 12, 2014
c1cc79b
Adaptations to make pattern matcher in new world
odersky Oct 11, 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
19 changes: 5 additions & 14 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ class Compiler {
* all refs to it would become outdated - they could not be dereferenced in the
* new phase.
*
* As an example, addGetters would change a field
*
* val x: T
*
* to a method
*
* def x: T
*
* but this would affect the signature of `x` (goes from NotAMethod to a method
* signature). So we can't do this before erasure.
*
* After erasure, signature changing denot-transformers are OK because erasure
* will make sure that only term refs with fixed SymDenotations survive beyond it. This
* is possible because:
Expand All @@ -57,13 +46,15 @@ class Compiler {
new TailRec),
List(new PatternMatcher,
new ExplicitOuter,
new LazyValsTransform,
// new LazyValTranformContext().transformer, // disabled, awaiting fixes
new Splitter),
List(new ElimByName,
new InterceptedMethods,
new Literalize),
new Literalize,
new GettersSetters),
List(new Erasure),
List(new CapturedVars)
List(new CapturedVars, new Constructors)/*,
List(new LambdaLift)*/
)

var runId = 1
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ElimLocals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ class ElimLocals extends MiniPhaseTransform with SymTransformer { thisTransforme
private def dropLocal(ref: SymDenotation)(implicit ctx: Context) =
if (ref.flags is Local) ref.copySymDenotation(initFlags = ref.flags &~ Local)
else ref
}
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/Flatten.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ class Flatten extends MiniPhaseTransform with SymTransformer { thisTransformer =
override def phaseName = "flatten"

def transformSym(ref: SymDenotation)(implicit ctx: Context) = ???
}
}
51 changes: 36 additions & 15 deletions src/dotty/tools/dotc/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object TypeErasure {
*/
def isErasedType(tp: Type)(implicit ctx: Context): Boolean = tp match {
case tp: TypeRef =>
tp.symbol.isClass
tp.symbol.isClass && tp.symbol != defn.AnyClass
case _: TermRef =>
true
case JavaArrayType(elem) =>
Expand Down Expand Up @@ -87,15 +87,36 @@ object TypeErasure {
private val javaSigFn = erasureFn(isJava = true, isSemi = false, isConstructor = false, wildcardOK = true)
private val semiErasureFn = erasureFn(isJava = false, isSemi = true, isConstructor = false, wildcardOK = false)

def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)
/** 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

def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)(erasureCtx)
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)(erasureCtx)
def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = {
val normTp =
if (tp.isRepeatedParam) tp.translateParameterized(defn.RepeatedParamClass, defn.SeqClass)
else tp
(if (isJava) javaSigFn else scalaSigFn).sigName(normTp)
(if (isJava) javaSigFn else scalaSigFn).sigName(normTp)(erasureCtx)
}

/** The erasure of a top-level reference. Differs from normal erasure in that
* TermRefs are kept instead of being widened away.
*/
def erasedRef(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: TermRef =>
assert(tp.symbol.exists, tp)
TermRef(erasedRef(tp.prefix), tp.symbol.asTerm)
case tp =>
erasure(tp)
}

/** The erasure of a function result type. Differs from normal erasure in that
* Unit is kept instead of being mapped to BoxedUnit.
*/
def eraseResult(tp: Type)(implicit ctx: Context): Type =
scalaErasureFn.eraseResult(tp)(erasureCtx)

/** The symbol's erased info. This is the type's erasure, except for the following symbols:
*
* - For $asInstanceOf : [T]T
Expand All @@ -113,8 +134,8 @@ 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))
else erase(tp)
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
else erase(tp)(erasureCtx)
}

def isUnboundedGeneric(tp: Type)(implicit ctx: Context) = !(
Expand Down Expand Up @@ -147,7 +168,7 @@ object TypeErasure {
def loop(bcs: List[ClassSymbol], bestSoFar: ClassSymbol): ClassSymbol = bcs match {
case bc :: bcs1 =>
if (cls2.derivesFrom(bc))
if (!bc.is(Trait)) bc
if (!bc.is(Trait) && bc != defn.AnyClass) bc
else loop(bcs1, if (bestSoFar.derivesFrom(bc)) bestSoFar else bc)
else
loop(bcs1, bestSoFar)
Expand Down Expand Up @@ -225,7 +246,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
* - For NoType or NoPrefix, the type itself.
* - For any other type, exception.
*/
def apply(tp: Type)(implicit ctx: Context): Type = tp match {
private def apply(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: TypeRef =>
val sym = tp.symbol
if (!sym.isClass) this(tp.info)
Expand All @@ -236,8 +257,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
if (parent isRef defn.ArrayClass) eraseArray(tp)
else this(parent)
case tp: TermRef =>
assert(tp.symbol.exists, tp)
TermRef(NoPrefix, tp.symbol.asTerm)
this(tp.widen)
case ThisType(_) | SuperType(_, _) =>
tp
case ExprType(rt) =>
Expand Down Expand Up @@ -269,7 +289,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
val parents: List[TypeRef] =
if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil
else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
tp.derivedClassInfo(NoPrefix, parents, decls, this(tp.selfType))
val erasedDecls = decls.filteredScope(d => !d.isType || d.isClass)
tp.derivedClassInfo(NoPrefix, parents, erasedDecls, erasedRef(tp.selfType))
// can't replace selftype by NoType because this would lose the sourceModule link
}
case NoType | NoPrefix | ErrorType | JavaArrayType(_) =>
Expand All @@ -278,7 +299,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
tp
}

def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
private def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
val defn.ArrayType(elemtp) = tp
if (elemtp derivesFrom defn.NullClass) JavaArrayType(defn.ObjectType)
else if (isUnboundedGeneric(elemtp))
Expand Down Expand Up @@ -327,7 +348,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
/** The name of the type as it is used in `Signature`s.
* Need to ensure correspondence with erasure!
*/
def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
private def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
case tp: TypeRef =>
val sym = tp.symbol
if (!sym.isClass) sigName(tp.info)
Expand All @@ -337,8 +358,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
sigName(this(tp))
case JavaArrayType(elem) =>
sigName(elem) ++ "[]"
case tp: TypeBounds =>
sigName(tp.hi)
case tp: TermRef =>
sigName(tp.widen)
case ExprType(rt) =>
sigName(defn.FunctionType(Nil, rt))
case tp: TypeProxy =>
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ object desugar {
def valDef(vdef: ValDef)(implicit ctx: Context): Tree = {
val ValDef(mods, name, tpt, rhs) = vdef
def setterNeeded =
(mods is Mutable) && ctx.owner.isClass && (!(mods is Private) || (ctx.owner is Trait))
(mods is Mutable) && ctx.owner.isClass && (!(mods is PrivateLocal) || (ctx.owner is Trait))
if (setterNeeded) {
// todo: copy of vdef as getter needed?
// val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos ?
Expand Down
9 changes: 2 additions & 7 deletions src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import core._
import Types._, Contexts._, Constants._, Names._, Flags._
import SymDenotations._, Symbols._, Annotations._, Trees._, Symbols._
import Denotations._, Decorators._
import dotty.tools.dotc.transform.SymUtils._

/** A map that applies three functions and a substitution together to a tree and
* makes sure they are coordinated so that the result is well-typed. The functions are
Expand Down Expand Up @@ -42,13 +43,7 @@ final class TreeTypeMap(
import tpd._

/** If `sym` is one of `oldOwners`, replace by corresponding symbol in `newOwners` */
def mapOwner(sym: Symbol) = {
def loop(from: List[Symbol], to: List[Symbol]): Symbol =
if (from.isEmpty) sym
else if (sym eq from.head) to.head
else loop(from.tail, to.tail)
loop(oldOwners, newOwners)
}
def mapOwner(sym: Symbol) = sym.subst(oldOwners, newOwners)

/** Replace occurrences of `This(oldOwner)` in some prefix of a type
* by the corresponding `This(newOwner)`.
Expand Down
24 changes: 15 additions & 9 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,6 @@ object Trees {
abstract class NameTree[-T >: Untyped] extends DenotingTree[T] {
type ThisTree[-T >: Untyped] <: NameTree[T]
def name: Name
def withName(name1: Name)(implicit ctx: Context): untpd.NameTree
}

/** Tree refers by name to a denotation */
Expand Down Expand Up @@ -449,7 +448,6 @@ object Trees {
case class Ident[-T >: Untyped] private[ast] (name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Ident[T]
def withName(name: Name)(implicit ctx: Context): untpd.Ident = untpd.cpy.Ident(this)(name)
def qualifier: Tree[T] = genericEmptyTree
}

Expand All @@ -460,7 +458,6 @@ object Trees {
case class Select[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Select[T]
def withName(name: Name)(implicit ctx: Context): untpd.Select = untpd.cpy.Select(this)(qualifier, name)
}

class SelectWithSig[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name, val sig: Signature)
Expand Down Expand Up @@ -656,7 +653,6 @@ object Trees {
case class SelectFromTypeTree[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = SelectFromTypeTree[T]
def withName(name: Name)(implicit ctx: Context): untpd.SelectFromTypeTree = untpd.cpy.SelectFromTypeTree(this)(qualifier, name)
}

/** left & right */
Expand Down Expand Up @@ -702,7 +698,6 @@ object Trees {
extends NameTree[T] with DefTree[T] with PatternTree[T] {
type ThisTree[-T >: Untyped] = Bind[T]
override def envelope: Position = pos union initialPos
def withName(name: Name)(implicit ctx: Context): untpd.Bind = untpd.cpy.Bind(this)(name, body)
}

/** tree_1 | ... | tree_n */
Expand Down Expand Up @@ -734,15 +729,13 @@ object Trees {
case class ValDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = ValDef[T]
def withName(name: Name)(implicit ctx: Context): untpd.ValDef = untpd.cpy.ValDef(this)(name = name.toTermName)
assert(isEmpty || tpt != genericEmptyTree)
}

/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
case class DefDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = DefDef[T]
def withName(name: Name)(implicit ctx: Context): untpd.DefDef = untpd.cpy.DefDef(this)(name = name.toTermName)
assert(tpt != genericEmptyTree)
}

Expand All @@ -754,7 +747,6 @@ object Trees {
case class TypeDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TypeName, rhs: Tree[T])
extends MemberDef[T] {
type ThisTree[-T >: Untyped] = TypeDef[T]
def withName(name: Name)(implicit ctx: Context): untpd.TypeDef = untpd.cpy.TypeDef(this)(name = name.toTypeName)

/** Is this a definition of a class? */
def isClassDef = rhs.isInstanceOf[Template[_]]
Expand Down Expand Up @@ -820,7 +812,7 @@ object Trees {
}

class EmptyValDef[T >: Untyped] extends ValDef[T](
Modifiers[T](Private), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] {
Modifiers[T](PrivateLocal), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] {
override def isEmpty: Boolean = true
}

Expand Down Expand Up @@ -1344,6 +1336,7 @@ object Trees {
abstract class TreeTraverser extends TreeAccumulator[Unit] {
def traverse(tree: Tree): Unit
def apply(x: Unit, tree: Tree) = traverse(tree)
protected def traverseChildren(tree: Tree) = foldOver((), tree)
}

/** Fold `f` over all tree nodes, in depth-first, prefix order */
Expand All @@ -1361,6 +1354,19 @@ object Trees {
else foldOver(x1, tree)
}
}

def rename(tree: NameTree, newName: Name)(implicit ctx: Context): tree.ThisTree[T] = {
tree match {
case tree: Ident => cpy.Ident(tree)(newName)
case tree: Select => cpy.Select(tree)(tree.qualifier, newName)
case tree: Bind => cpy.Bind(tree)(newName, tree.body)
case tree: ValDef => cpy.ValDef(tree)(name = newName.asTermName)
case tree: DefDef => cpy.DefDef(tree)(name = newName.asTermName)
case tree: untpd.PolyTypeDef => untpd.cpy.PolyTypeDef(tree)(tree.mods, newName.asTypeName, tree.tparams, tree.rhs)
case tree: TypeDef => cpy.TypeDef(tree)(name = newName.asTypeName)
case tree: SelectFromTypeTree => cpy.SelectFromTypeTree(tree)(tree.qualifier, newName)
}
}.asInstanceOf[tree.ThisTree[T]]
}
}
// ----- Helper functions and classes ---------------------------------------
Expand Down
Loading