Skip to content

Commit 3298e53

Browse files
committed
refactor: cleanup
1 parent 8ec6cde commit 3298e53

File tree

4 files changed

+63
-51
lines changed

4 files changed

+63
-51
lines changed

.changeset/weak-lamps-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-prettier": minor
3+
---
4+
5+
feat: support non-js languages like `css` for `@eslint/css` and `json` for `@eslint/json`

eslint-plugin-prettier.js

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@
77

88
/**
99
* @import {AST, ESLint, Linter, Rule, SourceCode} from 'eslint'
10+
* @import {Position} from 'estree'
1011
* @import {FileInfoOptions, Options as PrettierOptions} from 'prettier'
1112
* @import {Difference} from 'prettier-linter-helpers'
1213
*/
1314

1415
/**
15-
* @typedef {{ line: number; column: number; offset: number }} Location
16-
*
1716
* @typedef {PrettierOptions & {
1817
* onDiskFilepath: string;
1918
* parserMeta?: ESLint.ObjectMetaProperties['meta'];
@@ -27,11 +26,6 @@
2726
* options: Options,
2827
* fileInfoOptions: FileInfoOptions,
2928
* ) => string} PrettierFormat
30-
*
31-
*
32-
* @typedef {Parameters<
33-
* Exclude<ESLint.Plugin['rules'], undefined>[string]['create']
34-
* >[0]} RuleContext
3529
*/
3630

3731
'use strict';
@@ -64,29 +58,46 @@ let prettierFormat;
6458
// Rule Definition
6559
// ------------------------------------------------------------------------------
6660

61+
/** @type {WeakMap<SourceCode, number[]>} */
62+
const lineIndexesCache = new WeakMap();
63+
6764
/**
68-
* Converts a byte offset to a Location.
65+
* Ponyfill `sourceCode.getLocFromIndex` when it's unavailable.
6966
*
7067
* See also `getLocFromIndex` in `@eslint/js`.
7168
*
72-
* @param {number[]} lineIndexes
73-
* @param {number} offset
74-
* @returns {Location}
69+
* @param {SourceCode} sourceCode
70+
* @param {number} index
71+
* @returns {Position}
7572
*/
76-
function getLocFromOffset(lineIndexes, offset) {
73+
function getLocFromIndex(sourceCode, index) {
74+
if (typeof sourceCode.getLocFromIndex === 'function') {
75+
return sourceCode.getLocFromIndex(index);
76+
}
77+
78+
let lineIndexes = lineIndexesCache.get(sourceCode);
79+
if (!lineIndexes) {
80+
lineIndexes = [...sourceCode.text.matchAll(/\r?\n/g)].map(
81+
match => match.index,
82+
);
83+
// first line in the file starts at byte offset 0
84+
lineIndexes.unshift(0);
85+
lineIndexesCache.set(sourceCode, lineIndexes);
86+
}
87+
7788
let line = 0;
78-
while (line + 1 < lineIndexes.length && lineIndexes[line + 1] < offset) {
89+
while (line + 1 < lineIndexes.length && lineIndexes[line + 1] < index) {
7990
line += 1;
8091
}
92+
const column = index - lineIndexes[line];
8193

82-
const column = offset - lineIndexes[line];
83-
return { line: line + 1, column, offset };
94+
return { line: line + 1, column };
8495
}
8596

8697
/**
8798
* Reports a difference.
8899
*
89-
* @param {RuleContext} context - The ESLint rule context.
100+
* @param {Rule.RuleContext} context - The ESLint rule context.
90101
* @param {Difference} difference - The difference object.
91102
* @returns {void}
92103
*/
@@ -99,38 +110,7 @@ function reportDifference(context, difference) {
99110
// TODO: Only use property when our eslint peerDependency is >=8.40.0.
100111
const sourceCode = context.sourceCode ?? context.getSourceCode();
101112

102-
const lazy = {
103-
/**
104-
* Lazily computes the line indices for `sourceCode`.
105-
*
106-
* @returns {number[]}
107-
*/
108-
get lineIndexes() {
109-
// @ts-ignore
110-
delete this.lineIndexes;
111-
112-
if (!('text' in sourceCode)) {
113-
throw new Error(
114-
'prettier/prettier: non-textual source code is unsupported',
115-
);
116-
}
117-
118-
// @ts-ignore
119-
this.lineIndexes = [...sourceCode.text.matchAll(/\n/g)].map(
120-
match => match.index,
121-
);
122-
// first line in the file starts at byte offset 0
123-
this.lineIndexes.unshift(0);
124-
return this.lineIndexes;
125-
},
126-
};
127-
128-
const [start, end] = range.map(
129-
index =>
130-
// @ts-ignore
131-
sourceCode.getLocFromIndex?.(index) ??
132-
getLocFromOffset(lazy.lineIndexes, index),
133-
);
113+
const [start, end] = range.map(index => getLocFromIndex(sourceCode, index));
134114

135115
context.report({
136116
messageId: operation,
@@ -147,7 +127,7 @@ function reportDifference(context, difference) {
147127
// Module Definition
148128
// ------------------------------------------------------------------------------
149129

150-
/** @satisfies {ESLint.Plugin} */
130+
/** @type {ESLint.Plugin} */
151131
const eslintPluginPrettier = {
152132
meta: { name, version },
153133
configs: {
@@ -225,6 +205,7 @@ const eslintPluginPrettier = {
225205
const source = sourceCode.text;
226206

227207
return {
208+
/** @param {unknown} node */
228209
[sourceCode.ast.type](node) {
229210
if (!prettierFormat) {
230211
// Prettier is expensive to load, so only load it if needed.

test/fixtures/empty.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

test/prettier.mjs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,26 @@ runFixture('invalid-prettierrc/*', [
381381
],
382382
]);
383383

384+
runFixture('*.json', [
385+
[
386+
{
387+
column: 1,
388+
endColumn: 1,
389+
endLine: 2,
390+
fix: {
391+
range: [0, 1],
392+
text: '',
393+
},
394+
line: 1,
395+
message: 'Delete `⏎`',
396+
messageId: 'delete',
397+
nodeType: null,
398+
ruleId: 'prettier/prettier',
399+
severity: 2,
400+
},
401+
],
402+
]);
403+
384404
const jsonRuleTester = new RuleTester({
385405
plugins: {
386406
json: eslintPluginJson,
@@ -462,7 +482,7 @@ function getPrettierRcJsFilename(dir, file = 'dummy.js') {
462482
* @type {ESLint}
463483
* @import {ESLint} from 'eslint'
464484
*/
465-
let eslint;
485+
var eslint; // bad mocha: `ReferenceError: Cannot access 'eslint' before initialization`
466486

467487
/**
468488
* @param {string} pattern
@@ -530,11 +550,16 @@ async function runFixture(pattern, asserts, skip) {
530550
pug: eslintPluginPug,
531551
},
532552
},
553+
{
554+
files: ['**/*.json'],
555+
plugins: {
556+
json: eslintPluginJson,
557+
},
558+
},
533559
],
534560
ignore: false,
535561
});
536562
}
537-
538563
if (skip) {
539564
return;
540565
}

0 commit comments

Comments
 (0)