Skip to content

Simplify trees #1538

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 5 commits into from
Sep 26, 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
2 changes: 1 addition & 1 deletion docs/SyntaxSummary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ grammar.
WithType ::= AnnotType {`with' AnnotType} (deprecated)
AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
SimpleType ::= SimpleType (TypeArgs | NamedTypeArgs) AppliedTypeTree(t, args)
| SimpleType `#' id SelectFromTypeTree(t, name)
| SimpleType `#' id Select(t, name)
| StableId
| Path `.' `type' SingletonTypeTree(p)
| `(' ArgTypes ')' Tuple(ts)
Expand Down
35 changes: 9 additions & 26 deletions src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import collection.mutable.ListBuffer
import util.Attachment

object desugar {

/** Are we using the new unboxed pair scheme? */
private final val unboxedPairs = false

import untpd._

/** Tags a .withFilter call generated by desugaring a for expression.
Expand Down Expand Up @@ -923,25 +919,15 @@ object desugar {
case Parens(t) =>
t
case Tuple(ts) =>
if (unboxedPairs) {
def PairTypeTree(l: Tree, r: Tree) =
AppliedTypeTree(ref(defn.PairType), l :: r :: Nil)
if (ctx.mode is Mode.Type) ts.reduceRight(PairTypeTree)
else if (ts.isEmpty) unitLiteral
else ts.reduceRight(Pair(_, _))
}
else {
val arity = ts.length
def tupleTypeRef = defn.TupleType(arity)
if (arity > Definitions.MaxTupleArity) {
ctx.error(s"tuple too long (max allowed: ${Definitions.MaxTupleArity})", tree.pos)
unitLiteral
}
else if (arity == 1) ts.head
else if (ctx.mode is Mode.Type) AppliedTypeTree(ref(tupleTypeRef), ts)
else if (arity == 0) unitLiteral
else Apply(ref(tupleTypeRef.classSymbol.companionModule.valRef), ts)
}
val arity = ts.length
def tupleTypeRef = defn.TupleType(arity)
if (arity > Definitions.MaxTupleArity) {
ctx.error(s"tuple too long (max allowed: ${Definitions.MaxTupleArity})", tree.pos)
unitLiteral
} else if (arity == 1) ts.head
else if (ctx.mode is Mode.Type) AppliedTypeTree(ref(tupleTypeRef), ts)
else if (arity == 0) unitLiteral
else Apply(ref(tupleTypeRef.classSymbol.companionModule.valRef), ts)
case WhileDo(cond, body) =>
// { <label> def while$(): Unit = if (cond) { body; while$() } ; while$() }
val call = Apply(Ident(nme.WHILE_PREFIX), Nil)
Expand Down Expand Up @@ -1048,9 +1034,6 @@ object desugar {
add(id, TypeTree())
case Apply(_, args) =>
args foreach collect
case Pair(left, right) =>
collect(left)
collect(right)
case Typed(expr, _) =>
collect(expr)
case NamedArg(_, arg) =>
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
case OrTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind])
case AppliedTypeTree(tpt, args) => mayBeTypePat(tpt) || args.exists(_.isInstanceOf[Bind])
case SelectFromTypeTree(tpt, _) => mayBeTypePat(tpt)
case Select(tpt, _) => mayBeTypePat(tpt)
case Annotated(tpt, _) => mayBeTypePat(tpt)
case _ => false
}
Expand Down
41 changes: 2 additions & 39 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ object Trees {
override def toString = s"BackquotedIdent($name)"
}

/** qualifier.name */
/** qualifier.name, or qualifier#name, if qualifier is a type */
case class Select[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Select[T]
Expand Down Expand Up @@ -428,15 +428,6 @@ object Trees {
type ThisTree[-T >: Untyped] = New[T]
}

/** (left, right) */
case class Pair[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Pair[T]
override def isTerm = left.isTerm && right.isTerm
override def isType = left.isType && right.isType
override def isPattern = !isTerm && (left.isPattern || left.isTerm) && (right.isPattern || right.isTerm)
}

/** expr : tpt */
case class Typed[-T >: Untyped] private[ast] (expr: Tree[T], tpt: Tree[T])
extends ProxyTree[T] with TermTree[T] {
Expand Down Expand Up @@ -558,15 +549,6 @@ object Trees {
type ThisTree[-T >: Untyped] = SingletonTypeTree[T]
}

/** qualifier # name
* In Scala, this always refers to a type, but in a Java
* compilation unit this might refer to a term.
*/
case class SelectFromTypeTree[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = SelectFromTypeTree[T]
}

/** left & right */
case class AndTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
Expand Down Expand Up @@ -694,7 +676,7 @@ object Trees {

/** import expr.selectors
* where a selector is either an untyped `Ident`, `name` or
* an untyped `Pair` `name => rename`
* an untyped thicket consisting of `name` and `rename`.
*/
case class Import[-T >: Untyped] private[ast] (expr: Tree[T], selectors: List[Tree[Untyped]])
extends DenotingTree[T] {
Expand Down Expand Up @@ -836,7 +818,6 @@ object Trees {
type TypeApply = Trees.TypeApply[T]
type Literal = Trees.Literal[T]
type New = Trees.New[T]
type Pair = Trees.Pair[T]
type Typed = Trees.Typed[T]
type NamedArg = Trees.NamedArg[T]
type Assign = Trees.Assign[T]
Expand All @@ -851,7 +832,6 @@ object Trees {
type JavaSeqLiteral = Trees.JavaSeqLiteral[T]
type TypeTree = Trees.TypeTree[T]
type SingletonTypeTree = Trees.SingletonTypeTree[T]
type SelectFromTypeTree = Trees.SelectFromTypeTree[T]
type AndTypeTree = Trees.AndTypeTree[T]
type OrTypeTree = Trees.OrTypeTree[T]
type RefinedTypeTree = Trees.RefinedTypeTree[T]
Expand Down Expand Up @@ -955,10 +935,6 @@ object Trees {
case tree: New if tpt eq tree.tpt => tree
case _ => finalize(tree, untpd.New(tpt))
}
def Pair(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): Pair = tree match {
case tree: Pair if (left eq tree.left) && (right eq tree.right) => tree
case _ => finalize(tree, untpd.Pair(left, right))
}
def Typed(tree: Tree)(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed = tree match {
case tree: Typed if (expr eq tree.expr) && (tpt eq tree.tpt) => tree
case _ => finalize(tree, untpd.Typed(expr, tpt))
Expand Down Expand Up @@ -1014,10 +990,6 @@ object Trees {
case tree: SingletonTypeTree if ref eq tree.ref => tree
case _ => finalize(tree, untpd.SingletonTypeTree(ref))
}
def SelectFromTypeTree(tree: Tree)(qualifier: Tree, name: Name): SelectFromTypeTree = tree match {
case tree: SelectFromTypeTree if (qualifier eq tree.qualifier) && (name == tree.name) => tree
case _ => finalize(tree, untpd.SelectFromTypeTree(qualifier, name))
}
def AndTypeTree(tree: Tree)(left: Tree, right: Tree): AndTypeTree = tree match {
case tree: AndTypeTree if (left eq tree.left) && (right eq tree.right) => tree
case _ => finalize(tree, untpd.AndTypeTree(left, right))
Expand Down Expand Up @@ -1132,8 +1104,6 @@ object Trees {
tree
case New(tpt) =>
cpy.New(tree)(transform(tpt))
case Pair(left, right) =>
cpy.Pair(tree)(transform(left), transform(right))
case Typed(expr, tpt) =>
cpy.Typed(tree)(transform(expr), transform(tpt))
case NamedArg(name, arg) =>
Expand All @@ -1160,8 +1130,6 @@ object Trees {
tree
case SingletonTypeTree(ref) =>
cpy.SingletonTypeTree(tree)(transform(ref))
case SelectFromTypeTree(qualifier, name) =>
cpy.SelectFromTypeTree(tree)(transform(qualifier), name)
case AndTypeTree(left, right) =>
cpy.AndTypeTree(tree)(transform(left), transform(right))
case OrTypeTree(left, right) =>
Expand Down Expand Up @@ -1238,8 +1206,6 @@ object Trees {
x
case New(tpt) =>
this(x, tpt)
case Pair(left, right) =>
this(this(x, left), right)
case Typed(expr, tpt) =>
this(this(x, expr), tpt)
case NamedArg(name, arg) =>
Expand All @@ -1266,8 +1232,6 @@ object Trees {
x
case SingletonTypeTree(ref) =>
this(x, ref)
case SelectFromTypeTree(qualifier, name) =>
this(x, qualifier)
case AndTypeTree(left, right) =>
this(this(x, left), right)
case OrTypeTree(left, right) =>
Expand Down Expand Up @@ -1343,7 +1307,6 @@ object Trees {
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)
case tree: SelectFromTypeTree => cpy.SelectFromTypeTree(tree)(tree.qualifier, newName)
}
}.asInstanceOf[tree.ThisTree[T]]
}
Expand Down
20 changes: 3 additions & 17 deletions src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Select(qualifier: Tree, name: Name)(implicit ctx: Context): Select =
ta.assignType(untpd.Select(qualifier, name), qualifier)

def SelectFromTypeTree(qualifier: Tree, name: Name)(implicit ctx: Context): SelectFromTypeTree =
ta.assignType(untpd.SelectFromTypeTree(qualifier, name), qualifier)

def SelectFromTypeTree(qualifier: Tree, tp: NamedType)(implicit ctx: Context): SelectFromTypeTree =
untpd.SelectFromTypeTree(qualifier, tp.name).withType(tp)
def Select(qualifier: Tree, tp: NamedType)(implicit ctx: Context): Select =
untpd.Select(qualifier, tp.name).withType(tp)

def This(cls: ClassSymbol)(implicit ctx: Context): This =
untpd.This(cls.name).withType(cls.thisType)
Expand All @@ -59,9 +56,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {

def New(tp: Type)(implicit ctx: Context): New = New(TypeTree(tp))

def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair =
ta.assignType(untpd.Pair(left, right), left, right)

def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed =
ta.assignType(untpd.Typed(expr, tpt), tpt)

Expand Down Expand Up @@ -336,7 +330,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Ident(tp)
else tp.prefix match {
case pre: SingletonType => followOuterLinks(singleton(pre)).select(tp)
case pre => SelectFromTypeTree(TypeTree(pre), tp)
case pre => Select(TypeTree(pre), tp)
} // no checks necessary

def ref(sym: Symbol)(implicit ctx: Context): Tree =
Expand Down Expand Up @@ -493,14 +487,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
override def New(tree: Tree)(tpt: Tree)(implicit ctx: Context): New =
ta.assignType(untpd.cpy.New(tree)(tpt), tpt)

override def Pair(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): Pair = {
val tree1 = untpd.cpy.Pair(tree)(left, right)
tree match {
case tree: Pair if (left.tpe eq tree.left.tpe) && (right.tpe eq tree.right.tpe) => tree1.withTypeUnchecked(tree.tpe)
case _ => ta.assignType(tree1, left, right)
}
}

override def Typed(tree: Tree)(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed =
ta.assignType(untpd.cpy.Typed(tree)(expr, tpt), tpt)

Expand Down
2 changes: 0 additions & 2 deletions src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def TypeApply(fun: Tree, args: List[Tree]): TypeApply = new TypeApply(fun, args)
def Literal(const: Constant): Literal = new Literal(const)
def New(tpt: Tree): New = new New(tpt)
def Pair(left: Tree, right: Tree): Pair = new Pair(left, right)
def Typed(expr: Tree, tpt: Tree): Typed = new Typed(expr, tpt)
def NamedArg(name: Name, arg: Tree): NamedArg = new NamedArg(name, arg)
def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
Expand All @@ -155,7 +154,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def TypeTree(original: Tree): TypeTree = new TypeTree(original)
def TypeTree() = new TypeTree(EmptyTree)
def SingletonTypeTree(ref: Tree): SingletonTypeTree = new SingletonTypeTree(ref)
def SelectFromTypeTree(qualifier: Tree, name: Name): SelectFromTypeTree = new SelectFromTypeTree(qualifier, name)
def AndTypeTree(left: Tree, right: Tree): AndTypeTree = new AndTypeTree(left, right)
def OrTypeTree(left: Tree, right: Tree): OrTypeTree = new OrTypeTree(left, right)
def RefinedTypeTree(tpt: Tree, refinements: List[Tree]): RefinedTypeTree = new RefinedTypeTree(tpt, refinements)
Expand Down
5 changes: 2 additions & 3 deletions src/dotty/tools/dotc/core/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ Standard-Section: "ASTs" TopLevelStat*
SELECT possiblySigned_NameRef qual_Term
NEW cls_Type
SUPER Length this_Term mixinTrait_Type?
PAIR Length left_Term right_Term
TYPED Length expr_Term ascription_Type
NAMEDARG Length paramName_NameRef arg_Term
ASSIGN Length lhs_Term rhs_Term
Expand Down Expand Up @@ -300,7 +299,8 @@ object TastyFormat {
final val RENAMED = 138
final val APPLY = 139
final val TYPEAPPLY = 140
final val PAIR = 142


final val TYPED = 143
final val NAMEDARG = 144
final val ASSIGN = 145
Expand Down Expand Up @@ -452,7 +452,6 @@ object TastyFormat {
case APPLY => "APPLY"
case TYPEAPPLY => "TYPEAPPLY"
case NEW => "NEW"
case PAIR => "PAIR"
case TYPED => "TYPED"
case NAMEDARG => "NAMEDARG"
case ASSIGN => "ASSIGN"
Expand Down
5 changes: 1 addition & 4 deletions src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,6 @@ class TreePickler(pickler: TastyPickler) {
case New(tpt) =>
writeByte(NEW)
pickleTpt(tpt)
case Pair(left, right) =>
writeByte(PAIR)
withLength { pickleTree(left); pickleTree(right) }
case Typed(expr, tpt) =>
writeByte(TYPED)
withLength { pickleTree(expr); pickleTpt(tpt) }
Expand Down Expand Up @@ -496,7 +493,7 @@ class TreePickler(pickler: TastyPickler) {
withLength {
pickleTree(expr)
selectors foreach {
case Pair(Ident(from), Ident(to)) =>
case Thicket(Ident(from) :: Ident(to) :: Nil) =>
writeByte(RENAMED)
withLength { pickleName(from); pickleName(to) }
case Ident(name) =>
Expand Down
4 changes: 1 addition & 3 deletions src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
case RENAMED =>
readByte()
readEnd()
untpd.Pair(untpd.Ident(readName()), untpd.Ident(readName())) :: readSelectors()
untpd.Thicket(untpd.Ident(readName()), untpd.Ident(readName())) :: readSelectors()
case IMPORTED =>
readByte()
untpd.Ident(readName()) :: readSelectors()
Expand Down Expand Up @@ -915,8 +915,6 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
tpd.Apply(fn, until(end)(readArg()))
case TYPEAPPLY =>
tpd.TypeApply(readTerm(), until(end)(readTpt()))
case PAIR =>
Pair(readTerm(), readTerm())
case TYPED =>
val expr = readTerm()
val tpt = readTpt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
val toName = readNameRef()
val from = untpd.Ident(fromName)
val to = untpd.Ident(toName)
if (toName.isEmpty) from else untpd.Pair(from, untpd.Ident(toName))
if (toName.isEmpty) from else untpd.Thicket(from, untpd.Ident(toName))
})

Import(expr, selectors)
Expand Down Expand Up @@ -1194,7 +1194,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
case SELECTFROMTYPEtree =>
val qualifier = readTreeRef()
val selector = readTypeNameRef()
SelectFromTypeTree(qualifier, symbol.namedType)
Select(qualifier, symbol.namedType)

case COMPOUNDTYPEtree =>
readTemplateRef()
Expand Down
11 changes: 4 additions & 7 deletions src/dotty/tools/dotc/parsing/JavaParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ object JavaParsers {
def convertToTypeId(tree: Tree): Tree = convertToTypeName(tree) match {
case Some(t) => t withPos tree.pos
case _ => tree match {
case AppliedTypeTree(_, _) | SelectFromTypeTree(_, _) =>
case AppliedTypeTree(_, _) | Select(_, _) =>
tree
case _ =>
syntaxError("identifier expected", tree.pos)
Expand Down Expand Up @@ -281,14 +281,11 @@ object JavaParsers {
if (in.token == FINAL) in.nextToken()
if (in.token == IDENTIFIER) {
var t = typeArgs(atPos(in.offset)(Ident(ident())))
// typeSelect generates Select nodes is the lhs is an Ident or Select,
// SelectFromTypeTree otherwise. See #3567.
// Select nodes can be later
// converted in the typechecker to SelectFromTypeTree if the class
// turns out to be an instance ionner class instead of a static inner class.
// typeSelect generates Select nodes if the lhs is an Ident or Select,
// For other nodes it always assumes that the selected item is a type.
def typeSelect(t: Tree, name: Name) = t match {
case Ident(_) | Select(_, _) => Select(t, name)
case _ => SelectFromTypeTree(t, name.toTypeName)
case _ => Select(t, name.toTypeName)
}
while (in.token == DOT) {
in.nextToken()
Expand Down
Loading