diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 07100a982e7..9aa5741cc74 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1232,6 +1232,7 @@ namespace ts { export interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; + getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile; getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; @@ -1262,6 +1263,7 @@ namespace ts { export let objectAllocator: ObjectAllocator = { getNodeConstructor: () => Node, getTokenConstructor: () => Node, + getIdentifierConstructor: () => Node, getSourceFileConstructor: () => Node, getSymbolConstructor: () => Symbol, getTypeConstructor: () => Type, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9fc06dcba62..91097348589 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6,12 +6,16 @@ namespace ts { let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node { if (kind === SyntaxKind.SourceFile) { return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end); } + else if (kind === SyntaxKind.Identifier) { + return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end); + } else if (kind < SyntaxKind.FirstNode) { return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end); } @@ -471,6 +475,7 @@ namespace ts { // capture constructors in 'initializeState' to avoid null checks let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let sourceFile: SourceFile; @@ -582,6 +587,7 @@ namespace ts { function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { NodeConstructor = objectAllocator.getNodeConstructor(); TokenConstructor = objectAllocator.getTokenConstructor(); + IdentifierConstructor = objectAllocator.getIdentifierConstructor(); SourceFileConstructor = objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; @@ -1030,9 +1036,9 @@ namespace ts { pos = scanner.getStartPos(); } - return kind >= SyntaxKind.FirstNode ? - new NodeConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return kind >= SyntaxKind.FirstNode ? new NodeConstructor(kind, pos, pos) : + kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, pos, pos) : + new TokenConstructor(kind, pos, pos); } function finishNode(node: T, end?: number): T { diff --git a/src/services/services.ts b/src/services/services.ts index b734bb7f063..d519520540a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -180,8 +180,10 @@ namespace ts { ]; let jsDocCompletionEntries: CompletionEntry[]; - function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject { - const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) : new TokenObject(kind, pos, end); + function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { + const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) : + kind === SyntaxKind.Identifier ? new IdentifierObject(kind, pos, end) : + new TokenObject(kind, pos, end); node.parent = parent; return node; } @@ -343,7 +345,7 @@ namespace ts { } } - class TokenObject implements Token { + class TokenOrIdentifierObject implements Token { public kind: SyntaxKind; public pos: number; public end: number; @@ -351,11 +353,9 @@ namespace ts { public parent: Node; public jsDocComments: JSDocComment[]; - constructor(kind: SyntaxKind, pos: number, end: number) { - this.kind = kind; + constructor(pos: number, end: number) { this.pos = pos; this.end = end; - this.flags = NodeFlags.None; this.parent = undefined; } @@ -416,6 +416,21 @@ namespace ts { } } + class TokenObject extends TokenOrIdentifierObject { + constructor(kind: SyntaxKind, pos: number, end: number) { + super(pos, end); + this.kind = kind; + this.flags = NodeFlags.None; + } + } + + class IdentifierObject extends TokenOrIdentifierObject { + constructor(kind: SyntaxKind, pos: number, end: number) { + super(pos, end); + } + } + IdentifierObject.prototype.kind = SyntaxKind.Identifier; + class SymbolObject implements Symbol { flags: SymbolFlags; name: string; @@ -8768,6 +8783,7 @@ namespace ts { objectAllocator = { getNodeConstructor: () => NodeObject, getTokenConstructor: () => TokenObject, + getIdentifierConstructor: () => IdentifierObject, getSourceFileConstructor: () => SourceFileObject, getSymbolConstructor: () => SymbolObject, getTypeConstructor: () => TypeObject,