Merge pull request #9529 from Microsoft/identifierAndTokenConstructor

Create separate constructors for Tokens and Identifiers
This commit is contained in:
Sheetal Nandi 2016-07-14 13:35:09 -07:00 committed by GitHub
commit f16f27661f
4 changed files with 125 additions and 11 deletions

View file

@ -1239,6 +1239,8 @@ 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;
@ -1268,6 +1270,8 @@ namespace ts {
export let objectAllocator: ObjectAllocator = {
getNodeConstructor: () => <any>Node,
getTokenConstructor: () => <any>Node,
getIdentifierConstructor: () => <any>Node,
getSourceFileConstructor: () => <any>Node,
getSymbolConstructor: () => <any>Symbol,
getTypeConstructor: () => <any>Type,

View file

@ -5,12 +5,20 @@ namespace ts {
/* @internal */ export let parseTime = 0;
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);
}
else {
return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end);
}
@ -466,6 +474,8 @@ 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;
@ -576,6 +586,8 @@ 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;
@ -1018,13 +1030,15 @@ namespace ts {
}
// note: this function creates only node
function createNode(kind: SyntaxKind, pos?: number): Node {
function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
}
return new NodeConstructor(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<T extends Node>(node: T, end?: number): T {
@ -5096,7 +5110,7 @@ namespace ts {
}
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
modifiers.push(finishNode(<Modifier>createNode(modifierKind, modifierStart)));
}
if (modifiers) {
modifiers.flags = flags;
@ -5115,7 +5129,7 @@ namespace ts {
modifiers = <ModifiersArray>[];
modifiers.pos = modifierStart;
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
modifiers.push(finishNode(<Modifier>createNode(modifierKind, modifierStart)));
modifiers.flags = flags;
modifiers.end = scanner.getStartPos();
}

View file

@ -472,6 +472,10 @@ namespace ts {
flags: NodeFlags;
}
export interface Token extends Node {
__tokenTag: any;
}
// @kind(SyntaxKind.AbstractKeyword)
// @kind(SyntaxKind.AsyncKeyword)
// @kind(SyntaxKind.ConstKeyword)
@ -482,7 +486,7 @@ namespace ts {
// @kind(SyntaxKind.PrivateKeyword)
// @kind(SyntaxKind.ProtectedKeyword)
// @kind(SyntaxKind.StaticKeyword)
export interface Modifier extends Node { }
export interface Modifier extends Token { }
// @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {

View file

@ -180,9 +180,10 @@ namespace ts {
];
let jsDocCompletionEntries: CompletionEntry[];
function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject {
const node = new NodeObject(kind, pos, end);
node.flags = flags;
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;
}
@ -197,11 +198,11 @@ namespace ts {
private _children: Node[];
constructor(kind: SyntaxKind, pos: number, end: number) {
this.kind = kind;
this.pos = pos;
this.end = end;
this.flags = NodeFlags.None;
this.parent = undefined;
this.kind = kind;
}
public getSourceFile(): SourceFile {
@ -246,7 +247,7 @@ namespace ts {
const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan();
const textPos = scanner.getTextPos();
if (textPos <= end) {
nodes.push(createNode(token, pos, textPos, 0, this));
nodes.push(createNode(token, pos, textPos, this));
}
pos = textPos;
}
@ -254,7 +255,7 @@ namespace ts {
}
private createSyntaxList(nodes: NodeArray<Node>): Node {
const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, 0, this);
const list = <NodeObject>createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, this);
list._children = [];
let pos = nodes.pos;
@ -345,6 +346,95 @@ namespace ts {
}
}
class TokenOrIdentifierObject implements Token {
public kind: SyntaxKind;
public pos: number;
public end: number;
public flags: NodeFlags;
public parent: Node;
public jsDocComments: JSDocComment[];
public __tokenTag: any;
constructor(pos: number, end: number) {
// Set properties in same order as NodeObject
this.pos = pos;
this.end = end;
this.flags = NodeFlags.None;
this.parent = undefined;
}
public getSourceFile(): SourceFile {
return getSourceFileOfNode(this);
}
public getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number {
return getTokenPosOfNode(this, sourceFile, includeJsDocComment);
}
public getFullStart(): number {
return this.pos;
}
public getEnd(): number {
return this.end;
}
public getWidth(sourceFile?: SourceFile): number {
return this.getEnd() - this.getStart(sourceFile);
}
public getFullWidth(): number {
return this.end - this.pos;
}
public getLeadingTriviaWidth(sourceFile?: SourceFile): number {
return this.getStart(sourceFile) - this.pos;
}
public getFullText(sourceFile?: SourceFile): string {
return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
}
public getText(sourceFile?: SourceFile): string {
return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
}
public getChildCount(sourceFile?: SourceFile): number {
return 0;
}
public getChildAt(index: number, sourceFile?: SourceFile): Node {
return undefined;
}
public getChildren(sourceFile?: SourceFile): Node[] {
return emptyArray;
}
public getFirstToken(sourceFile?: SourceFile): Node {
return undefined;
}
public getLastToken(sourceFile?: SourceFile): Node {
return undefined;
}
}
class TokenObject extends TokenOrIdentifierObject {
public kind: SyntaxKind;
constructor(kind: SyntaxKind, pos: number, end: number) {
super(pos, end);
this.kind = kind;
}
}
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;
@ -8694,6 +8784,8 @@ namespace ts {
function initializeServices() {
objectAllocator = {
getNodeConstructor: () => NodeObject,
getTokenConstructor: () => TokenObject,
getIdentifierConstructor: () => IdentifierObject,
getSourceFileConstructor: () => SourceFileObject,
getSymbolConstructor: () => SymbolObject,
getTypeConstructor: () => TypeObject,