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
[labs/analyzer] Analyze overloaded functions and methods. #3702
Conversation
…ion's implementation node.
🦋 Changeset detectedLatest commit: 2feb32b The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📊 Tachometer Benchmark ResultsSummarynop-update
render
update
update-reflect
Resultslit-element-list
render
update
update-reflect
lit-html-kitchen-sink
render
update
nop-update
lit-html-repeat
render
update
lit-html-template-heavy
render
update
reactive-element-list
render
update
update-reflect
|
@@ -117,7 +117,9 @@ export const getModule = ( | |||
for (const statement of sourceFile.statements) { | |||
if (ts.isClassDeclaration(statement)) { | |||
addDeclaration(getClassDeclarationInfo(statement, analyzer)); | |||
} else if (ts.isFunctionDeclaration(statement)) { | |||
// Ignore non-implementation signatures of overloaded functions by | |||
// checking for `statement.body`. |
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 maybe expand on this a bit? Like why do we want to ignore overloads? What do we do with different docs on different overloads? I don't the the CEM format explicitly handles overloads, so if we generated multiple declarations with the same name but different parameters, that would basically work by default - with the exception that tools might expect names to be unique.
I could see us documenting in the CEM that names aren't unique and duplicates indicate overloads (though we might want a way to mark and/or hide the implementation declaration because its signature might not be pretty).
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.
IIRC, I went down this path because there are few places in the analyzer that currently require unique names (and I just assumed this was a requirement). Kevin's comment on my other PR about getField()
is related. Another example is here, where declarations in modules are collected:
lit/packages/labs/analyzer/src/lib/javascript/modules.ts
Lines 105 to 107 in be18292
throw new Error( | |
`Internal error: duplicate declaration '${name}' in ${sourceFile.fileName}` | |
); |
I think your suggestion of explicitly documenting that names of potentially overloadable items in collections are not necessarily unique sounds like the best way to go. That way I could remove the weird documentation merging stuff here and we would avoid losing information in the output. Conveniently, the CEM schema already seems prepared for this since most (all?) collections of declarations are arrays of items with name
properties and not an object / map that requires a unique key per item. This would also resolve the issue you pointed out in your other comment about this PR not matching TS's behavior around docs for overloads.
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.
which would move the responsibility for matching TS's behavior or not to consumers of the manifest. That sounds good to me.
@@ -36,3 +36,46 @@ export function function2(a, b = false, ...c) { | |||
export default function () { | |||
return 'default'; | |||
} | |||
|
|||
/** | |||
* This function has an overloaded signature in TS. |
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.
What does that mean exactly? Is this file associated with ts/functions/src/functions.ts
so that those overloads apply here? I would have thought that these were separate modules.
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.
Yes, the same tests are run twice (once for each analysis result from files in the ts
and js
directories) so the doc comments that those tests check for need to match. For overloaded functions in particular, the comments for the single declaration in JS need to match those from the particular overload that they're extracted from in TS. These could be rewritten to make what's happening here clearer though.
However, it also sounds like I need to update this PR to handle overloads by producing multiple entries rather than trying to merge into a single one and I'm not sure how this is going to affect what's in the JS version of these fixtures yet. I'll try to make these more self-explanatory once I know what's happening with them.
|
||
// Overloaded functions have mulitple declaration nodes. If there are no | ||
// JSDoc tags on the provided declaration, use the first one that does have | ||
// JSDoc tags for the purpose of extracting a description. |
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.
TypeScript's behavior seems to be to choose the matched overload if there is one, or the first overload with jsdocs, but, surprisingly, never show the impl docs. The impl basically doesn't exist.
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.
Apparently having any overload signatures hides the implementation signature w.r.t. type checking call sites, so I guess from that perspective it makes sense that the implementation signature's docs aren't ever shown for a given call site.
This PR adds an
overloads
field toFunctionLikeDeclaration
and fills it with declarations for each overload signature.