fix(42380): include JSDoc comments in declarations for static/prototype methods (#42454)

This commit is contained in:
Oleksandr T
2021-03-09 21:37:40 +02:00
committed by GitHub
parent d9f5a85d5b
commit 9610c16cc8
5 changed files with 519 additions and 3 deletions

View File

@@ -6816,8 +6816,7 @@ namespace ts {
for (const sig of signatures) {
// Each overload becomes a separate function declaration, in order
const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, { name: factory.createIdentifier(localName), privateSymbolVisitor: includePrivateSymbol, bundledImports: bundled }) as FunctionDeclaration;
// for expressions assigned to `var`s, use the `var` as the text range
addResult(setTextRange(decl, sig.declaration && isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags);
addResult(setTextRange(decl, getSignatureTextRangeLocation(sig)), modifierFlags);
}
// Module symbol emit will take care of module-y members, provided it has exports
if (!(symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && !!symbol.exports && !!symbol.exports.size)) {
@@ -6826,6 +6825,19 @@ namespace ts {
}
}
function getSignatureTextRangeLocation(signature: Signature) {
if (signature.declaration && signature.declaration.parent) {
if (isBinaryExpression(signature.declaration.parent) && getAssignmentDeclarationKind(signature.declaration.parent) === AssignmentDeclarationKind.Property) {
return signature.declaration.parent;
}
// for expressions assigned to `var`s, use the `var` as the text range
if (isVariableDeclaration(signature.declaration.parent) && signature.declaration.parent.parent) {
return signature.declaration.parent.parent;
}
}
return signature.declaration;
}
function serializeAsNamespaceDeclaration(props: readonly Symbol[], localName: string, modifierFlags: ModifierFlags, suppressNewPrivateContext: boolean) {
if (length(props)) {
const localVsRemoteMap = arrayToMultiMap(props, p =>
@@ -7422,7 +7434,8 @@ namespace ts {
modifiers: flag ? factory.createModifiersFromModifierFlags(flag) : undefined
}
);
results.push(setTextRange(decl, sig.declaration));
const location = sig.declaration && isPrototypePropertyAssignment(sig.declaration.parent) ? sig.declaration.parent : sig.declaration;
results.push(setTextRange(decl, location));
}
return results as unknown as T[];
}

View File

@@ -0,0 +1,179 @@
//// [jsDeclarationsClassMethod.js]
function C1() {
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
this.prop = function (x, y) {
return x + y;
}
}
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.prototype.method = function (x, y) {
return x + y;
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.staticProp = function (x, y) {
return x + y;
}
class C2 {
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x, y) {
return x + y;
}
}
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.prototype.method2 = function (x, y) {
return x + y;
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.staticProp = function (x, y) {
return x + y;
}
//// [jsDeclarationsClassMethod.js]
function C1() {
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
this.prop = function (x, y) {
return x + y;
};
}
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.prototype.method = function (x, y) {
return x + y;
};
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.staticProp = function (x, y) {
return x + y;
};
class C2 {
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x, y) {
return x + y;
}
}
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.prototype.method2 = function (x, y) {
return x + y;
};
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.staticProp = function (x, y) {
return x + y;
};
//// [jsDeclarationsClassMethod.d.ts]
declare function C1(): void;
declare class C1 {
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
prop: (x: number, y: number) => number;
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
method(x: number, y: number): number;
}
declare namespace C1 {
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
function staticProp(x: number, y: number): number;
}
declare class C2 {
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x: number, y: number): number;
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
method2(x: number, y: number): number;
}
declare namespace C2 {
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
function staticProp(x: number, y: number): number;
}

View File

@@ -0,0 +1,118 @@
=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassMethod.js ===
function C1() {
>C1 : Symbol(C1, Decl(jsDeclarationsClassMethod.js, 0, 0), Decl(jsDeclarationsClassMethod.js, 20, 1))
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
this.prop = function (x, y) {
>this.prop : Symbol(C1.prop, Decl(jsDeclarationsClassMethod.js, 0, 15))
>this : Symbol(C1, Decl(jsDeclarationsClassMethod.js, 0, 0), Decl(jsDeclarationsClassMethod.js, 20, 1))
>prop : Symbol(C1.prop, Decl(jsDeclarationsClassMethod.js, 0, 15))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 7, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 7, 28))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 7, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 7, 28))
}
}
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.prototype.method = function (x, y) {
>C1.prototype : Symbol(C1.method, Decl(jsDeclarationsClassMethod.js, 10, 1))
>C1 : Symbol(C1, Decl(jsDeclarationsClassMethod.js, 0, 0), Decl(jsDeclarationsClassMethod.js, 20, 1))
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
>method : Symbol(C1.method, Decl(jsDeclarationsClassMethod.js, 10, 1))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 18, 32))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 18, 34))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 18, 32))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 18, 34))
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.staticProp = function (x, y) {
>C1.staticProp : Symbol(C1.staticProp, Decl(jsDeclarationsClassMethod.js, 20, 1))
>C1 : Symbol(C1, Decl(jsDeclarationsClassMethod.js, 0, 0), Decl(jsDeclarationsClassMethod.js, 20, 1))
>staticProp : Symbol(C1.staticProp, Decl(jsDeclarationsClassMethod.js, 20, 1))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 28, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 28, 28))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 28, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 28, 28))
}
class C2 {
>C2 : Symbol(C2, Decl(jsDeclarationsClassMethod.js, 30, 1), Decl(jsDeclarationsClassMethod.js, 52, 1))
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x, y) {
>method1 : Symbol(C2.method1, Decl(jsDeclarationsClassMethod.js, 32, 10))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 39, 12))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 39, 14))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 39, 12))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 39, 14))
}
}
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.prototype.method2 = function (x, y) {
>C2.prototype.method2 : Symbol(C2.method2, Decl(jsDeclarationsClassMethod.js, 42, 1))
>C2.prototype : Symbol(C2.method2, Decl(jsDeclarationsClassMethod.js, 42, 1))
>C2 : Symbol(C2, Decl(jsDeclarationsClassMethod.js, 30, 1), Decl(jsDeclarationsClassMethod.js, 52, 1))
>prototype : Symbol(C2.prototype)
>method2 : Symbol(C2.method2, Decl(jsDeclarationsClassMethod.js, 42, 1))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 50, 33))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 50, 35))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 50, 33))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 50, 35))
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.staticProp = function (x, y) {
>C2.staticProp : Symbol(C2.staticProp, Decl(jsDeclarationsClassMethod.js, 52, 1))
>C2 : Symbol(C2, Decl(jsDeclarationsClassMethod.js, 30, 1), Decl(jsDeclarationsClassMethod.js, 52, 1))
>staticProp : Symbol(C2.staticProp, Decl(jsDeclarationsClassMethod.js, 52, 1))
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 60, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 60, 28))
return x + y;
>x : Symbol(x, Decl(jsDeclarationsClassMethod.js, 60, 26))
>y : Symbol(y, Decl(jsDeclarationsClassMethod.js, 60, 28))
}

