@@ -32,13 +32,18 @@ export interface ISignatureBuilderOptions {
3232 /**
3333 * The AST node that we will traverse to extract tokens
3434 */
35-
3635 startingNode : ts . Node ;
36+
3737 /**
38- * An AST node to stop at (e.g. the "{" after a class declaration).
39- * If omitted, then all child nodes for `startingNode` will be processed
38+ * Normally, the excerpt will include all child nodes for `startingNode`; whereas if `childKindToStopBefore`
39+ * is specified, then the node traversal will stop before (i.e. excluding) the first immediate child
40+ * of `startingNode` with the specified syntax kind.
41+ *
42+ * @remarks
43+ * For example, suppose the signature is `interface X: Y { z: string }`. The token `{` has syntax kind
44+ * `ts.SyntaxKind.FirstPunctuation`, so we can specify that to truncate the excerpt to `interface X: Y`.
4045 */
41- nodeToStopAt ?: ts . SyntaxKind ;
46+ stopBeforeChildKind ?: ts . SyntaxKind ;
4247
4348 /**
4449 * A list of child nodes whose token ranges we want to capture
@@ -50,7 +55,9 @@ export interface ISignatureBuilderOptions {
5055 * Internal state for ExcerptBuilder
5156 */
5257interface IBuildSpanState {
53- nodeToStopAt ?: ts . SyntaxKind ;
58+ startingNode : ts . Node ;
59+ stopBeforeChildKind : ts . SyntaxKind | undefined ;
60+
5461 tokenRangesByNode : Map < ts . Node , IExcerptTokenRange > ;
5562
5663 /**
@@ -75,7 +82,8 @@ export class ExcerptBuilder {
7582 const excerptTokens : IExcerptToken [ ] = [ ] ;
7683
7784 ExcerptBuilder . _buildSpan ( excerptTokens , span , {
78- nodeToStopAt : options . nodeToStopAt ,
85+ startingNode : options . startingNode ,
86+ stopBeforeChildKind : options . stopBeforeChildKind ,
7987 tokenRangesByNode,
8088 disableMergingForNextToken : false
8189 } ) ;
@@ -88,11 +96,6 @@ export class ExcerptBuilder {
8896 }
8997
9098 private static _buildSpan ( excerptTokens : IExcerptToken [ ] , span : Span , state : IBuildSpanState ) : boolean {
91-
92- if ( state . nodeToStopAt && span . kind === state . nodeToStopAt ) {
93- return false ;
94- }
95-
9699 if ( span . kind === ts . SyntaxKind . JSDocComment ) {
97100 // Discard any comments
98101 return true ;
@@ -119,6 +122,13 @@ export class ExcerptBuilder {
119122 }
120123
121124 for ( const child of span . children ) {
125+ if ( span . node === state . startingNode ) {
126+ if ( state . stopBeforeChildKind && child . kind === state . stopBeforeChildKind ) {
127+ // We reached the a child whose kind is stopBeforeChildKind, so stop traversing
128+ return false ;
129+ }
130+ }
131+
122132 if ( ! this . _buildSpan ( excerptTokens , child , state ) ) {
123133 return false ;
124134 }
0 commit comments