Generate Java doc comments in JavaDoc style
authorAdvay Mengle <advay.mengle.dev1@gmail.com>
Tue, 31 Mar 2015 11:21:47 +0000 (04:21 -0700)
committerWouter van Oortmerssen <wvo@google.com>
Thu, 2 Apr 2015 00:10:52 +0000 (17:10 -0700)
Tested by regenerating all tests/ generated sources; note that only
Monster.java changes.  Ran flattests as well.

Change-Id: I65b6ea7d208b0ccd6a0b34761162fed6ba391fc5

include/flatbuffers/idl.h
src/idl_gen_cpp.cpp
src/idl_gen_general.cpp
src/idl_gen_go.cpp
tests/MyGame/Example/Monster.java

index 6437362..7eb9fc4 100644 (file)
@@ -380,8 +380,12 @@ class Parser {
 // Utility functions for multiple generators:
 
 extern std::string MakeCamel(const std::string &in, bool first = true);
+
+struct CommentConfig;
+
 extern void GenComment(const std::vector<std::string> &dc,
                        std::string *code_ptr,
+                       const CommentConfig *config,
                        const char *prefix = "");
 
 // Container of options that may apply to any of the source/text generators.
index b8df56d..841c6ca 100644 (file)
@@ -124,13 +124,13 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
   if (enum_def.generated) return;
   std::string &code = *code_ptr;
   std::string &code_post = *code_ptr_post;
-  GenComment(enum_def.doc_comment, code_ptr);
+  GenComment(enum_def.doc_comment, code_ptr, nullptr);
   code += "enum " + enum_def.name + " {\n";
   for (auto it = enum_def.vals.vec.begin();
        it != enum_def.vals.vec.end();
        ++it) {
     auto &ev = **it;
-    GenComment(ev.doc_comment, code_ptr, "  ");
+    GenComment(ev.doc_comment, code_ptr, nullptr, "  ");
     code += "  " + GenEnumVal(enum_def, ev, opts) + " = ";
     code += NumToString(ev.value);
     code += (it + 1) != enum_def.vals.vec.end() ? ",\n" : "\n";
@@ -212,7 +212,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
 
   // Generate an accessor struct, with methods of the form:
   // type name() const { return GetField<type>(offset, defaultval); }
-  GenComment(struct_def.doc_comment, code_ptr);
+  GenComment(struct_def.doc_comment, code_ptr, nullptr);
   code += "struct " + struct_def.name;
   code += " FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table";
   code += " {\n";
@@ -221,7 +221,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
        ++it) {
     auto &field = **it;
     if (!field.deprecated) {  // Deprecated fields won't be accessible.
-      GenComment(field.doc_comment, code_ptr, "  ");
+      GenComment(field.doc_comment, code_ptr, nullptr, "  ");
       code += "  " + GenTypeGet(parser, field.value.type, " ", "const ", " *",
                                 true);
       code += field.name + "() const { return ";
@@ -436,7 +436,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
   // Generates manual padding and alignment.
   // Variables are private because they contain little endian data on all
   // platforms.
-  GenComment(struct_def.doc_comment, code_ptr);
+  GenComment(struct_def.doc_comment, code_ptr, nullptr);
   code += "MANUALLY_ALIGNED_STRUCT(" + NumToString(struct_def.minalign) + ") ";
   code += struct_def.name + " FLATBUFFERS_FINAL_CLASS {\n private:\n";
   int padding_id = 0;
@@ -501,7 +501,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
        it != struct_def.fields.vec.end();
        ++it) {
     auto &field = **it;
-    GenComment(field.doc_comment, code_ptr, "  ");
+    GenComment(field.doc_comment, code_ptr, nullptr, "  ");
     code += "  " + GenTypeGet(parser, field.value.type, " ", "const ", " &",
                               true);
     code += field.name + "() const { return ";
index 69c7313..f9190a2 100644 (file)
@@ -37,14 +37,34 @@ std::string MakeCamel(const std::string &in, bool first) {
   return s;
 }
 
+struct CommentConfig {
+  const char *first_line;
+  const char *content_line_prefix;
+  const char *last_line;
+};
+
 // Generate a documentation comment, if available.
 void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
-                const char *prefix) {
+                const CommentConfig *config, const char *prefix) {
+  if (dc.begin() == dc.end()) {
+    // Don't output empty comment blocks with 0 lines of comment content.
+    return;
+  }
+  
   std::string &code = *code_ptr;
+  if (config != nullptr && config->first_line != nullptr) {
+    code += std::string(prefix) + std::string(config->first_line) + "\n";
+  }
+  std::string line_prefix = std::string(prefix) +
+      ((config != nullptr && config->content_line_prefix != nullptr) ?
+       config->content_line_prefix : "///");
   for (auto it = dc.begin();
        it != dc.end();
        ++it) {
-    code += std::string(prefix) + "///" + *it + "\n";
+    code += line_prefix + *it + "\n";
+  }
+  if (config != nullptr && config->last_line != nullptr) {
+    code += std::string(prefix) + std::string(config->last_line) + "\n";
   }
 }
 
@@ -65,6 +85,7 @@ struct LanguageParameters {
   const char *namespace_end;
   const char *set_bb_byteorder;
   const char *includes;
+  CommentConfig comment_config;
 };
 
 LanguageParameters language_parameters[] = {
@@ -83,6 +104,11 @@ LanguageParameters language_parameters[] = {
     "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
     "import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
       "import com.google.flatbuffers.*;\n\n",
+    {
+      "/**",
+      " *",
+      " */",
+    },
   },
   {
     GeneratorOptions::kCSharp,
@@ -98,6 +124,11 @@ LanguageParameters language_parameters[] = {
     "\n}\n",
     "",
     "using FlatBuffers;\n\n",
+    {
+      nullptr,
+      "///",
+      nullptr,
+    },
   },
   // TODO: add Go support to the general generator.
   // WARNING: this is currently only used for generating make rules for Go.
@@ -115,6 +146,11 @@ LanguageParameters language_parameters[] = {
     "",
     "",
     "import (\n\tflatbuffers \"github.com/google/flatbuffers/go\"\n)",
+    {
+      nullptr,
+      "///",
+      nullptr,
+    },
   }
 };
 
@@ -228,13 +264,13 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def,
   // In Java, we use ints rather than the Enum feature, because we want them
   // to map directly to how they're used in C/C++ and file formats.
   // That, and Java Enums are expensive, and not universally liked.
-  GenComment(enum_def.doc_comment, code_ptr);
+  GenComment(enum_def.doc_comment, code_ptr, &lang.comment_config);
   code += "public class " + enum_def.name + lang.open_curly;
   for (auto it = enum_def.vals.vec.begin();
        it != enum_def.vals.vec.end();
        ++it) {
     auto &ev = **it;
-    GenComment(ev.doc_comment, code_ptr, "  ");
+    GenComment(ev.doc_comment, code_ptr, &lang.comment_config, "  ");
     code += "  public static";
     code += lang.const_decl;
     code += GenTypeBasic(lang, enum_def.underlying_type);
@@ -378,7 +414,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
   // public type name() {
   //   int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default;
   // }
-  GenComment(struct_def.doc_comment, code_ptr);
+  GenComment(struct_def.doc_comment, code_ptr, &lang.comment_config);
   code += "public class " + struct_def.name + lang.inheritance_marker;
   code += struct_def.fixed ? "Struct" : "Table";
   code += " {\n";
@@ -418,7 +454,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
        ++it) {
     auto &field = **it;
     if (field.deprecated) continue;
-    GenComment(field.doc_comment, code_ptr, "  ");
+    GenComment(field.doc_comment, code_ptr, &lang.comment_config, "  ");
     std::string type_name = GenTypeGet(lang, field.value.type);
     std::string type_name_dest =
       GenTypeGet(lang, DestinationType(lang, field.value.type, true));
index 24b7d03..b509439 100644 (file)
@@ -443,7 +443,7 @@ static void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
 static void GenStructAccessor(const StructDef &struct_def,
                               const FieldDef &field,
                               std::string *code_ptr) {
-  GenComment(field.doc_comment, code_ptr, "");
+  GenComment(field.doc_comment, code_ptr, nullptr, "");
   if (IsScalar(field.value.type.base_type)) {
     if (struct_def.fixed) {
       GetScalarFieldOfStruct(struct_def, field, code_ptr);
@@ -510,7 +510,7 @@ static void GenStruct(const StructDef &struct_def,
                       StructDef *root_struct_def) {
   if (struct_def.generated) return;
 
-  GenComment(struct_def.doc_comment, code_ptr);
+  GenComment(struct_def.doc_comment, code_ptr, nullptr);
   BeginClass(struct_def, code_ptr);
   if (&struct_def == root_struct_def) {
     // Generate a special accessor for the table that has been declared as
@@ -542,13 +542,13 @@ static void GenStruct(const StructDef &struct_def,
 static void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
   if (enum_def.generated) return;
 
-  GenComment(enum_def.doc_comment, code_ptr);
+  GenComment(enum_def.doc_comment, code_ptr, nullptr);
   BeginEnum(code_ptr);
   for (auto it = enum_def.vals.vec.begin();
        it != enum_def.vals.vec.end();
        ++it) {
     auto &ev = **it;
-    GenComment(ev.doc_comment, code_ptr, "\t");
+    GenComment(ev.doc_comment, code_ptr, nullptr, "\t");
     EnumMember(enum_def, ev, code_ptr);
   }
   EndEnum(code_ptr);
index 6104871..0c5d3d6 100644 (file)
@@ -30,8 +30,10 @@ public class Monster extends Table {
   public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
   public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
   public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
-  /// an example documentation comment: this will end up in the generated code
-  /// multiline too
+  /**
+   * an example documentation comment: this will end up in the generated code
+   * multiline too
+   */
   public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); }
   public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
   public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }