aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused')
-rw-r--r--src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused535
1 files changed, 0 insertions, 535 deletions
diff --git a/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused b/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused
deleted file mode 100644
index 672c85179..000000000
--- a/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused
+++ /dev/null
@@ -1,535 +0,0 @@
-package dotty.tools
-package dotc
-package parsing
-
-import core._
-import Flags._, Trees._, TypedTrees._, UntypedTrees._, Names._, StdNames._, NameOps._, Contexts._
-import scala.collection.mutable.ListBuffer
-import util.Positions._, Symbols._, Decorators._, Flags._, Constants._
-import TreeInfo._
-
-/** Methods for building trees, used in the parser. All the trees
- * returned by this class must be untyped.
- * Note: currently unused
- */
-class TreeBuilder(implicit ctx: Context) {
-
- import untpd._
-
- def scalaDot(name: Name): Select =
- Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name)
-
- def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
- def scalaAnyValConstr = scalaDot(tpnme.AnyVal)
- def scalaAnyConstr = scalaDot(tpnme.Any)
- def scalaUnitConstr = scalaDot(tpnme.Unit)
- def productConstr = scalaDot(tpnme.Product)
- def productConstrN(n: Int) = scalaDot(("Product" + n).toTypeName)
- def serializableConstr = scalaDot(tpnme.Serializable)
-
- def convertToTypeName(t: Tree): Tree = ???
-
- private implicit val cpos = NoPosition
-
- /** Convert all occurrences of (lower-case) variables in a pattern as follows:
- * x becomes x @ _
- * x: T becomes x @ (_: T)
- * Also covert all toplevel lower-case type arguments as follows:
- * t becomes t @ _
- */
- private object patvarTransformer extends TreeTransformer {
- override def transform(tree: Tree): Tree = tree match {
- case Ident(name) if isVarPattern(tree) && name != nme.WILDCARD =>
- Bind(
- name, Ident(nme.WILDCARD).withPos(tree.pos.focus)
- ).withPos(tree.pos)
- case Typed(id @ Ident(name), tpt) if isVarPattern(id) && name != nme.WILDCARD =>
- Bind(
- name,
- Typed(
- Ident(nme.WILDCARD).withPos(tree.pos.focus),
- transform(tpt)
- ).withPos(tree.pos.withStart(tree.pos.point))
- ).withPos(tree.pos.withPoint(id.pos.point))
- case Apply(fn @ Apply(_, _), args) =>
- tree.derivedApply(transform(fn), transform(args))
- case Apply(fn, args) =>
- tree.derivedApply(fn, transform(args))
- case Typed(expr, tpt) =>
- tree.derivedTyped(transform(expr), transform(tpt))
- case Bind(name, body) =>
- tree.derivedBind(name, transform(body))
- case AppliedTypeTree(tycon, args) =>
- tree.derivedAppliedTypeTree(tycon, args map transform)
- case Alternative(_) | Typed(_, _) | AndTypeTree(_, _) | Annotated(_, _) =>
- super.transform(tree)
- case Parens(_) =>
- stripParens(tree)
- case _ =>
- tree
- }
- }
-
- case class VariableInfo(name: Name, tree: Tree, pos: Position)
-
- /** Traverse pattern and collect all variable names with their types in buffer
- * The variables keep their positions; whereas the pattern is converted to be
- * synthetic for all nodes that contain a variable position.
- */
- object getVars extends TreeAccumulator[ListBuffer[VariableInfo]] {
-
- def namePos(tree: Tree, name: Name): Position =
- if (name contains '$') tree.pos.focus
- else {
- val start = tree.pos.start
- val end = start + name.decode.length
- Position(start, end)
- }
-
- override def apply(buf: ListBuffer[VariableInfo], tree: Tree): ListBuffer[VariableInfo] = {
- def seenName(name: Name) = buf exists (_.name == name)
- def add(name: Name, t: Tree): ListBuffer[VariableInfo] =
- if (seenName(name)) buf else buf += VariableInfo(name, t, namePos(tree, name))
-
- tree match {
- case Bind(nme.WILDCARD, _) =>
- foldOver(buf, tree)
- case Bind(name, Typed(tree1, tpt)) if !mayBeTypePat(tpt) =>
- apply(add(name, tpt), tree1)
- case Bind(name, tree1) =>
- apply(add(name, TypeTree()), tree1)
- case _ =>
- foldOver(buf, tree)
- }
- }
- }
-
- /** Returns list of all pattern variables, possibly with their types,
- * without duplicates
- */
- private def getVariables(tree: Tree): List[VariableInfo] =
- getVars(new ListBuffer[VariableInfo], tree).toList
-
- def byNameApplication(tpe: Tree): Tree =
- AppliedTypeTree(scalaDot(tpnme.BYNAME_PARAM_CLASS), List(tpe))
- def repeatedApplication(tpe: Tree): Tree =
- AppliedTypeTree(scalaDot(tpnme.REPEATED_PARAM_CLASS), List(tpe))
-
- def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = {
- def mkPair(t1: Tree, t2: Tree) = {
- if (t1.isType) AppliedTypeTree(scalaDot(tpnme.Pair), List(t1, t2))
- else Pair(t1, t2)
- }
- trees reduce mkPair
- }
-
- def stripParens(t: Tree) = t match {
- case Parens(t) => t
- case _ => t
- }
-
- def makeSelfDef(name: TermName, tpt: Tree): ValDef =
- ValDef(Modifiers(Private), name, tpt, EmptyTree())
-
- /** If tree is a variable pattern, return its variable info.
- * Otherwise return none.
- */
- private def matchVarPattern(tree: Tree): Option[VariableInfo] = {
- def wildType(t: Tree): Option[Tree] = t match {
- case Ident(x) if x.toTermName == nme.WILDCARD => Some(TypeTree())
- case Typed(Ident(x), tpt) if x.toTermName == nme.WILDCARD => Some(tpt)
- case _ => None
- }
- tree match {
- case Ident(name) => Some(VariableInfo(name, TypeTree(), tree.pos))
- case Bind(name, body) => wildType(body) map (x => VariableInfo(name, x, tree.pos))
- case Typed(id @ Ident(name), tpt) => Some(VariableInfo(name, tpt, id.pos))
- case _ => None
- }
- }
-
- /** Create tree representing (unencoded) binary operation expression or pattern. */
- def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = {
- def mkNamed(args: List[Tree]) =
- if (isExpr) args map {
- case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs).withPos(arg.pos)
- case arg => arg
- } else args
- val arguments = right match {
- case Parens(arg) => mkNamed(arg :: Nil)
- case _ => right :: Nil
- }
- if (isExpr) {
- if (isLeftAssoc(op)) {
- Apply(Select(stripParens(left), op.encode).withPos(opPos), arguments)
- } else {
- val x = ctx.freshName().toTermName
- Block(
- List(ValDef(Modifiers(Synthetic), x, TypeTree(), stripParens(left))),
- Apply(Select(stripParens(right), op.encode).withPos(opPos), List(Ident(x).withPos(left.pos))))
- }
- } else {
- Apply(Ident(op.encode).withPos(opPos), stripParens(left) :: arguments)
- }
- }
-
- /** tpt.<init> */
- def SelectConstructor(tpt: Tree): Tree =
- Select(tpt, nme.CONSTRUCTOR)
-
- private def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match {
- case Apply(tree, args) => splitArgss(tree, args :: outerArgss)
- case _ => (constr, if (outerArgss.isEmpty) ListOfNil else outerArgss)
- }
-
- /** new tpt(argss_1)...(argss_n)
- * @param npos the position spanning <new tpt>, without any arguments
- */
- def makeNew(parentConstr: Tree) = {
- val (tpt, argss) = splitArgss(parentConstr, Nil)
- New(tpt, argss)
- }
-
- /** Create positioned tree representing an object creation <new parents { self => stats }
- */
- def makeNew(templ: Template): Tree = {
- val x = tpnme.ANON_CLASS
- val nu = makeNew(Ident(x))
- val clsDef = {
- implicit val cpos = NoPosition
- ClassDef(Modifiers(Final), x, Nil, templ)
- }
- Block(clsDef, nu)
- }
-
- /** Create positioned tree representing an object creation <new parents { self => stats }
- * @param cpos the position of the new, focus should be the first parent's start.
- */
- def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree]): Tree = {
- val newPos = Position(cpos.start, cpos.point)
- val clsPos = Position(cpos.point, cpos.end)
- if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr.withPos(newPos.endPos)), self, stats)
- else if (parents.tail.isEmpty && stats.isEmpty)
- makeNew(parents.head)
- else {
- val x = tpnme.ANON_CLASS
- val nu = makeNew(Ident(x).withPos(newPos)).withPos(newPos)
- val clsDef = {
- implicit val cpos = clsPos
- ClassDef(Modifiers(Final), x, Nil, Template(???, parents, self, stats))
- }
- Block(clsDef, nu)
- }
- }
-
- /** Create a tree representing an assignment <lhs = rhs> */
- def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match {
- case Apply(fn, args) =>
- Apply(Select(fn, nme.update), args :+ rhs)
- case _ =>
- Assign(lhs, rhs)
- }
-
- /** A type tree corresponding to (possibly unary) intersection type
- def makeIntersectionTypeTree(tps: List[Tree]): Tree =
- if (tps.tail.isEmpty) tps.head
- else CompoundTypeTree(Template(tps, emptyValDef, Nil))*/
-
- private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
- val ldef = DefDef(Modifiers(Label).withPos(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs)
- Block(ldef, call)
- }
-
- private def labelCall(lname: TermName): Apply =
- Apply(Ident(lname), Nil)
-
- /** Create tree representing a while loop */
- def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
- val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos)
- val rhs = {
- implicit val cpos = NoPosition
- If(cond, Block(body, continu), Literal(Constant()).withPos(continu.pos))
- }
- labelDefAndCall(lname, rhs, continu)
- }
-
- /** Create tree representing a do-while loop */
- def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = {
- val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos)
- val rhs = Block(body, If(cond, continu, Literal(Constant()).withPos(continu.pos)))
- labelDefAndCall(lname, rhs, continu)
- }
-
- /** Create block of statements `stats` */
- def makeBlock(stats: List[Tree]): Tree =
- if (stats.isEmpty) Literal(Constant())
- else if (!stats.last.isTerm) Block(stats, Literal(Constant()).withPos(cpos.endPos))
- else if (stats.length == 1) stats.head
- else Block(stats.init, stats.last)
-
- def makePatFilter(tree: Tree, condition: Tree, canDrop: Boolean): Tree = {
- val cases = List(
- CaseDef(condition, EmptyTree(), Literal(Constant(true))),
- CaseDef(Ident(nme.WILDCARD), EmptyTree(), Literal(Constant(false)))
- )
- val matchTree = makeVisitor(cases, checkExhaustive = false, canDrop)
- locally {
- implicit val cpos = tree.pos
- Apply(Select(tree, nme.withFilter), matchTree :: Nil)
- }
- }
-
- /** Create tree for for-comprehension generator <pat <- rhs> or <pat = rhs> */
- def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = {
- val pat1 = patvarTransformer.transform(pat)
- if (valeq) ValEq(pat1, rhs)
- else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true))
- }
-
-/*
- def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) =
- TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds)
-*/
- abstract class Enumerator { def pos: Position }
- case class ValFrom(pat: Tree, rhs: Tree) extends Enumerator {
- val pos = cpos union pat.pos union rhs.pos
- }
- case class ValEq(pat: Tree, rhs: Tree) extends Enumerator {
- val pos = cpos union pat.pos union rhs.pos
- }
- case class Filter(test: Tree) extends Enumerator {
- val pos = cpos union test.pos
- }
-
- /** Create tree for for-comprehension <for (enums) do body> or
- * <for (enums) yield body> where mapName and flatMapName are chosen
- * corresponding to whether this is a for-do or a for-yield.
- * The creation performs the following rewrite rules:
- *
- * 1.
- *
- * for (P <- G) E ==> G.foreach (P => E)
- *
- * Here and in the following (P => E) is interpreted as the function (P => E)
- * if P is a variable pattern and as the partial function { case P => E } otherwise.
- *
- * 2.
- *
- * for (P <- G) yield E ==> G.map (P => E)
- *
- * 3.
- *
- * for (P_1 <- G_1; P_2 <- G_2; ...) ...
- * ==>
- * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
- *
- * 4.
- *
- * for (P <- G; E; ...) ...
- * =>
- * for (P <- G.filter (P => E); ...) ...
- *
- * 5. For any N:
- *
- * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
- * ==>
- * for (TupleN(P_1, P_2, ... P_N) <-
- * for (x_1 @ P_1 <- G) yield {
- * val x_2 @ P_2 = E_2
- * ...
- * val x_N & P_N = E_N
- * TupleN(x_1, ..., x_N)
- * } ...)
- *
- * If any of the P_i are variable patterns, the corresponding `x_i @ P_i' is not generated
- * and the variable constituting P_i is used instead of x_i
- *
- * @param mapName The name to be used for maps (either map or foreach)
- * @param flatMapName The name to be used for flatMaps (either flatMap or foreach)
- * @param enums The enumerators in the for expression
- * @param body The body of the for expression
- */
- private def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Enumerator], body: Tree): Tree = {
-
- /** make a closure pat => body.
- * The closure is assigned a transparent position with the point at pos.point and
- * the limits given by pat and body.
- */
- def makeClosure(pat: Tree, body: Tree): Tree =
- matchVarPattern(pat) match {
- case Some(VariableInfo(name, tpt, pos)) =>
- Function(ValDef(Modifiers(Param).withPos(cpos.startPos), name.toTermName, tpt, EmptyTree()).withPos(pos) :: Nil, body)
- case None =>
- makeVisitor(List(CaseDef(pat, EmptyTree(), body)), checkExhaustive = false)
- }
-
- /** Make an application qual.meth(pat => body) positioned at `pos`.
- */
- def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree): Tree =
- Apply(Select(qual, meth).withPos(NoPosition), makeClosure(pat, body))
-
- /** Optionally, if pattern is a `Bind`, the bound name, otherwise None.
- */
- def patternVar(pat: Tree): Option[Name] = pat match {
- case Bind(name, _) => Some(name)
- case _ => None
- }
-
- /** If `pat` is not yet a `Bind` wrap it in one with a fresh name
- */
- def makeBind(pat: Tree): Tree = pat match {
- case Bind(_, _) => pat
- case _ => Bind(ctx.freshName().toTermName, pat)
- }
-
- /** A reference to the name bound in Bind `pat`.
- */
- def makeValue(pat: Tree): Tree = pat match {
- case Bind(name, _) => Ident(name).withPos(pat.pos.focus)
- }
-
- enums match {
- case (enum @ ValFrom(pat, rhs)) :: Nil =>
- makeCombination(mapName, rhs, pat, body).withPos(enum.pos)
- case ValFrom(pat, rhs) :: (rest @ (ValFrom( _, _) :: _)) =>
- makeCombination(flatMapName, rhs, pat,
- makeFor(mapName, flatMapName, rest, body))
- case (enum @ ValFrom(pat, rhs)) :: Filter(test) :: rest =>
- makeFor(mapName, flatMapName,
- ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test)) :: rest,
- body)
- case (enum @ ValFrom(pat, rhs)) :: rest =>
- val (valeqs, rest1) = rest.span(_.isInstanceOf[ValEq])
- assert(!valeqs.isEmpty)
- val pats = valeqs map { case ValEq(pat, _) => pat }
- val rhss = valeqs map { case ValEq(_, rhs) => rhs }
- val defpat1 = makeBind(pat)
- val defpats = pats map makeBind
- val pdefs = (defpats, rhss).zipped flatMap (makePatDef)
- val ids = (defpat1 :: defpats) map makeValue
- val rhs1 = makeForYield(ValFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids)))
- val allpats = pat :: pats
- val vfrom1 = ValFrom(makeTuple(allpats), rhs1)
- makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
- case _ =>
- EmptyTree() //may happen for erroneous input
- }
- }
-
- /** Create tree for for-do comprehension <for (enums) body> */
- def makeFor(enums: List[Enumerator], body: Tree): Tree =
- makeFor(nme.foreach, nme.foreach, enums, body)
-
- /** Create tree for for-yield comprehension <for (enums) yield body> */
- def makeForYield(enums: List[Enumerator], body: Tree): Tree =
- makeFor(nme.map, nme.flatMap, enums, body)
-
- /** Create tree for a pattern alternative */
- def makeAlternative(ts: List[Tree]): Tree = Alternative(ts flatMap alternatives)
-
- def alternatives(t: Tree): List[Tree] = t match {
- case Alternative(ts) => ts
- case _ => List(t)
- }
-
- def mkAnnotated(cls: Symbol, tree: Tree) =
- Annotated(TypedSplice(tpd.New(cls.typeRef)), tree)
-
- /** Create visitor <x => x match cases> */
- def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean, canDrop: Boolean = false): Tree = {
- val x = ctx.freshName().toTermName
- val id = Ident(x)
- val sel =
- if (canDrop) mkAnnotated(???, id)
- else if (!checkExhaustive) mkAnnotated(defn.UncheckedAnnot, id)
- else id
- Function(List(ugen.syntheticParameter(x)), Match(sel, cases))
- }
-
- /** Create tree for case definition <case pat if guard => rhs> */
- def makeCaseDef(pat: Tree, guard: Tree, rhs: Tree): CaseDef =
- CaseDef(patvarTransformer.transform(pat), guard, rhs)
-
- /** Create tree for pattern definition <val pat0 = rhs> */
- def makePatDef(pat: Tree, rhs: Tree): List[Tree] =
- makePatDef(Modifiers(), pat, rhs)
-
- /** Create tree for pattern definition <mods val pat0 = rhs> */
- def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree, varsArePatterns: Boolean = false): List[Tree] = matchVarPattern(pat) match {
- case Some(VariableInfo(name, tpt, pos)) if varsArePatterns =>
- ValDef(mods, name.toTermName, tpt, rhs).withPos(pos) :: Nil // point comes from pat.pos
-
- case _ =>
- // in case there is exactly one variable x_1 in pattern
- // val/var p = e ==> val/var x_1 = e.match (case p => (x_1))
- //
- // in case there are zero or more than one variables in pattern
- // val/var p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
- // val/var x_1 = t$._1
- // ...
- // val/var x_N = t$._N
-
- val rhsUnchecked = mkAnnotated(defn.UncheckedAnnot, rhs)
-
- // TODO: clean this up -- there is too much information packed into makePatDef's `pat` argument
- // when it's a simple identifier (case Some((name, tpt)) -- above),
- // pat should have the type ascription that was specified by the user
- // however, in `case None` (here), we must be careful not to generate illegal pattern trees (such as `(a, b): Tuple2[Int, String]`)
- // i.e., this must hold: pat1 match { case Typed(expr, tp) => assert(expr.isInstanceOf[Ident]) case _ => }
- // if we encounter such an erroneous pattern, we strip off the type ascription from pat and propagate the type information to rhs
- val (pat1, rhs1) = patvarTransformer.transform(pat) match {
- // move the Typed ascription to the rhs
- case Typed(expr, tpt) if !expr.isInstanceOf[Ident] =>
- val rhsTypedUnchecked =
- if (tpt.isEmpty) rhsUnchecked else Typed(rhsUnchecked, tpt)
- (expr, rhsTypedUnchecked)
- case ok =>
- (ok, rhsUnchecked)
- }
- val vars = getVariables(pat1)
- val ids = vars map (v => Ident(v.name).withPos(v.pos))
- val caseDef = CaseDef(pat1, EmptyTree(), makeTuple(ids))
- val matchExpr = Match(rhs1, caseDef :: Nil)
- vars match {
- case List(VariableInfo(vname, tpt, pos)) =>
- ValDef(mods, vname.toTermName, tpt, matchExpr) :: Nil
- case _ =>
- val tmpName = ctx.freshName().toTermName
- val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
- val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
- val restDefs = for {
- (VariableInfo(vname, tpt, pos), n) <- vars.zipWithIndex
- } yield {
- val rhs = {
- implicit val cpos = pos.focus
- Select(Ident(tmpName), ("_" + n).toTermName)
- }
- ValDef(mods, vname.toTermName, tpt, rhs).withPos(pos)
- }
- firstDef :: restDefs
- }
- }
-
- /** Create a tree representing the function type (argtpes) => restpe */
- def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =
- AppliedTypeTree(scalaDot(("Function" + argtpes.length).toTypeName), argtpes ::: List(restpe))
-
- /** Append implicit parameter section if `contextBounds` nonempty */
- def addEvidenceParams(owner: Name, vparamss: List[List[ValDef]], contextBounds: List[Tree]): List[List[ValDef]] = {
- if (contextBounds.isEmpty) vparamss
- else {
- val mods = Modifiers(if (owner.isTypeName) PrivateLocal | ParamAccessor else Param)
- val evidenceParams = for (tpt <- contextBounds) yield {
- val pname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
- ValDef(mods | Implicit | Synthetic, pname, tpt, EmptyTree())
- }
- vparamss.reverse match {
- case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit =>
- vparamss.init :+ (evidenceParams ++ vparams)
- case _ =>
- vparamss :+ evidenceParams
- }
- }
- }
-}