Merge pull request #25698 from Microsoft/navigationBarUnrelatedGrandchildren

navigationBar: Don't merge unrelated grandchildren
This commit is contained in:
Mohamed Hegazy 2018-07-16 13:02:35 -07:00 committed by GitHub
commit d690835cb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 9 deletions

View File

@ -133,7 +133,7 @@ namespace ts.NavigationBar {
/** Call after calling `startNode` and adding children to it. */
function endNode(): void {
if (parent.children) {
mergeChildren(parent.children);
mergeChildren(parent.children, parent);
sortChildren(parent.children);
}
parent = parentsStack.pop()!;
@ -304,7 +304,7 @@ namespace ts.NavigationBar {
}
/** Merge declarations of the same kind. */
function mergeChildren(children: NavigationBarNode[]): void {
function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): void {
const nameToItems = createMap<NavigationBarNode | NavigationBarNode[]>();
filterMutate(children, child => {
const declName = getNameOfDeclaration(<Declaration>child.node);
@ -322,7 +322,7 @@ namespace ts.NavigationBar {
if (itemsWithSameName instanceof Array) {
for (const itemWithSameName of itemsWithSameName) {
if (tryMerge(itemWithSameName, child)) {
if (tryMerge(itemWithSameName, child, node)) {
return false;
}
}
@ -331,7 +331,7 @@ namespace ts.NavigationBar {
}
else {
const itemWithSameName = itemsWithSameName;
if (tryMerge(itemWithSameName, child)) {
if (tryMerge(itemWithSameName, child, node)) {
return false;
}
nameToItems.set(name, [itemWithSameName, child]);
@ -340,8 +340,8 @@ namespace ts.NavigationBar {
});
}
function tryMerge(a: NavigationBarNode, b: NavigationBarNode): boolean {
if (shouldReallyMerge(a.node, b.node)) {
function tryMerge(a: NavigationBarNode, b: NavigationBarNode, parent: NavigationBarNode): boolean {
if (shouldReallyMerge(a.node, b.node, parent)) {
merge(a, b);
return true;
}
@ -349,8 +349,8 @@ namespace ts.NavigationBar {
}
/** 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) {
function shouldReallyMerge(a: Node, b: Node, parent: NavigationBarNode): boolean {
if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) {
return false;
}
switch (a.kind) {
@ -366,6 +366,13 @@ namespace ts.NavigationBar {
}
}
// We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }`
// We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };`
function isOwnChild(n: Node, parent: NavigationBarNode): boolean {
const par = isModuleBlock(n.parent) ? n.parent.parent : n.parent;
return par === parent.node || contains(parent.additionalNodes, par);
}
// 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 {
@ -383,7 +390,7 @@ namespace ts.NavigationBar {
target.children = concatenate(target.children, source.children);
if (target.children) {
mergeChildren(target.children);
mergeChildren(target.children, target);
sortChildren(target.children);
}
}

View File

@ -0,0 +1,44 @@
/// <reference path="fourslash.ts"/>
////const o = {
//// a: {
//// m() {},
//// },
//// b: {
//// m() {},
//// },
////}
verify.navigationTree({
text: "<global>",
kind: "script",
childItems: [
{
text: "o",
kind: "const",
childItems: [
{ text: "m", kind: "method" },
{ text: "m", kind: "method" },
],
},
]
});
verify.navigationBar([
{
text: "<global>",
kind: "script",
childItems: [
{ text: "o", kind: "const" },
],
},
{
text: "o",
kind: "const",
childItems: [
{ text: "m", kind: "method" },
{ text: "m", kind: "method" },
],
indent: 1,
},
]);