Skip to content

Towards correct positions in TASTY types #1634

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 10 commits into from
Nov 21, 2016
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
4 changes: 2 additions & 2 deletions docs/syntax-summary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ grammar.
SimpleExpr1 ::= Literal
| Path
| `_'
| `(' ExprsInParens `)' Parens(exprs)
| `(' ExprsInParens2 `)' Parens(exprs)
| SimpleExpr `.' id Select(expr, id)
| SimpleExpr (TypeArgs | NamedTypeArgs) TypeApply(expr, args)
| SimpleExpr1 ArgumentExprs Apply(expr, args)
Expand Down Expand Up @@ -210,7 +210,7 @@ grammar.
| SimplePattern1 `.' id
PatVar ::= varid
| `_'
Patterns ::= Pattern [`,' Pattern]
Patterns ::= Pattern {`,' Pattern}
ArgumentPatterns ::= `(' [Patterns] `)' Apply(fn, pats)
| `(' [Patterns `,'] Pattern2 `:' `_' `*' ')

Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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 {
Expand Down
7 changes: 3 additions & 4 deletions src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ object desugar {
if (tdef.mods is PrivateLocalParam) {
val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner))
.withMods(tdef.mods &~ PrivateLocal | ExpandedName)
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam), tparams = Nil)
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam))
.withMods(tdef.mods & VarianceFlags | PrivateLocalParamAccessor | Synthetic)
Thicket(tparam, alias)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -461,8 +461,7 @@ object desugar {
val vparamAccessors = derivedVparamss.flatten.map(_.withMods(originalVparams.next.mods | caseAccessor))
cpy.TypeDef(cdef)(
rhs = cpy.Template(impl)(constr, parents1, self1,
tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths),
tparams = Nil)
tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths))
}

// install the watch on classTycon
Expand Down
17 changes: 11 additions & 6 deletions src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,12 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
case mdef: ValOrDefDef =>
mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
case mdef: TypeDef =>
mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
def isBounds(rhs: Tree): Boolean = rhs match {
case _: TypeBoundsTree => true
case PolyTypeTree(_, body) => isBounds(body)
case _ => false
}
mdef.rhs.isEmpty || isBounds(mdef.rhs)
case _ => false
}

Expand Down Expand Up @@ -382,9 +387,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
def isIdempotentRef(tree: Tree)(implicit ctx: Context) =
refPurity(tree) >= Idempotent

/** If `tree` is a constant expression, its value as a Literal,
/** If `tree` is a constant expression, its value as a Literal,
* or `tree` itself otherwise.
*
*
* Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose.
* Example
*
Expand All @@ -410,11 +415,11 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
*
* Revisit this issue once we have implemented `inline`. Then we can demand
* purity of the prefix unless the selection goes to an inline val.
*
*
* Note: This method should be applied to all term tree nodes that are not literals,
* that can be idempotent, and that can have constant types. So far, only nodes
* of the following classes qualify:
*
* of the following classes qualify:
*
* Ident
* Select
* TypeApply
Expand Down
41 changes: 17 additions & 24 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ object Trees {
with Cloneable {

if (Stats.enabled) ntrees += 1

private def nxId = {
nextId += 1
//assert(nextId != 199, this)
nextId
nextId
}

/** A unique identifier for this tree. Used for debugging, and potentially
* tracking presentation compiler interactions
*/
private var myUniqueId: Int = nxId

def uniqueId = myUniqueId

/** The type constructor at the root of the tree */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -192,7 +192,7 @@ object Trees {

override def hashCode(): Int = uniqueId // for debugging; was: System.identityHashCode(this)
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]

