From 93dca009f9725d2e7a777283c03770258c902889 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Nov 2017 15:25:06 -0800 Subject: [PATCH] In navigation tree, don't merge static with non-static (#20347) --- src/services/navigationBar.ts | 77 ++++++++++--------- ...gationBarItemsStaticAndNonStaticNoMerge.ts | 56 ++++++++++++++ 2 files changed, 98 insertions(+), 35 deletions(-) create mode 100644 tests/cases/fourslash/navigationBarItemsStaticAndNonStaticNoMerge.ts diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 06feabf439..599187cab7 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -336,46 +336,53 @@ namespace ts.NavigationBar { nameToItems.set(name, [itemWithSameName, child]); return true; } - - function tryMerge(a: NavigationBarNode, b: NavigationBarNode): boolean { - if (shouldReallyMerge(a.node, b.node)) { - merge(a, b); - return true; - } - return false; - } }); + } - /** a and b have the same name, but they may not be mergeable. */ - function shouldReallyMerge(a: Node, b: Node): boolean { - return a.kind === b.kind && (a.kind !== SyntaxKind.ModuleDeclaration || areSameModule(a, b)); + function tryMerge(a: NavigationBarNode, b: NavigationBarNode): boolean { + if (shouldReallyMerge(a.node, b.node)) { + merge(a, b); + return true; + } + return false; + } - // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes. - // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'! - function areSameModule(a: ModuleDeclaration, b: ModuleDeclaration): boolean { - if (a.body.kind !== b.body.kind) { - return false; - } - if (a.body.kind !== SyntaxKind.ModuleDeclaration) { - return true; - } - return areSameModule(a.body, b.body); - } + /** a and b have the same name, but they may not be mergeable. */ + function shouldReallyMerge(a: Node, b: Node): boolean { + if (a.kind !== b.kind) { + return false; + } + switch (a.kind) { + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return hasModifier(a, ModifierFlags.Static) === hasModifier(b, ModifierFlags.Static); + case SyntaxKind.ModuleDeclaration: + return areSameModule(a, b); + default: + return true; + } + } + + // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes. + // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'! + function areSameModule(a: ModuleDeclaration, b: ModuleDeclaration): boolean { + return a.body.kind === b.body.kind && (a.body.kind !== SyntaxKind.ModuleDeclaration || areSameModule(a.body, b.body)); + } + + /** Merge source into target. Source should be thrown away after this is called. */ + function merge(target: NavigationBarNode, source: NavigationBarNode): void { + target.additionalNodes = target.additionalNodes || []; + target.additionalNodes.push(source.node); + if (source.additionalNodes) { + target.additionalNodes.push(...source.additionalNodes); } - /** Merge source into target. Source should be thrown away after this is called. */ - function merge(target: NavigationBarNode, source: NavigationBarNode): void { - target.additionalNodes = target.additionalNodes || []; - target.additionalNodes.push(source.node); - if (source.additionalNodes) { - target.additionalNodes.push(...source.additionalNodes); - } - - target.children = concatenate(target.children, source.children); - if (target.children) { - mergeChildren(target.children); - sortChildren(target.children); - } + target.children = concatenate(target.children, source.children); + if (target.children) { + mergeChildren(target.children); + sortChildren(target.children); } } diff --git a/tests/cases/fourslash/navigationBarItemsStaticAndNonStaticNoMerge.ts b/tests/cases/fourslash/navigationBarItemsStaticAndNonStaticNoMerge.ts new file mode 100644 index 0000000000..007a2c79aa --- /dev/null +++ b/tests/cases/fourslash/navigationBarItemsStaticAndNonStaticNoMerge.ts @@ -0,0 +1,56 @@ +////class C { +//// static x; +//// x; +////} + +// Anonymous classes are still included. +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "x", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "x", + "kind": "property" + } + ] + } + ] +}); + +verify.navigationBar([ + { + "text": "", + "kind": "script", + "childItems": [ + { + "text": "C", + "kind": "class" + } + ] + }, + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "x", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "x", + "kind": "property" + } + ], + "indent": 1 + } +]);