@@ -16,11 +16,16 @@ namespace ts.Completions {
1616 return undefined ;
1717 }
1818
19- const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData ;
19+ const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName , requestJsDocTag } = completionData ;
2020
21- if ( isJsDocTagName ) {
21+ if ( requestJsDocTagName ) {
2222 // If the current position is a jsDoc tag name, only tag names should be provided for completion
23- return { isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : false , entries : JsDoc . getAllJsDocCompletionEntries ( ) } ;
23+ return { isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : false , entries : JsDoc . getJSDocTagNameCompletions ( ) } ;
24+ }
25+
26+ if ( requestJsDocTag ) {
27+ // If the current position is a jsDoc tag, only tags should be provided for completion
28+ return { isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : false , entries : JsDoc . getJSDocTagCompletions ( ) } ;
2429 }
2530
2631 const entries : CompletionEntry [ ] = [ ] ;
@@ -54,7 +59,7 @@ namespace ts.Completions {
5459 }
5560
5661 // Add keywords if this is not a member completion list
57- if ( ! isMemberCompletion && ! isJsDocTagName ) {
62+ if ( ! isMemberCompletion && ! requestJsDocTag && ! requestJsDocTagName ) {
5863 addRange ( entries , keywordCompletions ) ;
5964 }
6065
@@ -814,7 +819,10 @@ namespace ts.Completions {
814819 function getCompletionData ( typeChecker : TypeChecker , log : ( message : string ) => void , sourceFile : SourceFile , position : number ) {
815820 const isJavaScriptFile = isSourceFileJavaScript ( sourceFile ) ;
816821
817- let isJsDocTagName = false ;
822+ // JsDoc tag-name is just the name of the JSDoc tagname (exclude "@")
823+ let requestJsDocTagName = false ;
824+ // JsDoc tag includes both "@" and tag-name
825+ let requestJsDocTag = false ;
818826
819827 let start = timestamp ( ) ;
820828 const currentToken = getTokenAtPosition ( sourceFile , position ) ;
@@ -826,10 +834,32 @@ namespace ts.Completions {
826834 log ( "getCompletionData: Is inside comment: " + ( timestamp ( ) - start ) ) ;
827835
828836 if ( insideComment ) {
829- // The current position is next to the '@' sign, when no tag name being provided yet.
830- // Provide a full list of tag names
831- if ( hasDocComment ( sourceFile , position ) && sourceFile . text . charCodeAt ( position - 1 ) === CharacterCodes . at ) {
832- isJsDocTagName = true ;
837+ if ( hasDocComment ( sourceFile , position ) ) {
838+ // The current position is next to the '@' sign, when no tag name being provided yet.
839+ // Provide a full list of tag names
840+ if ( sourceFile . text . charCodeAt ( position - 1 ) === CharacterCodes . at ) {
841+ requestJsDocTagName = true ;
842+ }
843+ else {
844+ // When completion is requested without "@", we will have check to make sure that
845+ // there are no comments prefix the request position. We will only allow "*" and space.
846+ // e.g
847+ // /** |c| /*
848+ //
849+ // /**
850+ // |c|
851+ // */
852+ //
853+ // /**
854+ // * |c|
855+ // */
856+ //
857+ // /**
858+ // * |c|
859+ // */
860+ const lineStart = getLineStartPositionForPosition ( position , sourceFile ) ;
861+ requestJsDocTag = ! ( sourceFile . text . substring ( lineStart , position ) . match ( / [ ^ \* | \s | ( / \* \* ) ] / ) ) ;
862+ }
833863 }
834864
835865 // Completion should work inside certain JsDoc tags. For example:
@@ -839,7 +869,7 @@ namespace ts.Completions {
839869 const tag = getJsDocTagAtPosition ( sourceFile , position ) ;
840870 if ( tag ) {
841871 if ( tag . tagName . pos <= position && position <= tag . tagName . end ) {
842- isJsDocTagName = true ;
872+ requestJsDocTagName = true ;
843873 }
844874
845875 switch ( tag . kind ) {
@@ -854,8 +884,8 @@ namespace ts.Completions {
854884 }
855885 }
856886
857- if ( isJsDocTagName ) {
858- return { symbols : undefined , isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : false , location : undefined , isRightOfDot : false , isJsDocTagName } ;
887+ if ( requestJsDocTagName || requestJsDocTag ) {
888+ return { symbols : undefined , isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : false , location : undefined , isRightOfDot : false , requestJsDocTagName , requestJsDocTag } ;
859889 }
860890
861891 if ( ! insideJsDocTagExpression ) {
@@ -983,7 +1013,7 @@ namespace ts.Completions {
9831013
9841014 log ( "getCompletionData: Semantic work: " + ( timestamp ( ) - semanticStart ) ) ;
9851015
986- return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot : ( isRightOfDot || isRightOfOpenTag ) , isJsDocTagName } ;
1016+ return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot : ( isRightOfDot || isRightOfOpenTag ) , requestJsDocTagName , requestJsDocTag } ;
9871017
9881018 function getTypeScriptMemberSymbols ( ) : void {
9891019 // Right of dot member completion list
0 commit comments