Commit 86777bd6 authored by Kamil Rojewski's avatar Kamil Rojewski Committed by Wouter van Oortmerssen

Generating the most strict TS code possible (#4286)

* 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
parent 8b92122f
...@@ -414,13 +414,16 @@ std::string GenDefaultValue(const Value &value, const std::string &context) { ...@@ -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 (!input) {
if (type.base_type == BASE_TYPE_STRING) { if (type.base_type == BASE_TYPE_STRING || type.base_type == BASE_TYPE_STRUCT) {
return "string|Uint8Array"; std::string name;
} if (type.base_type == BASE_TYPE_STRING) {
if (type.base_type == BASE_TYPE_STRUCT) { name = "string|Uint8Array";
return WrapInNameSpace(*type.struct_def); } else {
name = WrapInNameSpace(*type.struct_def);
}
return (allowNull) ? (name + "|null") : (name);
} }
} }
...@@ -565,7 +568,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -565,7 +568,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
code += " /**\n"; code += " /**\n";
code += " * @type {flatbuffers.ByteBuffer}\n"; code += " * @type {flatbuffers.ByteBuffer}\n";
code += " */\n"; code += " */\n";
code += " bb: flatbuffers.ByteBuffer= null;\n"; code += " bb: flatbuffers.ByteBuffer;\n";
code += "\n"; code += "\n";
code += " /**\n"; code += " /**\n";
code += " * @type {number}\n"; code += " * @type {number}\n";
...@@ -590,7 +593,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -590,7 +593,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
code += " /**\n"; code += " /**\n";
code += " * @type {flatbuffers.ByteBuffer}\n"; code += " * @type {flatbuffers.ByteBuffer}\n";
code += " */\n"; code += " */\n";
code += " this.bb = null;\n"; code += " this.bb = undefined;\n";
code += "\n"; code += "\n";
code += " /**\n"; code += " /**\n";
code += " * @type {number}\n"; code += " * @type {number}\n";
...@@ -670,23 +673,23 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -670,23 +673,23 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
GenDocComment(field.doc_comment, code_ptr, GenDocComment(field.doc_comment, code_ptr,
std::string(field.value.type.base_type == BASE_TYPE_STRING ? std::string(field.value.type.base_type == BASE_TYPE_STRING ?
"@param {flatbuffers.Encoding=} optionalEncoding\n" : "") + "@param {flatbuffers.Encoding=} optionalEncoding\n" : "") +
"@returns {" + GenTypeName(field.value.type, false) + "}"); "@returns {" + GenTypeName(field.value.type, false, true) + "}");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
std::string prefix = MakeCamel(field.name, false) + "("; std::string prefix = MakeCamel(field.name, false) + "(";
if (field.value.type.base_type == BASE_TYPE_STRING) { if (field.value.type.base_type == BASE_TYPE_STRING) {
code += prefix + "):string\n"; code += prefix + "):string|null\n";
code += prefix + "optionalEncoding:flatbuffers.Encoding"+"):" + code += prefix + "optionalEncoding:flatbuffers.Encoding"+"):" +
GenTypeName(field.value.type, false)+"\n"; GenTypeName(field.value.type, false, true)+"\n";
code += prefix + "optionalEncoding?:any"; code += prefix + "optionalEncoding?:any";
} else { } else {
code += prefix; code += prefix;
} }
if (field.value.type.enum_def) { if (field.value.type.enum_def) {
code += "):" + code += "):" +
GenPrefixedTypeName(GenTypeName(field.value.type, false), GenPrefixedTypeName(GenTypeName(field.value.type, false, true),
field.value.type.enum_def->file) + " {\n"; field.value.type.enum_def->file) + " {\n";
} else { } else {
code += "):" + GenTypeName(field.value.type, false) + " {\n"; code += "):" + GenTypeName(field.value.type, false, true) + " {\n";
} }
} else { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
...@@ -717,11 +720,11 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -717,11 +720,11 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
auto type = WrapInNameSpace(*field.value.type.struct_def); auto type = WrapInNameSpace(*field.value.type.struct_def);
GenDocComment(field.doc_comment, code_ptr, GenDocComment(field.doc_comment, code_ptr,
"@param {" + type + "=} obj\n@returns {" + type + "}"); "@param {" + type + "=} obj\n@returns {" + type + "|null}");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
type = GenPrefixedTypeName(type, field.value.type.struct_def->file); type = GenPrefixedTypeName(type, field.value.type.struct_def->file);
code += MakeCamel(field.name, false); code += MakeCamel(field.name, false);
code += "(obj?:" + type + "):" + type + " {\n"; code += "(obj?:" + type + "):" + type + "|null {\n";
} else { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
code += " = function(obj) {\n"; code += " = function(obj) {\n";
...@@ -776,7 +779,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -776,7 +779,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
} else { } else {
code += prefix; code += prefix;
} }
code += "):" + vectortypename + " {\n"; code += "):" + vectortypename + "|null {\n";
} else { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
code += " = function(index"; code += " = function(index";
...@@ -828,7 +831,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -828,7 +831,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
"@returns {?flatbuffers.Table}"); "@returns {?flatbuffers.Table}");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += MakeCamel(field.name, false); 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 { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
code += " = function(obj) {\n"; code += " = function(obj) {\n";
...@@ -924,7 +927,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -924,7 +927,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += MakeCamel(field.name, false); code += MakeCamel(field.name, false);
code += "Array():" + GenType(vectorType) + "Array {\n" + code += "Array():" + GenType(vectorType) + "Array|null {\n" +
offset_prefix; offset_prefix;
} else { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
...@@ -954,7 +957,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -954,7 +957,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static create" + struct_def.name + "(builder:flatbuffers.Builder"; code += "static create" + struct_def.name + "(builder:flatbuffers.Builder";
code += arguments + "):flatbuffers.Offset {\n"; code += arguments + "):flatbuffers.Offset|null {\n";
} else { } else {
code += object_name + ".create" + struct_def.name + " = function(builder"; code += object_name + ".create" + struct_def.name + " = function(builder";
code += arguments + ") {\n"; code += arguments + ") {\n";
...@@ -1048,8 +1051,8 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -1048,8 +1051,8 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
type += " | Uint8Array"; type += " | Uint8Array";
} }
code += "Vector(builder:flatbuffers.Builder, data:" + type + code += "Vector(builder:flatbuffers.Builder, data:" + type +
"):flatbuffers.Offset {\n"; "):flatbuffers.Offset|null {\n";
code += "if(!data){\n return null\n}\n"; code += "if(!data){\n return null;\n}\n";
} else { } else {
code += object_name + ".create" + MakeCamel(field.name); code += object_name + ".create" + MakeCamel(field.name);
code += "Vector = function(builder, data) {\n"; code += "Vector = function(builder, data) {\n";
......
...@@ -18,6 +18,6 @@ pushd "$(dirname $0)" >/dev/null ...@@ -18,6 +18,6 @@ pushd "$(dirname $0)" >/dev/null
../flatc --ts --no-fb-import --gen-mutable -o ts monster_test.fbs ../flatc --ts --no-fb-import --gen-mutable -o ts monster_test.fbs
../flatc -b monster_test.fbs unicode_test.json ../flatc -b monster_test.fbs unicode_test.json
npm install @types/flatbuffers 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 npm uninstall @types/flatbuffers
node JavaScriptTest ./ts/monster_test_generated node JavaScriptTest ./ts/monster_test_generated
...@@ -50,7 +50,7 @@ MyGame.Example2.Monster = function() { ...@@ -50,7 +50,7 @@ MyGame.Example2.Monster = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -101,7 +101,7 @@ MyGame.Example.Test = function() { ...@@ -101,7 +101,7 @@ MyGame.Example.Test = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -185,7 +185,7 @@ MyGame.Example.TestSimpleTableWithEnum = function() { ...@@ -185,7 +185,7 @@ MyGame.Example.TestSimpleTableWithEnum = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -267,7 +267,7 @@ MyGame.Example.Vec3 = function() { ...@@ -267,7 +267,7 @@ MyGame.Example.Vec3 = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -439,7 +439,7 @@ MyGame.Example.Ability = function() { ...@@ -439,7 +439,7 @@ MyGame.Example.Ability = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -522,7 +522,7 @@ MyGame.Example.Stat = function() { ...@@ -522,7 +522,7 @@ MyGame.Example.Stat = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -552,7 +552,7 @@ MyGame.Example.Stat.getRootAsStat = function(bb, obj) { ...@@ -552,7 +552,7 @@ MyGame.Example.Stat.getRootAsStat = function(bb, obj) {
/** /**
* @param {flatbuffers.Encoding=} optionalEncoding * @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array} * @returns {string|Uint8Array|null}
*/ */
MyGame.Example.Stat.prototype.id = function(optionalEncoding) { MyGame.Example.Stat.prototype.id = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 4); var offset = this.bb.__offset(this.bb_pos, 4);
...@@ -654,7 +654,7 @@ MyGame.Example.Monster = function() { ...@@ -654,7 +654,7 @@ MyGame.Example.Monster = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -747,7 +747,7 @@ MyGame.Example.Monster.prototype.mutate_hp = function(value) { ...@@ -747,7 +747,7 @@ MyGame.Example.Monster.prototype.mutate_hp = function(value) {
/** /**
* @param {flatbuffers.Encoding=} optionalEncoding * @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array} * @returns {string|Uint8Array|null}
*/ */
MyGame.Example.Monster.prototype.name = function(optionalEncoding) { MyGame.Example.Monster.prototype.name = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 10); var offset = this.bb.__offset(this.bb_pos, 10);
......
...@@ -29,7 +29,7 @@ export class Monster { ...@@ -29,7 +29,7 @@ export class Monster {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -81,7 +81,7 @@ export class Test { ...@@ -81,7 +81,7 @@ export class Test {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -166,7 +166,7 @@ export class TestSimpleTableWithEnum { ...@@ -166,7 +166,7 @@ export class TestSimpleTableWithEnum {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -249,7 +249,7 @@ export class Vec3 { ...@@ -249,7 +249,7 @@ export class Vec3 {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -422,7 +422,7 @@ export class Ability { ...@@ -422,7 +422,7 @@ export class Ability {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -506,7 +506,7 @@ export class Stat { ...@@ -506,7 +506,7 @@ export class Stat {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -534,10 +534,10 @@ static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat { ...@@ -534,10 +534,10 @@ static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
/** /**
* @param {flatbuffers.Encoding=} optionalEncoding * @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array} * @returns {string|Uint8Array|null}
*/ */
id():string id():string|null
id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
id(optionalEncoding?:any):string|Uint8Array { id(optionalEncoding?:any):string|Uint8Array {
var offset = this.bb.__offset(this.bb_pos, 4); var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
...@@ -641,7 +641,7 @@ export class Monster { ...@@ -641,7 +641,7 @@ export class Monster {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -732,10 +732,10 @@ mutate_hp(value:number):boolean { ...@@ -732,10 +732,10 @@ mutate_hp(value:number):boolean {
/** /**
* @param {flatbuffers.Encoding=} optionalEncoding * @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array} * @returns {string|Uint8Array|null}
*/ */
name():string name():string|null
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
name(optionalEncoding?:any):string|Uint8Array { name(optionalEncoding?:any):string|Uint8Array {
var offset = this.bb.__offset(this.bb_pos, 10); var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
......
...@@ -28,7 +28,7 @@ NamespaceA.NamespaceB.TableInNestedNS = function() { ...@@ -28,7 +28,7 @@ NamespaceA.NamespaceB.TableInNestedNS = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -110,7 +110,7 @@ NamespaceA.NamespaceB.StructInNestedNS = function() { ...@@ -110,7 +110,7 @@ NamespaceA.NamespaceB.StructInNestedNS = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
......
...@@ -18,7 +18,7 @@ export class TableInNestedNS { ...@@ -18,7 +18,7 @@ export class TableInNestedNS {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -101,7 +101,7 @@ export class StructInNestedNS { ...@@ -101,7 +101,7 @@ export class StructInNestedNS {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
......
...@@ -25,7 +25,7 @@ NamespaceA.TableInFirstNS = function() { ...@@ -25,7 +25,7 @@ NamespaceA.TableInFirstNS = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -141,7 +141,7 @@ NamespaceC.TableInC = function() { ...@@ -141,7 +141,7 @@ NamespaceC.TableInC = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
...@@ -226,7 +226,7 @@ NamespaceA.SecondTableInA = function() { ...@@ -226,7 +226,7 @@ NamespaceA.SecondTableInA = function() {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
this.bb = null; this.bb = undefined;
/** /**
* @type {number} * @type {number}
......
...@@ -9,7 +9,7 @@ export class TableInFirstNS { ...@@ -9,7 +9,7 @@ export class TableInFirstNS {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -126,7 +126,7 @@ export class TableInC { ...@@ -126,7 +126,7 @@ export class TableInC {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
...@@ -212,7 +212,7 @@ export class SecondTableInA { ...@@ -212,7 +212,7 @@ export class SecondTableInA {
/** /**
* @type {flatbuffers.ByteBuffer} * @type {flatbuffers.ByteBuffer}
*/ */
bb: flatbuffers.ByteBuffer= null; bb: flatbuffers.ByteBuffer;
/** /**
* @type {number} * @type {number}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment