diff --git a/Units/parser-typescript.r/ts-class-fq.d/args.ctags b/Units/parser-typescript.r/ts-class-fq.d/args.ctags new file mode 100644 index 0000000000..23a1949f38 --- /dev/null +++ b/Units/parser-typescript.r/ts-class-fq.d/args.ctags @@ -0,0 +1,3 @@ +--sort=no +--typescript-kinds=fcigemnzpvCgGal +--extras=+q diff --git a/Units/parser-typescript.r/ts-class-fq.d/expected.tags b/Units/parser-typescript.r/ts-class-fq.d/expected.tags new file mode 100644 index 0000000000..5ccc002c34 --- /dev/null +++ b/Units/parser-typescript.r/ts-class-fq.d/expected.tags @@ -0,0 +1,103 @@ +CPoint input.ts /^class CPoint {$/;" c +x input.ts /^ x: number;$/;" p class:CPoint +CPoint.x input.ts /^ x: number;$/;" p class:CPoint +y input.ts /^ y: number;$/;" p class:CPoint +CPoint.y input.ts /^ y: number;$/;" p class:CPoint +constructor input.ts /^ constructor(x: number, y: number) {$/;" m class:CPoint +CPoint.constructor input.ts /^ constructor(x: number, y: number) {$/;" m class:CPoint +x input.ts /^ constructor(x: number, y: number) {$/;" z method:CPoint.constructor +CPoint.constructor.x input.ts /^ constructor(x: number, y: number) {$/;" z method:CPoint.constructor +y input.ts /^ constructor(x: number, y: number) {$/;" z method:CPoint.constructor +CPoint.constructor.y input.ts /^ constructor(x: number, y: number) {$/;" z method:CPoint.constructor +BankAccount input.ts /^class BankAccount {$/;" c +balance input.ts /^ balance = 0;$/;" p class:BankAccount +BankAccount.balance input.ts /^ balance = 0;$/;" p class:BankAccount +deposit input.ts /^ deposit(credit: number) {$/;" m class:BankAccount +BankAccount.deposit input.ts /^ deposit(credit: number) {$/;" m class:BankAccount +credit input.ts /^ deposit(credit: number) {$/;" z method:BankAccount.deposit +BankAccount.deposit.credit input.ts /^ deposit(credit: number) {$/;" z method:BankAccount.deposit +CheckingAccount input.ts /^class CheckingAccount extends BankAccount {$/;" c +constructor input.ts /^ constructor(balance: number) {$/;" m class:CheckingAccount +CheckingAccount.constructor input.ts /^ constructor(balance: number) {$/;" m class:CheckingAccount +balance input.ts /^ constructor(balance: number) {$/;" z method:CheckingAccount.constructor +CheckingAccount.constructor.balance input.ts /^ constructor(balance: number) {$/;" z method:CheckingAccount.constructor +writeCheck input.ts /^ writeCheck(debit: number) {$/;" m class:CheckingAccount +CheckingAccount.writeCheck input.ts /^ writeCheck(debit: number) {$/;" m class:CheckingAccount +debit input.ts /^ writeCheck(debit: number) {$/;" z method:CheckingAccount.writeCheck +CheckingAccount.writeCheck.debit input.ts /^ writeCheck(debit: number) {$/;" z method:CheckingAccount.writeCheck +List input.ts /^class List {$/;" c +next input.ts /^ next: List = null;$/;" p class:List +List.next input.ts /^ next: List = null;$/;" p class:List +constructor input.ts /^ constructor(public item: T) {$/;" m class:List +List.constructor input.ts /^ constructor(public item: T) {$/;" m class:List +item input.ts /^ constructor(public item: T) {$/;" p class:List +List.item input.ts /^ constructor(public item: T) {$/;" p class:List +insertAfter input.ts /^ insertAfter(item: T) {$/;" m class:List +List.insertAfter input.ts /^ insertAfter(item: T) {$/;" m class:List +item input.ts /^ insertAfter(item: T) {$/;" z method:List.insertAfter +List.insertAfter.item input.ts /^ insertAfter(item: T) {$/;" z method:List.insertAfter +temp input.ts /^ var temp = this.next;$/;" l method:List.insertAfter +List.insertAfter.temp input.ts /^ var temp = this.next;$/;" l method:List.insertAfter +log input.ts /^ log() {$/;" m class:List +List.log input.ts /^ log() {$/;" m class:List +C input.ts /^class C {$/;" c +x input.ts /^ x: number;$/;" p class:C +C.x input.ts /^ x: number;$/;" p class:C +x input.ts /^ static x: string;$/;" p class:C +C.x input.ts /^ static x: string;$/;" p class:C +Messenger input.ts /^class Messenger {$/;" c +message input.ts /^ message = "Hello World";$/;" p class:Messenger +Messenger.message input.ts /^ message = "Hello World";$/;" p class:Messenger +start input.ts /^ start() {$/;" m class:Messenger +Messenger.start input.ts /^ start() {$/;" m class:Messenger +_this input.ts /^ var _this = this;$/;" l method:Messenger.start +Messenger.start._this input.ts /^ var _this = this;$/;" l method:Messenger.start +D input.ts /^class D {$/;" c +data input.ts /^ data: string | string[];$/;" p class:D +D.data input.ts /^ data: string | string[];$/;" p class:D +getData input.ts /^ getData() {$/;" m class:D +D.getData input.ts /^ getData() {$/;" m class:D +data input.ts /^ var data = this.data;$/;" l method:D.getData +D.getData.data input.ts /^ var data = this.data;$/;" l method:D.getData +Point input.ts /^class Point {$/;" c +fakePointBuilder input.ts /^ protected fakePointBuilder: () => { x: number, y: number };$/;" p class:Point +Point.fakePointBuilder input.ts /^ protected fakePointBuilder: () => { x: number, y: number };$/;" p class:Point +constructor input.ts /^ constructor(public x: number, public y: number) { }$/;" m class:Point +Point.constructor input.ts /^ constructor(public x: number, public y: number) { }$/;" m class:Point +x input.ts /^ constructor(public x: number, public y: number) { }$/;" p class:Point +Point.x input.ts /^ constructor(public x: number, public y: number) { }$/;" p class:Point +y input.ts /^ constructor(public x: number, public y: number) { }$/;" p class:Point +Point.y input.ts /^ constructor(public x: number, public y: number) { }$/;" p class:Point +length input.ts /^ public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }$/;" m class:Point +Point.length input.ts /^ public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }$/;" m class:Point +origin input.ts /^ static origin = new Point(0, 0);$/;" p class:Point +Point.origin input.ts /^ static origin = new Point(0, 0);$/;" p class:Point +A input.ts /^class A {$/;" c +x input.ts /^ private x: number;$/;" p class:A +A.x input.ts /^ private x: number;$/;" p class:A +y input.ts /^ protected y: number;$/;" p class:A +A.y input.ts /^ protected y: number;$/;" p class:A +fun input.ts /^ public fun: (a: 22 | 30, b: CPoint) => number | string;$/;" p class:A +A.fun input.ts /^ public fun: (a: 22 | 30, b: CPoint) => number | string;$/;" p class:A +f input.ts /^ static f(a: A, b: B) {$/;" m class:A +A.f input.ts /^ static f(a: A, b: B) {$/;" m class:A +a input.ts /^ static f(a: A, b: B) {$/;" z method:A.f +A.f.a input.ts /^ static f(a: A, b: B) {$/;" z method:A.f +b input.ts /^ static f(a: A, b: B) {$/;" z method:A.f +A.f.b input.ts /^ static f(a: A, b: B) {$/;" z method:A.f +getXAsT input.ts /^ getXAsT(): T {$/;" m class:A +A.getXAsT input.ts /^ getXAsT(): T {$/;" m class:A +register input.ts /^ register(...args) {$/;" m class:A +A.register input.ts /^ register(...args) {$/;" m class:A +args input.ts /^ register(...args) {$/;" z method:A.register +A.register.args input.ts /^ register(...args) {$/;" z method:A.register +longArgsFun input.ts /^ longArgsFun(options: {$/;" m class:A +A.longArgsFun input.ts /^ longArgsFun(options: {$/;" m class:A +options input.ts /^ longArgsFun(options: {$/;" z method:A.longArgsFun +A.longArgsFun.options input.ts /^ longArgsFun(options: {$/;" z method:A.longArgsFun +closure input.ts /^ closure($/;" m class:A +A.closure input.ts /^ closure($/;" m class:A +x input.ts /^ x: number,$/;" z method:A.closure +A.closure.x input.ts /^ x: number,$/;" z method:A.closure +normalizedPath input.ts /^ const normalizedPath = path === '\/*' ? '' : path;$/;" C method:A.closure +A.closure.normalizedPath input.ts /^ const normalizedPath = path === '\/*' ? '' : path;$/;" C method:A.closure diff --git a/Units/parser-typescript.r/ts-class-fq.d/input.ts b/Units/parser-typescript.r/ts-class-fq.d/input.ts new file mode 100644 index 0000000000..7497b6b6a6 --- /dev/null +++ b/Units/parser-typescript.r/ts-class-fq.d/input.ts @@ -0,0 +1,104 @@ +class CPoint { + x: number; + y: number; + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +class BankAccount { + balance = 0; + deposit(credit: number) { + this.balance += credit; + return this.balance; + } +} + +class CheckingAccount extends BankAccount { + constructor(balance: number) { + super(balance); + } + writeCheck(debit: number) { + this.balance -= debit; + } +} + +class List { + next: List = null; + constructor(public item: T) { + } + insertAfter(item: T) { + var temp = this.next; + this.next = new List(item); + this.next.next = temp; + } + log() { + console.log(this.item.name); + } + // ... +} + +class C { + x: number; + static x: string; +} + +class Messenger { + message = "Hello World"; + start() { + var _this = this; + setTimeout(function() { alert(_this.message); }, 3000); + } +}; + +class D { + data: string | string[]; + getData() { + var data = this.data; + return typeof data === "string" ? data : data.join(" "); + } +} + +class Point { + protected fakePointBuilder: () => { x: number, y: number }; + constructor(public x: number, public y: number) { } + public length() { return Math.sqrt(this.x * this.x + this.y * this.y); } + static origin = new Point(0, 0); +} + +class A { + private x: number; + protected y: number; + public fun: (a: 22 | 30, b: CPoint) => number | string; + + static f(a: A, b: B) { + a.x = 1; // Ok + b.x = 1; // Ok + a.y = 1; // Ok + b.y = 1; // Ok + } + + getXAsT(): T { + return this.x as T; + } + + register(...args) { + return this.f(...args); + } + + longArgsFun(options: { + root: string; + prefix?: string; + setHeaders?: Function; + send?: any; + }) { + return this.f(options); + } + + closure( + x: number, + ): (path: string, callback: Function) => any { + const normalizedPath = path === '/*' ? '' : path; + } +} diff --git a/docs/developers.rst b/docs/developers.rst index 4a22175711..2a4903d088 100644 --- a/docs/developers.rst +++ b/docs/developers.rst @@ -70,3 +70,9 @@ Szymon Tomasz Stefanek I'm a multilanguage developer and I use ctags with my own text editor which has some IDE capabilities. I'm the maintainer of the new C/C++ parser. + +Karol Samborski + + I like programming in multiple languages such as Haskell, C/C++, + TypeScript, PHP to name a few. Ctags are useful for me as I code mostly in + Vim. My goal here is to take care of the TypeScript parser. diff --git a/parsers/typescript.c b/parsers/typescript.c index 9b18a4d516..4113469e03 100644 --- a/parsers/typescript.c +++ b/parsers/typescript.c @@ -150,8 +150,7 @@ typedef struct sTokenInfo { tokenType type; keywordId keyword; vString *string; - vString *scope; - tsKind scopeParentKind; + int scope; unsigned long lineNumber; MIOPos filePosition; keywordId accessKeyword; @@ -227,10 +226,10 @@ typedef void (*ParserStateFree)(void *); static bool tryParser(Parser parser, ParserStateInit stInit, ParserStateFree stFree, tokenInfo *const token); -static void emitTag(const tokenInfo *const token, const tsKind kind) +static int emitTag(const tokenInfo *const token, const tsKind kind) { if (! TsKinds [kind].enabled) - return; + return CORK_NIL; static const char *const access [3] = { "private", @@ -244,12 +243,7 @@ static void emitTag(const tokenInfo *const token, const tsKind kind) initTagEntry (&e, name, kind); e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; - - if (token->scope && vStringLength (token->scope) > 0) - { - e.extensionFields.scopeKindIndex = token->scopeParentKind; - e.extensionFields.scopeName = vStringValue (token->scope); - } + e.extensionFields.scopeIndex = token->scope; switch (token->accessKeyword) { @@ -264,13 +258,13 @@ static void emitTag(const tokenInfo *const token, const tsKind kind) break; } - makeTagEntry (&e); + return makeTagEntry (&e); } static void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED) { tokenInfo *token = xMalloc (1, tokenInfo); - token->scope = NULL; + token->scope = CORK_NIL; token->string = NULL; return token; @@ -285,9 +279,8 @@ static void clearPoolToken (void *data) token->lineNumber = uwiGetLineNumber (); token->filePosition = uwiGetFilePosition (); - token->scope = vStringNewOrClear (token->scope); + token->scope = CORK_NIL; - token->scopeParentKind = TSTAG_CLASS; token->accessKeyword = KEYWORD_NONE; token->string = vStringNewOrClear (token->string); @@ -298,8 +291,6 @@ static void deletePoolToken (void *data) tokenInfo *token = data; if (token->string) vStringDelete (token->string); - if (token->scope) - vStringDelete (token->scope); eFree (token); } @@ -311,8 +302,7 @@ static void copyToken (tokenInfo *const dest, const tokenInfo *const src, dest->type = src->type; dest->keyword = src->keyword; vStringCopy (dest->string, src->string); - if (scope) - vStringCopy (dest->scope, src->scope); + if (scope) dest->scope = src->scope; } static void initToken (tokenInfo *const token, tokenType type) @@ -859,7 +849,7 @@ static void skipBlocksTillType (tokenType type, tokenInfo *const token) } while (parsed && ! isType (token, type)); } -static void parseInterfaceBody (vString *const scope, tokenInfo *const token) +static void parseInterfaceBody (const int scope, tokenInfo *const token) { bool parsed; @@ -910,8 +900,7 @@ static void parseInterfaceBody (vString *const scope, tokenInfo *const token) { member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); - member->scopeParentKind = TSTAG_INTERFACE; + member->scope = scope; } else if (! member && isType (token, TOKEN_PARENS)) { @@ -948,7 +937,7 @@ static void parseInterfaceBody (vString *const scope, tokenInfo *const token) } } -static void parseInterface (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseInterface (const int scope, tokenInfo *const token) { bool parsed; @@ -965,28 +954,14 @@ static void parseInterface (vString *const scope, tsKind scopeParentKind, tokenI if (! parsed) return; - if (scope) - { - vStringCopy (token->scope, scope); - token->scopeParentKind = scopeParentKind; - } - - emitTag (token, TSTAG_INTERFACE); + token->scope = scope; - vString *nscope = vStringNew (); - if (scope) - { - vStringCopy (nscope, scope); - vStringPut (nscope, '.'); - } - vStringCat (nscope, token->string); + const int nscope = emitTag (token, TSTAG_INTERFACE); parseInterfaceBody (nscope, token); - - vStringDelete (nscope); } -static void parseType (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseType (const int scope, tokenInfo *const token) { bool parsed; @@ -1002,16 +977,12 @@ static void parseType (vString *const scope, tsKind scopeParentKind, tokenInfo * if (! parsed) return; - if (scope) - { - vStringCopy (token->scope, scope); - token->scopeParentKind = scopeParentKind; - } + token->scope = scope; emitTag (token, TSTAG_ALIAS); skipBlocksTillType (TOKEN_SEMICOLON, token); } -static void parseEnumBody (vString *const scope, tokenInfo *const token) +static void parseEnumBody (const int scope, tokenInfo *const token) { bool parsed; @@ -1057,8 +1028,7 @@ static void parseEnumBody (vString *const scope, tokenInfo *const token) { member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); - member->scopeParentKind = TSTAG_ENUM; + member->scope = scope; emitTag (member, TSTAG_ENUMERATOR); } else if (isType (token, TOKEN_COMMA)) @@ -1075,7 +1045,7 @@ static void parseEnumBody (vString *const scope, tokenInfo *const token) } } -static void parseEnum (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseEnum (const int scope, tokenInfo *const token) { bool parsed; @@ -1091,27 +1061,13 @@ static void parseEnum (vString *const scope, tsKind scopeParentKind, tokenInfo * if (! parsed) return; - if (scope) - { - vStringCopy (token->scope, scope); - token->scopeParentKind = scopeParentKind; - } - emitTag (token, TSTAG_ENUM); - - vString *nscope = vStringNew (); - if (scope) - { - vStringCopy (nscope, scope); - vStringPut (nscope, '.'); - } - vStringCat (nscope, token->string); + token->scope = scope; + const int nscope = emitTag (token, TSTAG_ENUM); parseEnumBody (nscope, token); - - vStringDelete (nscope); } -static void parseVariable (bool constVar, bool localVar, vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseVariable (bool constVar, bool localVar, const int scope, tokenInfo *const token) { tokenInfo *member = NULL; bool parsed = false; @@ -1187,11 +1143,7 @@ static void parseVariable (bool constVar, bool localVar, vString *const scope, t { member = newToken (); copyToken (member, token, false); - if (scope) - { - vStringCopy (member->scope, scope); - member->scopeParentKind = scopeParentKind; - } + member->scope = scope; emitTag (member, varKind); deleteToken (member); } @@ -1200,7 +1152,7 @@ static void parseVariable (bool constVar, bool localVar, vString *const scope, t switch (token->keyword) { case KEYWORD_enum: - parseEnum (scope, scopeParentKind, token); + parseEnum (scope, token); break; case KEYWORD_of: case KEYWORD_in: @@ -1217,7 +1169,7 @@ static void parseVariable (bool constVar, bool localVar, vString *const scope, t clearPoolToken (token); } -static void parseFunctionArgs (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseFunctionArgs (const int scope, tokenInfo *const token) { bool parsed = false; bool parsingType = false; @@ -1301,8 +1253,7 @@ static void parseFunctionArgs (vString *const scope, tsKind scopeParentKind, tok { member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); - member->scopeParentKind = scopeParentKind; + member->scope = scope; emitTag (member, TSTAG_PARAMETER); deleteToken (member); } @@ -1314,7 +1265,7 @@ static void parseFunctionArgs (vString *const scope, tsKind scopeParentKind, tok } while (parsed && token->type != TOKEN_CLOSE_PAREN); } -static void parseFunctionBody (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseFunctionBody (const int scope, tokenInfo *const token) { bool parsed = false; int nestLevel = 1; @@ -1371,10 +1322,10 @@ static void parseFunctionBody (vString *const scope, tsKind scopeParentKind, tok { case KEYWORD_var: case KEYWORD_let: - parseVariable (false, true, scope, scopeParentKind, token); + parseVariable (false, true, scope, token); break; case KEYWORD_const: - parseVariable (true, true, scope, scopeParentKind, token); + parseVariable (true, true, scope, token); break; } break; @@ -1387,7 +1338,7 @@ static void parseFunctionBody (vString *const scope, tsKind scopeParentKind, tok clearPoolToken (token); } -static void parseFunction (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseFunction (const int scope, tokenInfo *const token) { bool isGenerator = false; bool parsed; @@ -1408,29 +1359,12 @@ static void parseFunction (vString *const scope, tsKind scopeParentKind, tokenIn if (! parsed) return; - if (scope) - { - vStringCopy (token->scope, scope); - token->scopeParentKind = scopeParentKind; - } + token->scope = scope; - if (isGenerator) - emitTag (token, TSTAG_GENERATOR); - else - emitTag (token, TSTAG_FUNCTION); + const int nscope = emitTag (token, isGenerator ? TSTAG_GENERATOR : TSTAG_FUNCTION); - vString *nscope = vStringNew (); - if (scope) - { - vStringCopy (nscope, scope); - vStringPut (nscope, '.'); - } - vStringCat (nscope, token->string); - - parseFunctionArgs (nscope, isGenerator ? TSTAG_GENERATOR : TSTAG_FUNCTION, token); - parseFunctionBody (nscope, isGenerator ? TSTAG_GENERATOR : TSTAG_FUNCTION, token); - - vStringDelete (nscope); + parseFunctionArgs (nscope, token); + parseFunctionBody (nscope, token); } static void parsePropertyType (tokenInfo *const token) @@ -1474,7 +1408,7 @@ static void parsePropertyType (tokenInfo *const token) clearPoolToken (token); } -static void parseConstructorParams (vString *const scope, tokenInfo *const token) +static void parseConstructorParams (const int classScope, const int constrScope, tokenInfo *const token) { bool parsed = false; @@ -1539,17 +1473,15 @@ static void parseConstructorParams (vString *const scope, tokenInfo *const token case TOKEN_IDENTIFIER: member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); if (visibility) { member->accessKeyword = visibility; - member->scopeParentKind = TSTAG_CLASS; + member->scope = classScope; emitTag (member, TSTAG_PROPERTY); } else { - vStringCatS (member->scope, ".constructor"); - member->scopeParentKind = TSTAG_METHOD; + member->scope = constrScope; emitTag (member, TSTAG_PARAMETER); } deleteToken (member); @@ -1564,7 +1496,7 @@ static void parseConstructorParams (vString *const scope, tokenInfo *const token } -static void parseClassBody (vString *const scope, tokenInfo *const token) +static void parseClassBody (const int scope, tokenInfo *const token) { bool parsed = false; @@ -1631,26 +1563,21 @@ static void parseClassBody (vString *const scope, tokenInfo *const token) deleteToken (member); member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); - member->scopeParentKind = TSTAG_CLASS; + member->scope = scope; if (visibility) member->accessKeyword = visibility; else member->accessKeyword = KEYWORD_public; - emitTag (member, TSTAG_METHOD); + const int nscope = emitTag (member, TSTAG_METHOD); deleteToken (member); member = NULL; visibility = 0; - parseConstructorParams (scope, token); + parseConstructorParams (scope, nscope, token); - vString *methodScope = vStringNew (); - vStringCopy (methodScope, scope); - vStringCatS (methodScope, ".constructor"); - parseFunctionBody (methodScope, TSTAG_METHOD, token); - vStringDelete (methodScope); + parseFunctionBody (nscope, token); break; case KEYWORD_private: case KEYWORD_public: @@ -1685,23 +1612,14 @@ static void parseClassBody (vString *const scope, tokenInfo *const token) break; uwiUngetC ('('); - if (isGenerator) - emitTag (member, TSTAG_GENERATOR); - else - emitTag (member, TSTAG_METHOD); - - vString *methodScope = vStringNew (); - vStringCopy (methodScope, scope); - vStringPut (methodScope, '.'); - vStringCat (methodScope, member->string); + const int nscope = emitTag (member, isGenerator ? TSTAG_GENERATOR : TSTAG_METHOD); deleteToken (member); member = NULL; - parseFunctionArgs (methodScope, TSTAG_METHOD, token); - parseFunctionBody (methodScope, TSTAG_METHOD, token); + parseFunctionArgs (nscope, token); + parseFunctionBody (nscope, token); - vStringDelete (methodScope); isGenerator = false; visibility = 0; break; @@ -1710,8 +1628,7 @@ static void parseClassBody (vString *const scope, tokenInfo *const token) deleteToken (member); member = newToken (); copyToken (member, token, false); - vStringCopy (member->scope, scope); - member->scopeParentKind = TSTAG_CLASS; + member->scope = scope; if (visibility) member->accessKeyword = visibility; else @@ -1734,7 +1651,7 @@ static void parseClassBody (vString *const scope, tokenInfo *const token) deleteToken (member); } -static void parseClass (vString *const scope, tsKind scopeParentKind, tokenInfo *const token) +static void parseClass (const int scope, tokenInfo *const token) { bool parsed = false; @@ -1752,27 +1669,13 @@ static void parseClass (vString *const scope, tsKind scopeParentKind, tokenInfo if (! parsed) return; - if (scope) - { - vStringCopy (token->scope, scope); - token->scopeParentKind = scopeParentKind; - } - emitTag (token, TSTAG_CLASS); - - vString *nscope = vStringNew (); - if (scope) - { - vStringCopy (nscope, scope); - vStringPut (nscope, '.'); - } - vStringCat (nscope, token->string); + token->scope = scope; + const int nscope = emitTag (token, TSTAG_CLASS); parseClassBody (nscope, token); - - vStringDelete (nscope); } -static void parseNamespaceBody (vString *const scope, tokenInfo *const token) +static void parseNamespaceBody (const int scope, tokenInfo *const token) { bool parsed = false; @@ -1827,26 +1730,26 @@ static void parseNamespaceBody (vString *const scope, tokenInfo *const token) switch (token->keyword) { case KEYWORD_interface: - parseInterface (scope, TSTAG_NAMESPACE, token); + parseInterface (scope, token); break; case KEYWORD_type: - parseType (scope, TSTAG_NAMESPACE, token); + parseType (scope, token); break; case KEYWORD_enum: - parseEnum (scope, TSTAG_NAMESPACE, token); + parseEnum (scope, token); break; case KEYWORD_function: - parseFunction (scope, TSTAG_NAMESPACE, token); + parseFunction (scope, token); break; case KEYWORD_class: - parseClass (scope, TSTAG_NAMESPACE, token); + parseClass (scope, token); break; case KEYWORD_var: case KEYWORD_let: - parseVariable (false, false, scope, TSTAG_NAMESPACE, token); + parseVariable (false, false, scope, token); break; case KEYWORD_const: - parseVariable (true, false, scope, TSTAG_NAMESPACE, token); + parseVariable (true, false, scope, token); break; } break; @@ -1896,14 +1799,9 @@ static void parseNamespace (tokenInfo *const token) if (! parsed) return; - emitTag (token, TSTAG_NAMESPACE); - - vString *scope = vStringNew (); - vStringCopy (scope, token->string); + const int scope = emitTag (token, TSTAG_NAMESPACE); parseNamespaceBody (scope, token); - - vStringDelete (scope); } static void parseTsFile (tokenInfo *const token) @@ -1939,29 +1837,29 @@ static void parseTsFile (tokenInfo *const token) switch (token->keyword) { case KEYWORD_interface: - parseInterface (NULL, TSTAG_CLASS, token); + parseInterface (CORK_NIL, token); break; case KEYWORD_type: - parseType (NULL, TSTAG_CLASS, token); + parseType (CORK_NIL, token); break; case KEYWORD_enum: - parseEnum (NULL, TSTAG_CLASS, token); + parseEnum (CORK_NIL, token); break; case KEYWORD_function: - parseFunction (NULL, TSTAG_CLASS, token); + parseFunction (CORK_NIL, token); break; case KEYWORD_class: - parseClass (NULL, TSTAG_CLASS, token); + parseClass (CORK_NIL, token); break; case KEYWORD_namespace: parseNamespace (token); break; case KEYWORD_var: case KEYWORD_let: - parseVariable (false, false, NULL, TSTAG_CLASS, token); + parseVariable (false, false, CORK_NIL, token); break; case KEYWORD_const: - parseVariable (true, false, NULL, TSTAG_CLASS, token); + parseVariable (true, false, CORK_NIL, token); break; } break; @@ -2016,6 +1914,8 @@ extern parserDefinition *TypeScriptParser (void) def->finalize = finalize; def->keywordTable = TsKeywordTable; def->keywordCount = ARRAY_SIZE (TsKeywordTable); + def->useCork = true; + def->requestAutomaticFQTag = true; return def; }