-
-
Notifications
You must be signed in to change notification settings - Fork 525
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
feat(ast,parser): parse jsdoc #168
Comments
Prioritizing because @thepassle need this. See https://twitter.com/passle_/status/1637446645104164865 |
Update: The original intent was to come up with a generic comment attachment algorithm, where we attach comments to some AST node driven by a set of rules. After some research and reading about it in the ESLint and Babel codebases, I conclude that it is incomprehensible for me right now. So instead, let's reduce the problem space down to "attach jsdoc comments to specific AST node". This will be much more approachable. We will build the jsdoc data structure inside the semantic analyzer. When a jsdoc targeting AST node such as a Statement or Declaration is visited, we will ask |
I want to help somehow. What do you need or what can I do? :) |
Hi Ema! I've forgotten everything we wrote about jsdocs, but would you be interested in getting a https://github.com/gajus/eslint-plugin-jsdoc rule to work? I can guide you on the missing pieces in the discord channel. I think we had some of the infra working, targeting a lint rule would be the easiest to fill in the gaps. |
This comment was marked as outdated.
This comment was marked as outdated.
I'd love to be able to just see & access comment values instead of skipping them outright. I'd definitely consider it a bonus step for oxc to parse any JSDocs and translate its meaning(s) to the AST, but there are lots of instances where users either invent directives or just use a standard comment to transfer additional information Quick examples: /** @table "users" */
type User = { ... }
import(/* webpackChunkName: "my-chunk" */ "foobar");
// comptime
const DAY = ms(1, "day") |
We talked a bit about this in #2437 ...,
So, I spent these days reading through the code.
(There are 3 articles on my blog if you're interested. Sorry it's in Japanese.) As a result, although IMO, I'm not sure we should aim for 100% compatibility for this. For a number of reasons,
@Boshen Sorry for the long lines, then I'd like to confirm,
What do you think? 👀 |
@leaysgur Oh wow I didn't expect 3 blog posts on this topic, I thought jsdoc is a solved problem 😰 So in summary, it seems like the hardest part about jsdoc is comment attachment to AST nodes. We can leave this part out and focus our task on just jsdoc content rules, which is quiet easy as all we need to do is finish the jsdoc parser and run rules against these parsed jsdocs.
The intention was to pass all the tests, but we don't really need to do it if it's not a fun task. And if you're sick of jsdoc after looking at it for 3 days ... you may also join me on the eslint-plugin-import task. |
For future reference, let me elaborate.
This wasn't particularly difficult, at least if we trust the logic of To put it simply, it was just this: // findJSDocComment(node, sourceCode): Comment | null;
const beforeTokens = sourceCode.getTokensBefore(node, { includeComments: true });
while (let token = beforeTokens.pop()) {
if (token.type === 'Block' && token.value.startsWith('*')) return token;
}
return null; And I believe this behavior was already implemented in #2437 . The part I found to be the hardest was that some(about half of) rules can:
if (
esquery.matches(
astNode,
// from rule config
`MethodDefinition:not([accessibility="public"]):has(JsdocBlock)`
)
) {
const jsdocComment = findJSDocComment(astNode, sourceCode);
}
const jsdocAstNode = toESTreeLikeAST(jsdocComment);
if (
esquery.matches(
jsdocAstNode,
// from rule config
`JsdocBlock[postDelimiter=""]:has(JsdocTypeUnion > JsdocTypeName[value="Bar"]:nth-child(1))`
)
) {
ruleHandler({ astNode, jsdocAstNode });
}
(Actually, they seemed to have a bit more complicated logic...) About rest half of the rules seem to simply check "only the text of all JSDoc comments in the source". However, their implementation was like for (const { astNode, jsdocAstNode } of jsdocNodesWithAttachedNode)
// Why astNode required...??
ruleHandler({ astNode, jsdocAstNode });
// ...
for (const { jsdocAstNode } of jsdocNodesWithoutAttachedNode)
ruleHandler({ astNode: null, jsdocAstNode }); they are called differently for some reason. And when I tried to replace 💡 After additional research, I finally solved this mystery.
It seems that these 3 rules perform extra linting if
That sounds interesting as well. Either way, I'll think a bit more about how to conclude #2437 . |
Partial fix for #168 - [x] Fix general finding behavior for leading comments - [x] Accept multiple jsdoc comments per node - [x] Provide `get_one` and also `get_all` - [x] Add `iter_all()` for non-node related usage - [x] Limit AST node kinds to parse
@leaysgur is carrying this task 👍 . Future issues can be created separately now. |
Partial fix for oxc-project#168 - [x] Fix general finding behavior for leading comments - [x] Accept multiple jsdoc comments per node - [x] Provide `get_one` and also `get_all` - [x] Add `iter_all()` for non-node related usage - [x] Limit AST node kinds to parse
I see there are some demand for reading jsdoc information, let's do this in two steps:
Note: This is for parsing jsdoc comments to structured data. This is not about wiring up all the jsdoc comments into a document tree (which is the main purpose for jsdoc).
To parse jsdoc comments, we need to:
References:
The text was updated successfully, but these errors were encountered: