Skip to content

Commit

Permalink
[scalac-plugin] Fix #20 - 1.0.15-SNAPSHOT1
Browse files Browse the repository at this point in the history
  • Loading branch information
cchantep committed Feb 27, 2014
1 parent a87c56c commit 7bc9b54
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 75 deletions.
4 changes: 0 additions & 4 deletions project/Acolyte.scala
Expand Up @@ -14,10 +14,6 @@ object Acolyte extends Build
publishTo in ThisBuild := Some(Resolver.file("file",
new File(Path.userHome.absolutePath+"/.m2/repository"))),
pomExtra in ThisBuild := (
<organization>
<name>Acolyte</name>
<url>http://acolyte.eu.org</url>
</organization>
<url>https://github.com/cchantep/acolyte/</url>
<licenses>
<license>
Expand Down
2 changes: 2 additions & 0 deletions scalac-plugin/readme.md
Expand Up @@ -56,6 +56,8 @@ str match {

## Usage

Snapshot `1.0.15-SNAPSHOT1` is published on https://raw.github.com/applicius/mvn-repo/master/releases/ .

> If you have another `~` symbol, it will have to be renamed at `import pkg.{ ~ ⇒ renamed }`.
### SBT usage
Expand Down
120 changes: 57 additions & 63 deletions scalac-plugin/src/main/scala/acolyte/AcolytePlugin.scala
Expand Up @@ -34,13 +34,16 @@ class AcolytePlugin(val global: Global) extends Plugin {
import global.{
//abort,
reporter,
Apply,
Block,
CaseDef,
Match,
Position,
Tree,
ValDef
}
import scala.reflect.io.VirtualFile
import scala.reflect.internal.util.BatchSourceFile

override def transform(tree: Tree): Tree = tree match {
case m @ Match(_, _) {
Expand All @@ -59,51 +62,58 @@ class AcolytePlugin(val global: Global) extends Plugin {
@inline private def refactorMatch(orig: Match): Tree =
orig match {
case Match(t, cs) {
import global.{
Apply,
Bind,
Block,
Constant,
Ident,
Literal
}
import global.{ Bind, Ident }

val vds = ListBuffer[ValDef]()
val cds = cs.map {
case ocd @ CaseDef(Apply(Ident(it), x), g, by) if (
it == tildeTerm)
(x.headOption, x.tail) match {
case (Some(xt @ Apply(ex, xa)), Apply(_, ua) :: Nil)
val (vd, cd) = caseDef(vds.size, ocd.pos, xt.pos, ex, xa,
ua, g, by)
vds += vd
cd

case (Some(xt @ Apply(ex, xa)), Bind(uf, ua) :: Nil)
val (vd, cd) = caseDef(vds.size, ocd.pos, xt.pos, ex, xa,
List(Bind(uf, ua)), g, by)
vds += vd
cd

case (Some(xt @ Apply(ex, xa)), Ident(i) :: Nil)
val (vd, cd) = caseDef(vds.size, ocd.pos, xt.pos, ex, xa,
List(Ident(i)), g, by)
vds += vd
cd

case (Some(xt @ Apply(ex, xa)), Nil)
// no binding
val (vd, cd) = caseDef(vds.size, ocd.pos, xt.pos, ex, xa,
Nil, g, by)
vds += vd
cd

case _
reporter.error(ocd.pos, "Invalid ~ pattern")
//abort("Invalid ~ pattern"
ocd
case ocd @ CaseDef(pat, g, by) {
val ocp = ocd.pos // g, by

val tx = new global.Transformer {
override def transform(tree: Tree): Tree = tree match {
case oa @ Apply(Ident(it), x) if (it == tildeTerm) {
(x.headOption, x.tail) match {
case (Some(xt @ Apply(ex, xa)), bs) {
val xpo: Option[List[Tree]] = bs.headOption match {
case Some(Apply(_, ua)) Some(ua)
case Some(bn @ Bind(_, _)) Some(bn :: Nil)
case Some(id @ Ident(_)) Some(id :: Nil)
case None Some(Nil)
case _ None
}

xpo.fold({
reporter.error(oa.pos, "Invalid ~ pattern")
//abort("Invalid ~ pattern")
oa
}) { xp
val (vd, rp) = refactorPattern(xt.pos, ex, xa, xp)
vds += vd
rp
}
}
case _
reporter.error(oa.pos, "Invalid ~ pattern")
//abort("Invalid ~ pattern")
oa

}
}
case _ super.transform(tree)
}
}

val of = ocp.source.file
val file = new VirtualFile(of.name,
s"${of.path}#refactored-match-${ocp.line}")

val nc = CaseDef(tx.transform(pat), g, by)
val cdc = s"${global.show(nc)} // generated from ln ${ocp.line}, col ${ocp.column - 5}"
val cdp = ocp.withPoint(0).
withSource(new BatchSourceFile(file, cdc), 0)

global.atPos(cdp)(nc)
}
case cd cd
}

Expand All @@ -116,39 +126,23 @@ class AcolytePlugin(val global: Global) extends Plugin {
orig
}

@inline private def caseDef[T](i: Int, cp: Position, xp: Position, ex: Tree, xa: List[Tree], ua: List[Tree], g: Tree, b: Tree): (ValDef, CaseDef) = {

import scala.reflect.io.VirtualFile
import scala.reflect.internal.util.BatchSourceFile
import global.{
atPos,
show,
Apply,
Ident,
Literal,
Modifiers,
TypeTree
}
@inline private def refactorPattern[T](xp: Position, ex: Tree, xa: List[Tree], ua: List[Tree]): (ValDef, Apply) = {

import global.{ atPos, show, Ident, Modifiers }

val of = xp.source.file
val file = new VirtualFile(of.name, of.path + "#refactored-match-" + i)
val file = new VirtualFile(of.name,
s"${of.path}#refactored-match-${xp.line}")

// ValDef
val xn = global.treeBuilder.freshTermName("Xtr")
val vd = ValDef(Modifiers(), xn, TypeTree(), Apply(ex, xa))
val vd = ValDef(Modifiers(), xn, global.TypeTree(), Apply(ex, xa))
val vdc =
s"${show(vd)} // generated from ln ${xp.line}, col ${xp.column - 1}"

val vdp = xp.withPoint(0).withSource(new BatchSourceFile(file, vdc), 0)

// CaseDef
val pat = Apply(Ident(xn), ua)
val cd = CaseDef(pat, g, b)
val cdc =
s"${show(cd)} // generated from ln ${cp.line}, col ${cp.column - 5}"
val cdp = cp.withPoint(0).withSource(new BatchSourceFile(file, cdc), 0)

(atPos(vdp)(vd), atPos(cdp)(cd))
(atPos(vdp)(vd), Apply(Ident(xn), ua))
}
}
}
Expand Down
17 changes: 9 additions & 8 deletions scalac-plugin/src/test/scala/acolyte/MatchComponentSpec.scala
Expand Up @@ -35,20 +35,21 @@ object MatchComponentSpec
}

"rich match with several bindings: ~(Regex(re), (a, b))" in {
patternMatching("123;xyz") aka "matching" mustEqual List("xyz", "123")
patternMatching("123;xyz") aka "matching" mustEqual List(
"123;xyz", "xyz", "123")
}
}
}

sealed trait MatchTest {
def patternMatching(s: String): List[String] = s match {
case ~(IntRange(5, 10)) List("5-to-10")
case ~(IntRange(10, 20), i) List(s"range:$i")
case Integer(n) List(s"num-$n")
case ~(Regex("^a.*")) List("no-binding")
case ~(Regex("# ([A-Z]+).*"), a) List(a)
case re @ ~(Regex("([0-9]+);([a-z]+)"), (a, b)) List(b, a)
case x Nil
case ~(IntRange(5, 10)) List("5-to-10")
case ~(IntRange(10, 20), i) List(s"range:$i")
case Integer(n) List(s"num-$n")
case ~(Regex("^a.*")) List("no-binding")
case ~(Regex("# ([A-Z]+).*"), a) List(a)
case str @ ~(Regex("([0-9]+);([a-z]+)"), (a, b)) List(str, b, a)
case x Nil
}
}

Expand Down

0 comments on commit 7bc9b54

Please sign in to comment.