No error on unmatchable @param tags#22510
Conversation
Such as when the initializer is not a function, or when the function mentions `arguments` in its body.
@param tags@param tags
| // @noEmit: true | ||
| // @allowJs: true | ||
| // @checkJs: true | ||
| // @strict: true |
There was a problem hiding this comment.
No. It was part of my template when generating a bunch of these similar JSDoc bugs. I removed it.
| function checkJSDocParameterTag(node: JSDocParameterTag) { | ||
| checkSourceElement(node.typeExpression); | ||
| if (!getParameterSymbolFromJSDoc(node)) { | ||
| const decl = getHostSignatureFromJSDoc(node); |
There was a problem hiding this comment.
getHostSignatureFromJSDoc looks expensive and we won't use it if the param has a symbol; better to put it in an inner if.
There was a problem hiding this comment.
Yeah, good idea. It's also called twice -- once in getParameterSymbolFromJSDoc -- but I don't know that it's worthwhile to fix that.
| // @Filename: a.js | ||
|
|
||
| /** | ||
| * @param {string} first |
There was a problem hiding this comment.
This case I'm not so sure about supporting since people will think they're getting typing, when we just throw the type definition away without telling them and accept any. Instead we could add a better message telling them to use a rest parameter instead.
There was a problem hiding this comment.
Rest parameters don't exist in ES5, so the error would only apply to ES2015 and later. And we don't usually know whether a .js file targets ES2015 or later.
As for throwing away typing, I don't think there's much we can do -- maybe a noImplicitAny error instead?
I think it would be easier to error (to info-error?) whenever there's a reference to arguments. That error would be a lot easier to write, and would apply to both ES2015+ and TS, and should come with an associated quick fix. I'll open a separate issue for that.
There was a problem hiding this comment.
Currently we require the user to place a dummy-parameter and type it as a rest parameter:
/** @param {...string} x */
function f(x) {
return arguments[0];
}
f(1); // error, 1 is not a stringWe could make a codefix to convert @param {string} first to @param {...string} args and add the dummy parameter -- we could also stop requiring the dumy parameter.
There was a problem hiding this comment.
I like that. I'll see how hard it is to get the error for the {string} x case and then remove it when it's changed to {...string} x. We can do the code fix later, since @mhegazy wants to get this into 2.8.1.
1. JS functions that use `arguments` do not require a dummy parameter in order to get a type for the synthetic `args` parameter if there is an `@param` with a `...` type. 2.JS functions that use `arguments` and have an `@param` must have a type that is a `...` type.
|
OK, I improved the error message and type for functions that use |
| } | ||
| const lastParam = lastOrUndefined(declaration.parameters); | ||
| const lastParamTags = lastParam && getJSDocParameterTags(lastParam); | ||
| const lastParamTags = lastParam ? getJSDocParameterTags(lastParam) : getJSDocTags(declaration).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag)); |
There was a problem hiding this comment.
(tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) === isJSDocParameterTag
|
|
||
| /** | ||
| * A JS function gets a synthetic rest parameter if it references `arguments` AND: | ||
| * 1. It has no parameters and at least one `@param` and the first `@param` has a type and the type starts with `...` |
There was a problem hiding this comment.
Comment says the first @param, but we are looping over all of them.
There was a problem hiding this comment.
Good catch. I decided to change the comment in order to continue sharing most of the code here.
| Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, | ||
| idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); | ||
| const decl = getHostSignatureFromJSDoc(node); | ||
| if (decl) { |
There was a problem hiding this comment.
Might want to explicitly comment that we decided not to issue errors on @param tags in invalid locations.
| "category": "Error", | ||
| "code": 8028 | ||
| }, | ||
| "JSDoc '...' must appear on the last @param tag of a function that uses 'arguments'.": { |
There was a problem hiding this comment.
This sounds like it's complaining about ... in an invalid location. Would write this backwards: the last tag must have ....
| Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, | ||
| idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); | ||
| } | ||
| else if (lastOrUndefined(getJSDocTags(decl).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag))) === node && |
There was a problem hiding this comment.
(tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) === isJSDocParameterTag. Also, inefficient to filter entire array then take the last element, instead of findLast.
| */ | ||
| const lastParamDeclaration = host && last(host.parameters); | ||
| if (lastParamDeclaration.symbol === param && isRestParameter(lastParamDeclaration)) { | ||
| const lastParamDeclaration = host.parameters.length > 0 && last(host.parameters); |
There was a problem hiding this comment.
I guess so. lastOrUndefined is surprisingly complicated though.
There was a problem hiding this comment.
We could just make the implementation simpler? #22572
|
No errors and The error reporting in |
|
The error message currently says |
|
Or maybe just "The last unmatched I like "JSDoc |
* No errr on unmatchable `@param` tags Such as when the initializer is not a function, or when the function mentions `arguments` in its body. * Do not require dummy param for JS uses of arguments 1. JS functions that use `arguments` do not require a dummy parameter in order to get a type for the synthetic `args` parameter if there is an `@param` with a `...` type. 2.JS functions that use `arguments` and have an `@param` must have a type that is a `...` type. * Check for array type instead of syntactic `...` * Address PR comments * Update baselines
|
This is now in release 2.8. |
👍 |
|
#22577 improves the message. |
Such as when the initializer is not a function, or when the function mentions
argumentsin its body.Fixes #22410
Fixes #22411
This will need to be ported to 2.8 as well.