Skip to content

Commit 7f0637c

Browse files
committed
Make This and Super take idents as qualifier/mixin
The qualifier of a This and the mixin of a Super were names, which meant that their positions were lost. Now they are untyped idents.
1 parent 5c7617b commit 7f0637c

File tree

13 files changed

+79
-53
lines changed

13 files changed

+79
-53
lines changed

src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
973973
}
974974

975975
object This extends ThisDeconstructor {
976-
def get = field.qual
976+
def get = field.qual.name
977977
def apply(s: Symbol): This = tpd.This(s.asClass)
978978
}
979979

@@ -1020,7 +1020,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
10201020
}
10211021
object Super extends SuperDeconstructor {
10221022
def _1: Tree = field.qual
1023-
def _2: Name = field.mix
1023+
def _2: Name = field.mix.name
10241024
}
10251025
object ArrayValue extends ArrayValueDeconstructor {
10261026
def _1: Type = field.tpe match {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ object desugar {
340340
val isDefinedMeth = syntheticProperty(nme.isDefined, Literal(Constant(true)))
341341
val caseParams = constrVparamss.head.toArray
342342
val productElemMeths = for (i <- 0 until arity) yield
343-
syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeName), caseParams(i).name))
343+
syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeIdent), caseParams(i).name))
344344
def isRepeated(tree: Tree): Boolean = tree match {
345345
case PostfixOp(_, nme.raw.STAR) => true
346346
case ByNameTypeTree(tree1) => isRepeated(tree1)

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ object Trees {
159159
/** Does this tree define a new symbol that is not defined elsewhere? */
160160
def isDef: Boolean = false
161161

162-
/** Is this tree either the empty tree or the empty ValDef? */
162+
/** Is this tree either the empty tree or the empty ValDef or an empty type ident? */
163163
def isEmpty: Boolean = false
164164

165165
/** Convert tree to a list. Gives a singleton list, except
@@ -353,7 +353,7 @@ object Trees {
353353
}
354354

355355
/** qual.this */
356-
case class This[-T >: Untyped] private[ast] (qual: TypeName)
356+
case class This[-T >: Untyped] private[ast] (qual: untpd.Ident)
357357
extends DenotingTree[T] with TermTree[T] {
358358
type ThisTree[-T >: Untyped] = This[T]
359359
// Denotation of a This tree is always the underlying class; needs correction for modules.
@@ -368,7 +368,7 @@ object Trees {
368368
}
369369

370370
/** C.super[mix], where qual = C.this */
371-
case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: TypeName)
371+
case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: untpd.Ident)
372372
extends ProxyTree[T] with TermTree[T] {
373373
type ThisTree[-T >: Untyped] = Super[T]
374374
def forwardTo = qual
@@ -890,12 +890,12 @@ object Trees {
890890
case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
891891
case _ => finalize(tree, untpd.Select(qualifier, name))
892892
}
893-
def This(tree: Tree)(qual: TypeName): This = tree match {
894-
case tree: This if qual == tree.qual => tree
893+
def This(tree: Tree)(qual: untpd.Ident): This = tree match {
894+
case tree: This if qual eq tree.qual => tree
895895
case _ => finalize(tree, untpd.This(qual))
896896
}
897-
def Super(tree: Tree)(qual: Tree, mix: TypeName): Super = tree match {
898-
case tree: Super if (qual eq tree.qual) && (mix == tree.mix) => tree
897+
def Super(tree: Tree)(qual: Tree, mix: untpd.Ident): Super = tree match {
898+
case tree: Super if (qual eq tree.qual) && (mix eq tree.mix) => tree
899899
case _ => finalize(tree, untpd.Super(qual, mix))
900900
}
901901
def Apply(tree: Tree)(fun: Tree, args: List[Tree])(implicit ctx: Context): Apply = tree match {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
3131
untpd.Select(qualifier, tp.name).withType(tp)
3232

3333
def This(cls: ClassSymbol)(implicit ctx: Context): This =
34-
untpd.This(cls.name).withType(cls.thisType)
34+
untpd.This(untpd.Ident(cls.name)).withType(cls.thisType)
3535

36-
def Super(qual: Tree, mix: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
36+
def Super(qual: Tree, mix: untpd.Ident, inConstrCall: Boolean, mixinClass: Symbol)(implicit ctx: Context): Super =
3737
ta.assignType(untpd.Super(qual, mix), qual, inConstrCall, mixinClass)
3838

39+
def Super(qual: Tree, mixName: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
40+
Super(qual, if (mixName.isEmpty) untpd.EmptyTypeIdent else untpd.Ident(mixName), inConstrCall, mixinClass)
41+
3942
def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply =
4043
ta.assignType(untpd.Apply(fn, args), fn, args)
4144

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
8080
case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
8181
case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree
8282

83+
@sharable object EmptyTypeIdent extends Ident(tpnme.EMPTY) with WithoutTypeOrPos[Untyped] {
84+
override def isEmpty = true
85+
}
86+
8387
/** A block arising from a right-associative infix operation, where, e.g.
8488
*
8589
* a +: b
@@ -225,8 +229,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
225229
def BackquotedIdent(name: Name): BackquotedIdent = new BackquotedIdent(name)
226230
def Select(qualifier: Tree, name: Name): Select = new Select(qualifier, name)
227231
def SelectWithSig(qualifier: Tree, name: Name, sig: Signature): Select = new SelectWithSig(qualifier, name, sig)
228-
def This(qual: TypeName): This = new This(qual)
229-
def Super(qual: Tree, mix: TypeName): Super = new Super(qual, mix)
232+
def This(qual: Ident): This = new This(qual)
233+
def Super(qual: Tree, mix: Ident): Super = new Super(qual, mix)
230234
def Apply(fun: Tree, args: List[Tree]): Apply = new Apply(fun, args)
231235
def TypeApply(fun: Tree, args: List[Tree]): TypeApply = new TypeApply(fun, args)
232236
def Literal(const: Constant): Literal = new Literal(const)

src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ Standard-Section: "ASTs" TopLevelStat*
7373
Application
7474
IDENT NameRef Type // used when term ident’s type is not a TermRef
7575
SELECT possiblySigned_NameRef qual_Term
76+
QUALTHIS typeIdent_Tree
7677
NEW cls_Type
77-
SUPER Length this_Term mixinTrait_Type?
78+
SUPER Length this_Term mixinTypeIdent_Tree?
7879
TYPED Length expr_Term ascription_Type
7980
NAMEDARG Length paramName_NameRef arg_Term
8081
ASSIGN Length lhs_Term rhs_Term
@@ -279,16 +280,17 @@ object TastyFormat {
279280
final val RENAMED = 79
280281

281282
final val THIS = 96
282-
final val CLASSconst = 97
283-
final val ENUMconst = 98
284-
final val BYNAMEtype = 99
285-
final val BYNAMEtpt = 100
286-
final val NEW = 101
287-
final val IMPLICITarg = 102
288-
final val PRIVATEqualified = 103
289-
final val PROTECTEDqualified = 104
290-
final val RECtype = 105
291-
final val SINGLETONtpt = 106
283+
final val QUALTHIS = 97
284+
final val CLASSconst = 98
285+
final val ENUMconst = 99
286+
final val BYNAMEtype = 100
287+
final val BYNAMEtpt = 101
288+
final val NEW = 102
289+
final val IMPLICITarg = 103
290+
final val PRIVATEqualified = 104
291+
final val PROTECTEDqualified = 105
292+
final val RECtype = 106
293+
final val SINGLETONtpt = 107
292294

293295
final val IDENT = 112
294296
final val IDENTtpt = 113
@@ -506,6 +508,7 @@ object TastyFormat {
506508
case TEMPLATE => "TEMPLATE"
507509
case SELFDEF => "SELFDEF"
508510
case THIS => "THIS"
511+
case QUALTHIS => "QUALTHIS"
509512
case SUPER => "SUPER"
510513
case CLASSconst => "CLASSconst"
511514
case ENUMconst => "ENUMconst"

src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,13 @@ class TreePickler(pickler: TastyPickler) {
360360
pickleName(name)
361361
pickleType(tree.tpe)
362362
}
363-
case This(_) =>
364-
pickleType(tree.tpe)
363+
case This(qual) =>
364+
if (qual.isEmpty) pickleType(tree.tpe)
365+
else {
366+
writeByte(QUALTHIS)
367+
val ThisType(tref) = tree.tpe
368+
pickleTree(qual.withType(tref))
369+
}
365370
case Select(qual, name) =>
366371
writeByte(if (name.isTypeName) SELECTtpt else SELECT)
367372
val realName = tree.tpe match {
@@ -396,8 +401,8 @@ class TreePickler(pickler: TastyPickler) {
396401
withLength {
397402
pickleTree(qual);
398403
if (!mix.isEmpty) {
399-
val SuperType(_, mixinType) = tree.tpe
400-
pickleType(mixinType)
404+
val SuperType(_, mixinType: TypeRef) = tree.tpe
405+
pickleTree(mix.withType(mixinType))
401406
}
402407
}
403408
case New(tpt) =>

src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
885885
untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable))
886886
}
887887

888+
def readQualId(): (untpd.Ident, TypeRef) = {
889+
val qual = readTerm().asInstanceOf[untpd.Ident]
890+
(untpd.Ident(qual.name).withPos(qual.pos), qual.tpe.asInstanceOf[TypeRef])
891+
}
892+
888893
def readSimpleTerm(): Tree = tag match {
889894
case SHARED =>
890895
forkAt(readAddr()).readTerm()
@@ -902,6 +907,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
902907
case SELECTtpt =>
903908
val name = readName().toTypeName
904909
completeSelect(name, TypeRef(_, name))
910+
case QUALTHIS =>
911+
val (qual, tref) = readQualId()
912+
untpd.This(qual).withType(ThisType.raw(tref))
905913
case NEW =>
906914
New(readTpt())
907915
case SINGLETONtpt =>
@@ -933,9 +941,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
933941
(tag: @switch) match {
934942
case SUPER =>
935943
val qual = readTerm()
936-
val mixClass = ifBefore(end)(readType().typeSymbol, NoSymbol)
937-
val mixName = if (mixClass.exists) mixClass.name.asTypeName else tpnme.EMPTY
938-
tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass)
944+
val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
945+
tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol)
939946
case APPLY =>
940947
val fn = readTerm()
941948
val isJava = fn.symbol.is(JavaDefined)

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -527,27 +527,28 @@ object Parsers {
527527
*/
528528
def path(thisOK: Boolean, finish: Tree => Tree = id): Tree = {
529529
val start = in.offset
530-
def handleThis(name: TypeName) = {
530+
def handleThis(qual: Ident) = {
531531
in.nextToken()
532-
val t = atPos(start) { This(name) }
532+
val t = atPos(start) { This(qual) }
533533
if (!thisOK && in.token != DOT) syntaxError("`.' expected")
534534
dotSelectors(t, finish)
535535
}
536-
def handleSuper(name: TypeName) = {
536+
def handleSuper(qual: Ident) = {
537537
in.nextToken()
538538
val mix = mixinQualifierOpt()
539-
val t = atPos(start) { Super(This(name), mix) }
539+
val t = atPos(start) { Super(This(qual), mix) }
540540
accept(DOT)
541541
dotSelectors(selector(t), finish)
542542
}
543-
if (in.token == THIS) handleThis(tpnme.EMPTY)
544-
else if (in.token == SUPER) handleSuper(tpnme.EMPTY)
543+
if (in.token == THIS) handleThis(EmptyTypeIdent)
544+
else if (in.token == SUPER) handleSuper(EmptyTypeIdent)
545545
else {
546546
val t = termIdent()
547547
if (in.token == DOT) {
548+
def qual = cpy.Ident(t)(t.name.toTypeName)
548549
in.nextToken()
549-
if (in.token == THIS) handleThis(t.name.toTypeName)
550-
else if (in.token == SUPER) handleSuper(t.name.toTypeName)
550+
if (in.token == THIS) handleThis(qual)
551+
else if (in.token == SUPER) handleSuper(qual)
551552
else selectors(t, finish)
552553
}
553554
else t
@@ -556,9 +557,9 @@ object Parsers {
556557

557558
/** MixinQualifier ::= `[' Id `]'
558559
*/
559-
def mixinQualifierOpt(): TypeName =
560-
if (in.token == LBRACKET) inBrackets(ident().toTypeName)
561-
else tpnme.EMPTY
560+
def mixinQualifierOpt(): Ident =
561+
if (in.token == LBRACKET) inBrackets(atPos(in.offset) { typeIdent() })
562+
else EmptyTypeIdent
562563

563564
/** StableId ::= Id
564565
* | Path `.' Id
@@ -617,7 +618,7 @@ object Parsers {
617618
termIdent()
618619
else if (in.token == THIS) {
619620
in.nextToken()
620-
This(tpnme.EMPTY)
621+
This(EmptyTypeIdent)
621622
}
622623
else if (in.token == LBRACE)
623624
if (inPattern) Block(Nil, inBraces(pattern()))
@@ -2145,7 +2146,7 @@ object Parsers {
21452146
val first = expr1()
21462147
if (in.token == ARROW) {
21472148
first match {
2148-
case Typed(tree @ This(tpnme.EMPTY), tpt) =>
2149+
case Typed(tree @ This(EmptyTypeIdent), tpt) =>
21492150
self = makeSelfDef(nme.WILDCARD, tpt).withPos(first.pos)
21502151
case _ =>
21512152
val ValDef(name, tpt, _) = convertToParam(first, expected = "self type clause")

src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
127127
homogenize(tp) match {
128128
case tp: TypeType =>
129129
toTextRHS(tp)
130-
case tp: TermRef if !tp.denotationIsCurrent || tp.symbol.is(Module) || tp.symbol.name.isImportName =>
130+
case tp: TermRef
131+
if !tp.denotationIsCurrent && !homogenizedView || // always print underyling when testing picklers
132+
tp.symbol.is(Module) ||
133+
tp.symbol.name.isImportName =>
131134
toTextRef(tp) ~ ".type"
132135
case tp: TermRef if tp.denot.isOverloaded =>
133136
"<overloaded " ~ toTextRef(tp) ~ ">"

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,10 @@ object Erasure extends TypeTestsCasts{
352352
assignType(untpd.cpy.Select(tree)(qual, tree.name.primitiveArrayOp), qual)
353353

354354
def adaptIfSuper(qual: Tree): Tree = qual match {
355-
case Super(thisQual, tpnme.EMPTY) =>
355+
case Super(thisQual, untpd.EmptyTypeIdent) =>
356356
val SuperType(thisType, supType) = qual.tpe
357357
if (sym.owner is Flags.Trait)
358-
cpy.Super(qual)(thisQual, sym.owner.asClass.name)
358+
cpy.Super(qual)(thisQual, untpd.Ident(sym.owner.asClass.name))
359359
.withType(SuperType(thisType, sym.owner.typeRef))
360360
else
361361
qual.withType(SuperType(thisType, thisType.firstParent))

src/dotty/tools/dotc/transform/SuperAccessors.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,15 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
106106
ctx.error(s"super not allowed here: use this.${sel.name.decode} instead", sel.pos)
107107
else if (sym is Deferred) {
108108
val member = sym.overridingSymbol(clazz)
109-
if (mix != tpnme.EMPTY ||
109+
if (!mix.name.isEmpty ||
110110
!member.exists ||
111111
!((member is AbsOverride) && member.isIncompleteIn(clazz)))
112112
ctx.error(
113113
i"${sym.showLocated} is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'",
114114
sel.pos)
115115
else ctx.log(i"ok super $sel ${sym.showLocated} $member $clazz ${member.isIncompleteIn(clazz)}")
116116
}
117-
else if (mix == tpnme.EMPTY && !(sym.owner is Trait))
117+
else if (mix.name.isEmpty && !(sym.owner is Trait))
118118
// SI-4989 Check if an intermediate class between `clazz` and `sym.owner` redeclares the method as abstract.
119119
for (intermediateClass <- clazz.info.baseClasses.tail.takeWhile(_ != sym.owner)) {
120120
val overriding = sym.overridingSymbol(intermediateClass)
@@ -124,7 +124,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
124124
sel.pos)
125125

126126
}
127-
if (name.isTermName && mix == tpnme.EMPTY &&
127+
if (name.isTermName && mix.name.isEmpty &&
128128
((clazz is Trait) || clazz != ctx.owner.enclosingClass || !validCurrentClass))
129129
superAccessorCall(sel)(ctx.withPhase(thisTransformer.next))
130130
else sel

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ trait TypeAssigner {
282282
}
283283

284284
def assignType(tree: untpd.This)(implicit ctx: Context) = {
285-
val cls = qualifyingClass(tree, tree.qual, packageOK = false)
285+
val cls = qualifyingClass(tree, tree.qual.name, packageOK = false)
286286
tree.withType(cls.thisType)
287287
}
288288

@@ -291,7 +291,7 @@ trait TypeAssigner {
291291
val qtype @ ThisType(_) = qual.tpe
292292
val cls = qtype.cls
293293

294-
def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix) match {
294+
def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix.name) match {
295295
case p :: Nil =>
296296
p
297297
case Nil =>

0 commit comments

Comments
 (0)