Skip to content
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

fix: Update RuleVisitor type #135

Merged
merged 6 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#### Prerequisites checklist

- [ ] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).
- [ ] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

<!--
Please ensure your pull request is ready:
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Monorepo for the rewrite of ESLint.

This repository is the home of the following packages:

- [`@eslint/core`](packages/core)
- [`@eslint/compat`](packages/compat)
- [`@eslint/config-array`](packages/config-array)
- [`@eslint/object-schema`](packages/object-schema)
- [`@eslint/migrate-config`](packages/migrate-config)
- [`@eslint/core`](packages/core)
- [`@eslint/compat`](packages/compat)
- [`@eslint/config-array`](packages/config-array)
- [`@eslint/object-schema`](packages/object-schema)
- [`@eslint/migrate-config`](packages/migrate-config)

<!-- NOTE: This section is autogenerated. Do not manually edit.-->
<!--sponsorsstart-->
Expand Down
2 changes: 1 addition & 1 deletion decisions/001-rewrite-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ When the new core is ready, we will need to be careful about the migration plan

## See Also

- <https://github.com/eslint/eslint/discussions/16557>
- <https://github.com/eslint/eslint/discussions/16557>
10 changes: 5 additions & 5 deletions decisions/004-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ We do not intend to take over full maintenance of `@types/eslint`. Instead, we w

For the ESLint team, this decision will:

- Ensure we have control over our type definitions.
- Allow us to design a more coherent and well-integrated type system in the new `@eslint/core`.
- Provide a clear path for integrating these types with `@types/eslint`, improving consistency across the ecosystem.
- Ensure we have control over our type definitions.
- Allow us to design a more coherent and well-integrated type system in the new `@eslint/core`.
- Provide a clear path for integrating these types with `@types/eslint`, improving consistency across the ecosystem.

For the community, this decision may:

- Require adjustments to adapt to the new type definitions in `@eslint/core`.
- Improve the accuracy and reliability of type definitions used in ESLint-related projects.
- Require adjustments to adapt to the new type definitions in `@eslint/core`.
- Improve the accuracy and reliability of type definitions used in ESLint-related projects.

We recognize that this may frustrate or anger some contributors, but we believe that this approach balances the need for accurate type definitions with the practicalities of maintaining a complex project like ESLint.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"eslint-config-eslint": "^11.0.0",
"got": "^14.4.1",
"lint-staged": "^15.2.0",
"prettier": "^3.1.1",
"prettier": "^3.4.1",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.0",
"yorkie": "^2.0.0"
Expand Down
8 changes: 4 additions & 4 deletions packages/compat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ deno add @eslint/compat

This package exports the following functions in both ESM and CommonJS format:

- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result
- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules
- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()`
- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file
- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result
- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules
- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()`
- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file

### Fixing Rules

Expand Down
34 changes: 17 additions & 17 deletions packages/config-array/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ The config array always returns an object, even if there are no configs matching

A few things to keep in mind:

- If a filename is not an absolute path, it will be resolved relative to the base path directory.
- The returned config object never has `files`, `ignores`, or `name` properties; the only properties on the object will be the other configuration options specified.
- The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation.
- A config will only be generated if the filename matches an entry in a `files` key. A config will not be generated without matching a `files` key (configs without a `files` key are only applied when another config with a `files` key is applied; configs without `files` are never applied on their own). Any config with a `files` key entry that is `*` or ends with `/**` or `/*` will only be applied if another entry in the same `files` key matches or another config matches.
- If a filename is not an absolute path, it will be resolved relative to the base path directory.
- The returned config object never has `files`, `ignores`, or `name` properties; the only properties on the object will be the other configuration options specified.
- The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation.
- A config will only be generated if the filename matches an entry in a `files` key. A config will not be generated without matching a `files` key (configs without a `files` key are only applied when another config with a `files` key is applied; configs without `files` are never applied on their own). Any config with a `files` key entry that is `*` or ends with `/**` or `/*` will only be applied if another entry in the same `files` key matches or another config matches.

## Determining Ignored Paths

Expand All @@ -298,11 +298,11 @@ const ignored = configs.isFileIgnored("/foo/bar/baz.txt");

