Fix this-parameter emit for JSDocFunction types (#39814)

* Fix this parameter emit for JSDocFunction types

Previously, parameters with names that were not `new` were treated like
rest parameters. This is incorrect: parameters with the name `this`
should emit a `this` parameter.

Fixes #38550

* ❤️ quote style
This commit is contained in:
Nathan Shively-Sanders 2020-07-29 14:11:59 -07:00 committed by GitHub
parent f2d1531768
commit 9b2d487392
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 4 deletions

View file

@ -5777,7 +5777,7 @@ namespace ts {
/*decorators*/ undefined,
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
p.name || getEffectiveDotDotDotForParameter(p) ? `args` : `arg${i}`,
getNameForJSDocFunctionParameter(p, i),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols),
/*initializer*/ undefined
@ -5792,7 +5792,7 @@ namespace ts {
/*decorators*/ undefined,
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
p.name || getEffectiveDotDotDotForParameter(p) ? `args` : `arg${i}`,
getNameForJSDocFunctionParameter(p, i),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols),
/*initializer*/ undefined
@ -5847,6 +5847,13 @@ namespace ts {
return p.dotDotDotToken || (p.type && isJSDocVariadicType(p.type) ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined);
}
/** Note that `new:T` parameters are not handled, but should be before calling this function. */
function getNameForJSDocFunctionParameter(p: ParameterDeclaration, index: number) {
return p.name && isIdentifier(p.name) && p.name.escapedText === "this" ? "this"
: getEffectiveDotDotDotForParameter(p) ? `args`
: `arg${index}`;
}
function rewriteModuleSpecifier(parent: ImportTypeNode, lit: StringLiteral) {
if (bundled) {
if (context.tracker && context.tracker.moduleResolverHost) {

View file

@ -0,0 +1,32 @@
//// [bug38550.js]
export class Clazz {
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
method(functionDeclaration) {}
}
//// [bug38550.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Clazz = void 0;
var Clazz = /** @class */ (function () {
function Clazz() {
}
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
Clazz.prototype.method = function (functionDeclaration) { };
return Clazz;
}());
exports.Clazz = Clazz;
//// [bug38550.d.ts]
export class Clazz {
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
method(functionDeclaration: (this: any, ...args: any[]) => any): void;
}

View file

@ -0,0 +1,12 @@
=== tests/cases/conformance/jsdoc/declarations/bug38550.js ===
export class Clazz {
>Clazz : Symbol(Clazz, Decl(bug38550.js, 0, 0))
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
method(functionDeclaration) {}
>method : Symbol(Clazz.method, Decl(bug38550.js, 0, 20))
>functionDeclaration : Symbol(functionDeclaration, Decl(bug38550.js, 4, 9))
}

View file

@ -0,0 +1,12 @@
=== tests/cases/conformance/jsdoc/declarations/bug38550.js ===
export class Clazz {
>Clazz : Clazz
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
method(functionDeclaration) {}
>method : (functionDeclaration: (this: any, ...args: any[]) => any) => void
>functionDeclaration : (this: any, ...arg1: any[]) => any
}

View file

@ -35,7 +35,7 @@ function hof(ctor: function(new: number, string)) {
>'hi' : "hi"
}
function hof2(f: function(this: number, string): string) {
>hof2 : (f: (args: number, arg1: string) => string) => string
>hof2 : (f: (this: number, arg1: string) => string) => string
>f : (this: number, arg1: string) => string
>this : number

View file

@ -4,7 +4,7 @@
* @return {function(this: string, number): number}
*/
function id1(c) {
>id1 : (c: (args: string, arg1: number) => number) => (args: string, arg1: number) => number
>id1 : (c: (this: string, arg1: number) => number) => (this: string, arg1: number) => number
>c : (this: string, arg1: number) => number
return c

View file

@ -0,0 +1,12 @@
// @allowJs: true
// @checkJs: true
// @target: es5
// @outDir: ./out
// @declaration: true
// @filename: bug38550.js
export class Clazz {
/**
* @param {function(this:Object, ...*):*} functionDeclaration
*/
method(functionDeclaration) {}
}