Skip to content

Commit cec9313

Browse files
committed
feat: support non-js languages
1 parent aa4935c commit cec9313

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

eslint-plugin-prettier.js

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
*/
1313

1414
/**
15+
* @typedef {{
16+
* line: number;
17+
* column: number;
18+
* offset: number;
19+
* }} Location
20+
*
21+
*
1522
* @typedef {PrettierOptions & {
1623
* onDiskFilepath: string;
1724
* parserMeta?: ESLint.ObjectMetaProperties['meta'];
@@ -25,6 +32,9 @@
2532
* options: Options,
2633
* fileInfoOptions: FileInfoOptions,
2734
* ) => string} PrettierFormat
35+
*
36+
*
37+
* @typedef {Parameters<Exclude<ESLint.Plugin['rules'], undefined>[string]['create']>[0]} RuleContext
2838
*/
2939

3040
'use strict';
@@ -57,10 +67,31 @@ let prettierFormat;
5767
// Rule Definition
5868
// ------------------------------------------------------------------------------
5969

70+
/**
71+
* Converts a byte offset to a Location.
72+
*
73+
* See also `getLocFromIndex` in `@eslint/js`.
74+
*
75+
* @param {number[]} lineIndexes
76+
* @param {number} offset
77+
* @returns {Location}
78+
*/
79+
function getLocFromOffset(lineIndexes, offset) {
80+
const withSentinel = [-1, 0, ...lineIndexes];
81+
82+
let line = 0;
83+
while (line + 1 < withSentinel.length && withSentinel[line + 1] < offset) {
84+
line++;
85+
}
86+
87+
const column = offset - withSentinel[line];
88+
return { line, column, offset };
89+
}
90+
6091
/**
6192
* Reports a difference.
6293
*
63-
* @param {Rule.RuleContext} context - The ESLint rule context.
94+
* @param {RuleContext} context - The ESLint rule context.
6495
* @param {Difference} difference - The difference object.
6596
* @returns {void}
6697
*/
@@ -71,8 +102,14 @@ function reportDifference(context, difference) {
71102
// `context.getSourceCode()` was deprecated in ESLint v8.40.0 and replaced
72103
// with the `sourceCode` property.
73104
// TODO: Only use property when our eslint peerDependency is >=8.40.0.
105+
const sourceCode = context.sourceCode ?? context.getSourceCode();
106+
if (!('text' in sourceCode)) {
107+
throw new Error('prettier only supports textual source code');
108+
}
109+
110+
const lineIndexes = [...sourceCode.text.matchAll(/\n/g)].map(match => match.index);
74111
const [start, end] = range.map(index =>
75-
(context.sourceCode ?? context.getSourceCode()).getLocFromIndex(index),
112+
getLocFromOffset(lineIndexes, index)
76113
);
77114

78115
context.report({
@@ -90,7 +127,7 @@ function reportDifference(context, difference) {
90127
// Module Definition
91128
// ------------------------------------------------------------------------------
92129

93-
/** @type {ESLint.Plugin} */
130+
/** @satisfies {ESLint.Plugin} */
94131
const eslintPluginPrettier = {
95132
meta: { name, version },
96133
configs: {
@@ -168,7 +205,7 @@ const eslintPluginPrettier = {
168205
const source = sourceCode.text;
169206

170207
return {
171-
Program(node) {
208+
[sourceCode.ast.type](node) {
172209
if (!prettierFormat) {
173210
// Prettier is expensive to load, so only load it if needed.
174211
prettierFormat = /** @type {PrettierFormat} */ (
@@ -251,7 +288,7 @@ const eslintPluginPrettier = {
251288

252289
for (const difference of differences) {
253290
reportDifference(
254-
/** @type {Rule.RuleContext} */ (context),
291+
/** @type {Rule.RuleContext} */(context),
255292
difference,
256293
);
257294
}

0 commit comments

Comments
 (0)