diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts
index f30810ee2f4..d65e1d4a48d 100644
--- a/src/services/getScriptLexicalStructureWalker.ts
+++ b/src/services/getScriptLexicalStructureWalker.ts
@@ -1,17 +1,17 @@
///
-module TypeScript.Services {
- export function getNavigationBarItemsHelper(sourceUnit: TypeScript.SourceUnitSyntax): ts.NavigationBarItem[] {
+module ts {
+ export function getNavigationBarItemsHelper(sourceFile: SourceFile): ts.NavigationBarItem[] {
var hasGlobalNode = false;
- return getItemsWorker(getTopLevelNodes(sourceUnit), createTopLevelItem);
+ return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem);
- function getIndent(node: ISyntaxNode): number {
+ function getIndent(node: Node): number {
var indent = hasGlobalNode ? 1 : 0;
var current = node.parent;
while (current) {
- if (current.kind() === SyntaxKind.ModuleDeclaration || current.kind() === SyntaxKind.FunctionDeclaration) {
+ if (current.kind === SyntaxKind.ModuleDeclaration || current.kind === SyntaxKind.FunctionDeclaration) {
indent++;
}
@@ -21,47 +21,38 @@ module TypeScript.Services {
return indent;
}
- function getKindModifiers(modifiers: TypeScript.ISyntaxToken[]): string {
- var result: string[] = [];
-
- for (var i = 0, n = modifiers.length; i < n; i++) {
- result.push(modifiers[i].text());
- }
-
- return result.length > 0 ? result.join(',') : ts.ScriptElementKindModifier.none;
- }
-
- function getChildNodes(nodes: IModuleElementSyntax[]): ISyntaxNode[] {
- var childNodes: ISyntaxNode[] = [];
+ function getChildNodes(nodes: Node[]): Node[] {
+ var childNodes: Node[] = [];
for (var i = 0, n = nodes.length; i < n; i++) {
- var node = nodes[i];
+ var node = nodes[i];
- if (node.kind() === SyntaxKind.FunctionDeclaration) {
+ if (node.kind === SyntaxKind.FunctionDeclaration) {
childNodes.push(node);
}
- else if (node.kind() === SyntaxKind.VariableStatement) {
- var variableDeclaration = (node).variableDeclaration;
- childNodes.push.apply(childNodes, variableDeclaration.variableDeclarators);
+ else if (node.kind === SyntaxKind.VariableStatement) {
+ forEach((node).declarations, declaration => {
+ childNodes.push(declaration);
+ });
}
}
return childNodes;
}
- function getTopLevelNodes(node: SourceUnitSyntax): ISyntaxNode[] {
- var topLevelNodes: ISyntaxNode[] = [];
+ function getTopLevelNodes(node: SourceFile): Node[] {
+ var topLevelNodes: Node[] = [];
topLevelNodes.push(node);
- addTopLevelNodes(node.moduleElements, topLevelNodes);
+ addTopLevelNodes(node.statements, topLevelNodes);
return topLevelNodes;
}
- function addTopLevelNodes(nodes: IModuleElementSyntax[], topLevelNodes: ISyntaxNode[]): void {
+ function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void {
for (var i = 0, n = nodes.length; i < n; i++) {
var node = nodes[i];
- switch (node.kind()) {
+ switch (node.kind) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
@@ -69,32 +60,39 @@ module TypeScript.Services {
break;
case SyntaxKind.ModuleDeclaration:
- var moduleDeclaration = node;
+ var moduleDeclaration = node;
topLevelNodes.push(node);
- addTopLevelNodes(moduleDeclaration.moduleElements, topLevelNodes);
+ addTopLevelNodes((getInnermostModule(moduleDeclaration).body).statements, topLevelNodes);
break;
case SyntaxKind.FunctionDeclaration:
- var functionDeclaration = node;
+ var functionDeclaration = node;
if (isTopLevelFunctionDeclaration(functionDeclaration)) {
topLevelNodes.push(node);
- addTopLevelNodes(functionDeclaration.block.statements, topLevelNodes);
+ addTopLevelNodes((functionDeclaration.body).statements, topLevelNodes);
}
break;
}
}
}
- function isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclarationSyntax) {
+ function isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclaration) {
// A function declaration is 'top level' if it contains any function declarations
// within it.
- return functionDeclaration.block && ArrayUtilities.any(functionDeclaration.block.statements, s => s.kind() === SyntaxKind.FunctionDeclaration);
+ return functionDeclaration.kind === SyntaxKind.FunctionDeclaration &&
+ functionDeclaration.body &&
+ functionDeclaration.body.kind === SyntaxKind.FunctionBlock &&
+ forEach((functionDeclaration.body).statements, s => s.kind === SyntaxKind.FunctionDeclaration);
}
- function getItemsWorker(nodes: ISyntaxNode[], createItem: (n: ISyntaxNode) => ts.NavigationBarItem): ts.NavigationBarItem[] {
+ function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[]{
var items: ts.NavigationBarItem[] = [];
- var keyToItem = createIntrinsicsObject();
+ if (!nodes) {
+ return items;
+ }
+
+ var keyToItem: Map = {};
for (var i = 0, n = nodes.length; i < n; i++) {
var child = nodes[i];
@@ -149,147 +147,135 @@ module TypeScript.Services {
}
}
- function createChildItem(node: ISyntaxNode): ts.NavigationBarItem {
- switch (node.kind()) {
+ function createChildItem(node: Node): ts.NavigationBarItem {
+ switch (node.kind) {
case SyntaxKind.Parameter:
- var parameter = node;
- if (parameter.modifiers.length === 0) {
+ var parameter = node;
+ if ((node.flags & NodeFlags.Modifier) === 0) {
return undefined;
}
- return new ts.NavigationBarItem(parameter.identifier.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(parameter.modifiers), [TextSpan.fromBounds(start(node), end(node))]);
+ return new ts.NavigationBarItem(parameter.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]);
- case SyntaxKind.MemberFunctionDeclaration:
- var memberFunction = node;
- return new ts.NavigationBarItem(memberFunction.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, getKindModifiers(memberFunction.modifiers), [TextSpan.fromBounds(start(node), end(node))]);
+ case SyntaxKind.Method:
+ var memberFunction = node;
+ return new ts.NavigationBarItem(memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement, getNodeModifiers(node), [getNodeSpan(node)]);
case SyntaxKind.GetAccessor:
- var getAccessor = node;
- return new ts.NavigationBarItem(getAccessor.propertyName.text(), ts.ScriptElementKind.memberGetAccessorElement, getKindModifiers(getAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]);
+ var getAccessor = node;
+ return new ts.NavigationBarItem(getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]);
case SyntaxKind.SetAccessor:
- var setAccessor = node;
- return new ts.NavigationBarItem(setAccessor.propertyName.text(), ts.ScriptElementKind.memberSetAccessorElement, getKindModifiers(setAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]);
+ var setAccessor = node;
+ return new ts.NavigationBarItem(setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]);
case SyntaxKind.IndexSignature:
- var indexSignature = node;
- return new ts.NavigationBarItem("[]", ts.ScriptElementKind.indexSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ return new ts.NavigationBarItem("[]", ts.ScriptElementKind.indexSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]);
- case SyntaxKind.EnumElement:
- var enumElement = node;
- return new ts.NavigationBarItem(enumElement.propertyName.text(), ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ case SyntaxKind.EnumMember:
+ var enumElement = node;
+ return new ts.NavigationBarItem(enumElement.name.text, ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]);
case SyntaxKind.CallSignature:
- var callSignature = node;
- return new ts.NavigationBarItem("()", ts.ScriptElementKind.callSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ return new ts.NavigationBarItem("()", ts.ScriptElementKind.callSignatureElement, ts.ScriptElementKindModifier.none, []);
case SyntaxKind.ConstructSignature:
- var constructSignature = node;
- return new ts.NavigationBarItem("new()", ts.ScriptElementKind.constructSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ return new ts.NavigationBarItem("new()", ts.ScriptElementKind.constructSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]);
- case SyntaxKind.MethodSignature:
- var methodSignature = node;
- return new ts.NavigationBarItem(methodSignature.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
-
- case SyntaxKind.PropertySignature:
- var propertySignature = node;
- return new ts.NavigationBarItem(propertySignature.propertyName.text(), ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ case SyntaxKind.Property:
+ var propertySignature = node;
+ return new ts.NavigationBarItem(propertySignature.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]);
case SyntaxKind.FunctionDeclaration:
- var functionDeclaration = node;
+ var functionDeclaration = node;
if (!isTopLevelFunctionDeclaration(functionDeclaration)) {
- return new ts.NavigationBarItem(functionDeclaration.identifier.text(), ts.ScriptElementKind.functionElement, getKindModifiers(functionDeclaration.modifiers), [TextSpan.fromBounds(start(node), end(node))]);
+ return new ts.NavigationBarItem(functionDeclaration.name.text, ts.ScriptElementKind.functionElement, getNodeModifiers(node), [getNodeSpan(node)]);
}
break;
- case SyntaxKind.MemberVariableDeclaration:
- var memberVariableDeclaration = node;
- return new ts.NavigationBarItem(memberVariableDeclaration.variableDeclarator.propertyName.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(memberVariableDeclaration.modifiers), [TextSpan.fromBounds(start(memberVariableDeclaration.variableDeclarator), end(memberVariableDeclaration.variableDeclarator))]);
+ case SyntaxKind.VariableDeclaration:
+ var variableDeclaration = node;
+ return new ts.NavigationBarItem(variableDeclaration.name.text, ts.ScriptElementKind.variableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]);
- case SyntaxKind.VariableDeclarator:
- var variableDeclarator = node;
- return new ts.NavigationBarItem(variableDeclarator.propertyName.text(), ts.ScriptElementKind.variableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(variableDeclarator), end(variableDeclarator))]);
-
- case SyntaxKind.ConstructorDeclaration:
- var constructorDeclaration = node;
- return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]);
+ case SyntaxKind.Constructor:
+ return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]);
}
return undefined;
}
- function createTopLevelItem(node: ISyntaxNode): ts.NavigationBarItem {
- switch (node.kind()) {
- case SyntaxKind.SourceUnit:
- return createSourceUnitItem(node);
+ function createTopLevelItem(node: Node): ts.NavigationBarItem {
+ switch (node.kind) {
+ case SyntaxKind.SourceFile:
+ return createSourceFileItem(node);
case SyntaxKind.ClassDeclaration:
- return createClassItem(node);
+ return createClassItem(node);
case SyntaxKind.EnumDeclaration:
- return createEnumItem(node);
+ return createEnumItem(node);
case SyntaxKind.InterfaceDeclaration:
- return createIterfaceItem(node);
+ return createIterfaceItem(node);
case SyntaxKind.ModuleDeclaration:
- return createModuleItem(node);
+ return createModuleItem(node);
case SyntaxKind.FunctionDeclaration:
- return createFunctionItem(node);
+ return createFunctionItem(node);
}
return undefined;
- function getModuleNames(node: TypeScript.ModuleDeclarationSyntax): string[] {
+ function getModuleNames(moduleDeclaration: ModuleDeclaration): string[]{
+ // We want to maintain quotation marks.
+ if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) {
+ return [getSourceTextOfNode(moduleDeclaration.name)];
+ }
+
+ // Otherwise, we need to aggregate each identifier of the qualified name.
var result: string[] = [];
- if (node.stringLiteral) {
- result.push(node.stringLiteral.text());
- }
- else {
- getModuleNamesHelper(node.name, result);
- }
+ result.push(moduleDeclaration.name.text);
+
+ while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) {
+ moduleDeclaration = moduleDeclaration.body;
+
+ result.push(moduleDeclaration.name.text);
+ }
return result;
}
- function getModuleNamesHelper(name: TypeScript.INameSyntax, result: string[]): void {
- if (name.kind() === TypeScript.SyntaxKind.QualifiedName) {
- var qualifiedName = name;
- getModuleNamesHelper(qualifiedName.left, result);
- result.push(qualifiedName.right.text());
- }
- else {
- result.push((name).text());
- }
- }
-
- function createModuleItem(node: ModuleDeclarationSyntax): ts.NavigationBarItem {
+ function createModuleItem(node: ModuleDeclaration): NavigationBarItem {
var moduleNames = getModuleNames(node);
-
- var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n));
+
+ var childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem);
return new ts.NavigationBarItem(moduleNames.join("."),
ts.ScriptElementKind.moduleElement,
- getKindModifiers(node.modifiers),
- [TextSpan.fromBounds(start(node), end(node))],
+ getNodeModifiers(node),
+ [getNodeSpan(node)],
childItems,
getIndent(node));
}
- function createFunctionItem(node: FunctionDeclarationSyntax) {
- var childItems = getItemsWorker(node.block.statements, n => createChildItem(n));
+ function createFunctionItem(node: FunctionDeclaration) {
+ if (node.name && node.body && node.body.kind === SyntaxKind.FunctionBlock) {
+ var childItems = getItemsWorker((node.body).statements, createChildItem);
- return new ts.NavigationBarItem(node.identifier.text(),
- ts.ScriptElementKind.functionElement,
- getKindModifiers(node.modifiers),
- [TextSpan.fromBounds(start(node), end(node))],
- childItems,
- getIndent(node));
+ return new ts.NavigationBarItem(node.name.text,
+ ts.ScriptElementKind.functionElement,
+ getNodeModifiers(node),
+ [getNodeSpan(node)],
+ childItems,
+ getIndent(node));
+ }
+
+ return undefined;
}
- function createSourceUnitItem(node: SourceUnitSyntax): ts.NavigationBarItem {
- var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n));
+ function createSourceFileItem(node: SourceFile): ts.NavigationBarItem {
+ var childItems = getItemsWorker(getChildNodes(node.statements), createChildItem);
if (childItems === undefined || childItems.length === 0) {
return undefined;
@@ -299,50 +285,83 @@ module TypeScript.Services {
return new ts.NavigationBarItem("",
ts.ScriptElementKind.moduleElement,
ts.ScriptElementKindModifier.none,
- [TextSpan.fromBounds(start(node), end(node))],
+ [getNodeSpan(node)],
childItems);
}
- function createClassItem(node: ClassDeclarationSyntax): ts.NavigationBarItem {
- var constructor = ArrayUtilities.firstOrDefault(
- node.classElements, n => n.kind() === SyntaxKind.ConstructorDeclaration);
+ function createClassItem(node: ClassDeclaration): ts.NavigationBarItem {
+ var childItems: NavigationBarItem[];
- // Add the constructor parameters in as children of the class (for property parameters).
- var nodes: ISyntaxNode[] = constructor
- ? (constructor.callSignature.parameterList.parameters).concat(node.classElements)
- : node.classElements;
+ if (node.members) {
+ var constructor = forEach(node.members, member => {
+ return member.kind === SyntaxKind.Constructor && member;
+ });
+
+ // Add the constructor parameters in as children of the class (for property parameters).
+ var nodes: Node[] = constructor
+ ? (constructor.parameters).concat(node.members)
+ : node.members;
+
+ var childItems = getItemsWorker(nodes, createChildItem);
+ }
- var childItems = getItemsWorker(nodes, n => createChildItem(n));
return new ts.NavigationBarItem(
- node.identifier.text(),
+ node.name.text,
ts.ScriptElementKind.classElement,
- getKindModifiers(node.modifiers),
- [TextSpan.fromBounds(start(node), end(node))],
+ getNodeModifiers(node),
+ [getNodeSpan(node)],
childItems,
getIndent(node));
}
- function createEnumItem(node: TypeScript.EnumDeclarationSyntax): ts.NavigationBarItem {
- var childItems = getItemsWorker(node.enumElements, n => createChildItem(n));
+ function createEnumItem(node: EnumDeclaration): ts.NavigationBarItem {
+ var childItems = getItemsWorker(node.members, createChildItem);
return new ts.NavigationBarItem(
- node.identifier.text(),
+ node.name.text,
ts.ScriptElementKind.enumElement,
- getKindModifiers(node.modifiers),
- [TextSpan.fromBounds(start(node), end(node))],
+ getNodeModifiers(node),
+ [getNodeSpan(node)],
childItems,
getIndent(node));
}
- function createIterfaceItem(node: TypeScript.InterfaceDeclarationSyntax): ts.NavigationBarItem {
- var childItems = getItemsWorker(node.body.typeMembers, n => createChildItem(n));
+ function createIterfaceItem(node: InterfaceDeclaration): ts.NavigationBarItem {
+ var childItems = getItemsWorker(node.members, createChildItem);
return new ts.NavigationBarItem(
- node.identifier.text(),
+ node.name.text,
ts.ScriptElementKind.interfaceElement,
- getKindModifiers(node.modifiers),
- [TextSpan.fromBounds(start(node), end(node))],
+ getNodeModifiers(node),
+ [getNodeSpan(node)],
childItems,
getIndent(node));
}
}
+
+ // TODO: use implementation in services.ts
+ function getNodeModifiers(node: Node): string {
+ var flags = node.flags;
+ var result: string[] = [];
+
+ if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier);
+ if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier);
+ if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
+ if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
+ if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier);
+
+ return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none;
+ }
+
+ function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration {
+
+ while (node.body.kind === SyntaxKind.ModuleDeclaration) {
+ node = node.body;
+ }
+
+ return node;
+ }
+
+ function getNodeSpan(node: Node) {
+ return TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd());
+ }
}
}
\ No newline at end of file
diff --git a/src/services/services.ts b/src/services/services.ts
index ed32721a1ac..daaeb6d21bc 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -3121,9 +3121,7 @@ module ts {
function getNavigationBarItems(filename: string): NavigationBarItem[] {
filename = TypeScript.switchToForwardSlashes(filename);
-
- var syntaxTree = getSyntaxTree(filename);
- return TypeScript.Services.getNavigationBarItemsHelper(syntaxTree.sourceUnit());
+ return getNavigationBarItemsHelper(getCurrentSourceFile(filename));
}
function getOutliningSpans(filename: string): OutliningSpan[] {