Generating the most strict TS code possible (#4286)
authorKamil Rojewski <krojew@users.noreply.github.com>
Mon, 1 May 2017 23:05:53 +0000 (01:05 +0200)
committerWouter van Oortmerssen <aardappel@gmail.com>
Mon, 1 May 2017 23:05:53 +0000 (16:05 -0700)
* Eclipse ignore

* TypeScript support

* Prefixing enums

* Test results

* Merged JS and TS generators

* Fixed AppVeyor build problems

* Fixed more AppVeyor build problems

* Fixed more AppVeyor build problems

* Changed TS flag to options struct

* Storing options by value

* Removed unneeded const

* Re-export support for unions

* Uint support

* Casting bools to numbers for mutation

* TS shell tests

* Reverted generates js test file to original version

* Backing up js tests and properly generating test data

* Not importing flatbuffers for TS test generation

* Not overwriting generated js for tests

* AppVeyor test fixes

* Generating the most strict TS code possible

src/idl_gen_js.cpp
tests/TypeScriptTest.sh
tests/monster_test_generated.js
tests/monster_test_generated.ts
tests/namespace_test/namespace_test1_generated.js
tests/namespace_test/namespace_test1_generated.ts
tests/namespace_test/namespace_test2_generated.js
tests/namespace_test/namespace_test2_generated.ts

index b2839e1..6ce150e 100644 (file)
@@ -414,13 +414,16 @@ std::string GenDefaultValue(const Value &value, const std::string &context) {
   }
 }
 
