Commit 28e7dbd3 authored by Kamil Rojewski's avatar Kamil Rojewski Committed by Wouter van Oortmerssen

TypeScript support (#4232)

* 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
parent adc50051
......@@ -66,5 +66,8 @@ build/VS2010/FlatBuffers.opensdf
build/VS2010/ipch/**/*.ipch
*.so
Testing/Temporary
.cproject
.settings/
.project
net/**/obj
node_modules/
......@@ -114,6 +114,8 @@ class BaseGenerator {
std::string WrapInNameSpace(const Definition &def) const;
std::string GetNameSpace(const Definition &def) const;
const Parser &parser_;
const std::string &path_;
const std::string &file_name_;
......
......@@ -358,7 +358,9 @@ struct IDLOptions {
bool allow_non_utf8;
std::string include_prefix;
bool binary_schema_comments;
bool skip_flatbuffers_import;
std::string go_namespace;
bool reexport_ts_modules;
// Possible options for the more general generator below.
enum Language {
......@@ -371,6 +373,7 @@ struct IDLOptions {
kPhp = 1 << 6,
kJson = 1 << 7,
kBinary = 1 << 8,
kTs = 1 << 9,
kMAX
};
......@@ -400,6 +403,8 @@ struct IDLOptions {
union_value_namespacing(true),
allow_non_utf8(false),
binary_schema_comments(false),
skip_flatbuffers_import(false),
reexport_ts_modules(true),
lang(IDLOptions::kJava),
lang_to_generate(0) {}
};
......@@ -650,7 +655,7 @@ extern bool GenerateCPP(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate JavaScript code from the definitions in the Parser object.
// Generate JavaScript or TypeScript code from the definitions in the Parser object.
// See idl_gen_js.
extern std::string GenerateJS(const Parser &parser);
extern bool GenerateJS(const Parser &parser,
......@@ -701,7 +706,7 @@ extern bool GenerateFBS(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated JavaScript code.
// Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp.
extern std::string JSMakeRule(const Parser &parser,
const std::string &path,
......
......@@ -963,6 +963,15 @@ flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
this.bytes_[offset + 1] = value >> 8;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
};
/**
* @param {number} offset
* @param {number} value
......@@ -974,6 +983,17 @@ flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
this.bytes_[offset + 3] = value >> 24;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
this.bytes_[offset + 2] = value >> 16;
this.bytes_[offset + 3] = value >> 24;
};
/**
* @param {number} offset
* @param {flatbuffers.Long} value
......@@ -983,6 +1003,15 @@ flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
this.writeInt32(offset + 4, value.high);
};
/**
* @param {number} offset
* @param {flatbuffers.Long} value
*/
flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
this.writeUint32(offset, value.low);
this.writeUint32(offset + 4, value.high);
};
/**
* @param {number} offset
* @param {number} value
......
......@@ -135,6 +135,20 @@ std::string BaseGenerator::WrapInNameSpace(const Definition &def) const {
return WrapInNameSpace(def.defined_namespace, def.name);
}
std::string BaseGenerator::GetNameSpace(const Definition &def) const {
const Namespace *ns = def.defined_namespace;
if (CurrentNameSpace() == ns) return "";
std::string qualified_name = qualifying_start_;
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
qualified_name += *it;
if (std::next(it) != ns->components.end()) {
qualified_name += qualifying_separator_;
}
}
return qualified_name;
}
// Generate a documentation comment, if available.
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
const CommentConfig *config, const char *prefix) {
......
......@@ -103,6 +103,8 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
" PATH \n"
" --include-prefix Prefix this path to any generated include statements.\n"
" PATH\n"
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
"FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
"FILEs after the -- must be binary flatbuffer format files.\n"
"Output files are named using the base file name of the input,\n"
......@@ -216,6 +218,10 @@ int FlatCompiler::Compile(int argc, const char** argv) {
grpc_enabled = true;
} else if(arg == "--bfbs-comments") {
opts.binary_schema_comments = true;
} else if(arg == "--no-fb-import") {
opts.skip_flatbuffers_import = true;
} else if(arg == "--no-ts-reexport") {
opts.reexport_ts_modules = false;
} else {
for (size_t i = 0; i < params_.num_generators; ++i) {
if (arg == params_.generators[i].generator_opt_long ||
......
......@@ -76,6 +76,11 @@ int main(int argc, const char *argv[]) {
flatbuffers::IDLOptions::kJs,
"Generate JavaScript code for tables/structs",
flatbuffers::JSMakeRule },
{ flatbuffers::GenerateJS, "-T", "--ts", "TypeScript",
nullptr,
flatbuffers::IDLOptions::kTs,
"Generate TypeScript code for tables/structs",
flatbuffers::JSMakeRule },
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#",
nullptr,
flatbuffers::IDLOptions::kCSharp,
......
This diff is collapsed.
#!/bin/sh
#
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
pushd "$(dirname $0)" >/dev/null
../flatc --ts --no-fb-import --gen-mutable monster_test.fbs
../flatc -b monster_test.fbs unicode_test.json
npm install @types/flatbuffers
mv monster_test_generated.js monster_test_generated.js.bak
tsc monster_test_generated.ts
npm uninstall @types/flatbuffers
node JavaScriptTest
mv monster_test_generated.js.bak monster_test_generated.js
......@@ -14,8 +14,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
../flatc --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
../flatc --cpp -o union_vector ./union_vector/union_vector.fbs
../flatc -b --schema --bfbs-comments monster_test.fbs
cd ../samples
......
This diff is collapsed.
// automatically generated by the FlatBuffers compiler, do not modify
import { flatbuffers } from "./flatbuffers"
/**
* @enum
*/
export namespace NamespaceA.NamespaceB{
export enum EnumInNestedNS{
A= 0,
B= 1,
C= 2
}};
/**
* @constructor
*/
export namespace NamespaceA.NamespaceB{
export class TableInNestedNS {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer= null;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {TableInNestedNS}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):TableInNestedNS {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {TableInNestedNS=} obj
* @returns {TableInNestedNS}
*/
static getRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
foo():number {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_foo(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startTableInNestedNS(builder:flatbuffers.Builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} foo
*/
static addFoo(builder:flatbuffers.Builder, foo:number) {
builder.addFieldInt32(0, foo, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endTableInNestedNS(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
}
}
/**
* @constructor
*/
export namespace NamespaceA.NamespaceB{
export class StructInNestedNS {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer= null;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {StructInNestedNS}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):StructInNestedNS {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @returns {number}
*/
a():number {
return this.bb.readInt32(this.bb_pos);
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_a(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 0);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @returns {number}
*/
b():number {
return this.bb.readInt32(this.bb_pos + 4);
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_b(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} a
* @param {number} b
* @returns {flatbuffers.Offset}
*/
static createStructInNestedNS(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
builder.prep(4, 8);
builder.writeInt32(b);
builder.writeInt32(a);
return builder.offset();
};
}
}
// automatically generated by the FlatBuffers compiler, do not modify
import { flatbuffers } from "./flatbuffers"
import * as NS9459827973991502386 from "./namespace_test1_generated";
export * from "./namespace_test1_generated";
/**
* @constructor
*/
export namespace NamespaceA{
export class TableInFirstNS {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer= null;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {TableInFirstNS}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):TableInFirstNS {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {TableInFirstNS=} obj
* @returns {TableInFirstNS}
*/
static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.TableInNestedNS}
*/
fooTable(obj?:NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @returns {NamespaceA.NamespaceB.EnumInNestedNS}
*/
fooEnum():NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb.readInt8(this.bb_pos + offset)) : NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A;
};
/**
* @param {NamespaceA.NamespaceB.EnumInNestedNS} value
* @returns {boolean}
*/
mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
var offset = this.bb.__offset(this.bb_pos, 6);
if (offset === 0) {
return false;
}
this.bb.writeInt8(this.bb_pos + offset, value);
return true;
};
/**
* @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.StructInNestedNS}
*/
fooStruct(obj?:NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startTableInFirstNS(builder:flatbuffers.Builder) {
builder.startObject(3);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} fooTableOffset
*/
static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offset) {
builder.addFieldOffset(0, fooTableOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
*/
static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS) {
builder.addFieldInt8(1, fooEnum, NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} fooStructOffset
*/
static addFooStruct(builder:flatbuffers.Builder, fooStructOffset:flatbuffers.Offset) {
builder.addFieldStruct(2, fooStructOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endTableInFirstNS(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
}
}
/**
* @constructor
*/
export namespace NamespaceC{
export class TableInC {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer= null;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {TableInC}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):TableInC {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {TableInC=} obj
* @returns {TableInC}
*/
static getRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {NamespaceA.TableInFirstNS=} obj
* @returns {NamespaceA.TableInFirstNS}
*/
referToA1(obj?:NamespaceA.TableInFirstNS):NamespaceA.TableInFirstNS {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {NamespaceA.SecondTableInA=} obj
* @returns {NamespaceA.SecondTableInA}
*/
referToA2(obj?:NamespaceA.SecondTableInA):NamespaceA.SecondTableInA {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startTableInC(builder:flatbuffers.Builder) {
builder.startObject(2);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} referToA1Offset
*/
static addReferToA1(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.Offset) {
builder.addFieldOffset(0, referToA1Offset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} referToA2Offset
*/
static addReferToA2(builder:flatbuffers.Builder, referToA2Offset:flatbuffers.Offset) {
builder.addFieldOffset(1, referToA2Offset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endTableInC(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
}
}
/**
* @constructor
*/
export namespace NamespaceA{
export class SecondTableInA {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer= null;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {SecondTableInA}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):SecondTableInA {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {SecondTableInA=} obj
* @returns {SecondTableInA}
*/
static getRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {NamespaceC.TableInC=} obj
* @returns {NamespaceC.TableInC}
*/
referToC(obj?:NamespaceC.TableInC):NamespaceC.TableInC {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new NamespaceC.TableInC).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startSecondTableInA(builder:flatbuffers.Builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} referToCOffset
*/
static addReferToC(builder:flatbuffers.Builder, referToCOffset:flatbuffers.Offset) {
builder.addFieldOffset(0, referToCOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endSecondTableInA(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
}
}
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