Skip to content

Commit 7eaee33

Browse files
committed
Merge pull request #189 from dotty-staging/merge
constructors & getters-setters
2 parents 5f05c4b + f27010f commit 7eaee33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1717
-493
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,6 @@ class Compiler {
2424
* all refs to it would become outdated - they could not be dereferenced in the
2525
* new phase.
2626
*
27-
* As an example, addGetters would change a field
28-
*
29-
* val x: T
30-
*
31-
* to a method
32-
*
33-
* def x: T
34-
*
35-
* but this would affect the signature of `x` (goes from NotAMethod to a method
36-
* signature). So we can't do this before erasure.
37-
*
3827
* After erasure, signature changing denot-transformers are OK because erasure
3928
* will make sure that only term refs with fixed SymDenotations survive beyond it. This
4029
* is possible because:
@@ -57,13 +46,15 @@ class Compiler {
5746
new TailRec),
5847
List(new PatternMatcher,
5948
new ExplicitOuter,
60-
new LazyValsTransform,
49+
// new LazyValTranformContext().transformer, // disabled, awaiting fixes
6150
new Splitter),
6251
List(new ElimByName,
6352
new InterceptedMethods,
64-
new Literalize),
53+
new Literalize,
54+
new GettersSetters),
6555
List(new Erasure),
66-
List(new CapturedVars)
56+
List(new CapturedVars, new Constructors)/*,
57+
List(new LambdaLift)*/
6758
)
6859

6960
var runId = 1

src/dotty/tools/dotc/ElimLocals.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ class ElimLocals extends MiniPhaseTransform with SymTransformer { thisTransforme
1919
private def dropLocal(ref: SymDenotation)(implicit ctx: Context) =
2020
if (ref.flags is Local) ref.copySymDenotation(initFlags = ref.flags &~ Local)
2121
else ref
22-
}
22+
}

src/dotty/tools/dotc/Flatten.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ class Flatten extends MiniPhaseTransform with SymTransformer { thisTransformer =
1212
override def phaseName = "flatten"
1313

1414
def transformSym(ref: SymDenotation)(implicit ctx: Context) = ???
15-
}
15+
}

src/dotty/tools/dotc/TypeErasure.scala

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object TypeErasure {
3131
*/
3232
def isErasedType(tp: Type)(implicit ctx: Context): Boolean = tp match {
3333
case tp: TypeRef =>
34-
tp.symbol.isClass
34+
tp.symbol.isClass && tp.symbol != defn.AnyClass
3535
case _: TermRef =>
3636
true
3737
case JavaArrayType(elem) =>
@@ -87,15 +87,36 @@ object TypeErasure {
8787
private val javaSigFn = erasureFn(isJava = true, isSemi = false, isConstructor = false, wildcardOK = true)
8888
private val semiErasureFn = erasureFn(isJava = false, isSemi = true, isConstructor = false, wildcardOK = false)
8989

90-
def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)
91-
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)
90+
/** The current context with a phase no later than erasure */
91+
private def erasureCtx(implicit ctx: Context) =
92+
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase) else ctx
93+
94+
def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)(erasureCtx)
95+
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)(erasureCtx)
9296
def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = {
9397
val normTp =
9498
if (tp.isRepeatedParam) tp.translateParameterized(defn.RepeatedParamClass, defn.SeqClass)
9599
else tp
96-
(if (isJava) javaSigFn else scalaSigFn).sigName(normTp)
100+
(if (isJava) javaSigFn else scalaSigFn).sigName(normTp)(erasureCtx)
101+
}
102+
103+
/** The erasure of a top-level reference. Differs from normal erasure in that
104+
* TermRefs are kept instead of being widened away.
105+
*/
106+
def erasedRef(tp: Type)(implicit ctx: Context): Type = tp match {
107+
case tp: TermRef =>
108+
assert(tp.symbol.exists, tp)
109+
TermRef(erasedRef(tp.prefix), tp.symbol.asTerm)
110+
case tp =>
111+
erasure(tp)
97112
}
98113

114+
/** The erasure of a function result type. Differs from normal erasure in that
115+
* Unit is kept instead of being mapped to BoxedUnit.
116+
*/
117+
def eraseResult(tp: Type)(implicit ctx: Context): Type =
118+
scalaErasureFn.eraseResult(tp)(erasureCtx)
119+
99120
/** The symbol's erased info. This is the type's erasure, except for the following symbols:
100121
*
101122
* - For $asInstanceOf : [T]T
@@ -113,8 +134,8 @@ object TypeErasure {
113134

114135
if ((sym eq defn.Any_asInstanceOf) || (sym eq defn.Any_isInstanceOf)) eraseParamBounds(sym.info.asInstanceOf[PolyType])
115136
else if (sym.isAbstractType) TypeAlias(WildcardType)
116-
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp))
117-
else erase(tp)
137+
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
138+
else erase(tp)(erasureCtx)
118139
}
119140

120141
def isUnboundedGeneric(tp: Type)(implicit ctx: Context) = !(
@@ -147,7 +168,7 @@ object TypeErasure {
147168
def loop(bcs: List[ClassSymbol], bestSoFar: ClassSymbol): ClassSymbol = bcs match {
148169
case bc :: bcs1 =>
149170
if (cls2.derivesFrom(bc))
150-
if (!bc.is(Trait)) bc
171+
if (!bc.is(Trait) && bc != defn.AnyClass) bc
151172
else loop(bcs1, if (bestSoFar.derivesFrom(bc)) bestSoFar else bc)
152173
else
153174
loop(bcs1, bestSoFar)
@@ -225,7 +246,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
225246
* - For NoType or NoPrefix, the type itself.
226247
* - For any other type, exception.
227248
*/
228-
def apply(tp: Type)(implicit ctx: Context): Type = tp match {
249+
private def apply(tp: Type)(implicit ctx: Context): Type = tp match {
229250
case tp: TypeRef =>
230251
val sym = tp.symbol
231252
if (!sym.isClass) this(tp.info)
@@ -236,8 +257,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
236257
if (parent isRef defn.ArrayClass) eraseArray(tp)
237258
else this(parent)
238259
case tp: TermRef =>
239-
assert(tp.symbol.exists, tp)
240-
TermRef(NoPrefix, tp.symbol.asTerm)
260+
this(tp.widen)
241261
case ThisType(_) | SuperType(_, _) =>
242262
tp
243263
case ExprType(rt) =>
@@ -269,7 +289,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
269289
val parents: List[TypeRef] =
270290
if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil
271291
else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
272-
tp.derivedClassInfo(NoPrefix, parents, decls, this(tp.selfType))
292+
val erasedDecls = decls.filteredScope(d => !d.isType || d.isClass)
293+
tp.derivedClassInfo(NoPrefix, parents, erasedDecls, erasedRef(tp.selfType))
273294
// can't replace selftype by NoType because this would lose the sourceModule link
274295
}
275296
case NoType | NoPrefix | ErrorType | JavaArrayType(_) =>
@@ -278,7 +299,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
278299
tp
279300
}
280301

281-
def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
302+
private def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
282303
val defn.ArrayType(elemtp) = tp
283304
if (elemtp derivesFrom defn.NullClass) JavaArrayType(defn.ObjectType)
284305
else if (isUnboundedGeneric(elemtp))
@@ -327,7 +348,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
327348
/** The name of the type as it is used in `Signature`s.
328349
* Need to ensure correspondence with erasure!
329350
*/
330-
def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
351+
private def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
331352
case tp: TypeRef =>
332353
val sym = tp.symbol
333354
if (!sym.isClass) sigName(tp.info)
@@ -337,8 +358,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
337358
sigName(this(tp))
338359
case JavaArrayType(elem) =>
339360
sigName(elem) ++ "[]"
340-
case tp: TypeBounds =>
341-
sigName(tp.hi)
361+
case tp: TermRef =>
362+
sigName(tp.widen)
342363
case ExprType(rt) =>
343364
sigName(defn.FunctionType(Nil, rt))
344365
case tp: TypeProxy =>