override def clone: Tree[T] = {
val tree = super.clone.asInstanceOf[Tree[T]]
tree.myUniqueId = nxId
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -653,12 +653,6 @@ object Trees {

/** Is this a definition of a class? */
def isClassDef = rhs.isInstanceOf[Template[_]]

/** If this a non-class type definition, its type parameters.
* Can be different from Nil only for PolyTypeDefs, which are always
* untyped and get eliminated during desugaring.
*/
def tparams: List[untpd.TypeDef] = Nil
}

/** extends parents { self => body } */
Expand Down Expand Up @@ -896,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 {
Expand Down Expand Up @@ -1023,9 +1017,9 @@ object Trees {
case tree: DefDef if (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.unforcedRhs) => tree
case _ => finalize(tree, untpd.DefDef(name, tparams, vparamss, tpt, rhs))
}
def TypeDef(tree: Tree)(name: TypeName, rhs: Tree, tparams: List[untpd.TypeDef]): TypeDef = tree match {
case tree: TypeDef if (name == tree.name) && (rhs eq tree.rhs) && (tparams eq tree.tparams) => tree
case _ => finalize(tree, untpd.TypeDef(name, tparams, rhs))
def TypeDef(tree: Tree)(name: TypeName, rhs: Tree): TypeDef = tree match {
case tree: TypeDef if (name == tree.name) && (rhs eq tree.rhs) => tree
case _ => finalize(tree, untpd.TypeDef(name, rhs))
}
def Template(tree: Tree)(constr: DefDef, parents: List[Tree], self: ValDef, body: LazyTreeList): Template = tree match {
case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.unforcedBody) => tree
Expand Down Expand Up @@ -1064,8 +1058,8 @@ object Trees {
ValDef(tree: Tree)(name, tpt, rhs)
def DefDef(tree: DefDef)(name: TermName = tree.name, tparams: List[TypeDef] = tree.tparams, vparamss: List[List[ValDef]] = tree.vparamss, tpt: Tree = tree.tpt, rhs: LazyTree = tree.unforcedRhs): DefDef =
DefDef(tree: Tree)(name, tparams, vparamss, tpt, rhs)
def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs, tparams: List[untpd.TypeDef] = tree.tparams): TypeDef =
TypeDef(tree: Tree)(name, rhs, tparams)
def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs): TypeDef =
TypeDef(tree: Tree)(name, rhs)
def Template(tree: Template)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody): Template =
Template(tree: Tree)(constr, parents, self, body)
}
Expand Down Expand Up @@ -1146,7 +1140,7 @@ object Trees {
case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(tree.rhs))
case tree @ TypeDef(name, rhs) =>
cpy.TypeDef(tree)(name, transform(rhs), tree.tparams)
cpy.TypeDef(tree)(name, transform(rhs))
case tree @ Template(constr, parents, self, _) =>
cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(tree.body))
case Import(expr, selectors) =>
Expand Down Expand Up @@ -1294,7 +1288,6 @@ object Trees {
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)(newName.asTypeName, tree.tparams, tree.rhs).withMods(tree.rawMods)
case tree: TypeDef => cpy.TypeDef(tree)(name = newName.asTypeName)
}
}.asInstanceOf[tree.ThisTree[T]]
Expand Down
17 changes: 12 additions & 5 deletions src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -133,14 +136,18 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree =
ta.assignType(untpd.OrTypeTree(left, right), left, right)

// RefinedTypeTree is missing, handled specially in Typer and Unpickler.
def RefinedTypeTree(parent: Tree, refinements: List[Tree], refineCls: ClassSymbol)(implicit ctx: Context): Tree =
ta.assignType(untpd.RefinedTypeTree(parent, refinements), parent, refinements, refineCls)

def AppliedTypeTree(tycon: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree =
ta.assignType(untpd.AppliedTypeTree(tycon, args), tycon, args)

def ByNameTypeTree(result: Tree)(implicit ctx: Context): ByNameTypeTree =
ta.assignType(untpd.ByNameTypeTree(result), result)

def PolyTypeTree(tparams: List[TypeDef], body: Tree)(implicit ctx: Context): PolyTypeTree =
ta.assignType(untpd.PolyTypeTree(tparams, body), tparams, body)

def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
ta.assignType(untpd.TypeBoundsTree(lo, hi), lo, hi)

Expand Down Expand Up @@ -306,8 +313,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case _ =>
false
}
typeIsElidable ||
tp.symbol.is(JavaStatic) ||
typeIsElidable ||
tp.symbol.is(JavaStatic) ||
tp.symbol.hasAnnotation(defn.ScalaStaticAnnot)
}

Expand Down
29 changes: 8 additions & 21 deletions src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ 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

