treebuilder.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 458 行 · 第 1/2 页

SCALA
458
字号
  *    for (val 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 a variable pattern and as the partial function { case P => E } otherwise.  *  *  2.  *  *    for (val P <- G) yield E  ==>  G.map (P => E)  *  *  3.   *  *    for (val P_1 <- G_1; val P_2 <- G_2; ...) ...  *      ==>  *    G_1.flatMap (P_1 => for (val P_2 <- G_2; ...) ...)  *  *  4.  *  *    for (val P <- G; E; ...) ...  *      =>  *    for (val P <- G.filter (P => E); ...) ...  *  *  5. For N < MaxTupleArity:  *  *    for (val P_1 <- G; val P_2 = E_2; val P_N = E_N; ...)  *      ==>  *    for (val TupleN(P_1, P_2, ... P_N) <-  *      for (val 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  *  */  private def makeFor(mapName: Name, flatMapName: Name, enums: List[Enumerator], body: Tree): Tree = {    def makeClosure(pat: Tree, body: Tree): Tree = matchVarPattern(pat) match {      case Some((name, tpt)) =>        Function(List(ValDef(Modifiers(PARAM), name, tpt, EmptyTree)), body)      case None =>        makeVisitor(List(CaseDef(pat, EmptyTree, body)), false)    }    def makeCombination(meth: Name, qual: Tree, pat: Tree, body: Tree): Tree =       Apply(Select(qual, meth), List(makeClosure(pat, body)));    def patternVar(pat: Tree): Option[Name] = pat match {      case Bind(name, _) => Some(name)      case _ => None    }    def makeBind(pat: Tree): Tree = pat match {      case Bind(_, _) => pat      case _ => Bind(freshName(pat.pos), pat)    }    def makeValue(pat: Tree): Tree = pat match {      case Bind(name, _) => Ident(name)    }    enums match {      case ValFrom(pos, pat, rhs) :: Nil =>        atPos(pos) {          makeCombination(mapName, rhs, pat, body)        }      case ValFrom(pos, pat, rhs) :: (rest @ (ValFrom(_,  _, _) :: _)) =>        atPos(pos) {          makeCombination(flatMapName, rhs, pat, makeFor(mapName, flatMapName, rest, body))        }      case ValFrom(pos, pat, rhs) :: Filter(test) :: rest =>        makeFor(mapName, flatMapName,                ValFrom(pos, pat, makeCombination(nme.filter, rhs, pat.duplicate, test)) :: rest,                body)      case ValFrom(pos, pat, rhs) :: rest =>        val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(_.isInstanceOf[ValEq]);        assert(!valeqs.isEmpty)        val rest1 = rest.drop(valeqs.length)        val pats = valeqs map { case ValEq(_, pat, _) => pat }        val rhss = valeqs map { case ValEq(_, _, rhs) => rhs }        val defpats = pats map (x => makeBind(x.duplicate))        val pdefs = List.flatten(List.map2(defpats, rhss)(makePatDef))        val patX1 = makeBind(pat.duplicate);        val ids = (patX1 :: defpats) map makeValue        val rhs1 = makeForYield(          List(ValFrom(pos, patX1, rhs)),           Block(pdefs, makeTupleTerm(ids, true)))        makeFor(mapName, flatMapName, ValFrom(pos, makeTuple(pat :: pats, false), rhs1) :: rest1, body)      case _ =>        EmptyTree //may happen for erroneous input    }  }  /** Create tree for for-do comprehension &lt;for (enums) body&gt; */  def makeFor(enums: List[Enumerator], body: Tree): Tree =    makeFor(nme.foreach, nme.foreach, enums, body)  /** Create tree for for-yield comprehension &lt;for (enums) yield body&gt; */  def makeForYield(enums: List[Enumerator], body: Tree): Tree =    makeFor(nme.map, nme.flatMap, enums, body)  /** Create tree for a lifted expression XX-LIFTING   */  def makeLifted(gs: List[ValFrom], body: Tree): Tree = {    def combine(gs: List[ValFrom]): ValFrom = (gs: @unchecked) match {      case g :: Nil => g      case ValFrom(pos1, pat1, rhs1) :: gs2 =>         val ValFrom(pos2, pat2, rhs2) = combine(gs2)        ValFrom(pos1, makeTuple(List(pat1, pat2), false), Apply(Select(rhs1, nme.zip), List(rhs2)))    }    makeForYield(List(combine(gs)), body)  }  /** Create tree for a pattern alternative */  def makeAlternative(ts: List[Tree]): Tree = {    def alternatives(t: Tree): List[Tree] = t match {      case Alternative(ts) => ts      case _ => List(t)    }    Alternative(for (val t <- ts; val a <- alternatives(t)) yield a)  }  /** Create tree for a pattern sequence */  def makeSequence(ts: List[Tree]): Tree = {    def elements(t: Tree): List[Tree] = t match {      case Sequence(ts) => ts      case _ => List(t)    }    Sequence(for (val t <- ts; val e <- elements(t)) yield e)  }  /** Create tree for the p+ regex pattern, becomes p p*  */  def makePlus(p: Tree): Tree =    makeSequence(List(p, Star(p.duplicate)))  /** Create tree for the p? regex pattern, becomes (p| )         */  def makeOpt(p: Tree): Tree =    makeAlternative(List(p, Sequence(List())))  /** Create visitor <x => x match cases> */  def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean): Tree =    makeVisitor(cases, checkExhaustive, "x$")  private def makeUnchecked(expr: Tree): Tree =    Annotated(Annotation(New(scalaDot(definitions.UncheckedClass.name), List(List())), List()), expr)  /** Create visitor <x => x match cases> */  def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean, prefix: String): Tree = {    val x = freshName(posAssigner.pos, prefix)    val sel = if (checkExhaustive) Ident(x) else makeUnchecked(Ident(x))    Function(List(makeSyntheticParam(x)), Match(sel, cases))  }  /** Create tree for case definition &lt;case pat if guard => rhs&gt; */  def makeCaseDef(pat: Tree, guard: Tree, rhs: Tree): CaseDef =    CaseDef(patvarTransformer.transform(pat), guard, rhs)  /** Create tree for pattern definition &lt;val pat0 = rhs&gt; */  def makePatDef(pat: Tree, rhs: Tree): List[Tree] =    makePatDef(Modifiers(0), pat, rhs)  /** Create tree for pattern definition &lt;mods val pat0 = rhs&gt; */  def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): List[Tree] = matchVarPattern(pat) match {    case Some((name, tpt)) =>      List(ValDef(mods, name, tpt, rhs).setPos(pat.pos))    case None =>      //  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 pat1 = patvarTransformer.transform(pat)      val vars = getVariables(pat1)      val matchExpr = atPos(pat1.pos){        Match(          makeUnchecked(rhs),           List(CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))))      }      vars match {        case List((vname, tpt, pos)) =>          List(ValDef(mods, vname, tpt, matchExpr).setPos(pos))        case _ =>           val tmp = freshName(pat1.pos)          val firstDef = ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC | (mods.flags & LAZY)),                                 tmp, TypeTree(), matchExpr)          var cnt = 0          val restDefs = for (val (vname, tpt, pos) <- vars) yield atPos(pos) {            cnt = cnt + 1            ValDef(mods, vname, tpt, Select(Ident(tmp), newTermName("_" + cnt)))          }          firstDef :: restDefs      }  }  /** Create a tree representing the function type (argtpes) => restpe */  def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =    AppliedTypeTree(scalaDot(newTypeName("Function" + argtpes.length)), argtpes ::: List(restpe))  /** Create a tree representing a the name function type (=> argtpe) => restpe */  /*  def makeByNameFunctionTypeTree(argtpe: Tree, restpe: Tree): Tree =     AppliedTypeTree(scalaDot(newTypeName("ByNameFunction")), List(argtpe, restpe))  */  /** Append implicit view section if for `implicitViews' if nonempty */  def addImplicitViews(owner: Name, vparamss: List[List[ValDef]], implicitViews: List[Tree]): List[List[ValDef]] = {    val mods = Modifiers(if (owner.isTypeName) PARAMACCESSOR | LOCAL | PRIVATE else PARAM)    def makeViewParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName(tpt.pos, "view$"), tpt, EmptyTree)    if (implicitViews.isEmpty) vparamss    else vparamss ::: List(implicitViews map makeViewParam)  }  /** Create a tree representing a packaging */  def makePackaging(pkg: Tree, stats: List[Tree]): PackageDef = pkg match {    case Ident(name) =>      PackageDef(name, stats).setPos(pkg.pos)    case Select(qual, name) =>      makePackaging(qual, List(PackageDef(name, stats).setPos(pkg.pos)))  }  case class Parens(args: List[Tree]) extends Tree}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?