mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 11:50:54 -06:00
Merge pull request #14371 from Microsoft/master-fix14254
[Master] Fix 14254: Return JsDoc tagName when there is no "@" sign prefix
This commit is contained in:
commit
5abb8f3caa
@ -16,11 +16,16 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData;
|
||||
|
||||
if (isJsDocTagName) {
|
||||
if (requestJsDocTagName) {
|
||||
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagNameCompletions() };
|
||||
}
|
||||
|
||||
if (requestJsDocTag) {
|
||||
// If the current position is a jsDoc tag, only tags should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagCompletions() };
|
||||
}
|
||||
|
||||
const entries: CompletionEntry[] = [];
|
||||
@ -54,7 +59,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion && !isJsDocTagName) {
|
||||
if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||
addRange(entries, keywordCompletions);
|
||||
}
|
||||
|
||||
@ -814,7 +819,10 @@ namespace ts.Completions {
|
||||
function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number) {
|
||||
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
|
||||
|
||||
let isJsDocTagName = false;
|
||||
// JsDoc tag-name is just the name of the JSDoc tagname (exclude "@")
|
||||
let requestJsDocTagName = false;
|
||||
// JsDoc tag includes both "@" and tag-name
|
||||
let requestJsDocTag = false;
|
||||
|
||||
let start = timestamp();
|
||||
const currentToken = getTokenAtPosition(sourceFile, position);
|
||||
@ -826,10 +834,32 @@ namespace ts.Completions {
|
||||
log("getCompletionData: Is inside comment: " + (timestamp() - start));
|
||||
|
||||
if (insideComment) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
isJsDocTagName = true;
|
||||
if (hasDocComment(sourceFile, position)) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
else {
|
||||
// When completion is requested without "@", we will have check to make sure that
|
||||
// there are no comments prefix the request position. We will only allow "*" and space.
|
||||
// e.g
|
||||
// /** |c| /*
|
||||
//
|
||||
// /**
|
||||
// |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
const lineStart = getLineStartPositionForPosition(position, sourceFile);
|
||||
requestJsDocTag = !(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/));
|
||||
}
|
||||
}
|
||||
|
||||
// Completion should work inside certain JsDoc tags. For example:
|
||||
@ -839,7 +869,7 @@ namespace ts.Completions {
|
||||
const tag = getJsDocTagAtPosition(sourceFile, position);
|
||||
if (tag) {
|
||||
if (tag.tagName.pos <= position && position <= tag.tagName.end) {
|
||||
isJsDocTagName = true;
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
|
||||
switch (tag.kind) {
|
||||
@ -854,8 +884,8 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
if (isJsDocTagName) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
|
||||
if (requestJsDocTagName || requestJsDocTag) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag };
|
||||
}
|
||||
|
||||
if (!insideJsDocTagExpression) {
|
||||
@ -983,7 +1013,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
|
||||
@ -42,7 +42,8 @@ namespace ts.JsDoc {
|
||||
"prop",
|
||||
"version"
|
||||
];
|
||||
let jsDocCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagNameCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagCompletionEntries: CompletionEntry[];
|
||||
|
||||
export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) {
|
||||
// Only collect doc comments from duplicate declarations once:
|
||||
@ -88,8 +89,8 @@ namespace ts.JsDoc {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getAllJsDocCompletionEntries(): CompletionEntry[] {
|
||||
return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
export function getJSDocTagNameCompletions(): CompletionEntry[] {
|
||||
return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: tagName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
@ -99,6 +100,17 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export function getJSDocTagCompletions(): CompletionEntry[] {
|
||||
return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: `@${tagName}`,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: "",
|
||||
sortText: "0"
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
|
||||
@ -2,29 +2,57 @@
|
||||
|
||||
// @allowJs: true
|
||||
// @Filename: Foo.js
|
||||
/////** @/*1*/ */
|
||||
////var v1;
|
||||
//// /** @/*1*/ */
|
||||
//// var v1;
|
||||
////
|
||||
/////** @p/*2*/ */
|
||||
////var v2;
|
||||
//// /** @p/*2*/ */
|
||||
//// var v2;
|
||||
////
|
||||
/////** @param /*3*/ */
|
||||
////var v3;
|
||||
//// /** @param /*3*/ */
|
||||
//// var v3;
|
||||
////
|
||||
/////** @param { n/*4*/ } bar */
|
||||
////var v4;
|
||||
//// /** @param { n/*4*/ } bar */
|
||||
//// var v4;
|
||||
////
|
||||
/////** @type { n/*5*/ } */
|
||||
////var v5;
|
||||
//// /** @type { n/*5*/ } */
|
||||
//// var v5;
|
||||
////
|
||||
////// @/*6*/
|
||||
////var v6;
|
||||
//// // @/*6*/
|
||||
//// var v6;
|
||||
////
|
||||
////// @pa/*7*/
|
||||
////var v7;
|
||||
//// // @pa/*7*/
|
||||
//// var v7;
|
||||
////
|
||||
/////** @return { n/*8*/ } */
|
||||
////var v8;
|
||||
//// /** @return { n/*8*/ } */
|
||||
//// var v8;
|
||||
////
|
||||
//// /** /*9*/ */
|
||||
////
|
||||
//// /**
|
||||
//// /*10*/
|
||||
//// */
|
||||
////
|
||||
//// /**
|
||||
//// * /*11*/
|
||||
//// */
|
||||
////
|
||||
//// /**
|
||||
//// /*12*/
|
||||
//// */
|
||||
////
|
||||
//// /**
|
||||
//// * /*13*/
|
||||
//// */
|
||||
////
|
||||
//// /**
|
||||
//// * some comment /*14*/
|
||||
//// */
|
||||
////
|
||||
//// /**
|
||||
//// * @param /*15*/
|
||||
//// */
|
||||
////
|
||||
//// /** @param /*16*/ */
|
||||
|
||||
goTo.marker('1');
|
||||
verify.completionListContains("constructor");
|
||||
@ -55,3 +83,31 @@ verify.completionListIsEmpty();
|
||||
goTo.marker('8');
|
||||
verify.completionListContains('number');
|
||||
|
||||
goTo.marker('9');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@argument");
|
||||
|
||||
goTo.marker('10');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@returns");
|
||||
|
||||
goTo.marker('11');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@argument");
|
||||
|
||||
goTo.marker('12');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@constructor");
|
||||
|
||||
goTo.marker('13');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@param");
|
||||
|
||||
goTo.marker('14');
|
||||
verify.completionListIsEmpty();
|
||||
|
||||
goTo.marker('15');
|
||||
verify.completionListIsEmpty();
|
||||
|
||||
goTo.marker('16');
|
||||
verify.completionListIsEmpty();
|
||||
@ -1,28 +1,24 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////var v1 = '';
|
||||
////" /*openString1*/
|
||||
////var v2 = '';
|
||||
////"/*openString2*/
|
||||
////var v3 = '';
|
||||
////" bar./*openString3*/
|
||||
////var v4 = '';
|
||||
////// bar./*inComment1*/
|
||||
////var v6 = '';
|
||||
////// /*inComment2*/
|
||||
////var v7 = '';
|
||||
/////** /*inComment3*/
|
||||
////var v8 = '';
|
||||
/////** /*inComment4*/ **/
|
||||
////var v9 = '';
|
||||
/////* /*inComment5*/
|
||||
////var v11 = '';
|
||||
//// // /*inComment6*/
|
||||
////var v12 = '';
|
||||
////type htm/*inTypeAlias*/
|
||||
///
|
||||
////// /*inComment7*/
|
||||
////foo;
|
||||
////var v10 = /reg/*inRegExp1*/ex/;
|
||||
//// var v1 = '';
|
||||
//// " /*openString1*/
|
||||
//// var v2 = '';
|
||||
//// "/*openString2*/
|
||||
//// var v3 = '';
|
||||
//// " bar./*openString3*/
|
||||
//// var v4 = '';
|
||||
//// // bar./*inComment1*/
|
||||
//// var v6 = '';
|
||||
//// // /*inComment2*/
|
||||
//// var v7 = '';
|
||||
//// /* /*inComment3*/
|
||||
//// var v11 = '';
|
||||
//// // /*inComment4*/
|
||||
//// var v12 = '';
|
||||
//// type htm/*inTypeAlias*/
|
||||
////
|
||||
//// // /*inComment5*/
|
||||
//// foo;
|
||||
//// var v10 = /reg/*inRegExp1*/ex/;
|
||||
|
||||
goTo.eachMarker(() => verify.completionListIsEmpty());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user