class PolyTypeDef(name: TypeName, override val tparams: List[TypeDef], rhs: Tree)
extends TypeDef(name, rhs)
@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.
*
Expand Down Expand Up @@ -228,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)
Expand Down Expand Up @@ -310,9 +311,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

def TypeTree(tpe: Type)(implicit ctx: Context): TypedSplice = TypedSplice(TypeTree().withTypeUnchecked(tpe))

def TypeDef(name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef =
if (tparams.isEmpty) TypeDef(name, rhs) else new PolyTypeDef(name, tparams, rhs)

def unitLiteral = Literal(Constant(()))

def ref(tp: NamedType)(implicit ctx: Context): Tree =
Expand Down Expand Up @@ -348,6 +346,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def makeSyntheticParameter(n: Int = 1, tpt: Tree = TypeTree())(implicit ctx: Context): ValDef =
ValDef(nme.syntheticParamName(n), tpt, EmptyTree).withFlags(SyntheticTermParam)

def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context) =
if (tparams.isEmpty) tpt else PolyTypeTree(tparams, tpt)

/** A reference to given definition. If definition is a repeated
* parameter, the reference will be a repeated argument.
*/
Expand Down Expand Up @@ -392,10 +393,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
case _ => untpd.ParsedTry(expr, handler, finalizer).withPos(tree.pos)
}
def PolyTypeDef(tree: Tree)(name: TypeName, tparams: List[TypeDef], rhs: Tree) = tree match {
case tree: PolyTypeDef if (name eq tree.name) && (tparams eq tree.tparams) && (rhs eq tree.rhs) => tree
case _ => new PolyTypeDef(name, tparams, rhs).withPos(tree.pos)
}
def SymbolLit(tree: Tree)(str: String) = tree match {
case tree: SymbolLit if str == tree.str => tree
case _ => untpd.SymbolLit(str).withPos(tree.pos)
Expand Down Expand Up @@ -506,8 +503,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.ContextBounds(tree)(transformSub(bounds), transform(cxBounds))
case PatDef(mods, pats, tpt, rhs) =>
cpy.PatDef(tree)(mods, transform(pats), transform(tpt), transform(rhs))
case tree: PolyTypeDef =>
cpy.PolyTypeDef(tree)(tree.name, transformSub(tree.tparams), transform(tree.rhs))
case _ =>
super.transform(tree)
}
Expand Down Expand Up @@ -553,8 +548,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(this(x, bounds), cxBounds)
case PatDef(mods, pats, tpt, rhs) =>
this(this(this(x, pats), tpt), rhs)
case tree: PolyTypeDef =>
this(this(x, tree.tparams), tree.rhs)
case TypedSplice(tree) =>
this(x, tree)
case _ =>
Expand All @@ -566,10 +559,4 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
class UntypedDeepFolder[X](f: (X, Tree) => X) extends UntypedTreeAccumulator[X] {
def apply(x: X, tree: Tree)(implicit ctx: Context): X = foldOver(f(x, tree), tree)
}

override def rename(tree: NameTree, newName: Name)(implicit ctx: Context): tree.ThisTree[Untyped] = tree match {
case t: PolyTypeDef =>
cpy.PolyTypeDef(t)(newName.asTypeName, t.tparams, t.rhs).asInstanceOf[tree.ThisTree[Untyped]]
case _ => super.rename(tree, newName)
}
}
8 changes: 4 additions & 4 deletions src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,9 @@ class Definitions {
name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit)
}

def isBottomClass(cls: Symbol) =
def isBottomClass(cls: Symbol) =
cls == NothingClass || cls == NullClass
def isBottomType(tp: Type) =
def isBottomType(tp: Type) =
tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)

def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
Expand Down Expand Up @@ -785,8 +785,8 @@ class Definitions {
if (!_isInitialized) {
// force initialization of every symbol that is synthesized or hijacked by the compiler
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
// Enter all symbols from the scalaShadowing package in the scala package

// Enter all symbols from the scalaShadowing package in the scala package
for (m <- ScalaShadowingPackageClass.info.decls)
ScalaPackageClass.enter(m)

Expand Down
Loading