aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-11-21 10:22:07 +0100
committerMartin Odersky <odersky@gmail.com>2016-11-21 10:22:07 +0100
commit7f0637ce073131d8603c567329885e4443cd48d5 (patch)
treef94fa7e704b901d51fec272176090e174ffbb106 /src
parent5c7617b006fe4446a105b3db4916956a92826304 (diff)
downloaddotty-7f0637ce073131d8603c567329885e4443cd48d5.tar.gz
dotty-7f0637ce073131d8603c567329885e4443cd48d5.tar.bz2
dotty-7f0637ce073131d8603c567329885e4443cd48d5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/backend/jvm/DottyBackendInterface.scala4
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala2
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala14
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala7
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala8
-rw-r--r--src/dotty/tools/dotc/core/tasty/TastyFormat.scala25
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreePickler.scala13
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala13
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala27
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala5
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala4
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala6
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala4
13 files changed, 79 insertions, 53 deletions
diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 03c4315fe..a7c449947 100644
--- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -973,7 +973,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
object This extends ThisDeconstructor {
- def get = field.qual
+ def get = field.qual.name
def apply(s: Symbol): This = tpd.This(s.asClass)
}
@@ -1020,7 +1020,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
object Super extends SuperDeconstructor {
def _1: Tree = field.qual
- def _2: Name = field.mix
+ def _2: Name = field.mix.name
}
object ArrayValue extends ArrayValueDeconstructor {
def _1: Type = field.tpe match {
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 3c510c7b9..8f9c42e21 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -340,7 +340,7 @@ object desugar {
val isDefinedMeth = syntheticProperty(nme.isDefined, Literal(Constant(true)))
val caseParams = constrVparamss.head.toArray
val productElemMeths = for (i <- 0 until arity) yield
- syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeName), caseParams(i).name))
+ syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeIdent), caseParams(i).name))
def isRepeated(tree: Tree): Boolean = tree match {
case PostfixOp(_, nme.raw.STAR) => true
case ByNameTypeTree(tree1) => isRepeated(tree1)
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 78ac66812..2801bcae2 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -159,7 +159,7 @@ object Trees {
/** Does this tree define a new symbol that is not defined elsewhere? */
def isDef: Boolean = false
- /** Is this tree either the empty tree or the empty ValDef? */
+ /** Is this tree either the empty tree or the empty ValDef or an empty type ident? */
def isEmpty: Boolean = false
/** Convert tree to a list. Gives a singleton list, except
@@ -353,7 +353,7 @@ object Trees {
}
/** qual.this */
- case class This[-T >: Untyped] private[ast] (qual: TypeName)
+ case class This[-T >: Untyped] private[ast] (qual: untpd.Ident)
extends DenotingTree[T] with TermTree[T] {
type ThisTree[-T >: Untyped] = This[T]
// Denotation of a This tree is always the underlying class; needs correction for modules.
@@ -368,7 +368,7 @@ object Trees {
}
/** C.super[mix], where qual = C.this */
- case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: TypeName)
+ case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: untpd.Ident)
extends ProxyTree[T] with TermTree[T] {
type ThisTree[-T >: Untyped] = Super[T]
def forwardTo = qual
@@ -890,12 +890,12 @@ object Trees {
case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
case _ => finalize(tree, untpd.Select(qualifier, name))
}
- def This(tree: Tree)(qual: TypeName): This = tree match {
- case tree: This if qual == tree.qual => tree
+ def This(tree: Tree)(qual: untpd.Ident): This = tree match {
+ case tree: This if qual eq tree.qual => tree
case _ => finalize(tree, untpd.This(qual))
}
- def Super(tree: Tree)(qual: Tree, mix: TypeName): Super = tree match {
- case tree: Super if (qual eq tree.qual) && (mix == tree.mix) => tree
+ def Super(tree: Tree)(qual: Tree, mix: untpd.Ident): Super = tree match {
+ case tree: Super if (qual eq tree.qual) && (mix eq tree.mix) => tree
case _ => finalize(tree, untpd.Super(qual, mix))
}
def Apply(tree: Tree)(fun: Tree, args: List[Tree])(implicit ctx: Context): Apply = tree match {
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 09f2099d2..219d6d4ec 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -31,11 +31,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
untpd.Select(qualifier, tp.name).withType(tp)
def This(cls: ClassSymbol)(implicit ctx: Context): This =
- untpd.This(cls.name).withType(cls.thisType)
+ untpd.This(untpd.Ident(cls.name)).withType(cls.thisType)
- def Super(qual: Tree, mix: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
+ def Super(qual: Tree, mix: untpd.Ident, inConstrCall: Boolean, mixinClass: Symbol)(implicit ctx: Context): Super =
ta.assignType(untpd.Super(qual, mix), qual, inConstrCall, mixinClass)
+ def Super(qual: Tree, mixName: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
+ Super(qual, if (mixName.isEmpty) untpd.EmptyTypeIdent else untpd.Ident(mixName), inConstrCall, mixinClass)
+
def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply =
ta.assignType(untpd.Apply(fn, args), fn, args)
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index ac35ad09c..6c5210287 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -80,6 +80,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree
+ @sharable object EmptyTypeIdent extends Ident(tpnme.EMPTY) with WithoutTypeOrPos[Untyped] {
+ override def isEmpty = true
+ }
+
/** A block arising from a right-associative infix operation, where, e.g.
*
* a +: b
@@ -225,8 +229,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def BackquotedIdent(name: Name): BackquotedIdent = new BackquotedIdent(name)
def Select(qualifier: Tree, name: Name): Select = new Select(qualifier, name)
def SelectWithSig(qualifier: Tree, name: Name, sig: Signature): Select = new SelectWithSig(qualifier, name, sig)
- def This(qual: TypeName): This = new This(qual)
- def Super(qual: Tree, mix: TypeName): Super = new Super(qual, mix)
+ def This(qual: Ident): This = new This(qual)
+ def Super(qual: Tree, mix: Ident): Super = new Super(qual, mix)
def Apply(fun: Tree, args: List[Tree]): Apply = new Apply(fun, args)
def TypeApply(fun: Tree, args: List[Tree]): TypeApply = new TypeApply(fun, args)
def Literal(const: Constant): Literal = new Literal(const)
diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index 5e84c7428..cb1b56c3c 100644
--- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -73,8 +73,9 @@ Standard-Section: "ASTs" TopLevelStat*
Application
IDENT NameRef Type // used when term ident’s type is not a TermRef
SELECT possiblySigned_NameRef qual_Term
+ QUALTHIS typeIdent_Tree
NEW cls_Type
- SUPER Length this_Term mixinTrait_Type?
+ SUPER Length this_Term mixinTypeIdent_Tree?
TYPED Length expr_Term ascription_Type
NAMEDARG Length paramName_NameRef arg_Term
ASSIGN Length lhs_Term rhs_Term
@@ -279,16 +280,17 @@ object TastyFormat {
final val RENAMED = 79
final val THIS = 96
- final val CLASSconst = 97
- final val ENUMconst = 98
- final val BYNAMEtype = 99
- final val BYNAMEtpt = 100
- final val NEW = 101
- final val IMPLICITarg = 102
- final val PRIVATEqualified = 103
- final val PROTECTEDqualified = 104
- final val RECtype = 105
- final val SINGLETONtpt = 106
+ final val QUALTHIS = 97
+ final val CLASSconst = 98
+ final val ENUMconst = 99
+ final val BYNAMEtype = 100
+ final val BYNAMEtpt = 101
+ final val NEW = 102
+ final val IMPLICITarg = 103
+ final val PRIVATEqualified = 104
+ final val PROTECTEDqualified = 105
+ final val RECtype = 106
+ final val SINGLETONtpt = 107
final val IDENT = 112
final val IDENTtpt = 113
@@ -506,6 +508,7 @@ object TastyFormat {
case TEMPLATE => "TEMPLATE"
case SELFDEF => "SELFDEF"
case THIS => "THIS"
+ case QUALTHIS => "QUALTHIS"
case SUPER => "SUPER"
case CLASSconst => "CLASSconst"
case ENUMconst => "ENUMconst"
diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 279ab5026..80270aa25 100644
--- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -360,8 +360,13 @@ class TreePickler(pickler: TastyPickler) {
pickleName(name)
pickleType(tree.tpe)
}
- case This(_) =>
- pickleType(tree.tpe)
+ case This(qual) =>
+ if (qual.isEmpty) pickleType(tree.tpe)
+ else {
+ writeByte(QUALTHIS)
+ val ThisType(tref) = tree.tpe
+ pickleTree(qual.withType(tref))
+ }
case Select(qual, name) =>
writeByte(if (name.isTypeName) SELECTtpt else SELECT)
val realName = tree.tpe match {
@@ -396,8 +401,8 @@ class TreePickler(pickler: TastyPickler) {
withLength {
pickleTree(qual);
if (!mix.isEmpty) {
- val SuperType(_, mixinType) = tree.tpe
- pickleType(mixinType)
+ val SuperType(_, mixinType: TypeRef) = tree.tpe
+ pickleTree(mix.withType(mixinType))
}
}
case New(tpt) =>
diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index 1f0bbca19..eba9ab533 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -885,6 +885,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable))
}
+ def readQualId(): (untpd.Ident, TypeRef) = {
+ val qual = readTerm().asInstanceOf[untpd.Ident]
+ (untpd.Ident(qual.name).withPos(qual.pos), qual.tpe.asInstanceOf[TypeRef])
+ }
+
def readSimpleTerm(): Tree = tag match {
case SHARED =>
forkAt(readAddr()).readTerm()
@@ -902,6 +907,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
case SELECTtpt =>
val name = readName().toTypeName
completeSelect(name, TypeRef(_, name))
+ case QUALTHIS =>
+ val (qual, tref) = readQualId()
+ untpd.This(qual).withType(ThisType.raw(tref))
case NEW =>
New(readTpt())
case SINGLETONtpt =>
@@ -933,9 +941,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
(tag: @switch) match {
case SUPER =>
val qual = readTerm()
- val mixClass = ifBefore(end)(readType().typeSymbol, NoSymbol)
- val mixName = if (mixClass.exists) mixClass.name.asTypeName else tpnme.EMPTY
- tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass)
+ val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
+ tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol)
case APPLY =>
val fn = readTerm()
val isJava = fn.symbol.is(JavaDefined)
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index e0c6be8c8..68d7e1a53 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -527,27 +527,28 @@ object Parsers {
*/
def path(thisOK: Boolean, finish: Tree => Tree = id): Tree = {
val start = in.offset
- def handleThis(name: TypeName) = {
+ def handleThis(qual: Ident) = {
in.nextToken()
- val t = atPos(start) { This(name) }
+ val t = atPos(start) { This(qual) }
if (!thisOK && in.token != DOT) syntaxError("`.' expected")
dotSelectors(t, finish)
}
- def handleSuper(name: TypeName) = {
+ def handleSuper(qual: Ident) = {
in.nextToken()
val mix = mixinQualifierOpt()
- val t = atPos(start) { Super(This(name), mix) }
+ val t = atPos(start) { Super(This(qual), mix) }
accept(DOT)
dotSelectors(selector(t), finish)
}
- if (in.token == THIS) handleThis(tpnme.EMPTY)
- else if (in.token == SUPER) handleSuper(tpnme.EMPTY)
+ if (in.token == THIS) handleThis(EmptyTypeIdent)
+ else if (in.token == SUPER) handleSuper(EmptyTypeIdent)
else {
val t = termIdent()
if (in.token == DOT) {
+ def qual = cpy.Ident(t)(t.name.toTypeName)
in.nextToken()
- if (in.token == THIS) handleThis(t.name.toTypeName)
- else if (in.token == SUPER) handleSuper(t.name.toTypeName)
+ if (in.token == THIS) handleThis(qual)
+ else if (in.token == SUPER) handleSuper(qual)
else selectors(t, finish)
}
else t
@@ -556,9 +557,9 @@ object Parsers {
/** MixinQualifier ::= `[' Id `]'
*/
- def mixinQualifierOpt(): TypeName =
- if (in.token == LBRACKET) inBrackets(ident().toTypeName)
- else tpnme.EMPTY
+ def mixinQualifierOpt(): Ident =
+ if (in.token == LBRACKET) inBrackets(atPos(in.offset) { typeIdent() })
+ else EmptyTypeIdent
/** StableId ::= Id
* | Path `.' Id
@@ -617,7 +618,7 @@ object Parsers {
termIdent()
else if (in.token == THIS) {
in.nextToken()
- This(tpnme.EMPTY)
+ This(EmptyTypeIdent)
}
else if (in.token == LBRACE)
if (inPattern) Block(Nil, inBraces(pattern()))
@@ -2145,7 +2146,7 @@ object Parsers {
val first = expr1()
if (in.token == ARROW) {
first match {
- case Typed(tree @ This(tpnme.EMPTY), tpt) =>
+ case Typed(tree @ This(EmptyTypeIdent), tpt) =>
self = makeSelfDef(nme.WILDCARD, tpt).withPos(first.pos)
case _ =>
val ValDef(name, tpt, _) = convertToParam(first, expected = "self type clause")
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 06d44e301..4894fa019 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -127,7 +127,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
homogenize(tp) match {
case tp: TypeType =>
toTextRHS(tp)
- case tp: TermRef if !tp.denotationIsCurrent || tp.symbol.is(Module) || tp.symbol.name.isImportName =>
+ case tp: TermRef
+ if !tp.denotationIsCurrent && !homogenizedView || // always print underyling when testing picklers
+ tp.symbol.is(Module) ||
+ tp.symbol.name.isImportName =>
toTextRef(tp) ~ ".type"
case tp: TermRef if tp.denot.isOverloaded =>
"<overloaded " ~ toTextRef(tp) ~ ">"
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index a503d55e5..069176111 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -352,10 +352,10 @@ object Erasure extends TypeTestsCasts{
assignType(untpd.cpy.Select(tree)(qual, tree.name.primitiveArrayOp), qual)
def adaptIfSuper(qual: Tree): Tree = qual match {
- case Super(thisQual, tpnme.EMPTY) =>
+ case Super(thisQual, untpd.EmptyTypeIdent) =>
val SuperType(thisType, supType) = qual.tpe
if (sym.owner is Flags.Trait)
- cpy.Super(qual)(thisQual, sym.owner.asClass.name)
+ cpy.Super(qual)(thisQual, untpd.Ident(sym.owner.asClass.name))
.withType(SuperType(thisType, sym.owner.typeRef))
else
qual.withType(SuperType(thisType, thisType.firstParent))
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 10be6db65..fea478c9b 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -106,7 +106,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
ctx.error(s"super not allowed here: use this.${sel.name.decode} instead", sel.pos)
else if (sym is Deferred) {
val member = sym.overridingSymbol(clazz)
- if (mix != tpnme.EMPTY ||
+ if (!mix.name.isEmpty ||
!member.exists ||
!((member is AbsOverride) && member.isIncompleteIn(clazz)))
ctx.error(
@@ -114,7 +114,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
sel.pos)
else ctx.log(i"ok super $sel ${sym.showLocated} $member $clazz ${member.isIncompleteIn(clazz)}")
}
- else if (mix == tpnme.EMPTY && !(sym.owner is Trait))
+ else if (mix.name.isEmpty && !(sym.owner is Trait))
// SI-4989 Check if an intermediate class between `clazz` and `sym.owner` redeclares the method as abstract.
for (intermediateClass <- clazz.info.baseClasses.tail.takeWhile(_ != sym.owner)) {
val overriding = sym.overridingSymbol(intermediateClass)
@@ -124,7 +124,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
sel.pos)
}
- if (name.isTermName && mix == tpnme.EMPTY &&
+ if (name.isTermName && mix.name.isEmpty &&
((clazz is Trait) || clazz != ctx.owner.enclosingClass || !validCurrentClass))
superAccessorCall(sel)(ctx.withPhase(thisTransformer.next))
else sel
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 1599d95e6..ee2d68278 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -282,7 +282,7 @@ trait TypeAssigner {
}
def assignType(tree: untpd.This)(implicit ctx: Context) = {
- val cls = qualifyingClass(tree, tree.qual, packageOK = false)
+ val cls = qualifyingClass(tree, tree.qual.name, packageOK = false)
tree.withType(cls.thisType)
}
@@ -291,7 +291,7 @@ trait TypeAssigner {
val qtype @ ThisType(_) = qual.tpe
val cls = qtype.cls
- def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix) match {
+ def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix.name) match {
case p :: Nil =>
p
case Nil =>