Skip to content

Commit

Permalink
Update scalameta to 4.0.0 RC1 (#53)
Browse files Browse the repository at this point in the history
* Update sbt to 1.2.1

* Migrage to scalameta 4.0.0-RC1

* Document ScalametaUtils

* Construct Term.Ref and Type.Ref by hand

* Format files

* Simplify command and remove unused vars

* Run scalafmt
  • Loading branch information
ngbinh authored and muuki88 committed Sep 17, 2018
1 parent a7d27ca commit 6d8424a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 22 deletions.
5 changes: 3 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name := "sbt-graphql"
organization := "rocks.muki"
sbtPlugin := true
enablePlugins(SbtPlugin)

val circeVersion = "0.9.3"
val catsVersion = "1.4.0"
Expand All @@ -12,8 +13,8 @@ libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % catsVersion,
"org.typelevel" %% "cats-testkit" % catsVersion % Test,
"org.scalaj" %% "scalaj-http" % "2.3.0",
"org.scalameta" %% "scalameta" % "3.7.4",
"org.scalatest" %% "scalatest" % "3.0.4" % Test
"org.scalameta" %% "scalameta" % "4.0.0-RC1",
"org.scalatest" %% "scalatest" % "3.0.5" % Test
)

// scripted test settings
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.1.0
sbt.version=1.2.3
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3")
addSbtPlugin("com.dwijnand" % "sbt-travisci" % "1.1.1")

// plugin project
libraryDependencies += "org.typelevel" %% "cats-core" % "1.0.0-MF"
libraryDependencies += "org.typelevel" %% "cats-core" % "1.4.0"