A file is considered ignored if any of the following is true:

- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/a.js` is considered ignored.
- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/baz/a.js` is considered ignored.
- **It matches an ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.
- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/a.js` is considered ignored.
- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/baz/a.js` is considered ignored.
- **It matches an ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.

For directories, use the `isDirectoryIgnored()` method and pass in the path of any directory, as in this example:

Expand All @@ -312,11 +312,11 @@ const ignored = configs.isDirectoryIgnored("/foo/bar/");

A directory is considered ignored if any of the following is true:

- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/baz` is considered ignored.
- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/bar/baz/a.js` is considered ignored.
- **It matches and ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.
- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/baz` is considered ignored.
- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/bar/baz/a.js` is considered ignored.
- **It matches and ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.

**Important:** A pattern such as `foo/**` means that `foo` and `foo/` are _not_ ignored whereas `foo/bar` is ignored. If you want to ignore `foo` and all of its subdirectories, use the pattern `foo` or `foo/` in `ignores`.

Expand All @@ -331,9 +331,9 @@ Each `ConfigArray` aggressively caches configuration objects to avoid unnecessar

The design of this project was influenced by feedback on the ESLint RFC, and incorporates ideas from:

- Teddy Katz (@not-an-aardvark)
- Toru Nagashima (@mysticatea)
- Kai Cataldo (@kaicataldo)
- Teddy Katz (@not-an-aardvark)
- Toru Nagashima (@mysticatea)
- Kai Cataldo (@kaicataldo)

## License

Expand Down
13 changes: 5 additions & 8 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,17 @@ export type RuleType = "problem" | "suggestion" | "layout";
*/
export type RuleFixType = "code" | "whitespace";

/* eslint-disable @typescript-eslint/consistent-indexed-object-style -- Needs to be interface so people can extend it. */
/* eslint-disable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */
/**
* An object containing visitor information for a rule. Each method is either the
* name of a node type or a selector, or is a method that will be called at specific
* times during the traversal.
*/
export interface RuleVisitor {
/**
* Called for each node in the AST or at specific times during the traversal.
*/
[key: string]: (...args: any[]) => void;
}
/* eslint-enable @typescript-eslint/consistent-indexed-object-style -- Needs to be interface so people can extend it. */
export type RuleVisitor = Record<
string,
((...args: any[]) => void) | undefined
>;

/* eslint-enable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */

/**
Expand Down
6 changes: 3 additions & 3 deletions packages/migrate-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ This package aids in the migration of the legacy ESLint configuration file forma

This tool currently works well for the following config file formats:

- `.eslintrc`
- `.eslintrc.json`
- `.eslintrc.yml`
- `.eslintrc`
- `.eslintrc.json`
- `.eslintrc.yml`

If you are using a JavaScript configuration file (`.eslintrc.js`, `.eslintrc.cjs`, `.eslintrc.mjs`), this tool currently is only capable of migrating the _evaluated_ configuration. That means any logic you may have inside of the file will be lost. If your configuration file is mostly static, then you'll get a good result; if your configuration file is more complex (using functions, calculating paths, etc.) then this tool will not provide an equivalent configuration file.

Expand Down
20 changes: 10 additions & 10 deletions packages/object-schema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ const result = {

Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy:

- `"assign"` - use `Object.assign()` to merge the two values into one object.
- `"overwrite"` - the second value always replaces the first.
- `"replace"` - the second value replaces the first if the second is not `undefined`.
- `"assign"` - use `Object.assign()` to merge the two values into one object.
- `"overwrite"` - the second value always replaces the first.
- `"replace"` - the second value replaces the first if the second is not `undefined`.

For example:

Expand All @@ -113,13 +113,13 @@ const schema = new ObjectSchema({

Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy:

- `"array"` - value must be an array.
- `"boolean"` - value must be a boolean.
- `"number"` - value must be a number.
- `"object"` - value must be an object.
- `"object?"` - value must be an object or null.
- `"string"` - value must be a string.
- `"string!"` - value must be a non-empty string.
- `"array"` - value must be an array.
- `"boolean"` - value must be a boolean.
- `"number"` - value must be a number.
- `"object"` - value must be an object.
- `"object?"` - value must be an object or null.
- `"string"` - value must be a string.
- `"string!"` - value must be a non-empty string.

For example:

Expand Down
28 changes: 14 additions & 14 deletions packages/plugin-kit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ deno add @eslint/plugin-kit

This package exports the following utilities:

- `ConfigCommentParser` - used to parse ESLint configuration comments (i.e., `/* eslint-disable rule */`)
- `VisitNodeStep` and `CallMethodStep` - used to help implement `SourceCode#traverse()`
- `Directive` - used to help implement `SourceCode#getDisableDirectives()`
- `TextSourceCodeBase` - base class to help implement the `SourceCode` interface
- `ConfigCommentParser` - used to parse ESLint configuration comments (i.e., `/* eslint-disable rule */`)
- `VisitNodeStep` and `CallMethodStep` - used to help implement `SourceCode#traverse()`
- `Directive` - used to help implement `SourceCode#getDisableDirectives()`
- `TextSourceCodeBase` - base class to help implement the `SourceCode` interface

