Fix to #360 - Updated the general generator (Java/C#) to emit fully qualified names...
authorOli Wilkinson <oli@evolutional.co.uk>
Sun, 29 Nov 2015 20:31:55 +0000 (15:31 -0500)
committerOli Wilkinson <oli@evolutional.co.uk>
Sat, 5 Dec 2015 18:42:09 +0000 (13:42 -0500)
25 files changed:
src/idl_gen_general.cpp
tests/FlatBuffers.Test/FlatBuffers.Test.csproj
tests/JavaTest.bat
tests/JavaTest.java
tests/JavaTest.sh
tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java [new file with mode: 0644]
tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php [new file with mode: 0644]
tests/namespace_test/NamespaceA/TableInFirstNS.cs [new file with mode: 0644]
tests/namespace_test/NamespaceA/TableInFirstNS.go [new file with mode: 0644]
tests/namespace_test/NamespaceA/TableInFirstNS.java [new file with mode: 0644]
tests/namespace_test/NamespaceA/TableInFirstNS.php [new file with mode: 0644]
tests/namespace_test/namespace_test1.fbs [new file with mode: 0644]
tests/namespace_test/namespace_test1_generated.h [new file with mode: 0644]
tests/namespace_test/namespace_test2.fbs [new file with mode: 0644]
tests/namespace_test/namespace_test2_generated.h [new file with mode: 0644]

index 88aa4da..936892f 100644 (file)
@@ -198,7 +198,28 @@ static bool IsEnum(const Type& type) {
   return type.enum_def != nullptr && IsInteger(type.base_type);
 }
 
