Skip to content

Commit 4fad471

Browse files
chenzhuoyujenkins
authored andcommitted
scrooge: support fully-qualified type name for fields
Problem Currently scrooge-generator does not support more than one dot in thrift file name. Suppose we have a thrift file with the name com.whatever.product.module1.thrift: ``` struct Foo { 1: i32 foo_field; } ``` and another thrift file that includes com.whatever.product.module1.thrift: ``` include "com.whatever.product.module1.thrift" struct Bar { 1: com.whatever.product.module1.Foo bar_field; } ``` This doesn't work with the current version of scrooge-generator. Solution Changing the `scopePrefix` to `Identifier` & other related places fixes this problem. Signed-off-by: Bryce Anderson <[email protected]> Differential Revision: https://phabricator.twitter.biz/D467516
1 parent 2189d28 commit 4fad471

File tree

8 files changed

+38
-16
lines changed

8 files changed

+38
-16
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace java foo.qualified.included
2+
3+
struct Bar {
4+
1: i32 x;
5+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace java foo.qualified
2+
3+
include "namespace_full.qualified.filename.thrift"
4+
5+
struct Foo {
6+
1: namespace_full.qualified.filename.Bar bar;
7+
}

scrooge-generator/src/main/scala/com/twitter/scrooge/AST/Header.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ case class Include(filePath: String, document: Document) extends Header {
2121
* Then we can use type Bar like this:
2222
* foo.Bar
2323
*/
24-
val prefix: SimpleID = SimpleID(filePath.split('/').last.split('.').head)
24+
val prefix: Identifier = Identifier(filePath.split('/').last.split('.').toSeq match {
25+
case Seq(v) => v
26+
case head :+ _ => head.mkString(".")
27+
})
2528
}
2629

2730
case class CppInclude(file: String) extends Header

scrooge-generator/src/main/scala/com/twitter/scrooge/AST/Type.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,16 @@ sealed trait NamedType extends FieldType {
2727
def sid: SimpleID
2828

2929
/** Filename of the containing file if the type is included from another file */
30-
def scopePrefix: Option[SimpleID]
30+
def scopePrefix: Option[Identifier]
3131
}
3232

33-
case class StructType(struct: StructLike, scopePrefix: Option[SimpleID] = None) extends NamedType {
33+
case class StructType(struct: StructLike, scopePrefix: Option[Identifier] = None)
34+
extends NamedType {
3435
val sid: SimpleID = struct.sid
3536
override def toString: String = "Struct(?)"
3637
}
3738

38-
case class EnumType(enum: Enum, scopePrefix: Option[SimpleID] = None) extends NamedType {
39+
case class EnumType(enum: Enum, scopePrefix: Option[Identifier] = None) extends NamedType {
3940
val sid: SimpleID = enum.sid
4041
override def toString: String = "Enum(?)"
4142
}

scrooge-generator/src/main/scala/com/twitter/scrooge/backend/CocoaGenerator.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class CocoaGenerator(
262262

263263
override def qualifyNamedType(t: NamedType, namespace: Option[Identifier] = None): Identifier =
264264
t.scopePrefix match {
265-
case Some(scope) => t.sid.prepend(getIncludeNamespace(scope.name).fullName)
265+
case Some(scope) => t.sid.prepend(getIncludeNamespace(scope.fullName).fullName)
266266
case None => t.sid.prepend(currentNamespace)
267267
}
268268

scrooge-generator/src/main/scala/com/twitter/scrooge/backend/Generator.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ abstract class TemplateGenerator(val resolvedDoc: ResolvedDocument)
383383
*/
384384
def qualifyNamedType(t: NamedType, namespace: Option[Identifier] = None): Identifier =
385385
t.scopePrefix match {
386-
case Some(scope) => t.sid.addScope(getIncludeNamespace(scope.name))
386+
case Some(scope) => t.sid.addScope(getIncludeNamespace(scope.fullName))
387387
case None if namespace.isDefined => t.sid.addScope(namespace.get)
388388
case None => t.sid
389389
}

scrooge-generator/src/main/scala/com/twitter/scrooge/frontend/TypeResolver.scala

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ case class ResolvedDocument(document: Document, resolver: TypeResolver) {
5959
def qualifyName(name: NamedType, language: String, defaultNamespace: String): Identifier = {
6060
name.scopePrefix match {
6161
case Some(filename) =>
62-
resolver.includeMap(filename.name).qualifySimpleID(name.sid, language, defaultNamespace)
62+
resolver.includeMap(filename.fullName).qualifySimpleID(name.sid, language, defaultNamespace)
6363
case None =>
6464
qualifySimpleID(name.sid, language, defaultNamespace)
6565
}
@@ -128,7 +128,10 @@ case class TypeResolver(
128128
def resolveFieldType(id: Identifier): FieldType = id match {
129129
case sid: SimpleID =>
130130
typeMap.getOrElse(sid.name, throw new TypeNotFoundException(sid.name, id))
131-
case qid: QualifiedID => getResolver(qid.names.head, qid).resolveFieldType(qid.tail)
131+
case qid: QualifiedID =>
132+
qid.names match {
133+
case head :+ tail => getResolver(head.mkString("."), qid).resolveFieldType(SimpleID(tail))
134+
}
132135
}
133136

134137
protected def resolveServiceParent(parent: ServiceParent): Service =
@@ -144,7 +147,10 @@ case class TypeResolver(
144147
case SimpleID(name, _) =>
145148
val const = constMap.getOrElse(name, throw new UndefinedConstantException(name, id))
146149
(const.fieldType, const.value)
147-
case qid: QualifiedID => getResolver(qid.names.head).resolveConst(qid.tail)
150+
case qid: QualifiedID =>
151+
qid.names match {
152+
case head :+ tail => getResolver(head.mkString("."), qid).resolveConst(SimpleID(tail))
153+
}
148154
}
149155

150156
/**
@@ -153,7 +159,7 @@ case class TypeResolver(
153159
private[scrooge] def withInclude(inc: Include): TypeResolver = {
154160
val resolver = TypeResolver()
155161
val resolvedDocument = resolver(inc.document, Some(inc.prefix))
156-
copy(includeMap = includeMap + (inc.prefix.name -> resolvedDocument))
162+
copy(includeMap = includeMap + (inc.prefix.fullName -> resolvedDocument))
157163
}
158164

159165
/**
@@ -180,7 +186,7 @@ case class TypeResolver(
180186
/**
181187
* Returns a new TypeResolver with the top level consts of `doc` added to the type map lazily.
182188
*/
183-
protected def withConstsFrom(doc: Document, scopePrefix: Option[SimpleID]): TypeResolver = {
189+
protected def withConstsFrom(doc: Document, scopePrefix: Option[Identifier]): TypeResolver = {
184190
val toAdd = doc.defs.collect {
185191
case c: ConstDefinition => (c.sid.name -> c)
186192
}.toMap
@@ -191,7 +197,7 @@ case class TypeResolver(
191197
/**
192198
* Returns a new TypeResolver with the top level types of `doc` added to the type map lazily.
193199
*/
194-
protected def withTypesFrom(doc: Document, scopePrefix: Option[SimpleID]): TypeResolver = {
200+
protected def withTypesFrom(doc: Document, scopePrefix: Option[Identifier]): TypeResolver = {
195201
val toAdd = doc.defs.collect {
196202
case d: Typedef => (d.sid.name -> d.fieldType)
197203
case s: Struct => (s.sid.name -> StructType(s, scopePrefix))
@@ -209,7 +215,7 @@ case class TypeResolver(
209215
*
210216
* @param scopePrefix the scope of the document if the document is an include
211217
*/
212-
def apply(doc: Document, scopePrefix: Option[SimpleID] = None): ResolvedDocument = {
218+
def apply(doc: Document, scopePrefix: Option[Identifier] = None): ResolvedDocument = {
213219
var resolver = this
214220
val includes = doc.headers.collect { case i: Include => i }
215221
val defBuf = new ArrayBuffer[Definition](doc.defs.size)
@@ -245,7 +251,7 @@ case class TypeResolver(
245251
* typeMap, and then returns an updated TypeResolver with the new
246252
* definition bound, plus the resolved definition.
247253
*/
248-
def apply(definition: Definition, scopePrefix: Option[SimpleID]): ResolvedDefinition = {
254+
def apply(definition: Definition, scopePrefix: Option[Identifier]): ResolvedDefinition = {
249255
definition match {
250256
case d: Typedef =>
251257
val resolved = apply(d.fieldType)

scrooge-generator/src/main/scala/com/twitter/scrooge/java_generator/ApacheJavaGenerator.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,11 @@ class ApacheJavaGenerator(
150150
*/
151151
def qualifyNamedType(
152152
sid: SimpleID,
153-
scopePrefixOption: Option[SimpleID],
153+
scopePrefixOption: Option[Identifier],
154154
fileNamespaceOption: Option[Identifier] = None
155155
): Identifier = {
156156
scopePrefixOption
157-
.map { scopePrefix => sid.addScope(getIncludeNamespace(scopePrefix.name)) }.orElse {
157+
.map { scopePrefix => sid.addScope(getIncludeNamespace(scopePrefix.fullName)) }.orElse {
158158
fileNamespaceOption.map { fileNamespace => sid.addScope(fileNamespace) }
159159
}.getOrElse {
160160
sid

0 commit comments

Comments
 (0)