11/* @internal */
22namespace ts . JsDoc {
3+ const singleLineTemplate = { newText : "/** */" , caretOffset : 3 } ;
34 const jsDocTagNames = [
45 "augments" ,
56 "author" ,
@@ -170,15 +171,9 @@ namespace ts.JsDoc {
170171 /**
171172 * Checks if position points to a valid position to add JSDoc comments, and if so,
172173 * returns the appropriate template. Otherwise returns an empty string.
173- * Valid positions are
174- * - outside of comments, statements, and expressions, and
175- * - preceding a:
176- * - function/constructor/method declaration
177- * - class declarations
178- * - variable statements
179- * - namespace declarations
180- * - interface declarations
181- * - method signatures
174+ * Invalid positions are
175+ * - within comments, strings (including template literals and regex), and JSXText
176+ * - within a token
182177 *
183178 * Hosts should ideally check that:
184179 * - The line is all whitespace up to 'position' before performing the insertion.
@@ -204,17 +199,23 @@ namespace ts.JsDoc {
204199
205200 const commentOwnerInfo = getCommentOwnerInfo ( tokenAtPos ) ;
206201 if ( ! commentOwnerInfo ) {
207- return undefined ;
202+ // if climbing the tree did not find a declaration with parameters, complete to a single line comment
203+ return singleLineTemplate ;
208204 }
209205 const { commentOwner, parameters } = commentOwnerInfo ;
210- if ( commentOwner . getStart ( ) < position ) {
206+
207+ if ( commentOwner . kind === SyntaxKind . JsxText ) {
211208 return undefined ;
212209 }
213210
214- if ( ! parameters || parameters . length === 0 ) {
215- // if there are no parameters, just complete to a single line JSDoc comment
216- const singleLineResult = "/** */" ;
217- return { newText : singleLineResult , caretOffset : 3 } ;
211+ if ( commentOwner . getStart ( ) < position ) {
212+ // if climbing the tree found a declaration with parameters but the request was made inside it, complete to a single line comment
213+ return singleLineTemplate ;
214+ }
215+
216+ if ( parameters . length === 0 ) {
217+ // if there are no parameters, complete to a single line comment
218+ return singleLineTemplate ;
218219 }
219220
220221 const posLineAndChar = sourceFile . getLineAndCharacterOfPosition ( position ) ;
@@ -258,7 +259,7 @@ namespace ts.JsDoc {
258259
259260 interface CommentOwnerInfo {
260261 readonly commentOwner : Node ;
261- readonly parameters ? : ReadonlyArray < ParameterDeclaration > ;
262+ readonly parameters : ReadonlyArray < ParameterDeclaration > ;
262263 }
263264 function getCommentOwnerInfo ( tokenAtPos : Node ) : CommentOwnerInfo | undefined {
264265 for ( let commentOwner = tokenAtPos ; commentOwner ; commentOwner = commentOwner . parent ) {
@@ -270,32 +271,18 @@ namespace ts.JsDoc {
270271 const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature ;
271272 return { commentOwner, parameters } ;
272273
273- case SyntaxKind . ClassDeclaration :
274- case SyntaxKind . InterfaceDeclaration :
275- case SyntaxKind . PropertySignature :
276- case SyntaxKind . EnumDeclaration :
277- case SyntaxKind . EnumMember :
278- case SyntaxKind . TypeAliasDeclaration :
279- return { commentOwner } ;
280-
281274 case SyntaxKind . VariableStatement : {
282275 const varStatement = < VariableStatement > commentOwner ;
283276 const varDeclarations = varStatement . declarationList . declarations ;
284277 const parameters = varDeclarations . length === 1 && varDeclarations [ 0 ] . initializer
285278 ? getParametersFromRightHandSideOfAssignment ( varDeclarations [ 0 ] . initializer )
286279 : undefined ;
287- return { commentOwner, parameters } ;
280+ return parameters ? { commentOwner, parameters } : undefined ;
288281 }
289282
290283 case SyntaxKind . SourceFile :
291284 return undefined ;
292285
293- case SyntaxKind . ModuleDeclaration :
294- // If in walking up the tree, we hit a a nested namespace declaration,
295- // then we must be somewhere within a dotted namespace name; however we don't
296- // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
297- return commentOwner . parent . kind === SyntaxKind . ModuleDeclaration ? undefined : { commentOwner } ;
298-
299286 case SyntaxKind . BinaryExpression : {
300287 const be = commentOwner as BinaryExpression ;
301288 if ( getSpecialPropertyAssignmentKind ( be ) === ts . SpecialPropertyAssignmentKind . None ) {
@@ -304,6 +291,11 @@ namespace ts.JsDoc {
304291 const parameters = isFunctionLike ( be . right ) ? be . right . parameters : emptyArray ;
305292 return { commentOwner, parameters } ;
306293 }
294+
295+ case SyntaxKind . JsxText : {
296+ const parameters : ReadonlyArray < ParameterDeclaration > = emptyArray ;
297+ return { commentOwner, parameters } ;
298+ }
307299 }
308300 }
309301 }
0 commit comments