@@ -78,56 +78,63 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
7878 DefDef (showName, Nil , Nil , TypeTree (), showWithNullCheck).withFlags(Synthetic ).withPos(pos)
7979 }
8080
81- val (exps, other ) = trees.partition(_.isTerm)
82- val resX = exps.zipWithIndex.flatMap { case (exp, i ) =>
83- val resName = (str. REPL_RES_PREFIX + (i + state.valIndex)).toTermName
84- val show = createShow(resName, exp.pos)
85-
86- exp match {
87- case exp @ Assign ( id : Ident , rhs) =>
88- val assignName = (id. name ++ str. REPL_ASSIGN_SUFFIX ).toTermName
89- val assign = ValDef (assignName, TypeTree (), id).withPos(exp.pos)
90-
91- exp :: assign :: createShow(assignName, exp.pos) :: Nil
92- case _ =>
93- List ( ValDef (resName, TypeTree (), exp).withPos(exp.pos), show)
81+ def createPatDefShows ( patDef : PatDef ) = {
82+ def createDeepShows ( tree : untpd. Tree ) = {
83+ object PatFolder extends UntypedDeepFolder [ List [ DefDef ]] (
84+ (acc, tree) => tree match {
85+ case Ident (name) if name.isVariableName && name != nme. WILDCARD =>
86+ createShow(name.toTermName, tree.pos) :: acc
87+ case Bind (name, _) if name.isVariableName && name != nme. WILDCARD =>
88+ createShow( name.toTermName, tree.pos) :: acc
89+ case _ =>
90+ acc
91+ }
92+ )
93+ PatFolder .apply( Nil , tree).reverse
9494 }
95- }
9695
97- val othersWithShow = other.flatMap {
98- case t : ValDef =>
99- List (t, createShow(t.name, t.pos))
100- case t : PatDef => {
101- val variables = t.pats.flatMap {
102- case Ident (name) if name != nme.WILDCARD => List ((name.toTermName, t.pos))
103- case pat =>
104- new UntypedDeepFolder [List [(TermName , Position )]](
105- (acc : List [(TermName , Position )], t : Tree ) => t match {
106- case _ : BackquotedIdent =>
107- acc
108- case Ident (name) if name.isVariableName && name.toString != " _" =>
109- (name.toTermName, t.pos) :: acc
110- case Bind (name, _) if name.isVariableName =>
111- (name.toTermName, t.pos) :: acc
112- case _ =>
113- acc
114- }
115- ).apply(Nil , pat).reverse
116- }
117-
118- t :: variables.map { case (name, pos) => createShow(name, pos) }
96+ // cannot fold over the whole tree because we need to generate show methods
97+ // for top level identifier starting with an uppercase (e.g. val X, Y = 2)
98+ patDef.pats.flatMap {
99+ case id @ Ident (name) if name != nme.WILDCARD =>
100+ List (createShow(name.toTermName, id.pos))
101+ case bd @ Bind (name, body) if name != nme.WILDCARD =>
102+ createShow(name.toTermName, bd.pos) :: createDeepShows(body)
103+ case other =>
104+ createDeepShows(other)
119105 }
120- case t => List (t)
121106 }
122107
123- val newObjectIndex = state.objectIndex + {
124- if (resX.nonEmpty || othersWithShow.nonEmpty) 1 else 0
108+ var valIdx = state.valIndex
109+
110+ val defs = trees.flatMap {
111+ case vd : ValDef =>
112+ List (vd, createShow(vd.name, vd.pos))
113+ case pd : PatDef =>
114+ pd :: createPatDefShows(pd)
115+ case expr @ Assign (id : Ident , rhs) =>
116+ // special case simple reassignment (e.g. x = 3)
117+ // in order to print the new value in the REPL
118+ val assignName = (id.name ++ str.REPL_ASSIGN_SUFFIX ).toTermName
119+ val assign = ValDef (assignName, TypeTree (), id).withPos(expr.pos)
120+ val show = createShow(assignName, expr.pos)
121+ List (expr, assign, show)
122+ case expr if expr.isTerm =>
123+ val resName = (str.REPL_RES_PREFIX + valIdx).toTermName
124+ valIdx += 1
125+ val show = createShow(resName, expr.pos)
126+ val vd = ValDef (resName, TypeTree (), expr).withPos(expr.pos)
127+ List (vd, show)
128+ case other =>
129+ List (other)
125130 }
126- val newValIndex = state.valIndex + exps.filterNot(_.isInstanceOf [Assign ]).length
127131
128132 Definitions (
129- state.imports.map(_._1) ++ resX ++ othersWithShow,
130- state.copy(objectIndex = newObjectIndex, valIndex = newValIndex)
133+ state.imports.map(_._1) ++ defs,
134+ state.copy(
135+ objectIndex = state.objectIndex + (if (defs.isEmpty) 0 else 1 ),
136+ valIndex = valIdx
137+ )
131138 ).result
132139 }
133140
0 commit comments