src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ object desugar {
9090
def valDef(vdef: ValDef)(implicit ctx: Context): Tree = {
9191
val ValDef(mods, name, tpt, rhs) = vdef
9292
def setterNeeded =
93-
(mods is Mutable) && ctx.owner.isClass && (!(mods is Private) || (ctx.owner is Trait))
93+
(mods is Mutable) && ctx.owner.isClass && (!(mods is PrivateLocal) || (ctx.owner is Trait))
9494
if (setterNeeded) {
9595
// todo: copy of vdef as getter needed?
9696
// val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos ?

src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import core._
66
import Types._, Contexts._, Constants._, Names._, Flags._
77
import SymDenotations._, Symbols._, Annotations._, Trees._, Symbols._
88
import Denotations._, Decorators._
9+
import dotty.tools.dotc.transform.SymUtils._
910

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

4445
/** If `sym` is one of `oldOwners`, replace by corresponding symbol in `newOwners` */
45-
def mapOwner(sym: Symbol) = {
46-
def loop(from: List[Symbol], to: List[Symbol]): Symbol =
47-
if (from.isEmpty) sym
48-
else if (sym eq from.head) to.head
49-
else loop(from.tail, to.tail)
50-
loop(oldOwners, newOwners)
51-
}
46+
def mapOwner(sym: Symbol) = sym.subst(oldOwners, newOwners)
5247

5348
/** Replace occurrences of `This(oldOwner)` in some prefix of a type
5449
* by the corresponding `This(newOwner)`.

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,6 @@ object Trees {
408408
abstract class NameTree[-T >: Untyped] extends DenotingTree[T] {
409409
type ThisTree[-T >: Untyped] <: NameTree[T]
410410
def name: Name
411-
def withName(name1: Name)(implicit ctx: Context): untpd.NameTree
412411
}
413412

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

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

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

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

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

741735
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
742736
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])
743737
extends ValOrDefDef[T] {
744738
type ThisTree[-T >: Untyped] = DefDef[T]
745-
def withName(name: Name)(implicit ctx: Context): untpd.DefDef = untpd.cpy.DefDef(this)(name = name.toTermName)
746739
assert(tpt != genericEmptyTree)
747740
}
748741

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

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

822814
class EmptyValDef[T >: Untyped] extends ValDef[T](
823-
Modifiers[T](Private), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] {
815+
Modifiers[T](PrivateLocal), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] {
824816
override def isEmpty: Boolean = true
825817
}
826818

@@ -1344,6 +1336,7 @@ object Trees {
13441336
abstract class TreeTraverser extends TreeAccumulator[Unit] {
13451337
def traverse(tree: Tree): Unit
13461338
def apply(x: Unit, tree: Tree) = traverse(tree)
1339+
protected def traverseChildren(tree: Tree) = foldOver((), tree)
13471340
}
13481341

13491342
/** Fold `f` over all tree nodes, in depth-first, prefix order */
@@ -1361,6 +1354,19 @@ object Trees {
13611354
else foldOver(x1, tree)
13621355
}
13631356
}
1357+
1358+
def rename(tree: NameTree, newName: Name)(implicit ctx: Context): tree.ThisTree[T] = {
1359+
tree match {
1360+
case tree: Ident => cpy.Ident(tree)(newName)
1361+
case tree: Select => cpy.Select(tree)(tree.qualifier, newName)
1362+
case tree: Bind => cpy.Bind(tree)(newName, tree.body)
1363+
case tree: ValDef => cpy.ValDef(tree)(name = newName.asTermName)
1364+
case tree: DefDef => cpy.DefDef(tree)(name = newName.asTermName)
1365+
case tree: untpd.PolyTypeDef => untpd.cpy.PolyTypeDef(tree)(tree.mods, newName.asTypeName, tree.tparams, tree.rhs)
1366+
case tree: TypeDef => cpy.TypeDef(tree)(name = newName.asTypeName)
1367+
case tree: SelectFromTypeTree => cpy.SelectFromTypeTree(tree)(tree.qualifier, newName)
1368+
}
1369+
}.asInstanceOf[tree.ThisTree[T]]
13641370
}
13651371
}
13661372
// ----- Helper functions and classes ---------------------------------------

0 commit comments

Comments
 (0)