Skip to content

Commit f16f276

Browse files
authored
Merge pull request microsoft#9529 from Microsoft/identifierAndTokenConstructor
Create separate constructors for Tokens and Identifiers
2 parents b8e814e + 78a1ca7 commit f16f276

4 files changed

Lines changed: 125 additions & 11 deletions

File tree

src/compiler/core.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,8 @@ namespace ts {
12391239

12401240
export interface ObjectAllocator {
12411241
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
1242+
getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
1243+
getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
12421244
getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
12431245
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
12441246
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
@@ -1268,6 +1270,8 @@ namespace ts {
12681270

12691271
export let objectAllocator: ObjectAllocator = {
12701272
getNodeConstructor: () => <any>Node,
1273+
getTokenConstructor: () => <any>Node,
1274+
getIdentifierConstructor: () => <any>Node,
12711275
getSourceFileConstructor: () => <any>Node,
12721276
getSymbolConstructor: () => <any>Symbol,
12731277
getTypeConstructor: () => <any>Type,

src/compiler/parser.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,20 @@ namespace ts {
55
/* @internal */ export let parseTime = 0;
66

77
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
8+
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
9+
let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
810
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
911

1012
export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node {
1113
if (kind === SyntaxKind.SourceFile) {
1214
return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end);
1315
}
16+
else if (kind === SyntaxKind.Identifier) {
17+
return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end);
18+
}
19+
else if (kind < SyntaxKind.FirstNode) {
20+
return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end);
21+
}
1422
else {
1523
return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end);
1624
}
@@ -466,6 +474,8 @@ namespace ts {
466474

467475
// capture constructors in 'initializeState' to avoid null checks
468476
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
477+
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
478+
let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
469479
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
470480

471481
let sourceFile: SourceFile;
@@ -576,6 +586,8 @@ namespace ts {
576586

577587
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
578588
NodeConstructor = objectAllocator.getNodeConstructor();
589+
TokenConstructor = objectAllocator.getTokenConstructor();
590+
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
579591
SourceFileConstructor = objectAllocator.getSourceFileConstructor();
580592

581593
sourceText = _sourceText;
@@ -1018,13 +1030,15 @@ namespace ts {
10181030
}
10191031

10201032
// note: this function creates only node
1021-
function createNode(kind: SyntaxKind, pos?: number): Node {
1033+
function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
10221034
nodeCount++;
10231035
if (!(pos >= 0)) {
10241036
pos = scanner.getStartPos();
10251037
}
10261038

1027-
return new NodeConstructor(kind, pos, pos);
1039+
return kind >= SyntaxKind.FirstNode ? new NodeConstructor(kind, pos, pos) :
1040+
kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, pos, pos) :
1041+
new TokenConstructor(kind, pos, pos);
10281042
}
10291043

10301044
function finishNode<T extends Node>(node: T, end?: number): T {
@@ -5096,7 +5110,7 @@ namespace ts {
50965110
}
50975111

50985112
flags |= modifierToFlag(modifierKind);
5099-
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
5113+
modifiers.push(finishNode(<Modifier>createNode(modifierKind, modifierStart)));
51005114
}
51015115
if (modifiers) {
51025116
modifiers.flags = flags;
@@ -5115,7 +5129,7 @@ namespace ts {
51155129
modifiers = <ModifiersArray>[];
51165130
modifiers.pos = modifierStart;
51175131
flags |= modifierToFlag(modifierKind);
5118-
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
5132+
modifiers.push(finishNode(<Modifier>createNode(modifierKind, modifierStart)));
51195133
modifiers.flags = flags;
51205134
modifiers.end = scanner.getStartPos();
51215135
}

src/compiler/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,10 @@ namespace ts {
472472
flags: NodeFlags;
473473
}
474474

475+
export interface Token extends Node {
476+
__tokenTag: any;
477+
}
478+
475479
// @kind(SyntaxKind.AbstractKeyword)
476480
// @kind(SyntaxKind.AsyncKeyword)
477481
// @kind(SyntaxKind.ConstKeyword)
@@ -482,7 +486,7 @@ namespace ts {
482486
// @kind(SyntaxKind.PrivateKeyword)
483487
// @kind(SyntaxKind.ProtectedKeyword)
484488
// @kind(SyntaxKind.StaticKeyword)
485-
export interface Modifier extends Node { }
489+
export interface Modifier extends Token { }
486490

487491
// @kind(SyntaxKind.Identifier)
488492
export interface Identifier extends PrimaryExpression {

src/services/services.ts

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,10 @@ namespace ts {
180180
];
181181
let jsDocCompletionEntries: CompletionEntry[];
182182

183-
function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject {
184-
const node = new NodeObject(kind, pos, end);
185-
node.flags = flags;
183+
function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject {
184+
const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) :
185+
kind === SyntaxKind.Identifier ? new IdentifierObject(kind, pos, end) :
186+
new TokenObject(kind, pos, end);
186187
node.parent = parent;
187188
return node;
188189
}
@@ -197,11 +198,11 @@ namespace ts {
197198
private _children: Node[];
198199

199200
constructor(kind: SyntaxKind, pos: number, end: number) {
200-
this.kind = kind;
201201
this.pos = pos;
202202
this.end = end;
203203
this.flags = NodeFlags.None;
204204
this.parent = undefined;
205+
this.kind = kind;
205206
}
206207

207208
public getSourceFile(): SourceFile {
@@ -246,15 +247,15 @@ namespace ts {
246247
const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan();
247248
const textPos = scanner.getTextPos();
248249
if (textPos <= end) {
249-
nodes.push(createNode(token, pos, textPos, 0, this));
250+
nodes.push(createNode(token, pos, textPos, this));
250251
}
251252
pos = textPos;
252253
}
253254
return pos;
254255
}
255256

256257
private createSyntaxList(nodes: NodeArray<Node>): Node {
257-
const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, 0, this);
258+
const list = <NodeObject>createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, this);
258259
list._children = [];
259260
let pos = nodes.pos;
260261

@@ -345,6 +346,95 @@ namespace ts {
345346
}
346347
}
347348

349+
class TokenOrIdentifierObject implements Token {
350+
public kind: SyntaxKind;
351+
public pos: number;
352+
public end: number;
353+
public flags: NodeFlags;
354+
public parent: Node;
355+
public jsDocComments: JSDocComment[];
356+
public __tokenTag: any;
357+
358+
constructor(pos: number, end: number) {
359+
// Set properties in same order as NodeObject
360+
this.pos = pos;
361+
this.end = end;
362+
this.flags = NodeFlags.None;
363+
this.parent = undefined;
364+
}
365+
366+
public getSourceFile(): SourceFile {
367+
return getSourceFileOfNode(this);
368+
}
369+
370+
public getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number {
371+
return getTokenPosOfNode(this, sourceFile, includeJsDocComment);
372+
}
373+
374+
public getFullStart(): number {
375+
return this.pos;
376+
}
377+
378+
public getEnd(): number {
379+
return this.end;
380+
}
381+
382+
public getWidth(sourceFile?: SourceFile): number {
383+
return this.getEnd() - this.getStart(sourceFile);
384+
}
385+
386+
public getFullWidth(): number {
387+
return this.end - this.pos;
388+
}
389+
390+
public getLeadingTriviaWidth(sourceFile?: SourceFile): number {
391+
return this.getStart(sourceFile) - this.pos;
392+
}
393+
394+
public getFullText(sourceFile?: SourceFile): string {
395+
return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
396+
}
397+
398+
public getText(sourceFile?: SourceFile): string {
399+
return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
400+
}
401+
402+
public getChildCount(sourceFile?: SourceFile): number {
403+
return 0;
404+
}
405+
406+
public getChildAt(index: number, sourceFile?: SourceFile): Node {
407+
return undefined;
408+
}
409+
410+
public getChildren(sourceFile?: SourceFile): Node[] {
411+
return emptyArray;
412+
}
413+
414+
public getFirstToken(sourceFile?: SourceFile): Node {
415+
return undefined;
416+
}
417+
418+
public getLastToken(sourceFile?: SourceFile): Node {
419+
return undefined;
420+
}
421+
}
422+
423+
class TokenObject extends TokenOrIdentifierObject {
424+
public kind: SyntaxKind;
425+
constructor(kind: SyntaxKind, pos: number, end: number) {
426+
super(pos, end);
427+
this.kind = kind;
428+
}
429+
}
430+
431+
class IdentifierObject extends TokenOrIdentifierObject {
432+
constructor(kind: SyntaxKind, pos: number, end: number) {
433+
super(pos, end);
434+
}
435+
}
436+
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
437+
348438
class SymbolObject implements Symbol {
349439
flags: SymbolFlags;
350440
name: string;
@@ -8694,6 +8784,8 @@ namespace ts {
86948784
function initializeServices() {
86958785
objectAllocator = {
86968786
getNodeConstructor: () => NodeObject,
8787+
getTokenConstructor: () => TokenObject,
8788+
getIdentifierConstructor: () => IdentifierObject,
86978789
getSourceFileConstructor: () => SourceFileObject,
86988790
getSymbolConstructor: () => SymbolObject,
86998791
getTypeConstructor: () => TypeObject,

0 commit comments

Comments
 (0)