diff --git a/src/compiler/factoryPublic.ts b/src/compiler/factoryPublic.ts index d78fdfc4dac3a..ac1dcbb0435a6 100644 --- a/src/compiler/factoryPublic.ts +++ b/src/compiler/factoryPublic.ts @@ -2464,53 +2464,46 @@ namespace ts { // JSDoc - /* @internal */ export function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { const node = createSynthesizedNode(SyntaxKind.JSDocTypeExpression) as JSDocTypeExpression; node.type = type; return node; } - /* @internal */ export function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag { - const tag = createJSDocTag(SyntaxKind.JSDocTypeTag, "type"); + const tag = createJSDocTag(SyntaxKind.JSDocTypeTag, "type", comment); tag.typeExpression = typeExpression; - tag.comment = comment; return tag; } - /* @internal */ export function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag { - const tag = createJSDocTag(SyntaxKind.JSDocReturnTag, "returns"); + const tag = createJSDocTag(SyntaxKind.JSDocReturnTag, "returns", comment); tag.typeExpression = typeExpression; - tag.comment = comment; return tag; } - /** @internal */ export function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag { const tag = createJSDocTag(SyntaxKind.JSDocThisTag, "this"); tag.typeExpression = typeExpression; return tag; } - /* @internal */ + /** + * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. + */ export function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag { - const tag = createJSDocTag(SyntaxKind.JSDocParameterTag, "param"); + const tag = createJSDocTag(SyntaxKind.JSDocParameterTag, "param", comment); tag.typeExpression = typeExpression; tag.name = name; tag.isBracketed = isBracketed; - tag.comment = comment; return tag; } - /* @internal */ - export function createJSDocClassTag(): JSDocClassTag { - return createJSDocTag(SyntaxKind.JSDocClassTag, "class"); + export function createJSDocClassTag(comment?: string): JSDocClassTag { + return createJSDocTag(SyntaxKind.JSDocClassTag, "class", comment); } - /* @internal */ export function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined) { const node = createSynthesizedNode(SyntaxKind.JSDocComment) as JSDoc; node.comment = comment; @@ -2518,10 +2511,108 @@ namespace ts { return node; } - /* @internal */ - function createJSDocTag(kind: T["kind"], tagName: string): T { + export function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T { const node = createSynthesizedNode(kind) as T; node.tagName = createIdentifier(tagName); + node.comment = comment; + return node; + } + + export function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string) { + const tag = createJSDocTag(SyntaxKind.JSDocAugmentsTag, "augments", comment); + tag.class = classExpression; + return tag; + } + + export function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string) { + const tag = createJSDocTag(SyntaxKind.JSDocEnumTag, "enum", comment); + tag.typeExpression = typeExpression; + return tag; + } + + export function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string) { + const tag = createJSDocTag(SyntaxKind.JSDocTemplateTag, "template", comment); + tag.constraint = constraint; + tag.typeParameters = asNodeArray(typeParameters); + return tag; + } + + export function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral) { + const tag = createJSDocTag(SyntaxKind.JSDocTypedefTag, "typedef", comment); + tag.fullName = fullName; + tag.name = name; + tag.typeExpression = typeExpression; + return tag; + } + + export function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature) { + const tag = createJSDocTag(SyntaxKind.JSDocCallbackTag, "callback", comment); + tag.fullName = fullName; + tag.name = name; + tag.typeExpression = typeExpression; + return tag; + } + + export function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag) { + const tag = createSynthesizedNode(SyntaxKind.JSDocSignature) as JSDocSignature; + tag.typeParameters = typeParameters; + tag.parameters = parameters; + tag.type = type; + return tag; + } + + function createJSDocPropertyLikeTag(kind: T["kind"], tagName: "arg" | "argument" | "param", typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { + const tag = createJSDocTag(kind, tagName, comment); + tag.typeExpression = typeExpression; + tag.name = name; + tag.isNameFirst = isNameFirst; + tag.isBracketed = isBracketed; + return tag; + } + + export function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { + return createJSDocPropertyLikeTag(SyntaxKind.JSDocPropertyTag, "param", typeExpression, name, isNameFirst, isBracketed, comment); + } + + export function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { + return createJSDocPropertyLikeTag(SyntaxKind.JSDocParameterTag, "param", typeExpression, name, isNameFirst, isBracketed, comment); + } + + export function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean) { + const tag = createSynthesizedNode(SyntaxKind.JSDocTypeLiteral) as JSDocTypeLiteral; + tag.jsDocPropertyTags = jsDocPropertyTags; + tag.isArrayType = isArrayType; + return tag; + } + + export function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string) { + const tag = createJSDocTag(SyntaxKind.JSDocImplementsTag, "implements", comment); + tag.class = classExpression; + return tag; + } + + export function createJSDocAuthorTag(comment?: string) { + return createJSDocTag(SyntaxKind.JSDocAuthorTag, "author", comment); + } + + export function createJSDocPublicTag() { + return createJSDocTag(SyntaxKind.JSDocPublicTag, "public"); + } + + export function createJSDocPrivateTag() { + return createJSDocTag(SyntaxKind.JSDocPrivateTag, "private"); + } + + export function createJSDocProtectedTag() { + return createJSDocTag(SyntaxKind.JSDocProtectedTag, "protected"); + } + + export function createJSDocReadonlyTag() { + return createJSDocTag(SyntaxKind.JSDocReadonlyTag, "readonly"); + } + + export function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc) { + node.jsDoc = append(node.jsDoc, jsdoc); return node; } diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 7fa01819d2297..bf6b918086041 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -346,7 +346,7 @@ namespace ts.codefix { const typeNode = inference.type && getTypeNodeIfAccessible(inference.type, param, program, host); const name = getSynthesizedClone(param.name); setEmitFlags(name, EmitFlags.NoComments | EmitFlags.NoNestedComments); - return typeNode && createJSDocParamTag(name, !!inference.isOptional, createJSDocTypeExpression(typeNode), ""); + return typeNode && createJSDocParameterTag(createJSDocTypeExpression(typeNode), name, /* isNameFirst */ false, !!inference.isOptional, ""); }); addJSDocTags(changes, sourceFile, signature, paramTags); } @@ -382,7 +382,7 @@ namespace ts.codefix { const oldParam = oldTag as JSDocParameterTag; const newParam = newTag as JSDocParameterTag; return isIdentifier(oldParam.name) && isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText - ? createJSDocParamTag(newParam.name, newParam.isBracketed, newParam.typeExpression, oldParam.comment) + ? createJSDocParameterTag(newParam.typeExpression, newParam.name, newParam.isNameFirst, newParam.isBracketed, oldParam.comment) : undefined; } case SyntaxKind.JSDocReturnTag: diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c9c2c066f8361..b898d160f4845 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4247,6 +4247,33 @@ declare namespace ts { function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; function createExternalModuleReference(expression: Expression): ExternalModuleReference; function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; + function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; + function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; + function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; + function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag; + /** + * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. + */ + function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag; + function createJSDocClassTag(comment?: string): JSDocClassTag; + function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined): JSDoc; + function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T; + function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; + function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; + function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; + function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral): JSDocTypedefTag; + function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature): JSDocCallbackTag; + function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; + function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocPropertyTag; + function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocParameterTag; + function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; + function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; + function createJSDocAuthorTag(comment?: string): JSDocTag; + function createJSDocPublicTag(): JSDocTag; + function createJSDocPrivateTag(): JSDocTag; + function createJSDocProtectedTag(): JSDocTag; + function createJSDocReadonlyTag(): JSDocTag; + function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc): JSDocContainer; function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e1a34cf708250..f1a808da72863 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4247,6 +4247,33 @@ declare namespace ts { function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; function createExternalModuleReference(expression: Expression): ExternalModuleReference; function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; + function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; + function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; + function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; + function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag; + /** + * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. + */ + function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag; + function createJSDocClassTag(comment?: string): JSDocClassTag; + function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined): JSDoc; + function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T; + function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; + function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; + function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; + function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral): JSDocTypedefTag; + function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature): JSDocCallbackTag; + function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; + function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocPropertyTag; + function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocParameterTag; + function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; + function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; + function createJSDocAuthorTag(comment?: string): JSDocTag; + function createJSDocPublicTag(): JSDocTag; + function createJSDocPrivateTag(): JSDocTag; + function createJSDocProtectedTag(): JSDocTag; + function createJSDocReadonlyTag(): JSDocTag; + function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc): JSDocContainer; function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement;