We did not serialize the `AssignmentPattern` node inside `ObjectPattern`
properties.
```ts
({ a = b } = {})
```
This is a bit different in SWC and looks like I got confused with the
different AST formats.
Fixes https://github.com/denoland/deno/issues/28399
This PR adds support for `:has/:is/:where()` and `:not()`. The latter
was already present, but found a bunch of issues with it and I'd say
that it didn't really work before this PR.
Fixes https://github.com/denoland/deno/issues/28335
Internally, we use a group node for array-like children, which is hidden
from the user. When we're asking for a parent of a node we need to take
group nodes into account and walk over them.
Fixes one issue reported in
https://github.com/denoland/deno/issues/28355
This PR adds support for field selectors (`.<field>`) in the lint plugin
API. This is supported in ESLint as well, but was missing in our
implementation.
```css
/* Only search the test expression of an IfStatement */
IfStatement.test
```
Fixes https://github.com/denoland/deno/issues/28314
The code to support regex matching on attribute values was already
there. I just forgot to wire it up properly in the selector matching
code.
Fixes https://github.com/denoland/deno/issues/28336
The `:exit` selectors were called at the wrong time during visiting.
They need to be called when going upwards and a node and all its
children have been fully visited. Instead we called it when the node +
all its sibling were visited which is wrong.
Fixes https://github.com/denoland/deno/issues/28227
This PR fixes deviations in our AST format compared to TSEStree. They
are mostly a leftover for when I first started working on it and based
it off of babel instead.
One of the key changes why the changeset is a bit bigger is that
TSEStree uses `undefined` instead of `null` as the empty value for type
nodes. This is likely influenced by `tsc` which use `undefined`
everywhere. The rest of the nodes use `null` though. It's a little
weird, but for now it might be better to align.
(extracted from https://github.com/denoland/deno/pull/27977)
This commit adds an unstable lint plugin API.
Plugins are specified in the `deno.json` file under
`lint.plugins` option like so:
```
{
"lint": {
"plugins": [
"./plugins/my-plugin.ts",
"jsr:@deno/lint-plugin1",
"npm:@deno/lint-plugin2"
]
}
}
```
The API is considered unstable and might be subject
to changes in the future.
Plugin API was modelled after ESLint API for the
most part, but there are no guarantees for compatibility.
The AST format exposed to plugins is closely modelled
after the AST that `typescript-eslint` uses.
Lint plugins use the visitor pattern and can add
diagnostics like so:
```
export default {
name: "lint-plugin",
rules: {
"plugin-rule": {
create(context) {
return {
Identifier(node) {
if (node.name === "a") {
context.report({
node,
message: "should be b",
fix(fixer) {
return fixer.replaceText(node, "_b");
},
});
}
},
};
},
},
},
} satisfies Deno.lint.Plugin;
```
Besides reporting errors (diagnostics) plugins can provide
automatic fixes that use text replacement to apply changes.
---------
Co-authored-by: Marvin Hagemeister <marvin@deno.com>
Co-authored-by: David Sherret <dsherret@gmail.com>
This PR changes the underlying buffer backed AST format we use for
JavaScript-based linting plugins. It adds support for various new types,
makes traversal code a lot easier and is more polished compared to
previous iterations.
Here is a quick summary (in no particular order):
- Node prop data is separate from traversal, which makes traversal code
so much easier to reason about. Previously, it was interleaved with node
prop data
- spans are in a separate table as well, as they are rarely needed.
- schema is separate from SWC conversion logic, which makes
- supports recursive plain objects
- supports numbers
- supports bigint
- supports regex
- adds all SWC nodes
Apologies, this is kinda a big PR, but it's worth it imo.
_Marking as draft because I need to update some tests tomorrow._
When running selectors for JS linting plugins we would error when
encountering an unknown attribute name:
```js
// selector
Foo[non-existant]
// error
Error: Missing string id: <number>
```
This was caused by using `0` as the invalid marker, but also overloading
`0` with an actual node type. So the fix is to reserve `0` as the
invalid marker and move the property type to the next index.
This PR extracts the core part of
https://github.com/denoland/deno/pull/27203 to make it easier to review
and land in parts.
It contains:
- The JS plugin code the deserializes and walks the buffer
- The Rust portion to serialize SWC to the buffer format (a bunch of
nodes are still todos, but imo these can land anytime later)
- Basic lint plugin types, without the AST node types to make this PR
easier to review
- Added more code comments to explain the format etc.
More fixes and changes will be done in follow-up PRs.
---------
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>