diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 0ace63aaced71..2158270142a1e 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -183,6 +183,17 @@ namespace ts.NavigationBar { endNode(); } + function addNodeWithRecursiveInitializer(node: VariableDeclaration | PropertyAssignment | BindingElement | PropertyDeclaration): void { + if (node.initializer && isFunctionOrClassExpression(node.initializer)) { + startNode(node); + forEachChild(node.initializer, addChildrenRecursively); + endNode(); + } + else { + addNodeWithRecursiveChild(node, node.initializer); + } + } + /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ function addChildrenRecursively(node: Node | undefined): void { curCancellationToken.throwIfCancellationRequested(); @@ -215,8 +226,12 @@ namespace ts.NavigationBar { break; case SyntaxKind.PropertyDeclaration: + if (!hasDynamicName(node)) { + addNodeWithRecursiveInitializer(node); + } + break; case SyntaxKind.PropertySignature: - if (!hasDynamicName((node))) { + if (!hasDynamicName(node)) { addLeafNode(node); } break; @@ -255,22 +270,16 @@ namespace ts.NavigationBar { break; case SyntaxKind.BindingElement: case SyntaxKind.PropertyAssignment: - case SyntaxKind.VariableDeclaration: - const { name, initializer } = node; - if (isBindingPattern(name)) { - addChildrenRecursively(name); - } - else if (initializer && isFunctionOrClassExpression(initializer)) { - // Add a node for the VariableDeclaration, but not for the initializer. - startNode(node); - forEachChild(initializer, addChildrenRecursively); - endNode(); + case SyntaxKind.VariableDeclaration: { + const child = node; + if (isBindingPattern(child.name)) { + addChildrenRecursively(child.name); } else { - addNodeWithRecursiveChild(node, initializer); + addNodeWithRecursiveInitializer(child); } break; - + } case SyntaxKind.FunctionDeclaration: const nameNode = (node).name; // If we see a function declaration track as a possible ES5 class diff --git a/tests/cases/fourslash/navigationBarPropertyDeclarations.ts b/tests/cases/fourslash/navigationBarPropertyDeclarations.ts new file mode 100644 index 0000000000000..4de14049ab795 --- /dev/null +++ b/tests/cases/fourslash/navigationBarPropertyDeclarations.ts @@ -0,0 +1,295 @@ +/// + +////class A { +//// public A1 = class { +//// public x = 1; +//// private y() {} +//// protected z() {} +//// } +//// +//// public A2 = { +//// x: 1, +//// y() {}, +//// z() {} +//// } +//// +//// public A3 = function () {} +//// public A4 = () => {} +//// public A5 = 1; +//// public A6 = "A6"; +//// +//// public ["A7"] = class { +//// public x = 1; +//// private y() {} +//// protected z() {} +//// } +//// +//// public [1] = { +//// x: 1, +//// y() {}, +//// z() {} +//// } +//// +//// public [1 + 1] = 1; +////} + +verify.navigationTree({ + text: "", + kind: "script", + childItems: [ + { + text: "A", + kind: "class", + childItems: [ + { + text: "[1]", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property" + }, + { + text: "y", + kind: "method" + }, + { + text: "z", + kind: "method" + } + ] + }, + { + text: "A1", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property", + kindModifiers: "public" + }, + { + text: "y", + kind: "method", + kindModifiers: "private" + }, + { + text: "z", + kind: "method", + kindModifiers: "protected" + } + ] + }, + { + text: "A2", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property" + }, + { + text: "y", + kind: "method" + }, + { + text: "z", + kind: "method" + } + ] + }, + { + text: "A3", + kind: "property", + kindModifiers: "public" + }, + { + text: "A4", + kind: "property", + kindModifiers: "public" + }, + { + text: "A5", + kind: "property", + kindModifiers: "public" + }, + { + text: "A6", + kind: "property", + kindModifiers: "public" + }, + { + text: "[\"A7\"]", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property", + kindModifiers: "public" + }, + { + text: "y", + kind: "method", + kindModifiers: "private" + }, + { + text: "z", + kind: "method", + kindModifiers: "protected" + } + ] + } + ] + } + ] +}); + +verify.navigationBar([ + { + text: "", + kind: "script", + childItems: [ + { + text: "A", + kind: "class" + } + ] + }, + { + text: "A", + kind: "class", + childItems: [ + { + text: "[1]", + kind: "property", + kindModifiers: "public" + }, + { + text: "A1", + kind: "property", + kindModifiers: "public" + }, + { + text: "A2", + kind: "property", + kindModifiers: "public" + }, + { + text: "A3", + kind: "property", + kindModifiers: "public" + }, + { + text: "A4", + kind: "property", + kindModifiers: "public" + }, + { + text: "A5", + kind: "property", + kindModifiers: "public" + }, + { + text: "A6", + kind: "property", + kindModifiers: "public" + }, + { + text: "[\"A7\"]", + kind: "property", + kindModifiers: "public" + } + ], + indent: 1 + }, + { + text: "[1]", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property" + }, + { + text: "y", + kind: "method" + }, + { + text: "z", + kind: "method" + } + ], + indent: 2 + }, + { + text: "A1", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property", + kindModifiers: "public" + }, + { + text: "y", + kind: "method", + kindModifiers: "private" + }, + { + text: "z", + kind: "method", + kindModifiers: "protected" + } + ], + indent: 2 + }, + { + text: "A2", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property" + }, + { + text: "y", + kind: "method" + }, + { + text: "z", + kind: "method" + } + ], + indent: 2 + }, + { + text: "[\"A7\"]", + kind: "property", + kindModifiers: "public", + childItems: [ + { + text: "x", + kind: "property", + kindModifiers: "public" + }, + { + text: "y", + kind: "method", + kindModifiers: "private" + }, + { + text: "z", + kind: "method", + kindModifiers: "protected" + } + ], + indent: 2 + } +]);