Skip to content

Instantly share code, notes, and snippets.

@utaal
Last active August 29, 2015 14:27
Show Gist options
  • Save utaal/d7f0b037387fe9a957e4 to your computer and use it in GitHub Desktop.
Save utaal/d7f0b037387fe9a957e4 to your computer and use it in GitHub Desktop.
project/target/
target/
organization := "io.buildo"
version := "0.0.1-SNAPSHOT"
scalaVersion := "2.11.6"
scalacOptions := Seq("-unchecked",
"-deprecation",
"-encoding", "utf8",
"-feature",
"-language:implicitConversions",
"-language:postfixOps",
"-language:reflectiveCalls"
)
resolvers ++= Seq(
// "spray repo" at "http://repo.spray.io/",
// "Mandubian repository snapshots" at "https://github.com/mandubian/mandubian-mvn/raw/master/snapshots/",
// "Mandubian repository releases" at "https://github.com/mandubian/mandubian-mvn/raw/master/releases/",
// "Sonatype Nexus Releases" at "https://oss.sonatype.org/content/repositories/releases",
// "Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
// "Typesafe" at "http://repo.typesafe.com/typesafe/releases",
// "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/",
// "buildo mvn" at "https://raw.github.com/buildo/mvn/master/releases",
Resolver.sonatypeRepo("snapshots"),
DefaultMavenRepository
)
libraryDependencies ++= Seq(
"org.rogach" %% "scallop" % "0.9.5",
"org.scalameta" % "scalameta" % "0.1.0-SNAPSHOT" cross CrossVersion.binary,
"org.scalatest" %% "scalatest" % "2.1.3" % "test",
"org.scalaz" %% "scalaz-core" % "7.1.3",
"org.json4s" %% "json4s-jackson" % "3.2.11",
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % "2.5.4"
)
package morpheus
import scala.meta._
import scala.meta.dialects.Scala211
package object extractors {
def parse(file: java.io.File): scala.meta.Source = file.parse[Source]
private[this] def getAllInfix(ainfix: internal.ast.Term, op: String): List[internal.ast.Term] = {
import scala.meta.internal.ast._
ainfix match {
case Term.ApplyInfix(subinfix: Term.ApplyInfix, Term.Name(`op`), Nil, List(term : Term)) =>
getAllInfix(subinfix, `op`) :+ term
case Term.ApplyInfix(term1: Term, Term.Name(`op`), Nil, List(term2 : Term)) =>
term1 :: term2 :: Nil
case term: Term => term :: Nil
}
}
/* private */ def extractRouteTerms(source: scala.meta.Source) = {
import scala.meta.internal.ast._
val routesTerm = {
val Source(Seq(pkg)) = source
val Pkg(pkgRef, pkgStats) = pkg
val List(trait_) = pkgStats.collect { case x: Defn.Trait => x }
val List(route) = trait_.templ.stats.get.collect { case x: Defn.Val => x }
val List(Mod.Annot(t)) = route.mods
val Defn.Val(_, routePats, _, routeTerm) = route
val Term.Block(List(routeStat : Term)) = routeTerm
routeStat
}
def recurse(routesTerm: Term, prefix: List[String]): List[(List[String], Term.ApplyInfix, Term)] = {
val routeTerms = getAllInfix(routesTerm, "~")
routeTerms.flatMap {
case Term.Apply(
Term.Apply(
Term.Name("pathPrefix"),
List(Lit.String(addPrefix))
),
List(Term.Block(List(t : Term)))
) => recurse(t, prefix :+ addPrefix)
case Term.Apply(routeTpe : Term.ApplyInfix, List(routeTerm : Term)) =>
List(
(prefix, routeTpe, routeTerm)
)
}
}
recurse(routesTerm, Nil)
}
object Tmp {
val f = new java.io.File("/Users/utaal/Src/buildo/scala-base-example/src/main/scala/CampingRouter.scala")
morpheus.extractors.extractRouteTerms(morpheus.extractors.parse(f))
val s = f.parse[Source]
import scala.meta.internal.ast._
val Source(Seq(pkg)) = s
val Pkg(pkgRef, pkgStats) = pkg
val List(trait_) = pkgStats.collect { case x: Defn.Trait => x }
val List(route) = trait_.templ.stats.get.collect { case x: Defn.Val => x }
val List(Mod.Annot(t)) = route.mods
val Defn.Val(_, routePats, _, routeTerm) = route
val Term.Block(List(routeStat)) = routeTerm
val Term.Apply(routeTpe, List(Term.Block(List(innerStat : Term.ApplyInfix)))) = routeStat
def getAllInfix(ainfix: Term.ApplyInfix, op: String): List[Term] = ainfix match {
case Term.ApplyInfix(subinfix: Term.ApplyInfix, Term.Name(op), Nil, List(term : Term)) =>
getAllInfix(subinfix, op) :+ term
case Term.ApplyInfix(term1: Term, Term.Name(op), Nil, List(term2 : Term)) =>
term1 :: term2 :: Nil
}
val List(r1, r2) = getAllInfix(innerStat, "~")
val Term.Apply(r1tpe : Term.ApplyInfix, r1term :: Nil) = r1
val Term.Apply(r2tpe : Term.ApplyInfix, r2term :: Nil) = r2
//comment in r1tpe.tokens
val r1dirs = getAllInfix(r1tpe, "&")
val List(
Term.Name("get"),
Term.Name("pathEnd"),
Term.Apply(Term.Name("parameters"), List(
Term.ApplyType(
Term.Select(Lit.Symbol('coolness), Term.Name("as")),
List(Type.Name("String"))
)
))
) = r1dirs
r1term.show[Structure]
val Term.Apply(
Term.Select(
Term.ApplyType(
Term.Name("returns"),
List(Type.Apply(Type.Name("List"), List(Type.Name("Camping"))))
),
Term.Name("ctrl")
),
List(Term.Eta(
Term.Select(Term.Name("campingController"), Term.Name("getByCoolness"))
))
) = r1term
}
}
package morpheus
package intermediate
sealed trait Type
object Type {
case class Name(name: String)
case class Apply(tpe: Type, args: Seq[Type])
}
case class CaseEnum(
name: String,
members: List[String])
case class CaseClass(
name: String, members: List[CaseClass.Member])
object CaseClass {
case class Member(
name: String, tpe: Type, desc: Option[String])
}
case class RouteParam(
name: Option[String],
tpe: Type,
required: Boolean,
desc: Option[String])
sealed trait RouteSegment
case object RouteSegment {
case class Param(rp: RouteParam) extends RouteSegment
case class String(str: String) extends RouteSegment
}
case class Route(
method: String,
route: List[RouteSegment],
params: List[RouteParam],
returns: Type,
body: Option[Route.Body],
ctrl: List[String],
// authenticated: Boolean,
desc: Option[String])
object Route {
case class Body(tpe: Type, desc: Option[String])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment