Permalink
Browse files

re-apply the struct branch.

  • Loading branch information...
1 parent 8d8a296 commit b291ac00b840fb000f80a0ec4e6864e95c17c9c1 Robey Pointer committed May 2, 2012
@@ -29,6 +29,10 @@ import com.twitter.util.Duration
import java.util.concurrent.atomic.AtomicReference
{{/ostrichServer}}
+{{#imports}}
+import {{parentPackage}}.{{{subPackage}} => _{{alias}}_}
+{{/imports}}
+
object {{name}} {
trait Iface {{syncExtends}}{
{{#syncFunctions}}
@@ -7,6 +7,9 @@ import java.nio.ByteBuffer
import com.twitter.finagle.SourcedException
import scala.collection.mutable
import scala.collection.{Map, Set}
+{{#imports}}
+import {{parentPackage}}.{{{subPackage}} => _{{alias}}_}
+{{/imports}}
{{/public}}
object {{name}} extends ThriftStructCodec[{{name}}] {
@@ -92,7 +95,6 @@ object {{name}} extends ThriftStructCodec[{{name}}] {
{{/fields}}
) extends {{name}}
-
{{#withProxy}}
/**
* This Proxy trait allows you to extend the {{name}} trait with additional state or
@@ -16,14 +16,6 @@
package com.twitter.handlebar
-case class Unpacker[T](
- document: AST.Document,
- unpacker: T => Dictionary,
- handlebar: Handlebar
-) extends (T => String) {
- def apply(item: T) = Handlebar.generate(document, unpacker(item))
-}
-
object Handlebar {
import AST._
import Dictionary._
@@ -121,5 +113,16 @@ case class Handlebar(document: AST.Document) {
* new function of `T => String` that unpacks items of type `T` and runs them through the
* template.
*/
- def generate[T](unpacker: T => Dictionary) = new Unpacker[T](document, unpacker, this)
+ def generate[T](unpacker: T => Dictionary) = new (T => String) {
+ def apply(item: T) = Handlebar.generate(document, unpacker(item))
+ }
+
+ def generate[T1, T2](unpacker: (T1, T2) => Dictionary) = new ((T1, T2) => String) {
+ def apply(t1: T1, t2: T2) = Handlebar.generate(document, unpacker(t1, t2))
+ }
+
+ def generate[T1, T2, T3](unpacker: (T1, T2, T3) => Dictionary) = new ((T1, T2, T3) => String) {
+ def apply(t1: T1, t2: T2, t3: T3) = Handlebar.generate(document, unpacker(t1, t2, t3))
+ }
}
+
@@ -83,7 +83,7 @@ case class TypeResolver(
/**
* Resolves all types in the given document.
*/
- def resolve(doc: Document): ResolvedDocument = {
+ def resolve(doc: Document, forcePrefix: Option[String] = None): ResolvedDocument = {
var resolver = this
val includes = doc.headers.collect { case i: Include => i }
val defBuf = new ArrayBuffer[Definition](doc.defs.size)
@@ -93,7 +93,7 @@ case class TypeResolver(
}
for (d <- doc.defs) {
- val ResolvedDefinition(d2, r2) = resolver.resolve(d)
+ val ResolvedDefinition(d2, r2) = resolver.resolve(d, forcePrefix)
resolver = r2
defBuf += d2
}
@@ -105,7 +105,7 @@ case class TypeResolver(
* Returns a new TypeResolver with the given include mapping added.
*/
def include(inc: Include): TypeResolver = {
- val resolvedDocument = TypeResolver().resolve(inc.document)
+ val resolvedDocument = TypeResolver().resolve(inc.document, Some("_" + inc.prefix + "_"))
copy(includeMap = includeMap + (inc.prefix -> resolvedDocument))
}
@@ -114,12 +114,12 @@ case class TypeResolver(
* typeMap, and then returns an updated TypeResolver with the new
* definition bound, plus the resolved definition.
*/
- def resolve(definition: Definition): ResolvedDefinition = {
+ def resolve(definition: Definition, forcePrefix: Option[String]): ResolvedDefinition = {
apply(definition) match {
case d @ Typedef(name, t) => ResolvedDefinition(d, define(name, t))
case e @ Enum(name, _) => ResolvedDefinition(e, define(name, EnumType(e)))
case s @ Senum(name, _) => ResolvedDefinition(s, define(name, TString))
- case s @ Struct(name, _) => ResolvedDefinition(s, define(name, StructType(s)))
+ case s @ Struct(name, _) => ResolvedDefinition(s, define(name, StructType(s, prefix = forcePrefix)))
case e @ Exception_(name, _) => ResolvedDefinition(e, define(e.name, StructType(e)))
case c @ Const(_, _, v) => ResolvedDefinition(c, define(c))
case s @ Service(name, _, _) => ResolvedDefinition(s, define(s))
@@ -229,6 +229,9 @@ abstract class JavaLike extends Generator with StructTemplate with ServiceTempla
val doc = normalizeCase(_doc)
val namespace_ = namespace(_doc)
val packageDir = namespacedFolder(outputPath, namespace_)
+ val includes = doc.headers.collect {
+ case x @ AST.Include(_, doc) => x
+ }
if (doc.consts.nonEmpty) {
val file = new File(packageDir, "Constants" + fileExtension)
@@ -241,11 +244,11 @@ abstract class JavaLike extends Generator with StructTemplate with ServiceTempla
}
doc.structs.foreach { struct =>
val file = new File(packageDir, struct.name + fileExtension)
- write(file, structTemplate((Some(namespace_), struct)))
+ write(file, structTemplate(struct, Some(namespace_), includes))
}
doc.services.foreach { service =>
val file = new File(packageDir, service.name + fileExtension)
- write(file, serviceTemplate((namespace_, JavaService(service, serviceOptions))))
+ write(file, serviceTemplate(JavaService(service, serviceOptions), namespace_, includes))
}
}
@@ -110,15 +110,14 @@ trait ServiceTemplate extends Generator { self: JavaLike =>
def ostrichService(s: Service) = Dictionary()
- lazy val serviceTemplate = templates("service").generate { pair: (String, JavaService) =>
- val (namespace, s) = pair
+ lazy val serviceTemplate = templates("service").generate { (s: JavaService, namespace: String, includes: Seq[Include]) =>
val service = s.service
val functionStructs =
service.functions flatMap { f =>
Seq(serviceFunctionArgsStruct(f), serviceFunctionResultStruct(f))
} map { struct =>
- structTemplate((None, struct)).indent
+ structTemplate(struct, None, includes).indent
} mkString("", "\n\n", "\n")
val parentName = service.parent.flatMap(_.service).map(_.name)
Dictionary(
@@ -197,8 +197,7 @@ trait StructTemplate extends Generator { self: JavaLike =>
// ----- struct
- lazy val structTemplate = templates("struct").generate { pair: (Option[String], StructLike) =>
- val (namespace, struct) = pair
+ lazy val structTemplate = templates("struct").generate { (struct: StructLike, myNamespace: Option[String], includes: Seq[Include]) =>
val fieldDictionaries = struct.fields.zipWithIndex map {
case (field, index) =>
Dictionary(
@@ -268,9 +267,23 @@ trait StructTemplate extends Generator { self: JavaLike =>
} else {
"Product"
}
+
+ val imports = includes map { include =>
+ (namespace(include.document), include.prefix)
+ } map {
+ case (PackageName(parentPackage, subPackage), prefix) => {
+ Dictionary(
+ "parentPackage" -> parentPackage,
+ "subPackage" -> subPackage,
+ "alias" -> prefix
+ )
+ }
+ }
+
Dictionary(
- "public" -> v(namespace.isDefined),
- "package" -> v(namespace.getOrElse("")),
+ "public" -> v(myNamespace.isDefined),
+ "package" -> v(myNamespace.getOrElse("")),
+ "imports" -> v(imports),
"name" -> v(struct.name),
"parentType" -> v(parentType),
"fields" -> v(fieldDictionaries),
@@ -0,0 +1,7 @@
+namespace java thrift.typedef1
+
+struct OneInt {
+ 1: i32 id
+}
+
+typedef list<OneInt> ManyInts
@@ -0,0 +1,8 @@
+namespace java thrift.typedef2
+
+include "typedef1.thrift"
+
+struct IntCollection {
+ 1: typedef1.ManyInts scores1
+ 2: set<typedef1.OneInt> scores2
+}
@@ -36,9 +36,9 @@ object TypeResolverSpec extends Specification {
}
"resolve dependent types" in {
- TypeResolver().resolve(enum) must beLike {
+ TypeResolver().resolve(enum, None) must beLike {
case ResolvedDefinition(enum2, resolver2) =>
- resolver2.resolve(struct) must beLike {
+ resolver2.resolve(struct, None) must beLike {
case ResolvedDefinition(struct2: Struct, _) =>
struct2.fields(3).`type` mustEqual enumType
true
@@ -131,5 +131,29 @@ object TypeResolverSpec extends Specification {
val resolver = TypeResolver().include(include)
resolver(service2) mustEqual service2.copy(parent = Some(ServiceParent("other.Super", Some(service1))))
}
+
+ "resolve a typedef from an included scope" in {
+ val oneInt = Struct("OneInt", Seq(Field(1, "id", TI32, None, Requiredness.Default)))
+ val typedefInt = Typedef("ManyInts", ListType(ReferenceType("OneInt"), None))
+ val doc1 = Document(Nil, Seq(oneInt, typedefInt))
+
+ val collectionStruct = Struct("IntCollection", Seq(
+ Field(1, "scores1", ReferenceType("typedef1.ManyInts"), None, Requiredness.Default),
+ Field(2, "scores2", SetType(ReferenceType("typedef1.OneInt"), None), None, Requiredness.Default)
+ ))
+ val doc2 = Document(Seq(Include("typedef1.thrift", doc1)), Seq(collectionStruct))
+
+ val resolvedDoc = TypeResolver().resolve(doc2).document
+ resolvedDoc.defs(0) must beLike {
+ case Struct(name, fields) => {
+ fields(0) must beLike {
+ case Field(1, _, ListType(StructType(_, Some("_typedef1_")), None), _, _) => true
+ }
+ fields(1) must beLike {
+ case Field(2, _, SetType(StructType(_, Some("_typedef1_")), None), _, _) => true
+ }
+ }
+ }
+ }
}
}

0 comments on commit b291ac0

Please sign in to comment.