diff options
author | Li Haoyi <haoyi@dropbox.com> | 2014-11-01 00:56:12 -0700 |
---|---|---|
committer | Li Haoyi <haoyi@dropbox.com> | 2014-11-01 00:56:12 -0700 |
commit | 3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9 (patch) | |
tree | 9f1846359c784a6e4bfc4682fddc8b6c884bf811 /api/src/main/scala/twist/stages/Compiler.scala | |
parent | 058e9bac2dd8166051bafa16d51f27ee5856929a (diff) | |
download | hands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.tar.gz hands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.tar.bz2 hands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.zip |
works, with a compiler-plugin based architecture supporting incremental compilation
Diffstat (limited to 'api/src/main/scala/twist/stages/Compiler.scala')
-rw-r--r-- | api/src/main/scala/twist/stages/Compiler.scala | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/api/src/main/scala/twist/stages/Compiler.scala b/api/src/main/scala/twist/stages/Compiler.scala deleted file mode 100644 index e00c373..0000000 --- a/api/src/main/scala/twist/stages/Compiler.scala +++ /dev/null @@ -1,161 +0,0 @@ -package twist.stages -import acyclic.file - -import scala.reflect.macros.Context -import scala.reflect.internal.util.{Position, OffsetPosition} - -/** - * Walks the parsed AST, converting it into an un-structured Scala source-blob - * which when compiled results in a function that can be used to generate the - * given Frag at runtime. - */ -object Compiler{ - val WN = TwistNodes - def apply(c: Context)(literalPos: c.Position, template: WN.Template): c.Tree = { - - import c.universe._ - def fragType = tq"scalatags.Text.all.Frag" - def posFor(offset: Int) = { - new OffsetPosition( - literalPos.source, - offset - ).asInstanceOf[c.universe.Position] - } - def compileTree(frag: WN.TemplateTree): Tree = { - -// println(frag) - val fragPos = posFor(literalPos.point + frag.offset) - -// println(s"${frag.offset}\n${literalPos.point}\n${pos.point}\n$frag\n") - - val f: Tree = frag match { - case WN.Plain(text, offset) => q"$text" - case WN.Display(exp, offset) => compileTree(exp) - case WN.Comment(msg, offset) => q"" - case WN.ScalaExp(Seq(WN.Simple(first, _), WN.Block(ws, args, content, _)), offset) - if first.startsWith("for(") => - val fresh = c.fresh() - val skeleton: Tree = c.parse(first + s"{$fresh}").asInstanceOf[Apply] -// println("FIRST " + first) - skeleton.foreach{x => - x - if (x.pos != NoPosition) x.pos = posFor(x.pos.point + fragPos.point + 1) - } - val b = content.map(compileTree(_)) - def rec(t: Tree): Tree = t match { - case a @ Apply(fun, List(f @ Function(vparams, body))) => - val f2 = Function(vparams, rec(body)) - val a2 = Apply(fun, List(f2)) - a2.pos = a.pos - f2.pos = f.pos - a2 - case Ident(x: TermName) if x.decoded == fresh => - q"Seq[$fragType](..$b)" - } - - val out = rec(skeleton) - - - out - - case WN.ScalaExp(WN.Simple(first, _) +: WN.Block(_, None, content1, _) +: rest, offset) - if first.startsWith("if(") => - - val b1 = content1.map(compileTree(_)) - val tree = c.parse(first + "{}").asInstanceOf[If] - tree.foreach{x => - x.pos = posFor(x.pos.point + fragPos.point + 1) - } - val If(cond, _, _) = tree - val b2 = rest match{ - case Seq(WN.Simple(next, _), WN.Block(_, None, content2, _)) => - content2.map(compileTree(_)) - case Seq() => Nil - } - q"if($cond){ Seq[$fragType](..$b1): $fragType } else { Seq[$fragType](..$b2): $fragType }" - - case xx @ WN.ScalaExp(WN.Simple(first, _) +: rest, offset) => - val firstTree = c.parse(first) - - firstTree.foreach{x => - x.pos = posFor(x.pos.point + fragPos.point) - } - - val s = rest.foldLeft[Tree](firstTree) { - case (l, WN.Simple(code, _)) => - val fresh = c.fresh() - - val snippet = s"$fresh$code" - val skeleton = c.parse(snippet) - - def rec(t: Tree): Tree = { - val newPos = posFor(fragPos.point + t.pos.point + first.length - fresh.length) - val res = t match { - case Apply(fun, args) => - for(arg <- args; tree <- arg if tree.pos != NoPosition){ - tree.pos = posFor(tree.pos.point + newPos.point - t.pos.point) - } - - Apply(rec(fun), args) - case Select(qualifier, name) => Select(rec(qualifier), name) - case Ident(x: TermName) if x.decoded == fresh => l - } - res.pos = newPos - -// println(Position.formatMessage(newPos.asInstanceOf[scala.reflect.internal.util.Position], "", true)) - res - } - - - rec(skeleton) - - case (l, WN.Block(ws, None, content, _)) => - q"$l(..${content.map(compileTree(_))})" - - case (l, WN.Block(ws, Some(args), content, _)) => - val snippet = s"{$args ()}" - val skeleton = c.parse(snippet) - val Function(vparamss, body) = skeleton - - val func = Function(vparamss, q"Seq[$fragType](..${content.map(compileTree(_))})") - func.pos = posFor(fragPos.point + skeleton.pos.point) - q"$l($func)" - } - - s - } - -// f.foreach(_.pos = pos) - -// println("XXX " + f.pos) -// println("F " + f) - f - } - - def compileTemplate(tmpl: WN.Template): Tree = { - val WN.Template(name, comment, params, topImports, imports, subs, content, offset) = tmpl - val fullName = if (name.toString == "") c.fresh("outer") else name - - val DefDef(mods, realName, tparams, vparamss, tpt, rhs) = { - val snippet = s"def $fullName$params = {}" - val z = c.parse(snippet).asInstanceOf[DefDef] - z - } - - val innerDefs = subs.map(compileTemplate(_)) - - val body = atPos(literalPos)(q"""{ - import scalatags.Text.all._ - ..${topImports.map(i => c.parse(i.code))} - ..$innerDefs - - Seq[scalatags.Text.all.Frag](..${content.map(compileTree(_))}) - }""") - - if (name.toString == "") body - else DefDef(mods, realName, tparams, vparamss, tpt, body) - } - - atPos(literalPos)(q"${compileTemplate(template)}") - } -}
\ No newline at end of file |