@@ -56,7 +56,7 @@ namespace ts.NavigationBar {
5656 curCancellationToken = cancellationToken ;
5757 curSourceFile = sourceFile ;
5858 try {
59- return map ( topLevelItems ( rootNavigationBarNode ( sourceFile ) ) , convertToTopLevelItem ) ;
59+ return map ( primaryNavBarMenuItems ( rootNavigationBarNode ( sourceFile ) ) , convertToPrimaryNavBarMenuItem ) ;
6060 }
6161 finally {
6262 reset ( ) ;
@@ -111,8 +111,8 @@ namespace ts.NavigationBar {
111111 return root ;
112112 }
113113
114- function addLeafNode ( node : Node ) : void {
115- pushChild ( parent , emptyNavigationBarNode ( node ) ) ;
114+ function addLeafNode ( node : Node , name ?: DeclarationName ) : void {
115+ pushChild ( parent , emptyNavigationBarNode ( node , name ) ) ;
116116 }
117117
118118 function emptyNavigationBarNode ( node : Node , name ?: DeclarationName ) : NavigationBarNode {
@@ -243,23 +243,26 @@ namespace ts.NavigationBar {
243243 }
244244 break ;
245245
246+ case SyntaxKind . ShorthandPropertyAssignment :
247+ addNodeWithRecursiveChild ( node , ( < ShorthandPropertyAssignment > node ) . name ) ;
248+ break ;
249+ case SyntaxKind . SpreadAssignment :
250+ const { expression } = < SpreadAssignment > node ;
251+ // Use the expression as the name of the SpreadAssignment, otherwise show as <unknown>.
252+ isIdentifier ( expression ) ? addLeafNode ( node , expression ) : addLeafNode ( node ) ;
253+ break ;
246254 case SyntaxKind . BindingElement :
255+ case SyntaxKind . PropertyAssignment :
247256 case SyntaxKind . VariableDeclaration :
248- const { name, initializer } = < VariableDeclaration | BindingElement > node ;
257+ const { name, initializer } = < VariableDeclaration | PropertyAssignment | BindingElement > node ;
249258 if ( isBindingPattern ( name ) ) {
250259 addChildrenRecursively ( name ) ;
251260 }
252261 else if ( initializer && isFunctionOrClassExpression ( initializer ) ) {
253- if ( initializer . name ) {
254- // Don't add a node for the VariableDeclaration, just for the initializer.
255- addChildrenRecursively ( initializer ) ;
256- }
257- else {
258- // Add a node for the VariableDeclaration, but not for the initializer.
259- startNode ( node ) ;
260- forEachChild ( initializer , addChildrenRecursively ) ;
261- endNode ( ) ;
262- }
262+ // Add a node for the VariableDeclaration, but not for the initializer.
263+ startNode ( node ) ;
264+ forEachChild ( initializer , addChildrenRecursively ) ;
265+ endNode ( ) ;
263266 }
264267 else {
265268 addNodeWithRecursiveChild ( node , initializer ) ;
@@ -699,12 +702,15 @@ namespace ts.NavigationBar {
699702 }
700703 }
701704
702- /** Flattens the NavNode tree to a list, keeping only the top-level items. */
703- function topLevelItems ( root : NavigationBarNode ) : NavigationBarNode [ ] {
704- const topLevel : NavigationBarNode [ ] = [ ] ;
705+ /** Flattens the NavNode tree to a list of items to appear in the primary navbar menu. */
706+ function primaryNavBarMenuItems ( root : NavigationBarNode ) : NavigationBarNode [ ] {
707+ // The primary (middle) navbar menu displays the general code navigation hierarchy, similar to the navtree.
708+ // The secondary (right) navbar menu displays the child items of whichever primary item is selected.
709+ // Some less interesting items without their own child navigation items (e.g. a local variable declaration) only show up in the secondary menu.
710+ const primaryNavBarMenuItems : NavigationBarNode [ ] = [ ] ;
705711 function recur ( item : NavigationBarNode ) {
706- if ( isTopLevel ( item ) ) {
707- topLevel . push ( item ) ;
712+ if ( shouldAppearInPrimaryNavBarMenu ( item ) ) {
713+ primaryNavBarMenuItems . push ( item ) ;
708714 if ( item . children ) {
709715 for ( const child of item . children ) {
710716 recur ( child ) ;
@@ -713,9 +719,16 @@ namespace ts.NavigationBar {
713719 }
714720 }
715721 recur ( root ) ;
716- return topLevel ;
722+ return primaryNavBarMenuItems ;
717723
718- function isTopLevel ( item : NavigationBarNode ) : boolean {
724+ /** Determines if a node should appear in the primary navbar menu. */
725+ function shouldAppearInPrimaryNavBarMenu ( item : NavigationBarNode ) : boolean {
726+ // Items with children should always appear in the primary navbar menu.
727+ if ( item . children ) {
728+ return true ;
729+ }
730+
731+ // Some nodes are otherwise important enough to always include in the primary navigation menu.
719732 switch ( navigationBarNodeKind ( item ) ) {
720733 case SyntaxKind . ClassDeclaration :
721734 case SyntaxKind . ClassExpression :
@@ -728,13 +741,6 @@ namespace ts.NavigationBar {
728741 case SyntaxKind . JSDocCallbackTag :
729742 return true ;
730743
731- case SyntaxKind . Constructor :
732- case SyntaxKind . MethodDeclaration :
733- case SyntaxKind . GetAccessor :
734- case SyntaxKind . SetAccessor :
735- case SyntaxKind . VariableDeclaration :
736- return hasSomeImportantChild ( item ) ;
737-
738744 case SyntaxKind . ArrowFunction :
739745 case SyntaxKind . FunctionDeclaration :
740746 case SyntaxKind . FunctionExpression :
@@ -755,15 +761,9 @@ namespace ts.NavigationBar {
755761 case SyntaxKind . Constructor :
756762 return true ;
757763 default :
758- return hasSomeImportantChild ( item ) ;
764+ return false ;
759765 }
760766 }
761- function hasSomeImportantChild ( item : NavigationBarNode ) : boolean {
762- return some ( item . children , child => {
763- const childKind = navigationBarNodeKind ( child ) ;
764- return childKind !== SyntaxKind . VariableDeclaration && childKind !== SyntaxKind . BindingElement ;
765- } ) ;
766- }
767767 }
768768 }
769769
@@ -778,19 +778,19 @@ namespace ts.NavigationBar {
778778 } ;
779779 }
780780
781- function convertToTopLevelItem ( n : NavigationBarNode ) : NavigationBarItem {
781+ function convertToPrimaryNavBarMenuItem ( n : NavigationBarNode ) : NavigationBarItem {
782782 return {
783783 text : getItemName ( n . node , n . name ) ,
784784 kind : getNodeKind ( n . node ) ,
785785 kindModifiers : getModifiers ( n . node ) ,
786786 spans : getSpans ( n ) ,
787- childItems : map ( n . children , convertToChildItem ) || emptyChildItemArray ,
787+ childItems : map ( n . children , convertToSecondaryNavBarMenuItem ) || emptyChildItemArray ,
788788 indent : n . indent ,
789789 bolded : false ,
790790 grayed : false
791791 } ;
792792
793- function convertToChildItem ( n : NavigationBarNode ) : NavigationBarItem {
793+ function convertToSecondaryNavBarMenuItem ( n : NavigationBarNode ) : NavigationBarItem {
794794 return {
795795 text : getItemName ( n . node , n . name ) ,
796796 kind : getNodeKind ( n . node ) ,
0 commit comments