From 12d3d8a7418063203b812e01aac227d58c4aeada Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 4 Nov 2014 00:49:42 -0800 Subject: [PATCH] Specialize findToken walk. --- src/services/syntax/SyntaxGenerator.js | 4 +- src/services/syntax/syntaxElement.ts | 39 ++++++++++++++++--- src/services/syntax/syntaxGenerator.ts | 7 +++- .../syntax/syntaxUtilities.generated.ts | 4 ++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/services/syntax/SyntaxGenerator.js b/src/services/syntax/SyntaxGenerator.js index b7f88fd66f6..0da69eec942 100644 --- a/src/services/syntax/SyntaxGenerator.js +++ b/src/services/syntax/SyntaxGenerator.js @@ -2261,7 +2261,6 @@ function generateServicesUtilities() { } result += "undefined"; } - ; for (var i = 0; i < definitions.length; i++) { var definition = definitions[i]; result += ",\r\n"; @@ -2282,6 +2281,9 @@ function generateServicesUtilities() { result += " export function childAt(element: ISyntaxElement, index: number): ISyntaxElement {\r\n"; result += " if (isList(element)) { return (element)[index]; }\r\n"; result += " return childAtArray[element.kind](element, index);\r\n"; + result += " }\r\n\r\n"; + result += " export function getChildAtFunction(element: ISyntaxNodeOrToken): (nodeOrToken: ISyntaxElement, index: number) => ISyntaxElement {\r\n"; + result += " return childAtArray[element.kind];\r\n"; result += " }\r\n"; result += "}"; return result; diff --git a/src/services/syntax/syntaxElement.ts b/src/services/syntax/syntaxElement.ts index 4fcb3276516..e42d9d44cdb 100644 --- a/src/services/syntax/syntaxElement.ts +++ b/src/services/syntax/syntaxElement.ts @@ -53,7 +53,7 @@ module TypeScript { throw Errors.argumentOutOfRange("position"); } - var token = findTokenWorker(sourceUnit, 0, position); + var token = findTokenInNodeOrToken(sourceUnit, 0, position); if (token) { Debug.assert(token.fullWidth() > 0); return token; @@ -113,13 +113,40 @@ module TypeScript { } function findTokenWorker(element: ISyntaxElement, elementPosition: number, position: number): ISyntaxToken { - if (isToken(element)) { - return element; + if (isList(element)) { + return findTokenInList(element, elementPosition, position); + } + else { + return findTokenInNodeOrToken(element, elementPosition, position); + } + } + + function findTokenInList(list: ISyntaxNodeOrToken[], elementPosition: number, position: number): ISyntaxToken { + for (var i = 0, n = list.length; i < n; i++) { + var child = list[i]; + + var childFullWidth = fullWidth(child); + var elementEndPosition = elementPosition + childFullWidth; + + if (position < elementEndPosition) { + return findTokenWorker(child, elementPosition, position); + } + + elementPosition = elementEndPosition; } - // Consider: we could use a binary search here to find the child more quickly. - for (var i = 0, n = childCount(element); i < n; i++) { - var child = childAt(element, i); + return undefined; + } + + + function findTokenInNodeOrToken(nodeOrToken: ISyntaxNodeOrToken, elementPosition: number, position: number): ISyntaxToken { + if (isToken(nodeOrToken)) { + return nodeOrToken; + } + + var childAtFunction = getChildAtFunction(nodeOrToken); + for (var i = 0, n = childCount(nodeOrToken); i < n; i++) { + var child = childAtFunction(nodeOrToken, i); if (child) { var childFullWidth = fullWidth(child); diff --git a/src/services/syntax/syntaxGenerator.ts b/src/services/syntax/syntaxGenerator.ts index 68a596fe23e..a9ae6ff5d53 100644 --- a/src/services/syntax/syntaxGenerator.ts +++ b/src/services/syntax/syntaxGenerator.ts @@ -1534,7 +1534,7 @@ function generateServicesUtilities(): string { result += "0"; } else { - var definition = TypeScript.ArrayUtilities.first(definitions,d => firstKind(d) === i); + var definition = TypeScript.ArrayUtilities.first(definitions, d => firstKind(d) === i); result += definition.children.length; } } @@ -1609,8 +1609,13 @@ function generateServicesUtilities(): string { //} //result += " }\r\n"; + result += " }\r\n\r\n"; + + result += " export function getChildAtFunction(element: ISyntaxNodeOrToken): (nodeOrToken: ISyntaxElement, index: number) => ISyntaxElement {\r\n"; + result += " return childAtArray[element.kind];\r\n"; result += " }\r\n"; + result += "}"; diff --git a/src/services/syntax/syntaxUtilities.generated.ts b/src/services/syntax/syntaxUtilities.generated.ts index 973c7571864..17152889f5c 100644 --- a/src/services/syntax/syntaxUtilities.generated.ts +++ b/src/services/syntax/syntaxUtilities.generated.ts @@ -696,4 +696,8 @@ module TypeScript { if (isList(element)) { return (element)[index]; } return childAtArray[element.kind](element, index); } + + export function getChildAtFunction(element: ISyntaxNodeOrToken): (nodeOrToken: ISyntaxElement, index: number) => ISyntaxElement { + return childAtArray[element.kind]; + } } \ No newline at end of file