### `ConfigCommentParser`

Expand Down Expand Up @@ -85,9 +85,9 @@ The `VisitNodeStep` and `CallMethodStep` classes represent steps in the traversa

The `VisitNodeStep` class is the more common of the two, where you are describing a visit to a particular node during the traversal. The constructor accepts three arguments:

- `target` - the node being visited. This is used to determine the method to call inside of a rule. For instance, if the node's type is `Literal` then ESLint will call a method named `Literal()` on the rule (if present).
- `phase` - either 1 for enter or 2 for exit.
- `args` - an array of arguments to pass into the visitor method of a rule.
- `target` - the node being visited. This is used to determine the method to call inside of a rule. For instance, if the node's type is `Literal` then ESLint will call a method named `Literal()` on the rule (if present).
- `phase` - either 1 for enter or 2 for exit.
- `args` - an array of arguments to pass into the visitor method of a rule.

For example:

Expand Down Expand Up @@ -115,8 +115,8 @@ class MySourceCode {

The `CallMethodStep` class is less common and is used to tell ESLint to call a specific method on the rule. The constructor accepts two arguments:

- `target` - the name of the method to call, frequently beginning with `"on"` such as `"onCodePathStart"`.
- `args` - an array of arguments to pass to the method.
- `target` - the name of the method to call, frequently beginning with `"on"` such as `"onCodePathStart"`.
- `args` - an array of arguments to pass to the method.

For example:

Expand Down Expand Up @@ -205,11 +205,11 @@ class MySourceCode {

The `TextSourceCodeBase` class is intended to be a base class that has several of the common members found in `SourceCode` objects already implemented. Those members are:

- `lines` - an array of text lines that is created automatically when the constructor is called.
- `getLoc(node)` - gets the location of a node. Works for nodes that have the ESLint-style `loc` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different location format, you'll still need to implement this method yourself.
- `getRange(node)` - gets the range of a node within the source text. Works for nodes that have the ESLint-style `range` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different range format, you'll still need to implement this method yourself.
- `getText(nodeOrToken, charsBefore, charsAfter)` - gets the source text for the given node or token that has range information attached. Optionally, can return additional characters before and after the given node or token. As long as `getRange()` is properly implemented, this method will just work.
- `getAncestors(node)` - returns the ancestry of the node. In order for this to work, you must implement the `getParent()` method yourself.
- `lines` - an array of text lines that is created automatically when the constructor is called.
- `getLoc(node)` - gets the location of a node. Works for nodes that have the ESLint-style `loc` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different location format, you'll still need to implement this method yourself.
- `getRange(node)` - gets the range of a node within the source text. Works for nodes that have the ESLint-style `range` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different range format, you'll still need to implement this method yourself.
- `getText(nodeOrToken, charsBefore, charsAfter)` - gets the source text for the given node or token that has range information attached. Optionally, can return additional characters before and after the given node or token. As long as `getRange()` is properly implemented, this method will just work.
- `getAncestors(node)` - returns the ancestry of the node. In order for this to work, you must implement the `getParent()` method yourself.

Here's an example:

Expand Down