View File

@@ -0,0 +1,135 @@
=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassMethod.js ===
function C1() {
>C1 : typeof C1
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
this.prop = function (x, y) {
>this.prop = function (x, y) { return x + y; } : (x: number, y: number) => number
>this.prop : any
>this : this
>prop : any
>function (x, y) { return x + y; } : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}
}
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.prototype.method = function (x, y) {
>C1.prototype.method = function (x, y) { return x + y;} : (x: number, y: number) => number
>C1.prototype.method : any
>C1.prototype : any
>C1 : typeof C1
>prototype : any
>method : any
>function (x, y) { return x + y;} : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.staticProp = function (x, y) {
>C1.staticProp = function (x, y) { return x + y;} : (x: number, y: number) => number
>C1.staticProp : (x: number, y: number) => number
>C1 : typeof C1
>staticProp : (x: number, y: number) => number
>function (x, y) { return x + y;} : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}
class C2 {
>C2 : C2
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x, y) {
>method1 : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}
}
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.prototype.method2 = function (x, y) {
>C2.prototype.method2 = function (x, y) { return x + y;} : (x: number, y: number) => number
>C2.prototype.method2 : (x: number, y: number) => number
>C2.prototype : C2
>C2 : typeof C2
>prototype : C2
>method2 : (x: number, y: number) => number
>function (x, y) { return x + y;} : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.staticProp = function (x, y) {
>C2.staticProp = function (x, y) { return x + y;} : (x: number, y: number) => number
>C2.staticProp : (x: number, y: number) => number
>C2 : typeof C2
>staticProp : (x: number, y: number) => number
>function (x, y) { return x + y;} : (x: number, y: number) => number
>x : number
>y : number
return x + y;
>x + y : number
>x : number
>y : number
}

View File

@@ -0,0 +1,71 @@
// @allowJs: true
// @checkJs: true
// @target: esnext
// @noImplicitAny: true
// @declaration: true
// @outDir: out
// @Filename: jsDeclarationsClassMethod.js
function C1() {
/**
* A comment prop
* @param {number} x
* @param {number} y
* @returns {number}
*/
this.prop = function (x, y) {
return x + y;
}
}
/**
* A comment method
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.prototype.method = function (x, y) {
return x + y;
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C1.staticProp = function (x, y) {
return x + y;
}
class C2 {
/**
* A comment method1
* @param {number} x
* @param {number} y
* @returns {number}
*/
method1(x, y) {
return x + y;
}
}
/**
* A comment method2
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.prototype.method2 = function (x, y) {
return x + y;
}
/**
* A comment staticProp
* @param {number} x
* @param {number} y
* @returns {number}
*/
C2.staticProp = function (x, y) {
return x + y;
}