@@ -3172,6 +3172,7 @@ function getCompletionData(
31723172 log ( "getCompletionData: Is inside comment: " + ( timestamp ( ) - start ) ) ;
31733173
31743174 let insideJsDocTagTypeExpression = false ;
3175+ let insideJsDocImportTypeTag = false ;
31753176 let isInSnippetScope = false ;
31763177 if ( insideComment ) {
31773178 if ( hasDocComment ( sourceFile , position ) ) {
@@ -3212,25 +3213,30 @@ function getCompletionData(
32123213 if ( tag . tagName . pos <= position && position <= tag . tagName . end ) {
32133214 return { kind : CompletionDataKind . JsDocTagName } ;
32143215 }
3215- const typeExpression = tryGetTypeExpressionFromTag ( tag ) ;
3216- if ( typeExpression ) {
3217- currentToken = getTokenAtPosition ( sourceFile , position ) ;
3218- if (
3219- ! currentToken ||
3220- ( ! isDeclarationName ( currentToken ) &&
3221- ( currentToken . parent . kind !== SyntaxKind . JSDocPropertyTag ||
3222- ( currentToken . parent as JSDocPropertyTag ) . name !== currentToken ) )
3223- ) {
3224- // Use as type location if inside tag's type expression
3225- insideJsDocTagTypeExpression = isCurrentlyEditingNode ( typeExpression ) ;
3226- }
3216+ if ( isJSDocImportTypeTag ( tag ) ) {
3217+ insideJsDocImportTypeTag = true ;
32273218 }
3228- if ( ! insideJsDocTagTypeExpression && isJSDocParameterTag ( tag ) && ( nodeIsMissing ( tag . name ) || tag . name . pos <= position && position <= tag . name . end ) ) {
3229- return { kind : CompletionDataKind . JsDocParameterName , tag } ;
3219+ else {
3220+ const typeExpression = tryGetTypeExpressionFromTag ( tag ) ;
3221+ if ( typeExpression ) {
3222+ currentToken = getTokenAtPosition ( sourceFile , position ) ;
3223+ if (
3224+ ! currentToken ||
3225+ ( ! isDeclarationName ( currentToken ) &&
3226+ ( currentToken . parent . kind !== SyntaxKind . JSDocPropertyTag ||
3227+ ( currentToken . parent as JSDocPropertyTag ) . name !== currentToken ) )
3228+ ) {
3229+ // Use as type location if inside tag's type expression
3230+ insideJsDocTagTypeExpression = isCurrentlyEditingNode ( typeExpression ) ;
3231+ }
3232+ }
3233+ if ( ! insideJsDocTagTypeExpression && isJSDocParameterTag ( tag ) && ( nodeIsMissing ( tag . name ) || tag . name . pos <= position && position <= tag . name . end ) ) {
3234+ return { kind : CompletionDataKind . JsDocParameterName , tag } ;
3235+ }
32303236 }
32313237 }
32323238
3233- if ( ! insideJsDocTagTypeExpression ) {
3239+ if ( ! insideJsDocTagTypeExpression && ! insideJsDocImportTypeTag ) {
32343240 // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
32353241 // comment or the plain text part of a jsDoc comment, so no completion should be available
32363242 log ( "Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment." ) ;
@@ -3241,7 +3247,7 @@ function getCompletionData(
32413247 start = timestamp ( ) ;
32423248 // The decision to provide completion depends on the contextToken, which is determined through the previousToken.
32433249 // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
3244- const isJsOnlyLocation = ! insideJsDocTagTypeExpression && isSourceFileJS ( sourceFile ) ;
3250+ const isJsOnlyLocation = ! insideJsDocTagTypeExpression && ! insideJsDocImportTypeTag && isSourceFileJS ( sourceFile ) ;
32453251 const tokens = getRelevantTokens ( position , sourceFile ) ;
32463252 const previousToken = tokens . previousToken ! ;
32473253 let contextToken = tokens . contextToken ! ;
@@ -3922,6 +3928,7 @@ function getCompletionData(
39223928
39233929 function isTypeOnlyCompletion ( ) : boolean {
39243930 return insideJsDocTagTypeExpression
3931+ || insideJsDocImportTypeTag
39253932 || ! ! importStatementCompletion && isTypeOnlyImportOrExportDeclaration ( location . parent )
39263933 || ! isContextTokenValueLocation ( contextToken ) &&
39273934 ( isPossiblyTypeArgumentPosition ( contextToken , sourceFile , typeChecker )
0 commit comments