// testing
libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ case class ApolloSourceGenerator(fileName: String,
generateFieldType(field) { tpe =>
if (field.isObjectLike || field.isUnion) {
// prepend the type qualifier for nested object/case class structures
Type.Name((typeQualifiers :+ field.name.capitalize).mkString("."))
ScalametaUtils.typeRefOf(typeQualifiers, field.name.capitalize)
} else {
// this branch handles non-enum or case class types, which means we don't need the
// typeQualifiers here.
Expand Down Expand Up @@ -310,7 +310,7 @@ case class ApolloSourceGenerator(fileName: String,
val tpe = generateFieldType(field) { tpe =>
field.selection.map(_.interfaces).filter(_.nonEmpty) match {
case Some(interfaces) =>
interfaces.map(x => Type.Name(x): Type).reduce(Type.With(_, _))
interfaces.map(t => Type.Name(t): Type).reduce(Type.With(_, _))
case None =>
Type.Name(tpe.namedType.name)
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/rocks/muki/graphql/codegen/CodeGenStyles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object CodeGenStyles {
val Apollo: Style = context => {
val schema = context.schema
val inputFiles = context.graphQLFiles
val packageName = Term.Name(context.packageName)
val packageName = ScalametaUtils.termRefOf(context.packageName)

// Generate the GraphQLQuery trait
val graphQLQueryFile = context.targetDirectory / s"${GraphQLQueryGenerator.name}.scala"
Expand Down Expand Up @@ -129,7 +129,7 @@ object CodeGenStyles {
val Sangria: Style = context => {
val schema = context.schema
val inputFiles = context.graphQLFiles
val packageName = Term.Name(context.packageName)
val packageName = ScalametaUtils.termRefOf(context.packageName)

val result = for {
queryDocument <- DocumentLoader.merged(schema, inputFiles.toList)
Expand All @@ -151,7 +151,7 @@ object CodeGenStyles {
case Right(file) =>
List(file)
case Left(error) =>
context.log.err(s"Error during code genreation $error")
context.log.err(s"Error during code generation $error")
sys.error("Code generation failed")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object GraphQLQueryGenerator {
* @return the GraphQLTrait source code
*/
def sourceCode(packageName: String): Pkg =
q"""package ${Term.Name(packageName)} {
q"""package ${ScalametaUtils.termRefOf(packageName)} {
$traitDefinition
}"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ case class ScalametaGenerator(moduleName: Term.Name,
def generateTemplate(traits: List[String],
prefix: String = moduleName.value + "."): Template = {
// TODO fix constructor names
val templateInits = traits
.map(prefix + _)
.map(name => Init(Type.Name(name), Name.Anonymous(), Nil))
val templateInits = traits.map(name =>
Init(ScalametaUtils.typeRefOf(prefix, name), Name.Anonymous(), Nil))

val emptySelf = Self(Name.Anonymous(), None)

Template(Nil, templateInits, emptySelf, List.empty)
Expand All @@ -74,7 +74,7 @@ case class ScalametaGenerator(moduleName: Term.Name,
case schema.ListInputType(wrapped) =>
t"List[${typeOf(wrapped)}]"
case tpe: schema.ScalarType[_] if tpe == schema.IDType =>
Type.Name(moduleName.value + ".ID")
ScalametaUtils.typeRefOf(moduleName.value, "ID")
case tpe: schema.Type =>
genType(tpe)
}
Expand All @@ -85,7 +85,7 @@ case class ScalametaGenerator(moduleName: Term.Name,
def fieldType(field: TypedDocument.Field, prefix: String = ""): Type =
generateFieldType(field) { tpe =>
if (field.isObjectLike || field.isUnion)
Type.Name(prefix + field.name.capitalize)
ScalametaUtils.typeRefOf(prefix, field.name.capitalize)
else
Type.Name(tpe.namedType.name)
}
Expand All @@ -101,7 +101,7 @@ case class ScalametaGenerator(moduleName: Term.Name,
selection: TypedDocument.Selection): List[Stat] =
selection.fields.flatMap {
// render enumerations (union types)
case TypedDocument.Field(name, tpe, None, unionTypes)
case TypedDocument.Field(name, _, None, unionTypes)
if unionTypes.nonEmpty =>
val unionName = Type.Name(name.capitalize)
val objectName = Term.Name(unionName.value)
Expand Down Expand Up @@ -129,7 +129,7 @@ case class ScalametaGenerator(moduleName: Term.Name,
)

// render a nested case class for a deeper selection
case TypedDocument.Field(name, tpe, Some(selection), _) =>
case TypedDocument.Field(name, _, Some(selection), _) =>
val stats =
generateSelectionStats(prefix + name.capitalize + ".")(selection)
val params =
Expand Down Expand Up @@ -158,14 +158,15 @@ case class ScalametaGenerator(moduleName: Term.Name,
termParam(varDef.name, fieldType(varDef))
}

val name = operation.name.getOrElse(sys.error("found unnamed operation"))
val prefix = moduleName.value + "." + name + "."
val operationName =
operation.name.getOrElse(sys.error("found unnamed operation"))
val prefix = moduleName.value + "." + operationName + "."
val stats = generateSelectionStats(prefix)(operation.selection)
val params = generateSelectionParams(prefix)(operation.selection)

val tpeName = Type.Name(name)
val termName = Term.Name(name)
val variableTypeName = Type.Name(name + "Variables")
val tpeName = Type.Name(operationName)
val termName = Term.Name(operationName)
val variableTypeName = Type.Name(operationName + "Variables")

List[Stat](
q"case class $tpeName(..$params)",
Expand Down
40 changes: 40 additions & 0 deletions src/main/scala/rocks/muki/graphql/codegen/ScalametaUtils.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package rocks.muki.graphql.codegen

import scala.meta._

/**
* More robust way to parse [[Type.Ref]] and [[Term.Ref]] from String.
* More discussion: https://gitter.im/scalameta/scalameta?at=5b9ba14f8909f71f75d1b4bd
*/
object ScalametaUtils {

def typeRefOf(typeTerm: String): Type.Ref = {
typeTerm.parse[Type].get.asInstanceOf[Type.Ref]
}

def typeRefOf(term: String, typeTerm: String): Type.Ref = {
typeRefOf(term.split('.'), typeTerm)
}

def typeRefOf(terms: Seq[String], typeTerm: String): Type.Ref = {
if (terms.isEmpty) {
Type.Name(typeTerm)
} else {
Type.Select(termRefOf(terms), Type.Name(typeTerm))
}
}

// terms must not be empty
def termRefOf(terms: Seq[String]): Term.Ref = {
val termArray = terms.map(Term.Name(_))
termArray.headOption.fold(
throw new IllegalStateException("Term must not be empty")
) { head =>
termArray.drop(1).foldLeft[Term.Ref](head)((r, t) => Term.Select(r, t))
}
}

def termRefOf(term: String): Term.Ref = {
termRefOf(term.split('.'))
}
}

0 comments on commit 6d8424a

Please sign in to comment.