-std::string GenTypeName(const Type &type, bool input) {
+std::string GenTypeName(const Type &type, bool input, bool allowNull = false) {
   if (!input) {
-    if (type.base_type == BASE_TYPE_STRING) {
-      return "string|Uint8Array";
-    }
-    if (type.base_type == BASE_TYPE_STRUCT) {
-      return WrapInNameSpace(*type.struct_def);
+    if (type.base_type == BASE_TYPE_STRING || type.base_type == BASE_TYPE_STRUCT) {
+      std::string name;
+      if (type.base_type == BASE_TYPE_STRING) {
+        name = "string|Uint8Array";
+      } else {
+        name = WrapInNameSpace(*type.struct_def);
+      }
+      return (allowNull) ? (name + "|null") : (name);
     }
   }
 
@@ -565,7 +568,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
     code += "  /**\n";
     code += "   * @type {flatbuffers.ByteBuffer}\n";
     code += "   */\n";
-    code += "  bb: flatbuffers.ByteBuffer= null;\n";
+    code += "  bb: flatbuffers.ByteBuffer;\n";
     code += "\n";
     code += "  /**\n";
     code += "   * @type {number}\n";
@@ -590,7 +593,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
     code += "  /**\n";
     code += "   * @type {flatbuffers.ByteBuffer}\n";
     code += "   */\n";
-    code += "  this.bb = null;\n";
+    code += "  this.bb = undefined;\n";
     code += "\n";
     code += "  /**\n";
     code += "   * @type {number}\n";
@@ -670,23 +673,23 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
       GenDocComment(field.doc_comment, code_ptr,
         std::string(field.value.type.base_type == BASE_TYPE_STRING ?
           "@param {flatbuffers.Encoding=} optionalEncoding\n" : "") +
-        "@returns {" + GenTypeName(field.value.type, false) + "}");
+        "@returns {" + GenTypeName(field.value.type, false, true) + "}");
       if (lang_.language == IDLOptions::kTs) {
         std::string prefix = MakeCamel(field.name, false) + "(";
         if (field.value.type.base_type == BASE_TYPE_STRING) {
-          code += prefix + "):string\n";
+          code += prefix + "):string|null\n";
           code += prefix + "optionalEncoding:flatbuffers.Encoding"+"):" +
-                  GenTypeName(field.value.type, false)+"\n";
+                  GenTypeName(field.value.type, false, true)+"\n";
           code += prefix + "optionalEncoding?:any";
         } else {
           code += prefix;
         }
         if (field.value.type.enum_def) {
           code += "):" +
-                  GenPrefixedTypeName(GenTypeName(field.value.type, false),
+                  GenPrefixedTypeName(GenTypeName(field.value.type, false, true),
                                       field.value.type.enum_def->file) + " {\n";
         } else {
-          code += "):" + GenTypeName(field.value.type, false) + " {\n";
+          code += "):" + GenTypeName(field.value.type, false, true) + " {\n";
         }
       } else {
         code += object_name + ".prototype." + MakeCamel(field.name, false);
@@ -717,11 +720,11 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
         case BASE_TYPE_STRUCT: {
           auto type = WrapInNameSpace(*field.value.type.struct_def);
           GenDocComment(field.doc_comment, code_ptr,
-            "@param {" + type + "=} obj\n@returns {" + type + "}");
+            "@param {" + type + "=} obj\n@returns {" + type + "|null}");
           if (lang_.language == IDLOptions::kTs) {
             type = GenPrefixedTypeName(type, field.value.type.struct_def->file);
             code += MakeCamel(field.name, false);
-            code += "(obj?:" + type + "):" + type + " {\n";
+            code += "(obj?:" + type + "):" + type + "|null {\n";
           } else {
             code += object_name + ".prototype." + MakeCamel(field.name, false);
             code += " = function(obj) {\n";
@@ -776,7 +779,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
             } else {
               code += prefix;
             }
-            code += "):" + vectortypename + " {\n";
+            code += "):" + vectortypename + "|null {\n";
           } else {
             code += object_name + ".prototype." + MakeCamel(field.name, false);
             code += " = function(index";
@@ -828,7 +831,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
             "@returns {?flatbuffers.Table}");
           if (lang_.language == IDLOptions::kTs) {
             code += MakeCamel(field.name, false);
-            code += "<T extends flatbuffers.Table>(obj:T):T {\n";
+            code += "<T extends flatbuffers.Table>(obj:T):T|null {\n";
           } else {
             code += object_name + ".prototype." + MakeCamel(field.name, false);
             code += " = function(obj) {\n";
@@ -924,7 +927,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
 
         if (lang_.language == IDLOptions::kTs) {
           code += MakeCamel(field.name, false);
-          code += "Array():" + GenType(vectorType) + "Array {\n" +
+          code += "Array():" + GenType(vectorType) + "Array|null {\n" +
                   offset_prefix;
         } else {
           code += object_name + ".prototype." + MakeCamel(field.name, false);
@@ -954,7 +957,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
 
     if (lang_.language == IDLOptions::kTs) {
       code += "static create" + struct_def.name + "(builder:flatbuffers.Builder";
-      code += arguments + "):flatbuffers.Offset {\n";
+      code += arguments + "):flatbuffers.Offset|null {\n";
     } else {
       code += object_name + ".create" + struct_def.name + " = function(builder";
       code += arguments + ") {\n";
@@ -1048,8 +1051,8 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
               type += " | Uint8Array";
             }
             code += "Vector(builder:flatbuffers.Builder, data:" + type +
-                    "):flatbuffers.Offset {\n";
-            code += "if(!data){\n  return null\n}\n";
+                    "):flatbuffers.Offset|null {\n";
+            code += "if(!data){\n  return null;\n}\n";
           } else {
             code += object_name + ".create" + MakeCamel(field.name);
             code += "Vector = function(builder, data) {\n";
index a5d44d5..54c6d08 100755 (executable)
@@ -18,6 +18,6 @@ pushd "$(dirname $0)" >/dev/null
 ../flatc --ts --no-fb-import --gen-mutable -o ts monster_test.fbs
 ../flatc -b monster_test.fbs unicode_test.json
 npm install @types/flatbuffers
-tsc ts/monster_test_generated.ts
+tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts
 npm uninstall @types/flatbuffers
 node JavaScriptTest ./ts/monster_test_generated
index 7b0165c..b49af0e 100644 (file)
@@ -50,7 +50,7 @@ MyGame.Example2.Monster = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -101,7 +101,7 @@ MyGame.Example.Test = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -185,7 +185,7 @@ MyGame.Example.TestSimpleTableWithEnum = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -267,7 +267,7 @@ MyGame.Example.Vec3 = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -439,7 +439,7 @@ MyGame.Example.Ability = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -522,7 +522,7 @@ MyGame.Example.Stat = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -552,7 +552,7 @@ MyGame.Example.Stat.getRootAsStat = function(bb, obj) {
 
 /**
  * @param {flatbuffers.Encoding=} optionalEncoding
- * @returns {string|Uint8Array}
+ * @returns {string|Uint8Array|null}
  */
 MyGame.Example.Stat.prototype.id = function(optionalEncoding) {
   var offset = this.bb.__offset(this.bb_pos, 4);
@@ -654,7 +654,7 @@ MyGame.Example.Monster = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -747,7 +747,7 @@ MyGame.Example.Monster.prototype.mutate_hp = function(value) {
 
 /**
  * @param {flatbuffers.Encoding=} optionalEncoding
- * @returns {string|Uint8Array}
+ * @returns {string|Uint8Array|null}
  */
 MyGame.Example.Monster.prototype.name = function(optionalEncoding) {
   var offset = this.bb.__offset(this.bb_pos, 10);
index 3ff1bf9..88bab89 100644 (file)
@@ -29,7 +29,7 @@ export class Monster {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -81,7 +81,7 @@ export class Test {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -166,7 +166,7 @@ export class TestSimpleTableWithEnum {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -249,7 +249,7 @@ export class Vec3 {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -422,7 +422,7 @@ export class Ability {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -506,7 +506,7 @@ export class Stat {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -534,10 +534,10 @@ static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
 
 /**
  * @param {flatbuffers.Encoding=} optionalEncoding
- * @returns {string|Uint8Array}
+ * @returns {string|Uint8Array|null}
  */
-id():string
-id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+id():string|null
+id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
 id(optionalEncoding?:any):string|Uint8Array {
   var offset = this.bb.__offset(this.bb_pos, 4);
   return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
@@ -641,7 +641,7 @@ export class Monster {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -732,10 +732,10 @@ mutate_hp(value:number):boolean {
 
 /**
  * @param {flatbuffers.Encoding=} optionalEncoding
- * @returns {string|Uint8Array}
+ * @returns {string|Uint8Array|null}
  */
-name():string
-name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+name():string|null
+name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
 name(optionalEncoding?:any):string|Uint8Array {
   var offset = this.bb.__offset(this.bb_pos, 10);
   return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
index 7551a18..ab61534 100644 (file)
@@ -28,7 +28,7 @@ NamespaceA.NamespaceB.TableInNestedNS = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -110,7 +110,7 @@ NamespaceA.NamespaceB.StructInNestedNS = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
index 42a1a69..54d935a 100644 (file)
@@ -18,7 +18,7 @@ export class TableInNestedNS {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -101,7 +101,7 @@ export class StructInNestedNS {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
index c1c25ef..4c083ed 100644 (file)
@@ -25,7 +25,7 @@ NamespaceA.TableInFirstNS = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -141,7 +141,7 @@ NamespaceC.TableInC = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
@@ -226,7 +226,7 @@ NamespaceA.SecondTableInA = function() {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  this.bb = null;
+  this.bb = undefined;
 
   /**
    * @type {number}
index d08366b..4d31bd1 100644 (file)
@@ -9,7 +9,7 @@ export class TableInFirstNS {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -126,7 +126,7 @@ export class TableInC {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}
@@ -212,7 +212,7 @@ export class SecondTableInA {
   /**
    * @type {flatbuffers.ByteBuffer}
    */
-  bb: flatbuffers.ByteBuffer= null;
+  bb: flatbuffers.ByteBuffer;
 
   /**
    * @type {number}