Skip to content

Commit 47a3410

Browse files
Merge pull request #1050 from Microsoft/incrementalPerf2
More incremental perf tweaks.
2 parents b49762d + 12d3d8a commit 47a3410

25 files changed

+1332
-1565
lines changed

src/services/compiler/precompile.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,26 @@ module TypeScript {
9999
var start = new Date().getTime();
100100
// Look for:
101101
// import foo = module("foo")
102-
while (token.kind() !== SyntaxKind.EndOfFileToken) {
103-
if (token.kind() === SyntaxKind.ImportKeyword) {
102+
while (token.kind !== SyntaxKind.EndOfFileToken) {
103+
if (token.kind === SyntaxKind.ImportKeyword) {
104104
var importToken = token;
105105
token = scanner.scan(/*allowRegularExpression:*/ false);
106106

107107
if (SyntaxFacts.isIdentifierNameOrAnyKeyword(token)) {
108108
token = scanner.scan(/*allowRegularExpression:*/ false);
109109

110-
if (token.kind() === SyntaxKind.EqualsToken) {
110+
if (token.kind === SyntaxKind.EqualsToken) {
111111
token = scanner.scan(/*allowRegularExpression:*/ false);
112112

113-
if (token.kind() === SyntaxKind.ModuleKeyword || token.kind() === SyntaxKind.RequireKeyword) {
113+
if (token.kind === SyntaxKind.ModuleKeyword || token.kind === SyntaxKind.RequireKeyword) {
114114
token = scanner.scan(/*allowRegularExpression:*/ false);
115115

116-
if (token.kind() === SyntaxKind.OpenParenToken) {
116+
if (token.kind === SyntaxKind.OpenParenToken) {
117117
token = scanner.scan(/*allowRegularExpression:*/ false);
118118

119119
lineMap.fillLineAndCharacterFromPosition(TypeScript.start(importToken, text), lineChar);
120120

121-
if (token.kind() === SyntaxKind.StringLiteral) {
121+
if (token.kind === SyntaxKind.StringLiteral) {
122122
var ref = {
123123
line: lineChar.line,
124124
character: lineChar.character,

src/services/formatting/formatter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ module TypeScript.Services.Formatting {
7878
}
7979

8080
// Push the token
81-
var currentTokenSpan = new TokenSpan(token.kind(), position, width(token));
81+
var currentTokenSpan = new TokenSpan(token.kind, position, width(token));
8282
if (!this.parent().hasSkippedOrMissingTokenChild()) {
8383
if (this.previousTokenSpan) {
8484
// Note that formatPair calls TrimWhitespaceInLineRange in between the 2 tokens

src/services/formatting/formattingManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ module TypeScript.Services.Formatting {
4242
var sourceUnit = this.syntaxTree.sourceUnit();
4343
var semicolonPositionedToken = findToken(sourceUnit, caretPosition - 1);
4444

45-
if (semicolonPositionedToken.kind() === SyntaxKind.SemicolonToken) {
45+
if (semicolonPositionedToken.kind === SyntaxKind.SemicolonToken) {
4646
// Find the outer most parent that this semicolon terminates
4747
var current: ISyntaxElement = semicolonPositionedToken;
4848
while (current.parent !== null &&
4949
end(current.parent) === end(semicolonPositionedToken) &&
50-
current.parent.kind() !== SyntaxKind.List) {
50+
current.parent.kind !== SyntaxKind.List) {
5151
current = current.parent;
5252
}
5353

@@ -65,12 +65,12 @@ module TypeScript.Services.Formatting {
6565
var sourceUnit = this.syntaxTree.sourceUnit();
6666
var closeBracePositionedToken = findToken(sourceUnit, caretPosition - 1);
6767

68-
if (closeBracePositionedToken.kind() === SyntaxKind.CloseBraceToken) {
68+
if (closeBracePositionedToken.kind === SyntaxKind.CloseBraceToken) {
6969
// Find the outer most parent that this closing brace terminates
7070
var current: ISyntaxElement = closeBracePositionedToken;
7171
while (current.parent !== null &&
7272
end(current.parent) === end(closeBracePositionedToken) &&
73-
current.parent.kind() !== SyntaxKind.List) {
73+
current.parent.kind !== SyntaxKind.List) {
7474
current = current.parent;
7575
}
7676

src/services/formatting/indentationNodeContext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ module TypeScript.Services.Formatting {
6666
}
6767

6868
public kind(): SyntaxKind {
69-
return this._node.kind();
69+
return this._node.kind;
7070
}
7171

7272
public hasSkippedOrMissingTokenChild(): boolean {

src/services/formatting/indentationTrackingWalker.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ module TypeScript.Services.Formatting {
103103
if (isToken(element)) {
104104
this.visitToken(<ISyntaxToken>element);
105105
}
106-
else if (element.kind() === SyntaxKind.List) {
106+
else if (element.kind === SyntaxKind.List) {
107107
for (var i = 0, n = childCount(element); i < n; i++) {
108108
this.walk(childAt(element, i));
109109
}
@@ -148,9 +148,9 @@ module TypeScript.Services.Formatting {
148148
// }
149149
// Also in a do-while statement, the while should be indented like the parent.
150150
if (firstToken(this._parent.node()) === token ||
151-
token.kind() === SyntaxKind.OpenBraceToken || token.kind() === SyntaxKind.CloseBraceToken ||
152-
token.kind() === SyntaxKind.OpenBracketToken || token.kind() === SyntaxKind.CloseBracketToken ||
153-
(token.kind() === SyntaxKind.WhileKeyword && this._parent.node().kind() == SyntaxKind.DoStatement)) {
151+
token.kind === SyntaxKind.OpenBraceToken || token.kind === SyntaxKind.CloseBraceToken ||
152+
token.kind === SyntaxKind.OpenBracketToken || token.kind === SyntaxKind.CloseBracketToken ||
153+
(token.kind === SyntaxKind.WhileKeyword && this._parent.node().kind == SyntaxKind.DoStatement)) {
154154
return this._parent.indentationAmount();
155155
}
156156

@@ -161,7 +161,7 @@ module TypeScript.Services.Formatting {
161161
// If this is token terminating an indentation scope, leading comments should be indented to follow the children
162162
// indentation level and not the node
163163

164-
if (token.kind() === SyntaxKind.CloseBraceToken || token.kind() === SyntaxKind.CloseBracketToken) {
164+
if (token.kind === SyntaxKind.CloseBraceToken || token.kind === SyntaxKind.CloseBracketToken) {
165165
return (this._parent.indentationAmount() + this._parent.childIndentationAmountDelta());
166166
}
167167
return this._parent.indentationAmount();
@@ -213,7 +213,7 @@ module TypeScript.Services.Formatting {
213213
var indentationAmountDelta: number;
214214
var parentNode = parent.node();
215215

216-
switch (node.kind()) {
216+
switch (node.kind) {
217217
default:
218218
// General case
219219
// This node should follow the child indentation set by its parent

src/services/formatting/multipleTokenIndenter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ module TypeScript.Services.Formatting {
119119

120120
}
121121

122-
if (token.kind() !== SyntaxKind.EndOfFileToken && indentNextTokenOrTrivia) {
122+
if (token.kind !== SyntaxKind.EndOfFileToken && indentNextTokenOrTrivia) {
123123
// If the last trivia item was a new line, or no trivia items were encounterd record the
124124
// indentation edit at the token position
125125
if (indentationString.length > 0) {

src/services/syntax/SyntaxGenerator.js

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,7 @@ function generateConstructorFunction(definition) {
19821982
result += ";\r\n";
19831983
}
19841984
result += " };\r\n";
1985-
result += " " + definition.name + ".prototype.kind = function() { return SyntaxKind." + getNameWithoutSuffix(definition) + "; }\r\n";
1985+
result += " " + definition.name + ".prototype.kind = SyntaxKind." + getNameWithoutSuffix(definition) + ";\r\n";
19861986
return result;
19871987
}
19881988
function generateSyntaxInterfaces() {
@@ -2154,16 +2154,28 @@ function max(array, func) {
21542154
}
21552155
return max;
21562156
}
2157+
function generateUtilities() {
2158+
var result = "";
2159+
result += " var fixedWidthArray = [";
2160+
for (var i = 0; i <= TypeScript.SyntaxKind.LastFixedWidth; i++) {
2161+
if (i) {
2162+
result += ", ";
2163+
}
2164+
if (i < TypeScript.SyntaxKind.FirstFixedWidth) {
2165+
result += "0";
2166+
}
2167+
else {
2168+
result += TypeScript.SyntaxFacts.getText(i).length;
2169+
}
2170+
}
2171+
result += "];\r\n";
2172+
result += " function fixedWidthTokenLength(kind: SyntaxKind) {\r\n";
2173+
result += " return fixedWidthArray[kind];\r\n";
2174+
result += " }\r\n";
2175+
return result;
2176+
}
21572177
function generateScannerUtilities() {
21582178
var result = "///<reference path='references.ts' />\r\n" + "\r\n" + "module TypeScript {\r\n" + " export module ScannerUtilities {\r\n";
2159-
result += " export function fixedWidthTokenLength(kind: SyntaxKind) {\r\n";
2160-
result += " switch (kind) {\r\n";
2161-
for (var k = TypeScript.SyntaxKind.FirstFixedWidth; k <= TypeScript.SyntaxKind.LastFixedWidth; k++) {
2162-
result += " case SyntaxKind." + syntaxKindName(k) + ": return " + TypeScript.SyntaxFacts.getText(k).length + ";\r\n";
2163-
}
2164-
result += " default: throw new Error();\r\n";
2165-
result += " }\r\n";
2166-
result += " }\r\n\r\n";
21672179
var i;
21682180
var keywords = [];
21692181
for (i = TypeScript.SyntaxKind.FirstKeyword; i <= TypeScript.SyntaxKind.LastKeyword; i++) {
@@ -2202,7 +2214,7 @@ function generateVisitor() {
22022214
result += "module TypeScript {\r\n";
22032215
result += " export function visitNodeOrToken(visitor: ISyntaxVisitor, element: ISyntaxNodeOrToken): any {\r\n";
22042216
result += " if (element === undefined) { return undefined; }\r\n";
2205-
result += " switch (element.kind()) {\r\n";
2217+
result += " switch (element.kind) {\r\n";
22062218
for (var i = 0; i < definitions.length; i++) {
22072219
var definition = definitions[i];
22082220
result += " case SyntaxKind." + getNameWithoutSuffix(definition) + ": ";
@@ -2240,31 +2252,38 @@ function generateServicesUtilities() {
22402252
result += "];\r\n\r\n";
22412253
result += " export function childCount(element: ISyntaxElement): number {\r\n";
22422254
result += " if (isList(element)) { return (<ISyntaxNodeOrToken[]>element).length; }\r\n";
2243-
result += " return childCountArray[element.kind()];\r\n";
2255+
result += " return childCountArray[element.kind];\r\n";
22442256
result += " }\r\n\r\n";
2257+
result += " var childAtArray: ((nodeOrToken: ISyntaxElement, index: number) => ISyntaxElement)[] = [\r\n ";
2258+
for (var i = 0; i < TypeScript.SyntaxKind.FirstNode; i++) {
2259+
if (i) {
2260+
result += ", ";
2261+
}
2262+
result += "undefined";
2263+
}
22452264
for (var i = 0; i < definitions.length; i++) {
22462265
var definition = definitions[i];
2247-
result += " function " + camelCase(getNameWithoutSuffix(definition)) + "ChildAt(node: " + definition.name + ", index: number): ISyntaxElement {\r\n";
2266+
result += ",\r\n";
2267+
result += " (node: " + definition.name + ", index: number): ISyntaxElement => {\r\n";
22482268
if (definition.children.length) {
2249-
result += " switch (index) {\r\n";
2269+
result += " switch (index) {\r\n";
22502270
for (var j = 0; j < definition.children.length; j++) {
2251-
result += " case " + j + ": return node." + definition.children[j].name + ";\r\n";
2271+
result += " case " + j + ": return node." + definition.children[j].name + ";\r\n";
22522272
}
2253-
result += " }\r\n";
2273+
result += " }\r\n";
22542274
}
22552275
else {
2256-
result += " throw Errors.invalidOperation();\r\n";
2276+
result += " throw Errors.invalidOperation();\r\n";
22572277
}
2258-
result += " }\r\n";
2278+
result += " }";
22592279
}
2280+
result += "\r\n ];\r\n";
22602281
result += " export function childAt(element: ISyntaxElement, index: number): ISyntaxElement {\r\n";
22612282
result += " if (isList(element)) { return (<ISyntaxNodeOrToken[]>element)[index]; }\r\n";
2262-
result += " switch (element.kind()) {\r\n";
2263-
for (var i = 0; i < definitions.length; i++) {
2264-
var definition = definitions[i];
2265-
result += " case SyntaxKind." + getNameWithoutSuffix(definition) + ": return " + camelCase(getNameWithoutSuffix(definition)) + "ChildAt(<" + definition.name + ">element, index);\r\n";
2266-
}
2267-
result += " }\r\n";
2283+
result += " return childAtArray[element.kind](element, index);\r\n";
2284+
result += " }\r\n\r\n";
2285+
result += " export function getChildAtFunction(element: ISyntaxNodeOrToken): (nodeOrToken: ISyntaxElement, index: number) => ISyntaxElement {\r\n";
2286+
result += " return childAtArray[element.kind];\r\n";
22682287
result += " }\r\n";
22692288
result += "}";
22702289
return result;
@@ -2275,9 +2294,11 @@ var walker = generateWalker();
22752294
var scannerUtilities = generateScannerUtilities();
22762295
var visitor = generateVisitor();
22772296
var servicesUtilities = generateServicesUtilities();
2297+
var utilities = generateUtilities();
22782298
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\syntaxNodes.concrete.generated.ts", syntaxNodesConcrete, false);
22792299
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\syntaxInterfaces.generated.ts", syntaxInterfaces, false);
22802300
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\syntaxWalker.generated.ts", walker, false);
22812301
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\scannerUtilities.generated.ts", scannerUtilities, false);
22822302
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\syntaxVisitor.generated.ts", visitor, false);
22832303
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\syntaxUtilities.generated.ts", servicesUtilities, false);
2304+
sys.writeFile(sys.getCurrentDirectory() + "\\src\\services\\syntax\\utilities.generated.ts", utilities, false);

src/services/syntax/incrementalParser.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,20 @@ module TypeScript.IncrementalParser {
235235
!_oldSourceUnitCursor.isFinished();
236236
}
237237

238-
function updateTokens(nodeOrToken: ISyntaxNodeOrToken): void {
238+
function updateTokenPosition(token: ISyntaxToken): void {
239+
// If we got a node or token, and we're past the range of edited text, then walk its
240+
// constituent tokens, making sure all their positions are correct. We don't need to
241+
// do this for the tokens before the edited range (since their positions couldn't have
242+
// been affected by the edit), and we don't need to do this for the tokens in the
243+
// edited range, as their positions will be correct when the underlying parser source
244+
// creates them.
245+
246+
if (isPastChangeRange()) {
247+
token.setFullStart(absolutePosition());
248+
}
249+
}
250+
251+
function updateNodePosition(node: ISyntaxNode): void {
239252
// If we got a node or token, and we're past the range of edited text, then walk its
240253
// constituent tokens, making sure all their positions are correct. We don't need to
241254
// do this for the tokens before the edited range (since their positions couldn't have
@@ -246,18 +259,13 @@ module TypeScript.IncrementalParser {
246259
if (isPastChangeRange()) {
247260
var position = absolutePosition();
248261

249-
if (isToken(nodeOrToken)) {
250-
(<ISyntaxToken>nodeOrToken).setFullStart(position);
251-
}
252-
else {
253-
var tokens = getTokens(<ISyntaxNode>nodeOrToken);
262+
var tokens = getTokens(node);
254263

255-
for (var i = 0, n = tokens.length; i < n; i++) {
256-
var token = tokens[i];
257-
token.setFullStart(position);
264+
for (var i = 0, n = tokens.length; i < n; i++) {
265+
var token = tokens[i];
266+
token.setFullStart(position);
258267

259-
position += token.fullWidth();
260-
}
268+
position += token.fullWidth();
261269
}
262270
}
263271
}
@@ -284,7 +292,7 @@ module TypeScript.IncrementalParser {
284292
var node = tryGetNodeFromOldSourceUnit();
285293
if (node) {
286294
// Make sure the positions for the tokens in this node are correct.
287-
updateTokens(node);
295+
updateNodePosition(node);
288296
return node;
289297
}
290298
}
@@ -298,7 +306,7 @@ module TypeScript.IncrementalParser {
298306
var token = tryGetTokenFromOldSourceUnit();
299307
if (token) {
300308
// Make sure the token's position/text is correct.
301-
updateTokens(token);
309+
updateTokenPosition(token);
302310
return token;
303311
}
304312
}

0 commit comments

Comments
 (0)