-static std::string GenTypeBasic(const LanguageParameters &lang,
+// Ensure that a type is prefixed with its namespace whenever it is used
+// outside of its namespace.
+static std::string WrapInNameSpace(const Parser &parser, const Namespace *ns,
+    const std::string &name) {
+        if (parser.namespaces_.back() != ns) {
+            std::string qualified_name;
+            for (auto it = ns->components.begin();
+                it != ns->components.end(); ++it) {
+                    qualified_name += *it + ".";
+            }
+            return qualified_name + name;
+        } else {
+            return name;
+        }
+}
+
+static std::string WrapInNameSpace(const Parser &parser,
+    const Definition &def) {
+        return WrapInNameSpace(parser, def.defined_namespace, def.name);
+}
+
+static std::string GenTypeBasic(const LanguageParameters &lang, const Parser &parser,
                                 const Type &type,
                                 bool enableLangOverrides) {
   static const char *gtypename[] = {
@@ -210,30 +231,33 @@ static std::string GenTypeBasic(const LanguageParameters &lang,
 
   if (enableLangOverrides) {
     if (lang.language == IDLOptions::kCSharp) {
-      if (IsEnum(type)) return type.enum_def->name;
-      if (type.base_type == BASE_TYPE_STRUCT) return "Offset<" + type.struct_def->name + ">";
+      if (IsEnum(type)) return WrapInNameSpace(parser, *type.enum_def);
+      if (type.base_type == BASE_TYPE_STRUCT) {
+          return "Offset<" + WrapInNameSpace(parser, *type.struct_def) + ">";
+      }
     }
   }
 
   return gtypename[type.base_type * IDLOptions::kMAX + lang.language];
 }
 
-static std::string GenTypeBasic(const LanguageParameters &lang, const Type &type) {
-  return GenTypeBasic(lang, type, true);
+static std::string GenTypeBasic(const LanguageParameters &lang, const Parser &parser,
+                                const Type &type) {
+  return GenTypeBasic(lang, parser, type, true);
 }
 
-static std::string GenTypeGet(const LanguageParameters &lang,
+static std::string GenTypeGet(const LanguageParameters &lang, const Parser &parser,
                               const Type &type);
 
-static std::string GenTypePointer(const LanguageParameters &lang,
+static std::string GenTypePointer(const LanguageParameters &lang, const Parser &parser,
                                   const Type &type) {
   switch (type.base_type) {
     case BASE_TYPE_STRING:
       return lang.string_type;
     case BASE_TYPE_VECTOR:
-      return GenTypeGet(lang, type.VectorType());
+      return GenTypeGet(lang, parser, type.VectorType());
     case BASE_TYPE_STRUCT:
-      return type.struct_def->name;
+      return WrapInNameSpace(parser, *type.struct_def);
     case BASE_TYPE_UNION:
       // Unions in C# use a generic Table-derived type for better type safety
       if (lang.language == IDLOptions::kCSharp) return "TTable";
@@ -243,16 +267,16 @@ static std::string GenTypePointer(const LanguageParameters &lang,
   }
 }
 
-static std::string GenTypeGet(const LanguageParameters &lang,
+static std::string GenTypeGet(const LanguageParameters &lang, const Parser &parser,
                               const Type &type) {
   return IsScalar(type.base_type)
-    ? GenTypeBasic(lang, type)
-    : GenTypePointer(lang, type);
+    ? GenTypeBasic(lang, parser, type)
+    : GenTypePointer(lang, parser, type);
 }
 
 // Find the destination type the user wants to receive the value in (e.g.
 // one size higher signed types for unsigned serialized values in Java).
-static Type DestinationType(const LanguageParameters &lang, const Type &type,
+static Type DestinationType(const LanguageParameters &lang, const Parser &parser, const Type &type,
                             bool vectorelem) {
   if (lang.language != IDLOptions::kJava) return type;
   switch (type.base_type) {
@@ -263,26 +287,27 @@ static Type DestinationType(const LanguageParameters &lang, const Type &type,
     case BASE_TYPE_UINT:   return Type(BASE_TYPE_LONG);
     case BASE_TYPE_VECTOR:
       if (vectorelem)
-        return DestinationType(lang, type.VectorType(), vectorelem);
+        return DestinationType(lang, parser, type.VectorType(), vectorelem);
       // else fall thru:
     default: return type;
   }
 }
 
-static std::string GenOffsetType(const LanguageParameters &lang, const StructDef &struct_def) {
+static std::string GenOffsetType(const LanguageParameters &lang, const Parser &parser, 
+                                 const StructDef &struct_def) {
   if(lang.language == IDLOptions::kCSharp) {
-    return "Offset<" + struct_def.name + ">";
+    return "Offset<" + WrapInNameSpace(parser, struct_def) + ">";
   } else {
     return "int";
   }
 }
 
-static std::string GenOffsetConstruct(const LanguageParameters &lang,
+static std::string GenOffsetConstruct(const LanguageParameters &lang, const Parser &parser,
                                       const StructDef &struct_def,
                                       const std::string &variable_name)
 {
   if(lang.language == IDLOptions::kCSharp) {
-    return "new Offset<" + struct_def.name + ">(" + variable_name + ")";
+    return "new Offset<" + WrapInNameSpace(parser, struct_def) + ">(" + variable_name + ")";
   }
   return variable_name;
 }
@@ -296,9 +321,9 @@ static std::string GenVectorOffsetType(const LanguageParameters &lang) {
 }
 
 // Generate destination type name
-static std::string GenTypeNameDest(const LanguageParameters &lang, const Type &type)
+static std::string GenTypeNameDest(const LanguageParameters &lang, const Parser &parser, const Type &type)
 {
-  return GenTypeGet(lang, DestinationType(lang, type, true));
+  return GenTypeGet(lang, parser, DestinationType(lang, parser, type, true));
 }
 
 // Mask to turn serialized value into destination type value.
@@ -318,10 +343,10 @@ static std::string DestinationMask(const LanguageParameters &lang,
 }
 
 // Casts necessary to correctly read serialized data
-static std::string DestinationCast(const LanguageParameters &lang,
+static std::string DestinationCast(const LanguageParameters &lang, const Parser &parser,
                                    const Type &type) {
   if (type.base_type == BASE_TYPE_VECTOR) {
-    return DestinationCast(lang, type.VectorType());
+    return DestinationCast(lang, parser, type.VectorType());
   } else {
     switch (lang.language) {
     case IDLOptions::kJava:
@@ -331,7 +356,7 @@ static std::string DestinationCast(const LanguageParameters &lang,
 
     case IDLOptions::kCSharp:
       // Cast from raw integral types to enum.
-      if (IsEnum(type)) return "(" + type.enum_def->name + ")";
+      if (IsEnum(type)) return "(" + WrapInNameSpace(parser, *type.enum_def) + ")";
       break;
 
     default:
@@ -345,11 +370,11 @@ static std::string DestinationCast(const LanguageParameters &lang,
 // In Java, parameters representing unsigned numbers need to be cast down to their respective type.
 // For example, a long holding an unsigned int value would be cast down to int before being put onto the buffer.
 // In C#, one cast directly cast an Enum to its underlying type, which is essential before putting it onto the buffer.
-static std::string SourceCast(const LanguageParameters &lang,
+static std::string SourceCast(const LanguageParameters &lang, const Parser &parser,
                               const Type &type,
                               bool castFromDest) {
   if (type.base_type == BASE_TYPE_VECTOR) {
-    return SourceCast(lang, type.VectorType(), castFromDest);
+    return SourceCast(lang, parser, type.VectorType(), castFromDest);
   } else {
     switch (lang.language) {
       case IDLOptions::kJava:
@@ -360,7 +385,7 @@ static std::string SourceCast(const LanguageParameters &lang,
         }
         break;
       case IDLOptions::kCSharp:
-        if (IsEnum(type)) return "(" + GenTypeBasic(lang, type, false) + ")";
+        if (IsEnum(type)) return "(" + GenTypeBasic(lang, parser, type, false) + ")";
         break;
       default:
         break;
@@ -369,24 +394,24 @@ static std::string SourceCast(const LanguageParameters &lang,
   return "";
 }
 
-static std::string SourceCast(const LanguageParameters &lang,
+static std::string SourceCast(const LanguageParameters &lang, const Parser &parser,
                               const Type &type) {
-  return SourceCast(lang, type, true);
+  return SourceCast(lang, parser, type, true);
 }
 
-static std::string SourceCastBasic(const LanguageParameters &lang,
+static std::string SourceCastBasic(const LanguageParameters &lang, const Parser &parser,
                                    const Type &type,
                                    bool castFromDest) {
-  return IsScalar(type.base_type) ? SourceCast(lang, type, castFromDest) : "";
+  return IsScalar(type.base_type) ? SourceCast(lang, parser, type, castFromDest) : "";
 }
 
-static std::string SourceCastBasic(const LanguageParameters &lang,
+static std::string SourceCastBasic(const LanguageParameters &lang, const Parser &parser,
                                    const Type &type) {
-  return SourceCastBasic(lang, type, true);
+  return SourceCastBasic(lang, parser, type, true);
 }
 
 
-static std::string GenEnumDefaultValue(const Value &value) {
+static std::string GenEnumDefaultValue(const Parser &parser, const Value &value) {
   auto enum_def = value.type.enum_def;
   auto vec = enum_def->vals.vec;
   auto default_value = StringToInt(value.constant.c_str());
@@ -395,7 +420,7 @@ static std::string GenEnumDefaultValue(const Value &value) {
   for (auto it = vec.begin(); it != vec.end(); ++it) {
     auto enum_val = **it;
     if (enum_val.value == default_value) {
-      result = enum_def->name + "." + enum_val.name;
+      result = WrapInNameSpace(parser, *enum_def) + "." + enum_val.name;
       break;
     }
   }
@@ -403,13 +428,14 @@ static std::string GenEnumDefaultValue(const Value &value) {
   return result;
 }
 
-static std::string GenDefaultValue(const LanguageParameters &lang, const Value &value, bool enableLangOverrides) {
+static std::string GenDefaultValue(const LanguageParameters &lang, const Parser &parser, 
+                                   const Value &value, bool enableLangOverrides) {
   if (enableLangOverrides) {
     // handles both enum case and vector of enum case
     if (lang.language == IDLOptions::kCSharp &&
         value.type.enum_def != nullptr &&
         value.type.base_type != BASE_TYPE_UNION) {
-      return GenEnumDefaultValue(value);
+      return GenEnumDefaultValue(parser, value);
     }
   }
   return value.type.base_type == BASE_TYPE_BOOL
@@ -417,11 +443,13 @@ static std::string GenDefaultValue(const LanguageParameters &lang, const Value &
            : value.constant;
 }
 
-static std::string GenDefaultValue(const LanguageParameters &lang, const Value &value) {
-  return GenDefaultValue(lang, value, true);
+static std::string GenDefaultValue(const LanguageParameters &lang, const Parser &parser,
+                                   const Value &value) {
+  return GenDefaultValue(lang, parser, value, true);
 }
 
-static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Value &value, bool enableLangOverrides) {
+static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Parser &parser, 
+                                        const Value &value, bool enableLangOverrides) {
   if (!IsScalar(value.type.base_type)) {
     if (enableLangOverrides) {
       if (lang.language == IDLOptions::kCSharp) {
@@ -429,7 +457,7 @@ static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Va
         case BASE_TYPE_STRING:
           return "default(StringOffset)";
         case BASE_TYPE_STRUCT:
-          return "default(Offset<" + value.type.struct_def->name + ">)";
+          return "default(Offset<" + WrapInNameSpace(parser, *value.type.struct_def) + ">)";
         case BASE_TYPE_VECTOR:
           return "default(VectorOffset)";
         default:
@@ -439,14 +467,15 @@ static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Va
     }
     return "0";
   }
-  return GenDefaultValue(lang, value, enableLangOverrides);
+  return GenDefaultValue(lang, parser, value, enableLangOverrides);
 }
 
-static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Value &value) {
-  return GenDefaultValueBasic(lang, value, true);
+static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Parser &parser, 
+                                        const Value &value) {
+  return GenDefaultValueBasic(lang, parser, value, true);
 }
 
-static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def,
+static void GenEnum(const LanguageParameters &lang, const Parser &parser, EnumDef &enum_def,
                     std::string *code_ptr) {
   std::string &code = *code_ptr;
   if (enum_def.generated) return;
@@ -459,7 +488,7 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def,
   GenComment(enum_def.doc_comment, code_ptr, &lang.comment_config);
   code += std::string("public ") + lang.enum_decl + enum_def.name;
   if (lang.language == IDLOptions::kCSharp) {
-    code += lang.inheritance_marker + GenTypeBasic(lang, enum_def.underlying_type, false);
+    code += lang.inheritance_marker + GenTypeBasic(lang, parser, enum_def.underlying_type, false);
   }
   code += lang.open_curly;
   if (lang.language == IDLOptions::kJava) {
@@ -473,7 +502,7 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def,
     if (lang.language != IDLOptions::kCSharp) {
       code += "  public static";
       code += lang.const_decl;
-      code += GenTypeBasic(lang, enum_def.underlying_type, false);
+      code += GenTypeBasic(lang, parser, enum_def.underlying_type, false);
     }
     code += " " + ev.name + " = ";
     code += NumToString(ev.value);
@@ -519,19 +548,19 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def,
 }
 
 // Returns the function name that is able to read a value of the given type.
-static std::string GenGetter(const LanguageParameters &lang,
+static std::string GenGetter(const LanguageParameters &lang, const Parser &parser,
                              const Type &type) {
   switch (type.base_type) {
     case BASE_TYPE_STRING: return "__string";
     case BASE_TYPE_STRUCT: return "__struct";
     case BASE_TYPE_UNION:  return "__union";
-    case BASE_TYPE_VECTOR: return GenGetter(lang, type.VectorType());
+    case BASE_TYPE_VECTOR: return GenGetter(lang, parser, type.VectorType());
     default: {
       std::string getter = "bb." + FunctionStart(lang, 'G') + "et";
       if (type.base_type == BASE_TYPE_BOOL) {
         getter = "0!=" + getter;
-      } else if (GenTypeBasic(lang, type, false) != "byte") {
-        getter += MakeCamel(GenTypeBasic(lang, type, false));
+      } else if (GenTypeBasic(lang, parser, type, false) != "byte") {
+        getter += MakeCamel(GenTypeBasic(lang, parser, type, false));
       }
       return getter;
     }
@@ -540,13 +569,13 @@ static std::string GenGetter(const LanguageParameters &lang,
 
 // Direct mutation is only allowed for scalar fields.
 // Hence a setter method will only be generated for such fields.
-static std::string GenSetter(const LanguageParameters &lang,
+static std::string GenSetter(const LanguageParameters &lang, const Parser &parser,
                              const Type &type) {
   if (IsScalar(type.base_type)) {
     std::string setter = "bb." + FunctionStart(lang, 'P') + "ut";
-    if (GenTypeBasic(lang, type, false) != "byte" &&
+    if (GenTypeBasic(lang, parser, type, false) != "byte" && 
         type.base_type != BASE_TYPE_BOOL) {
-      setter += MakeCamel(GenTypeBasic(lang, type, false));
+      setter += MakeCamel(GenTypeBasic(lang, parser, type, false));
     }
     return setter;
   } else {
@@ -555,15 +584,15 @@ static std::string GenSetter(const LanguageParameters &lang,
 }
 
 // Returns the method name for use with add/put calls.
-static std::string GenMethod(const LanguageParameters &lang, const Type &type) {
+static std::string GenMethod(const LanguageParameters &lang, const Parser &parser, const Type &type) {
   return IsScalar(type.base_type)
-    ? MakeCamel(GenTypeBasic(lang, type, false))
+    ? MakeCamel(GenTypeBasic(lang, parser, type, false))
     : (IsStruct(type) ? "Struct" : "Offset");
 }
 
 // Recursively generate arguments for a constructor, to deal with nested
 // structs.
-static void GenStructArgs(const LanguageParameters &lang,
+static void GenStructArgs(const LanguageParameters &lang, const Parser &parser,
                           const StructDef &struct_def,
                           std::string *code_ptr, const char *nameprefix) {
   std::string &code = *code_ptr;
@@ -575,11 +604,11 @@ static void GenStructArgs(const LanguageParameters &lang,
       // Generate arguments for a struct inside a struct. To ensure names
       // don't clash, and to make it obvious these arguments are constructing
       // a nested struct, prefix the name with the field name.
-      GenStructArgs(lang, *field.value.type.struct_def, code_ptr,
+      GenStructArgs(lang, parser, *field.value.type.struct_def, code_ptr,
                     (nameprefix + (field.name + "_")).c_str());
     } else {
       code += ", ";
-      code += GenTypeBasic(lang, DestinationType(lang,field.value.type, false));
+      code += GenTypeBasic(lang, parser, DestinationType(lang, parser, field.value.type, false));
       code += " ";
       code += nameprefix;
       code += MakeCamel(field.name, lang.first_camel_upper);
@@ -590,7 +619,7 @@ static void GenStructArgs(const LanguageParameters &lang,
 // Recusively generate struct construction statements of the form:
 // builder.putType(name);
 // and insert manual padding.
-static void GenStructBody(const LanguageParameters &lang,
+static void GenStructBody(const LanguageParameters &lang, const Parser &parser,
                           const StructDef &struct_def,
                           std::string *code_ptr, const char *nameprefix) {
   std::string &code = *code_ptr;
@@ -605,12 +634,12 @@ static void GenStructBody(const LanguageParameters &lang,
       code += NumToString(field.padding) + ");\n";
     }
     if (IsStruct(field.value.type)) {
-      GenStructBody(lang, *field.value.type.struct_def, code_ptr,
+      GenStructBody(lang, parser, *field.value.type.struct_def, code_ptr,
                     (nameprefix + (field.name + "_")).c_str());
     } else {
       code += "    builder." + FunctionStart(lang, 'P') + "ut";
-      code += GenMethod(lang, field.value.type) + "(";
-      code += SourceCast(lang, field.value.type);
+      code += GenMethod(lang, parser, field.value.type) + "(";
+      code += SourceCast(lang, parser, field.value.type);
       auto argname = nameprefix + MakeCamel(field.name, lang.first_camel_upper);
       code += argname;
       code += ");\n";
@@ -675,11 +704,11 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
     auto &field = **it;
     if (field.deprecated) continue;
     GenComment(field.doc_comment, code_ptr, &lang.comment_config, "  ");
-    std::string type_name = GenTypeGet(lang, field.value.type);
-    std::string type_name_dest = GenTypeNameDest(lang, field.value.type);
+    std::string type_name = GenTypeGet(lang, parser, field.value.type);
+    std::string type_name_dest = GenTypeNameDest(lang, parser, field.value.type);
     std::string dest_mask = DestinationMask(lang, field.value.type, true);
-    std::string dest_cast = DestinationCast(lang, field.value.type);
-    std::string src_cast = SourceCast(lang, field.value.type);
+    std::string dest_cast = DestinationCast(lang, parser, field.value.type);
+    std::string src_cast = SourceCast(lang, parser, field.value.type);
     std::string method_start = "  public " + type_name_dest + " " +
                                MakeCamel(field.name, lang.first_camel_upper);
 
@@ -729,7 +758,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         type_name = type_name_dest;
       }
     }
-    std::string getter = dest_cast + GenGetter(lang, field.value.type);
+    std::string getter = dest_cast + GenGetter(lang, parser, field.value.type);
     code += method_start;
     std::string default_cast = "";
     // only create default casts for c# scalars or vectors of scalars
@@ -754,7 +783,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
       } else {
         code += offset_prefix + getter;
         code += "(o + bb_pos)" + dest_mask + " : " + default_cast;
-        code += GenDefaultValue(lang, field.value);
+        code += GenDefaultValue(lang, parser, field.value);
       }
     } else {
       switch (field.value.type.base_type) {
@@ -846,7 +875,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
       auto mutator_prefix = MakeCamel("mutate", lang.first_camel_upper);
       //a vector mutator also needs the index of the vector element it should mutate
       auto mutator_params = (field.value.type.base_type == BASE_TYPE_VECTOR ? "(int j, " : "(") +
-                            GenTypeNameDest(lang, underlying_type) + " " +
+                            GenTypeNameDest(lang, parser, underlying_type) + " " +
                             field.name + ") { ";
       auto setter_index = field.value.type.base_type == BASE_TYPE_VECTOR
                     ? "__vector(o) + j * " + NumToString(InlineSize(underlying_type))
@@ -859,11 +888,11 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         code += mutator_prefix + MakeCamel(field.name, true);
         code += mutator_params;
         if (struct_def.fixed) {
-          code += GenSetter(lang, underlying_type) + "(" + setter_index + ", ";
+          code += GenSetter(lang, parser, underlying_type) + "(" + setter_index + ", ";
           code += src_cast + setter_parameter + "); }\n";
         } else {
           code += "int o = __offset(" + NumToString(field.value.offset) + ");";
-          code += " if (o != 0) { " + GenSetter(lang, underlying_type);
+          code += " if (o != 0) { " + GenSetter(lang, parser, underlying_type);
           code += "(" + setter_index + ", " + src_cast + setter_parameter + "); return true; } else { return false; } }\n";
         }
       }
@@ -872,14 +901,14 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
   code += "\n";
   if (struct_def.fixed) {
     // create a struct constructor function
-    code += "  public static " + GenOffsetType(lang, struct_def) + " ";
+    code += "  public static " + GenOffsetType(lang, parser, struct_def) + " ";
     code += FunctionStart(lang, 'C') + "reate";
     code += struct_def.name + "(FlatBufferBuilder builder";
-    GenStructArgs(lang, struct_def, code_ptr, "");
+    GenStructArgs(lang, parser, struct_def, code_ptr, "");
     code += ") {\n";
-    GenStructBody(lang, struct_def, code_ptr, "");
+    GenStructBody(lang, parser, struct_def, code_ptr, "");
     code += "    return ";
-    code += GenOffsetConstruct(lang, struct_def, "builder." + std::string(lang.get_fbb_offset));
+    code += GenOffsetConstruct(lang, parser, struct_def, "builder." + std::string(lang.get_fbb_offset));
     code += ";\n  }\n";
   } else {
     // Generate a method that creates a table in one go. This is only possible
@@ -900,7 +929,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
     if (has_no_struct_fields && num_fields) {
       // Generate a table constructor of the form:
       // public static int createName(FlatBufferBuilder builder, args...)
-      code += "  public static " + GenOffsetType(lang, struct_def) + " ";
+      code += "  public static " + GenOffsetType(lang, parser, struct_def) + " ";
       code += FunctionStart(lang, 'C') + "reate" + struct_def.name;
       code += "(FlatBufferBuilder builder";
       for (auto it = struct_def.fields.vec.begin();
@@ -908,7 +937,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         auto &field = **it;
         if (field.deprecated) continue;
         code += ",\n      ";
-        code += GenTypeBasic(lang, DestinationType(lang, field.value.type, false));
+        code += GenTypeBasic(lang, parser, DestinationType(lang, parser, field.value.type, false));
         code += " ";
         code += field.name;
         if (!IsScalar(field.value.type.base_type)) code += "Offset";
@@ -917,7 +946,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         // supply all arguments, and thus won't compile when fields are added.
         if (lang.language != IDLOptions::kJava) {
           code += " = ";
-          code += GenDefaultValueBasic(lang, field.value);
+          code += GenDefaultValueBasic(lang, parser, field.value);
         }
       }
       code += ") {\n    builder.";
@@ -961,18 +990,18 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
       code += "  public static void " + FunctionStart(lang, 'A') + "dd";
       code += MakeCamel(field.name);
       code += "(FlatBufferBuilder builder, ";
-      code += GenTypeBasic(lang, DestinationType(lang, field.value.type, false));
+      code += GenTypeBasic(lang, parser, DestinationType(lang, parser, field.value.type, false));
       auto argname = MakeCamel(field.name, false);
       if (!IsScalar(field.value.type.base_type)) argname += "Offset";
       code += " " + argname + ") { builder." + FunctionStart(lang, 'A') + "dd";
-      code += GenMethod(lang, field.value.type) + "(";
+      code += GenMethod(lang, parser, field.value.type) + "(";
       code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
-      code += SourceCastBasic(lang, field.value.type);
+      code += SourceCastBasic(lang, parser, field.value.type);
       code += argname;
       if(!IsScalar(field.value.type.base_type) && field.value.type.base_type != BASE_TYPE_UNION && lang.language == IDLOptions::kCSharp) {
         code += ".Value";
       }
-      code += ", " + GenDefaultValue(lang, field.value, false);
+      code += ", " + GenDefaultValue(lang, parser, field.value, false);
       code += "); }\n";
       if (field.value.type.base_type == BASE_TYPE_VECTOR) {
         auto vector_type = field.value.type.VectorType();
@@ -983,7 +1012,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
           code += "  public static " + GenVectorOffsetType(lang) + " " + FunctionStart(lang, 'C') + "reate";
           code += MakeCamel(field.name);
           code += "Vector(FlatBufferBuilder builder, ";
-          code += GenTypeBasic(lang, vector_type) + "[] data) ";
+          code += GenTypeBasic(lang, parser, vector_type) + "[] data) ";
           code += "{ builder." + FunctionStart(lang, 'S') + "tartVector(";
           code += NumToString(elem_size);
           code += ", data." + FunctionStart(lang, 'L') + "ength, ";
@@ -991,9 +1020,9 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
           code += "); for (int i = data.";
           code += FunctionStart(lang, 'L') + "ength - 1; i >= 0; i--) builder.";
           code += FunctionStart(lang, 'A') + "dd";
-          code += GenMethod(lang, vector_type);
+          code += GenMethod(lang, parser, vector_type);
           code += "(";
-          code += SourceCastBasic(lang, vector_type, false);
+          code += SourceCastBasic(lang, parser, vector_type, false);
           code += "data[i]";
           if (lang.language == IDLOptions::kCSharp &&
             (vector_type.base_type == BASE_TYPE_STRUCT || vector_type.base_type == BASE_TYPE_STRING))
@@ -1011,7 +1040,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         code += "); }\n";
       }
     }
-    code += "  public static " + GenOffsetType(lang, struct_def) + " ";
+    code += "  public static " + GenOffsetType(lang, parser, struct_def) + " ";
     code += FunctionStart(lang, 'E') + "nd" + struct_def.name;
     code += "(FlatBufferBuilder builder) {\n    int o = builder.";
     code += FunctionStart(lang, 'E') + "ndObject();\n";
@@ -1025,11 +1054,11 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
         code += ");  // " + field.name + "\n";
       }
     }
-    code += "    return " + GenOffsetConstruct(lang, struct_def, "o") + ";\n  }\n";
+    code += "    return " + GenOffsetConstruct(lang, parser, struct_def, "o") + ";\n  }\n";
     if (parser.root_struct_def_ == &struct_def) {
       code += "  public static void ";
       code += FunctionStart(lang, 'F') + "inish" + struct_def.name;
-      code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(lang, struct_def) + " offset) {";
+      code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(lang, parser, struct_def) + " offset) {";
       code += " builder." + FunctionStart(lang, 'F') + "inish(offset";
       if (lang.language == IDLOptions::kCSharp) {
         code += ".Value";
@@ -1088,7 +1117,7 @@ bool GenerateGeneral(const Parser &parser,
   for (auto it = parser.enums_.vec.begin();
        it != parser.enums_.vec.end(); ++it) {
     std::string enumcode;
-    GenEnum(lang, **it, &enumcode);
+    GenEnum(lang, parser, **it, &enumcode);
     if (parser.opts.one_file) {
       one_file_code += enumcode;
     }
index c292a9c..13b1faa 100644 (file)
     <Compile Include="..\MyGame\Example\Vec3.cs">
       <Link>MyGame\Example\Vec3.cs</Link>
     </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\EnumInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\EnumInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\StructInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\StructInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\TableInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\TableInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\TableInFirstNS.cs">
+      <Link>NamespaceA\TableInFirstNS.cs</Link>
+    </Compile>
     <Compile Include="Assert.cs" />
     <Compile Include="ByteBufferTests.cs" />
     <Compile Include="FlatBuffersFuzzTests.cs" />
index 9ee9c4b..aa72613 100755 (executable)
@@ -17,5 +17,5 @@ rem Compile then run the Java test.
 
 set batch_file_dir=%~d0%~p0
 
-javac -g -classpath %batch_file_dir%\..\java;%batch_file_dir% JavaTest.java
-java -classpath %batch_file_dir%\..\java;%batch_file_dir% JavaTest
+javac -g -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test JavaTest.java
+java -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test JavaTest
index e017016..0bc0dba 100755 (executable)
@@ -17,6 +17,8 @@
 import java.io.*;
 import java.nio.ByteBuffer;
 import MyGame.Example.*;
+import NamespaceA.*;
+import NamespaceA.NamespaceB.*;
 import com.google.flatbuffers.FlatBufferBuilder;
 
 class JavaTest {
@@ -155,6 +157,8 @@ class JavaTest {
 
         TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
 
+        TestNamespaceNesting();
+
         System.out.println("FlatBuffers test: completed successfully");
     }
 
@@ -225,6 +229,19 @@ class JavaTest {
 
         TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
     }
+    
+    static void TestNamespaceNesting() {
+        // reference / manipulate these to verify compilation
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+        
+        TableInNestedNS.startTableInNestedNS(fbb);
+        TableInNestedNS.addFoo(fbb, 1234);
+        int nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb);
+        
+        TableInFirstNS.startTableInFirstNS(fbb);      
+        TableInFirstNS.addFooTable(fbb, nestedTableOff);
+        int off = TableInFirstNS.endTableInFirstNS(fbb);
+    }
 
     static <T> void TestEq(T a, T b) {
         if (!a.equals(b)) {
index 1a93aec..7dd7ea9 100755 (executable)
@@ -25,5 +25,5 @@ if [[ "$testdir" != "$thisdir" ]]; then
        exit 1
 fi
 
-javac -classpath ${testdir}/../java:${testdir} JavaTest.java
-java -classpath ${testdir}/../java:${testdir} JavaTest
+javac -classpath ${testdir}/../java:${testdir}:${testdir}/namespace_test JavaTest.java
+java -classpath ${testdir}/../java:${testdir}:${testdir}/namespace_test JavaTest
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
new file mode 100644 (file)
index 0000000..e57e1dc
--- /dev/null
@@ -0,0 +1,14 @@
+// automatically generated, do not modify
+
+namespace NamespaceA.NamespaceB
+{
+
+public enum EnumInNestedNS : sbyte
+{
+ A = 0,
+ B = 1,
+ C = 2,
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
new file mode 100644 (file)
index 0000000..4de2d0e
--- /dev/null
@@ -0,0 +1,9 @@
+// automatically generated, do not modify
+
+package NamespaceB
+
+const (
+       EnumInNestedNSA = 0
+       EnumInNestedNSB = 1
+       EnumInNestedNSC = 2
+)
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java
new file mode 100644 (file)
index 0000000..a919ace
--- /dev/null
@@ -0,0 +1,15 @@
+// automatically generated, do not modify
+
+package NamespaceA.NamespaceB;
+
+public final class EnumInNestedNS {
+  private EnumInNestedNS() { }
+  public static final byte A = 0;
+  public static final byte B = 1;
+  public static final byte C = 2;
+
+  private static final String[] names = { "A", "B", "C", };
+
+  public static String name(int e) { return names[e]; }
+};
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php
new file mode 100644 (file)
index 0000000..a39c0d7
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+// automatically generated, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+class EnumInNestedNS
+{
+    const A = 0;
+    const B = 1;
+    const C = 2;
+
+    private static $names = array(
+        "A",
+        "B",
+        "C",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
new file mode 100644 (file)
index 0000000..9eb853c
--- /dev/null
@@ -0,0 +1,25 @@
+// automatically generated, do not modify
+
+namespace NamespaceA.NamespaceB
+{
+
+using FlatBuffers;
+
+public sealed class StructInNestedNS : Struct {
+  public StructInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public int A { get { return bb.GetInt(bb_pos + 0); } }
+  public void MutateA(int a) { bb.PutInt(bb_pos + 0, a); }
+  public int B { get { return bb.GetInt(bb_pos + 4); } }
+  public void MutateB(int b) { bb.PutInt(bb_pos + 4, b); }
+
+  public static Offset<StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
+    builder.Prep(4, 8);
+    builder.PutInt(B);
+    builder.PutInt(A);
+    return new Offset<StructInNestedNS>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
new file mode 100644 (file)
index 0000000..66943e3
--- /dev/null
@@ -0,0 +1,25 @@
+// automatically generated, do not modify
+
+package NamespaceB
+
+import (
+       flatbuffers "github.com/google/flatbuffers/go"
+)
+type StructInNestedNS struct {
+       _tab flatbuffers.Struct
+}
+
+func (rcv *StructInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+       rcv._tab.Bytes = buf
+       rcv._tab.Pos = i
+}
+
+func (rcv *StructInNestedNS) A() int32 { return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(0)) }
+func (rcv *StructInNestedNS) B() int32 { return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(4)) }
+
+func CreateStructInNestedNS(builder *flatbuffers.Builder, a int32, b int32) flatbuffers.UOffsetT {
+    builder.Prep(4, 8)
+    builder.PrependInt32(b)
+    builder.PrependInt32(a)
+    return builder.Offset()
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
new file mode 100644 (file)
index 0000000..dfbe23e
--- /dev/null
@@ -0,0 +1,26 @@
+// automatically generated, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class StructInNestedNS extends Struct {
+  public StructInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public int a() { return bb.getInt(bb_pos + 0); }
+  public void mutateA(int a) { bb.putInt(bb_pos + 0, a); }
+  public int b() { return bb.getInt(bb_pos + 4); }
+  public void mutateB(int b) { bb.putInt(bb_pos + 4, b); }
+
+  public static int createStructInNestedNS(FlatBufferBuilder builder, int a, int b) {
+    builder.prep(4, 8);
+    builder.putInt(b);
+    builder.putInt(a);
+    return builder.offset();
+  }
+};
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php
new file mode 100644 (file)
index 0000000..962ea2c
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+// automatically generated, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class StructInNestedNS extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return StructInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetA()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+    /**
+     * @return int
+     */
+    public function GetB()
+    {
+        return $this->bb->getInt($this->bb_pos + 4);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createStructInNestedNS(FlatBufferBuilder $builder, $a, $b)
+    {
+        $builder->prep(4, 8);
+        $builder->putInt($b);
+        $builder->putInt($a);
+        return $builder->offset();
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
new file mode 100644 (file)
index 0000000..e04bc7c
--- /dev/null
@@ -0,0 +1,32 @@
+// automatically generated, do not modify
+
+namespace NamespaceA.NamespaceB
+{
+
+using FlatBuffers;
+
+public sealed class TableInNestedNS : Table {
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb) { return GetRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public TableInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public int Foo { get { int o = __offset(4); return o != 0 ? bb.GetInt(o + bb_pos) : (int)0; } }
+  public bool MutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.PutInt(o + bb_pos, foo); return true; } else { return false; } }
+
+  public static Offset<TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
+      int foo = 0) {
+    builder.StartObject(1);
+    TableInNestedNS.AddFoo(builder, foo);
+    return TableInNestedNS.EndTableInNestedNS(builder);
+  }
+
+  public static void StartTableInNestedNS(FlatBufferBuilder builder) { builder.StartObject(1); }
+  public static void AddFoo(FlatBufferBuilder builder, int foo) { builder.AddInt(0, foo, 0); }
+  public static Offset<TableInNestedNS> EndTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.EndObject();
+    return new Offset<TableInNestedNS>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
new file mode 100644 (file)
index 0000000..09815c4
--- /dev/null
@@ -0,0 +1,27 @@
+// automatically generated, do not modify
+
+package NamespaceB
+
+import (
+       flatbuffers "github.com/google/flatbuffers/go"
+)
+type TableInNestedNS struct {
+       _tab flatbuffers.Table
+}
+
+func (rcv *TableInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+       rcv._tab.Bytes = buf
+       rcv._tab.Pos = i
+}
+
+func (rcv *TableInNestedNS) Foo() int32 {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+       if o != 0 {
+               return rcv._tab.GetInt32(o + rcv._tab.Pos)
+       }
+       return 0
+}
+
+func TableInNestedNSStart(builder *flatbuffers.Builder) { builder.StartObject(1) }
+func TableInNestedNSAddFoo(builder *flatbuffers.Builder, foo int32) { builder.PrependInt32Slot(0, foo, 0) }
+func TableInNestedNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
new file mode 100644 (file)
index 0000000..344005d
--- /dev/null
@@ -0,0 +1,33 @@
+// automatically generated, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInNestedNS extends Table {
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb) { return getRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public TableInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public int foo() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, foo); return true; } else { return false; } }
+
+  public static int createTableInNestedNS(FlatBufferBuilder builder,
+      int foo) {
+    builder.startObject(1);
+    TableInNestedNS.addFoo(builder, foo);
+    return TableInNestedNS.endTableInNestedNS(builder);
+  }
+
+  public static void startTableInNestedNS(FlatBufferBuilder builder) { builder.startObject(1); }
+  public static void addFoo(FlatBufferBuilder builder, int foo) { builder.addInt(0, foo, 0); }
+  public static int endTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.endObject();
+    return o;
+  }
+};
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php
new file mode 100644 (file)
index 0000000..6bedae9
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+// automatically generated, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInNestedNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInNestedNS
+     */
+    public static function getRootAsTableInNestedNS(ByteBuffer $bb)
+    {
+        $obj = new TableInNestedNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFoo()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInNestedNS
+     */
+    public static function createTableInNestedNS(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->startObject(1);
+        self::addFoo($builder, $foo);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFoo(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->addIntX(0, $foo, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
new file mode 100644 (file)
index 0000000..a82b83c
--- /dev/null
@@ -0,0 +1,31 @@
+// automatically generated, do not modify
+
+namespace NamespaceA
+{
+
+using FlatBuffers;
+
+public sealed class TableInFirstNS : Table {
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb) { return GetRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public TableInFirstNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS FooTable { get { return GetFooTable(new NamespaceA.NamespaceB.TableInNestedNS()); } }
+  public NamespaceA.NamespaceB.TableInNestedNS GetFooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+  public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get { int o = __offset(6); return o != 0 ? (NamespaceA.NamespaceB.EnumInNestedNS)bb.GetSbyte(o + bb_pos) : NamespaceA.NamespaceB.EnumInNestedNS.A; } }
+  public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __offset(6); if (o != 0) { bb.PutSbyte(o + bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS FooStruct { get { return GetFooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); } }
+  public NamespaceA.NamespaceB.StructInNestedNS GetFooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
+
+  public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartObject(3); }
+  public static void AddFooTable(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.TableInNestedNS> fooTableOffset) { builder.AddOffset(0, fooTableOffset.Value, 0); }
+  public static void AddFooEnum(FlatBufferBuilder builder, NamespaceA.NamespaceB.EnumInNestedNS fooEnum) { builder.AddSbyte(1, (sbyte)fooEnum, 0); }
+  public static void AddFooStruct(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.StructInNestedNS> fooStructOffset) { builder.AddStruct(2, fooStructOffset.Value, 0); }
+  public static Offset<TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.EndObject();
+    return new Offset<TableInFirstNS>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.go b/tests/namespace_test/NamespaceA/TableInFirstNS.go
new file mode 100644 (file)
index 0000000..2f6f726
--- /dev/null
@@ -0,0 +1,55 @@
+// automatically generated, do not modify
+
+package NamespaceA
+
+import (
+       flatbuffers "github.com/google/flatbuffers/go"
+)
+type TableInFirstNS struct {
+       _tab flatbuffers.Table
+}
+
+func (rcv *TableInFirstNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+       rcv._tab.Bytes = buf
+       rcv._tab.Pos = i
+}
+
+func (rcv *TableInFirstNS) FooTable(obj *TableInNestedNS) *TableInNestedNS {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+       if o != 0 {
+               x := rcv._tab.Indirect(o + rcv._tab.Pos)
+               if obj == nil {
+                       obj = new(TableInNestedNS)
+               }
+               obj.Init(rcv._tab.Bytes, x)
+               return obj
+       }
+       return nil
+}
+
+func (rcv *TableInFirstNS) FooEnum() int8 {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+       if o != 0 {
+               return rcv._tab.GetInt8(o + rcv._tab.Pos)
+       }
+       return 0
+}
+
+func (rcv *TableInFirstNS) FooStruct(obj *StructInNestedNS) *StructInNestedNS {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+       if o != 0 {
+               x := o + rcv._tab.Pos
+               if obj == nil {
+                       obj = new(StructInNestedNS)
+               }
+               obj.Init(rcv._tab.Bytes, x)
+               return obj
+       }
+       return nil
+}
+
+func TableInFirstNSStart(builder *flatbuffers.Builder) { builder.StartObject(3) }
+func TableInFirstNSAddFooTable(builder *flatbuffers.Builder, fooTable flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(fooTable), 0) }
+func TableInFirstNSAddFooEnum(builder *flatbuffers.Builder, fooEnum int8) { builder.PrependInt8Slot(1, fooEnum, 0) }
+func TableInFirstNSAddFooStruct(builder *flatbuffers.Builder, fooStruct flatbuffers.UOffsetT) { builder.PrependStructSlot(2, flatbuffers.UOffsetT(fooStruct), 0) }
+func TableInFirstNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.java b/tests/namespace_test/NamespaceA/TableInFirstNS.java
new file mode 100644 (file)
index 0000000..c92c0f3
--- /dev/null
@@ -0,0 +1,32 @@
+// automatically generated, do not modify
+
+package NamespaceA;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInFirstNS extends Table {
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public TableInFirstNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+  public byte fooEnum() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateFooEnum(byte foo_enum) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
+
+  public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startObject(3); }
+  public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
+  public static void addFooEnum(FlatBufferBuilder builder, byte fooEnum) { builder.addByte(1, fooEnum, 0); }
+  public static void addFooStruct(FlatBufferBuilder builder, int fooStructOffset) { builder.addStruct(2, fooStructOffset, 0); }
+  public static int endTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.endObject();
+    return o;
+  }
+};
+
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.php b/tests/namespace_test/NamespaceA/TableInFirstNS.php
new file mode 100644 (file)
index 0000000..09a2c55
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+// automatically generated, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInFirstNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInFirstNS
+     */
+    public static function getRootAsTableInFirstNS(ByteBuffer $bb)
+    {
+        $obj = new TableInFirstNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInFirstNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getFooTable()
+    {
+        $obj = new TableInNestedNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function getFooEnum()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \NamespaceA\NamespaceB\EnumInNestedNS::A;
+    }
+
+    public function getFooStruct()
+    {
+        $obj = new StructInNestedNS();
+        $o = $this->__offset(8);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(3);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInFirstNS
+     */
+    public static function createTableInFirstNS(FlatBufferBuilder $builder, $foo_table, $foo_enum, $foo_struct)
+    {
+        $builder->startObject(3);
+        self::addFooTable($builder, $foo_table);
+        self::addFooEnum($builder, $foo_enum);
+        self::addFooStruct($builder, $foo_struct);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooTable(FlatBufferBuilder $builder, $fooTable)
+    {
+        $builder->addOffsetX(0, $fooTable, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param sbyte
+     * @return void
+     */
+    public static function addFooEnum(FlatBufferBuilder $builder, $fooEnum)
+    {
+        $builder->addSbyteX(1, $fooEnum, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooStruct(FlatBufferBuilder $builder, $fooStruct)
+    {
+        $builder->addStructX(2, $fooStruct, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/namespace_test1.fbs b/tests/namespace_test/namespace_test1.fbs
new file mode 100644 (file)
index 0000000..49449bf
--- /dev/null
@@ -0,0 +1,17 @@
+namespace NamespaceA.NamespaceB;
+
+table TableInNestedNS
+{
+    foo:int;
+}
+
+enum EnumInNestedNS:byte
+{
+       A, B, C
+}
+
+struct StructInNestedNS
+{
+    a:int;
+       b:int;
+}
\ No newline at end of file
diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h
new file mode 100644 (file)
index 0000000..3c5b9c4
--- /dev/null
@@ -0,0 +1,76 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+
+namespace NamespaceA {
+namespace NamespaceB {
+
+struct TableInNestedNS;
+struct StructInNestedNS;
+
+enum EnumInNestedNS {
+  EnumInNestedNS_A = 0,
+  EnumInNestedNS_B = 1,
+  EnumInNestedNS_C = 2
+};
+
+inline const char **EnumNamesEnumInNestedNS() {
+  static const char *names[] = { "A", "B", "C", nullptr };
+  return names;
+}
+
+inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) { return EnumNamesEnumInNestedNS()[static_cast<int>(e)]; }
+
+MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t a_;
+  int32_t b_;
+
+ public:
+  StructInNestedNS(int32_t _a, int32_t _b)
+    : a_(flatbuffers::EndianScalar(_a)), b_(flatbuffers::EndianScalar(_b)) { }
+
+  int32_t a() const { return flatbuffers::EndianScalar(a_); }
+  void mutate_a(int32_t _a) { flatbuffers::WriteScalar(&a_, _a); }
+  int32_t b() const { return flatbuffers::EndianScalar(b_); }
+  void mutate_b(int32_t _b) { flatbuffers::WriteScalar(&b_, _b); }
+};
+STRUCT_END(StructInNestedNS, 8);
+
+struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  int32_t foo() const { return GetField<int32_t>(4, 0); }
+  bool mutate_foo(int32_t _foo) { return SetField(4, _foo); }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, 4 /* foo */) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInNestedNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo(int32_t foo) { fbb_.AddElement<int32_t>(4, foo, 0); }
+  TableInNestedNSBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
+  TableInNestedNSBuilder &operator=(const TableInNestedNSBuilder &);
+  flatbuffers::Offset<TableInNestedNS> Finish() {
+    auto o = flatbuffers::Offset<TableInNestedNS>(fbb_.EndTable(start_, 1));
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb,
+   int32_t foo = 0) {
+  TableInNestedNSBuilder builder_(_fbb);
+  builder_.add_foo(foo);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceB
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
diff --git a/tests/namespace_test/namespace_test2.fbs b/tests/namespace_test/namespace_test2.fbs
new file mode 100644 (file)
index 0000000..59b9bb2
--- /dev/null
@@ -0,0 +1,10 @@
+include "namespace_test1.fbs";
+
+namespace NamespaceA;
+
+table TableInFirstNS
+{
+    foo_table:NamespaceB.TableInNestedNS;
+       foo_enum:NamespaceB.EnumInNestedNS;
+       foo_struct:NamespaceB.StructInNestedNS;
+}
diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h
new file mode 100644 (file)
index 0000000..0395824
--- /dev/null
@@ -0,0 +1,63 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace NamespaceA {
+namespace NamespaceB {
+struct TableInNestedNS;
+struct StructInNestedNS;
+}  // namespace NamespaceB
+}  // namespace NamespaceA
+
+namespace NamespaceA {
+
+struct TableInFirstNS;
+
+struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const { return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(4); }
+  NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() { return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(4); }
+  NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const { return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(6, 0)); }
+  bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) { return SetField(6, static_cast<int8_t>(_foo_enum)); }
+  const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const { return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(8); }
+  NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() { return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(8); }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<flatbuffers::uoffset_t>(verifier, 4 /* foo_table */) &&
+           verifier.VerifyTable(foo_table()) &&
+           VerifyField<int8_t>(verifier, 6 /* foo_enum */) &&
+           VerifyField<NamespaceA::NamespaceB::StructInNestedNS>(verifier, 8 /* foo_struct */) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInFirstNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) { fbb_.AddOffset(4, foo_table); }
+  void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) { fbb_.AddElement<int8_t>(6, static_cast<int8_t>(foo_enum), 0); }
+  void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) { fbb_.AddStruct(8, foo_struct); }
+  TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
+  TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &);
+  flatbuffers::Offset<TableInFirstNS> Finish() {
+    auto o = flatbuffers::Offset<TableInFirstNS>(fbb_.EndTable(start_, 3));
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb,
+   flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
+   NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
+   const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
+  TableInFirstNSBuilder builder_(_fbb);
+  builder_.add_foo_struct(foo_struct);
+  builder_.add_foo_table(foo_table);
+  builder_.add_foo_enum(foo_enum);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_