Skip to content

Commit f8acf11

Browse files
author
Andy Hanson
committed
Fix algorithm and include function expressions.
Previous algorithm would sort *after* adding to top-level nodes. This was broken because top-level nodes were simply all in a flat array, so this would cause sorting among unrelated elements. Now we collect all the nodes in a single logical level and sort them before adding them to topLevelNodes.
1 parent dda27f7 commit f8acf11

10 files changed

+213
-195
lines changed

src/harness/fourslash.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -2058,15 +2058,24 @@ namespace FourSlash {
20582058
}
20592059
}
20602060

2061-
public printNavigationBar() {
2061+
public printNavigationBar(showChildItems = false) {
20622062
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
20632063
const length = items && items.length;
20642064

20652065
Harness.IO.log(`Navigation bar (${length} items)`);
20662066

20672067
for (let i = 0; i < length; i++) {
20682068
const item = items[i];
2069-
Harness.IO.log(`name: ${item.text}, kind: ${item.kind}`);
2069+
const childrenText = showChildItems ? `, children: ${item.childItems.map(child => child.text)}` : "";
2070+
Harness.IO.log(`${strRepeat(" ", item.indent)}name: ${item.text}, kind: ${item.kind}${childrenText}`);
2071+
}
2072+
2073+
function strRepeat(str: string, times: number) {
2074+
let out = "";
2075+
for (let i = 0; i < times; i++) {
2076+
out += str;
2077+
}
2078+
return out;
20702079
}
20712080
}
20722081

@@ -3267,8 +3276,8 @@ namespace FourSlashInterface {
32673276
this.state.printNavigationItems(searchValue);
32683277
}
32693278

3270-
public printNavigationBar() {
3271-
this.state.printNavigationBar();
3279+
public printNavigationBar(showChildItems = false) {
3280+
this.state.printNavigationBar(showChildItems);
32723281
}
32733282

32743283
public printReferences() {

src/services/navigationBar.ts

+154-126
Large diffs are not rendered by default.

tests/cases/fourslash/fourslash.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ declare namespace FourSlashInterface {
238238
printBreakpointAtCurrentLocation(): void;
239239
printNameOrDottedNameSpans(pos: number): void;
240240
printErrorList(): void;
241-
printNavigationBar(): void;
241+
printNavigationBar(showChildItems?: boolean): void;
242242
printNavigationItems(searchValue?: string): void;
243243
printScriptLexicalStructureItems(): void;
244244
printReferences(): void;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////global.cls = class { };
4+
////(function() {
5+
//// const x = () => {
6+
//// // Presence of inner function causes x to be a top-level function.
7+
//// function xx() {}
8+
//// };
9+
//// const y = {
10+
//// // This is not a top-level function (contains nothing, but shows up in childItems of its parent.)
11+
//// foo: function() {}
12+
//// };
13+
//// (function nest() {
14+
//// function moreNest() {}
15+
//// })();
16+
////})();
17+
////(function() { // Different anonymous functions are not merged
18+
//// These will only show up as childItems.
19+
//// function z() {}
20+
//// console.log(function() {})
21+
////})
22+
////(function classes() {
23+
//// // Classes show up in top-level regardless of whether they have names or inner declarations.
24+
//// const cls2 = class { };
25+
//// console.log(class cls3 {});
26+
//// (class { });
27+
////})
28+
29+
verify.navigationBarCount(21);
30+
verify.navigationBarIndex("<global>", 0);
31+
verify.navigationBarIndex("<function>", 1);
32+
verify.navigationBarIndex("x", 2);
33+
verify.navigationBarIndex("nest", 3);
34+
verify.navigationBarIndex("<function>", 4);
35+
verify.navigationBarIndex("global.cls", 5);
36+
verify.navigationBarIndex("classes", 6);
37+
verify.navigationBarIndex("cls2", 7);
38+
verify.navigationBarIndex("<class>", 8);
39+
verify.navigationBarIndex("cls3", 9);
40+
41+
verify.navigationBarContains("global.cls", "class");
42+

tests/cases/fourslash/navigationBarItemsFunctions.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ test.markers().forEach((marker) => {
2020
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
2121
});
2222

23-
verify.navigationBarCount(8); // 4 functions + global. Note: there are 8 because of the functions show up at the top level and as child items.
23+
verify.navigationBarCount(11); // Includes many nested functions, with duplications as they appear both at top-level and as childItems

tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ test.markers().forEach((marker) => {
99
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
1010
});
1111

12-
verify.navigationBarCount(3); // <global> and 'f'.
12+
verify.navigationBarCount(4); // <global> with child 'f' and 'f' with child '<function>'.

tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ test.markers().forEach((marker) => {
1010
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
1111
});
1212

13-
verify.navigationBarCount(3); // <global> and 'f'
13+
verify.navigationBarCount(5); // <global> with children '<function>' and 'f', and 'f' with child '<function>'

tests/cases/fourslash/navigationBarItemsItemsContainsNoAnonymousFunctions.ts

-44
This file was deleted.

tests/cases/fourslash/navigationBarItemsMissingName1.ts

-16
This file was deleted.

tests/cases/fourslash/navigationBarItemsModules.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
////{| "itemName": "\"X.Y.Z\"", "kind": "module" |}
32
////declare module "X.Y.Z" {
43
////}

0 commit comments

Comments
 (0)