From 520ec2059b385a805668a0fb776d9a74c68c014c Mon Sep 17 00:00:00 2001 From: Ben Perlmutter Date: Sun, 29 Jan 2023 21:10:58 -0500 Subject: [PATCH 01/11] docs: Custom Processors cleanup and expansion --- docs/src/extend/custom-processors.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index a2f1d805993..57b983f6e27 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -7,11 +7,12 @@ eleventyNavigation: order: 5 --- -You can also create custom processors that tell ESLint how to process files other than JavaScript. + +You can also create custom processors that tell ESLint how to process files other than standard JavaScript. For example, you could write a custom processor to extract and process JavaScript from Markdown files ([eslint-plugin-markdown](https://www.npmjs.com/package/eslint-plugin-markdown) includes a custom processor for this). ## Custom Processor Specification -In order to create a processor, the object that is exported from your module has to conform to the following interface: +In order to create a custom processor, the object exported from your module has to conform to the following interface: ```js module.exports = { @@ -46,27 +47,27 @@ module.exports = { **The `preprocess` method** takes the file contents and filename as arguments, and returns an array of code blocks to lint. The code blocks will be linted separately but still be registered to the filename. -A code block has two properties `text` and `filename`; the `text` property is the content of the block and the `filename` property is the name of the block. Name of the block can be anything, but should include the file extension, that would tell the linter how to process the current block. The linter will check [`--ext` CLI option](../use/command-line-interface#--ext) to see if the current block should be linted, and resolve `overrides` configs to check how to process the current block. +A code block has two properties `text` and `filename`. The `text` property is the content of the block and the `filename` property is the name of the block. The name of the block can be anything, but should include the file extension, which tells the linter how to process the current block. The linter checks the [`--ext` CLI option](../use/command-line-interface#--ext) to see if the current block should be linted and resolves `overrides` configs to check how to process the current block. -It's up to the plugin to decide if it needs to return just one part, or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts, but for `.md` file where each JavaScript block might be independent, you can return multiple items. +It's up to the plugin to decide if it needs to return just one part of the non-JavaScript file or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts. However, for `.md` files, because each JavaScript block might be independent, you can return multiple items. **The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. Reported problems have the following location information: ```typescript +// TODO: are these the messages? { line: number, column: number, - endLine?: number, endColumn?: number } ``` -By default, ESLint will not perform autofixes when a processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: +By default, ESLint does not perform autofixes when a custom processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: -1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems will have a `fix` property, which is an object with the following schema: +1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems have a `fix` property, which is an object with the following schema: ```js { @@ -81,7 +82,9 @@ By default, ESLint will not perform autofixes when a processor is used, even whe 2. Add a `supportsAutofix: true` property to the processor. -You can have both rules and processors in a single plugin. You can also have multiple processors in one plugin. +TODO: i don't understand what this next paragraph means + +You can have both rules and custom processors in a single plugin. You can also have multiple processors in one plugin. To support multiple extensions, add each one to the `processors` element and point them to the same object. ## Specifying Processor in Config Files @@ -102,7 +105,11 @@ See [Specify a Processor](../use/configure/plugins#specify-a-processor) in the P ## File Extension-named Processor -If a processor name starts with `.`, ESLint handles the processor as a **file extension-named processor** especially and applies the processor to the kind of files automatically. People don't need to specify the file extension-named processors in their config files. +> TODO: i don't understand this line. is it saying that as long as the file extension named processor +> is inclueded in the plugin, it runs? +> Users don't need to specify the file extension-named processors in their config files. + +If a custom processor name starts with `.`, ESLint handles the processor as a **file extension-named processor**. ESLint applies the processor to files with that filename extension automatically. Users don't need to specify the file extension-named processors in their config files. For example: @@ -110,7 +117,7 @@ For example: module.exports = { processors: { // This processor will be applied to `*.md` files automatically. - // Also, people can use this processor as "plugin-id/.md" explicitly. + // Also, you can use this processor as "plugin-id/.md" explicitly. ".md": { preprocess(text, filename) { /* ... */ }, postprocess(messageLists, filename) { /* ... */ } From 50228936805a9a94957c458c27ec488493b59aad Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Tue, 31 Jan 2023 21:40:16 -0500 Subject: [PATCH 02/11] remove TODO --- docs/src/extend/custom-processors.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 57b983f6e27..0d1afd252dd 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -105,9 +105,6 @@ See [Specify a Processor](../use/configure/plugins#specify-a-processor) in the P ## File Extension-named Processor -> TODO: i don't understand this line. is it saying that as long as the file extension named processor -> is inclueded in the plugin, it runs? -> Users don't need to specify the file extension-named processors in their config files. If a custom processor name starts with `.`, ESLint handles the processor as a **file extension-named processor**. ESLint applies the processor to files with that filename extension automatically. Users don't need to specify the file extension-named processors in their config files. From 142f4ee1f34aa5d24e174444bd3265b87ecb88f8 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Tue, 31 Jan 2023 21:40:39 -0500 Subject: [PATCH 03/11] remove extra white space --- docs/src/extend/custom-processors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 0d1afd252dd..44a20baf12d 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -105,7 +105,6 @@ See [Specify a Processor](../use/configure/plugins#specify-a-processor) in the P ## File Extension-named Processor - If a custom processor name starts with `.`, ESLint handles the processor as a **file extension-named processor**. ESLint applies the processor to files with that filename extension automatically. Users don't need to specify the file extension-named processors in their config files. For example: From 22d3d866d6fb1bb88aaa970b6d2dd68ba514e354 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Tue, 31 Jan 2023 21:42:57 -0500 Subject: [PATCH 04/11] remove TODO comment --- docs/src/extend/custom-processors.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 44a20baf12d..992fd6c9664 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -82,8 +82,6 @@ By default, ESLint does not perform autofixes when a custom processor is used, e 2. Add a `supportsAutofix: true` property to the processor. -TODO: i don't understand what this next paragraph means - You can have both rules and custom processors in a single plugin. You can also have multiple processors in one plugin. To support multiple extensions, add each one to the `processors` element and point them to the same object. From d4cdf924cdb0c0f74882af00916108c1ebdb0e10 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter Date: Sun, 5 Feb 2023 15:31:03 -0500 Subject: [PATCH 05/11] implement NZ feedback --- docs/src/extend/custom-processors.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 992fd6c9664..e29ab09ac7b 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -53,11 +53,10 @@ It's up to the plugin to decide if it needs to return just one part of the non-J **The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. -Reported problems have the following location information: +Reported problems have the following location information in each lint message: ```typescript -// TODO: are these the messages? -{ +type LintMessage = { line: number, column: number, endLine?: number, @@ -69,7 +68,7 @@ By default, ESLint does not perform autofixes when a custom processor is used, e 1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems have a `fix` property, which is an object with the following schema: - ```js + ```typescript { range: [number, number], text: string @@ -82,8 +81,7 @@ By default, ESLint does not perform autofixes when a custom processor is used, e 2. Add a `supportsAutofix: true` property to the processor. -You can have both rules and custom processors in a single plugin. You can also have multiple processors in one plugin. -To support multiple extensions, add each one to the `processors` element and point them to the same object. +You can have both rules and custom processors in a single plugin. You can also have multiple processors in one plugin. To support multiple extensions, add each one to the `processors` element and point them to the same object. ## Specifying Processor in Config Files @@ -116,6 +114,13 @@ module.exports = { preprocess(text, filename) { /* ... */ }, postprocess(messageLists, filename) { /* ... */ } } + // This processor will not be applied to any files automatically. + // To use this processor, you must explicitly specify it + // in your configuration as "plugin-id/markdown". + "markdown": { + preprocess(text, filename) { /* ... */ }, + postprocess(messageLists, filename) { /* ... */ } + } } } ``` From 8f9a3007b9f90e9e6629b045c01847b13e5a784a Mon Sep 17 00:00:00 2001 From: Ben Perlmutter Date: Tue, 7 Feb 2023 20:16:06 -0500 Subject: [PATCH 06/11] Add multiple custom processors --- docs/src/extend/custom-processors.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index e29ab09ac7b..cc3675b4e52 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -124,3 +124,16 @@ module.exports = { } } ``` + +You can also use the same custom processor with multiple filename extensions. The following example shows using same processor for both `.md` and `.mdx` files: + +```js +module.exports = { + // The same custom processor is applied to both + // `.md` and `.mdx` files. + processors: { + ".md": myCustomProcessor, + ".mdx": myCustomProcessor + } +} +``` From b2f4dbdc037e1abd72c5059e32c50843d01861f5 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Sun, 12 Feb 2023 13:43:30 -0500 Subject: [PATCH 07/11] implement NZ's suggestion about defining `myCustomProcessor` --- docs/src/extend/custom-processors.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index cc3675b4e52..5e4e3961437 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -128,6 +128,8 @@ module.exports = { You can also use the same custom processor with multiple filename extensions. The following example shows using same processor for both `.md` and `.mdx` files: ```js +const myCustomProcessor = { /* processor methods */ }; + module.exports = { // The same custom processor is applied to both // `.md` and `.mdx` files. From 239b615eacef0e4b77fb4a6c23d2e1bb1fab5afa Mon Sep 17 00:00:00 2001 From: Ben Perlmutter Date: Wed, 15 Feb 2023 21:28:14 -0500 Subject: [PATCH 08/11] add message type --- docs/src/extend/custom-processors.md | 45 +++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 5e4e3961437..c83e52d87e2 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -57,11 +57,48 @@ Reported problems have the following location information in each lint message: ```typescript type LintMessage = { - line: number, - column: number, - endLine?: number, - endColumn?: number + /// The 1-based column number where the message occurs. + column: number; + + /// The 1-based column number of the end location. + endColumn: number; + + /// The 1-based line number of the end location. + endLine: number; + + /// If `true`, this is a fatal error. + fatal: boolean; + + /// Information for an autofix. + fix: Fix; + + /// The 1-based line number where the message occurs. + line: number; + + /// The error message. + message: string; + + /// The ID of the rule which generated the message, or `null` if not applicable. + ruleId: string | null; + + /// The severity of the message. + severity: 0 | 1 | 2; + + /// Information for suggestions. + suggestions?: Suggestion[]; +}; + +type Fix = { + range: [number, number]; + text: string; } + +type Suggestion = { + desc?: string; + messageId?: string; + fix: Fix; +} + ``` By default, ESLint does not perform autofixes when a custom processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: From 4077bfb8a628e2ce814e97d64d37291ce0c23c09 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Thu, 16 Feb 2023 21:07:16 -0500 Subject: [PATCH 09/11] Apply suggestions from code review --- docs/src/extend/custom-processors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index c83e52d87e2..413ad664142 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -49,7 +49,7 @@ module.exports = { A code block has two properties `text` and `filename`. The `text` property is the content of the block and the `filename` property is the name of the block. The name of the block can be anything, but should include the file extension, which tells the linter how to process the current block. The linter checks the [`--ext` CLI option](../use/command-line-interface#--ext) to see if the current block should be linted and resolves `overrides` configs to check how to process the current block. -It's up to the plugin to decide if it needs to return just one part of the non-JavaScript file or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts. However, for `.md` files, because each JavaScript block might be independent, you can return multiple items. +It's up to the plugin to decide if it needs to return just one part of the non-JavaScript file or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts. However, for `.md` files, you can return multiple items because each JavaScript block might be independent. **The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. From ffeacd1d666a2775dee5d8f1c2f627eacf78568a Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Thu, 16 Feb 2023 21:08:46 -0500 Subject: [PATCH 10/11] Update docs/src/extend/custom-processors.md --- docs/src/extend/custom-processors.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 413ad664142..8a80faf1345 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -57,24 +57,25 @@ Reported problems have the following location information in each lint message: ```typescript type LintMessage = { + + /// The 1-based line number where the message occurs. + line: number; + /// The 1-based column number where the message occurs. column: number; - /// The 1-based column number of the end location. - endColumn: number; - /// The 1-based line number of the end location. endLine: number; + /// The 1-based column number of the end location. + endColumn: number; + /// If `true`, this is a fatal error. fatal: boolean; /// Information for an autofix. fix: Fix; - /// The 1-based line number where the message occurs. - line: number; - /// The error message. message: string; From c09e1736ac671229cfa89bf84554544cfc66c7b2 Mon Sep 17 00:00:00 2001 From: Ben Perlmutter <57849986+bpmutter@users.noreply.github.com> Date: Sat, 11 Mar 2023 15:30:28 -0500 Subject: [PATCH 11/11] Update docs/src/extend/custom-processors.md Co-authored-by: Brandon Mills --- docs/src/extend/custom-processors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md index 8a80faf1345..b5161b7824b 100644 --- a/docs/src/extend/custom-processors.md +++ b/docs/src/extend/custom-processors.md @@ -163,7 +163,7 @@ module.exports = { } ``` -You can also use the same custom processor with multiple filename extensions. The following example shows using same processor for both `.md` and `.mdx` files: +You can also use the same custom processor with multiple filename extensions. The following example shows using the same processor for both `.md` and `.mdx` files: ```js const myCustomProcessor = { /* processor methods */ };