-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add @callback jsdoc tag #9546
Add @callback jsdoc tag #9546
Conversation
… addCallbackJsdocTag # Conflicts: # src/compiler/checker.ts
@@ -264,6 +265,14 @@ namespace ts { | |||
let functionType = <JSDocFunctionType>node.parent; | |||
let index = indexOf(functionType.parameters, node); | |||
return "p" + index; | |||
case SyntaxKind.JSDocParameterTag: | |||
Debug.assert(node.parent.kind === SyntaxKind.JSDocCallbackType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a message to the assert here and above? There's not much distinguishing a stack trace from a user otherwise.
} | ||
|
||
export interface JSDocCallbackType extends JSDocType, Declaration { | ||
parameterTags?: NodeArray<JSDocParameterTag>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use @return
here in @callback
too, right? I think JSDocCallbackType should have a field for that too.
@@ -221,7 +221,7 @@ namespace ts.NavigationBar { | |||
if (node.jsDocComments) { | |||
for (const jsDocComment of node.jsDocComments) { | |||
for (const tag of jsDocComment.tags) { | |||
if (tag.kind === SyntaxKind.JSDocTypedefTag) { | |||
if (tag.kind === SyntaxKind.JSDocTypedefTag || tag.kind === SyntaxKind.JSDocCallbackTag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does the fourslash rename test cover this? I didn't think that it does
// This is different kind of jsDoc parameter tag. Here is the address the case when | ||
// the parameter declaration is a normal one (in the code), while the type of the | ||
// parameter may be found in the jsdoc comment. | ||
const paramTag = getCorrespondingJSDocParameterTag(node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to simplify this code and have getCorrespondingJSDocParameterTag
return a paramTag
that works whether or not node
is aParameterDeclaration
or a JSDocParameterTag
.
@@ -1528,6 +1530,15 @@ namespace ts { | |||
jsDocTypeLiteral?: JSDocTypeLiteral; | |||
} | |||
|
|||
export interface JSDocCallbackTag extends JSDocTag, Declaration { | |||
name: Identifier; | |||
type: JSDocCallbackType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually quite a bit like an @typedef
in that they both support multiple lines and both produce a single type (declaration?). Could the interfaces be shared?
Maybe even some of the machinery could be shared. I haven't read that part yet.
@@ -2397,7 +2408,7 @@ namespace ts { | |||
} | |||
|
|||
export interface Signature { | |||
declaration: SignatureDeclaration; // Originating declaration | |||
declaration: SignatureDeclaration | JSDocCallbackType; // Originating declaration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why doesn't @typedef
need to be special-cased onto a declaration like this? At least I don't find an example of it happening.
@@ -3178,6 +3178,14 @@ namespace ts { | |||
type = checkExpressionCached((<BinaryExpression>declaration.parent).right); | |||
} | |||
} | |||
else if (declaration.kind == SyntaxKind.JSDocParameterTag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when can this happen?
if (minArgumentCount < 0) { | ||
minArgumentCount = i - (hasThisParameter ? 1 : 0); | ||
if (isJSDocParameterTag(param)) { | ||
if (isJSDocOptionalParameterTag(param)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is really almost the same as the code in the !isJSDocParameterTag
branch. I think you should get rid of the true branch and find a way to make the already-existing isJSDocOptionalParameterTag
(currently, line 4545) check work.
@@ -4474,7 +4496,7 @@ namespace ts { | |||
} | |||
} | |||
|
|||
function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { | |||
function getSignatureFromDeclaration(declaration: SignatureDeclaration | JSDocCallbackType): Signature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have to getSignatureFromDeclaration for JSDocCallbackType and not for JSDocTypedefTag?
case SyntaxKind.AtToken: | ||
if (canParseTag) { | ||
parentTagTerminated = !tryParseChildTag(parentTag); | ||
if (!parentTagTerminated) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you invert parentTagTerminated
and rename it? I'd much rather read parentTagContinues = tryParseChild(parentTag); if (parentTagContinues) resumePos = scanner.getStartPos();
|
||
//// /** | ||
//// * @callback FooHandler | ||
//// * @param {string} eventName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add some documentation? I don't think it'll work now, but once my jsdoc change is also merged, then parseParamTag
should also parse documentation. In the meantime, it should be skipped correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the parser in services almost certainly won't skip it or retrieve it correctly. I don't think that's a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parser changes look good but the binder looks like it could be simplified and I don't understand why some parts of the checker need to change, like getDeclarationFromSignature
.
We should discuss which order to merge this vs #10671. As far as I can tell, they shouldn't overlap very much except
|
@zhengbli can you update his change? |
closing this for now. |
Note that once |
Fixes #7515
Example:
is the equivalent of TypeScript code:
Types defined by
@callback
tag are block scoped, and will show up in thenavigate to
list.