Skip to content

Commit d690835

Browse files
authored
Merge pull request #25698 from Microsoft/navigationBarUnrelatedGrandchildren
navigationBar: Don't merge unrelated grandchildren
2 parents 93ab352 + 1038c76 commit d690835

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

src/services/navigationBar.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ namespace ts.NavigationBar {
133133
/** Call after calling `startNode` and adding children to it. */
134134
function endNode(): void {
135135
if (parent.children) {
136-
mergeChildren(parent.children);
136+
mergeChildren(parent.children, parent);
137137
sortChildren(parent.children);
138138
}
139139
parent = parentsStack.pop()!;
@@ -304,7 +304,7 @@ namespace ts.NavigationBar {
304304
}
305305

306306
/** Merge declarations of the same kind. */
307-
function mergeChildren(children: NavigationBarNode[]): void {
307+
function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): void {
308308
const nameToItems = createMap<NavigationBarNode | NavigationBarNode[]>();
309309
filterMutate(children, child => {
310310
const declName = getNameOfDeclaration(<Declaration>child.node);
@@ -322,7 +322,7 @@ namespace ts.NavigationBar {
322322

323323
if (itemsWithSameName instanceof Array) {
324324
for (const itemWithSameName of itemsWithSameName) {
325-
if (tryMerge(itemWithSameName, child)) {
325+
if (tryMerge(itemWithSameName, child, node)) {
326326
return false;
327327
}
328328
}
@@ -331,7 +331,7 @@ namespace ts.NavigationBar {
331331
}
332332
else {
333333
const itemWithSameName = itemsWithSameName;
334-
if (tryMerge(itemWithSameName, child)) {
334+
if (tryMerge(itemWithSameName, child, node)) {
335335
return false;
336336
}
337337
nameToItems.set(name, [itemWithSameName, child]);
@@ -340,17 +340,17 @@ namespace ts.NavigationBar {
340340
});
341341
}
342342

343-
function tryMerge(a: NavigationBarNode, b: NavigationBarNode): boolean {
344-
if (shouldReallyMerge(a.node, b.node)) {
343+
function tryMerge(a: NavigationBarNode, b: NavigationBarNode, parent: NavigationBarNode): boolean {
344+
if (shouldReallyMerge(a.node, b.node, parent)) {
345345
merge(a, b);
346346
return true;
347347
}
348348
return false;
349349
}
350350

351351
/** a and b have the same name, but they may not be mergeable. */
352-
function shouldReallyMerge(a: Node, b: Node): boolean {
353-
if (a.kind !== b.kind) {
352+
function shouldReallyMerge(a: Node, b: Node, parent: NavigationBarNode): boolean {
353+
if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) {
354354
return false;
355355
}
356356
switch (a.kind) {
@@ -366,6 +366,13 @@ namespace ts.NavigationBar {
366366
}
367367
}
368368

369+
// We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }`
370+
// We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };`
371+
function isOwnChild(n: Node, parent: NavigationBarNode): boolean {
372+
const par = isModuleBlock(n.parent) ? n.parent.parent : n.parent;
373+
return par === parent.node || contains(parent.additionalNodes, par);
374+
}
375+
369376
// We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
370377
// Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
371378
function areSameModule(a: ModuleDeclaration, b: ModuleDeclaration): boolean {
@@ -383,7 +390,7 @@ namespace ts.NavigationBar {
383390

384391
target.children = concatenate(target.children, source.children);
385392
if (target.children) {
386-
mergeChildren(target.children);
393+
mergeChildren(target.children, target);
387394
sortChildren(target.children);
388395
}
389396
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////const o = {
4+
//// a: {
5+
//// m() {},
6+
//// },
7+
//// b: {
8+
//// m() {},
9+
//// },
10+
////}
11+
12+
verify.navigationTree({
13+
text: "<global>",
14+
kind: "script",
15+
childItems: [
16+
{
17+
text: "o",
18+
kind: "const",
19+
childItems: [
20+
{ text: "m", kind: "method" },
21+
{ text: "m", kind: "method" },
22+
],
23+
},
24+
]
25+
});
26+
27+
verify.navigationBar([
28+
{
29+
text: "<global>",
30+
kind: "script",
31+
childItems: [
32+
{ text: "o", kind: "const" },
33+
],
34+
},
35+
{
36+
text: "o",
37+
kind: "const",
38+
childItems: [
39+
{ text: "m", kind: "method" },
40+
{ text: "m", kind: "method" },
41+
],
42+
indent: 1,
43+
},
44+
]);

0 commit comments

Comments
 (0)