12
12
*/
13
13
14
14
/**
15
+ * @typedef {{
16
+ * line: number;
17
+ * column: number;
18
+ * offset: number;
19
+ * }} Location
20
+ *
21
+ *
15
22
* @typedef {PrettierOptions & {
16
23
* onDiskFilepath: string;
17
24
* parserMeta?: ESLint.ObjectMetaProperties['meta'];
25
32
* options: Options,
26
33
* fileInfoOptions: FileInfoOptions,
27
34
* ) => string} PrettierFormat
35
+ *
36
+ *
37
+ * @typedef {Parameters<Exclude<ESLint.Plugin['rules'], undefined>[string]['create']>[0] } RuleContext
28
38
*/
29
39
30
40
'use strict' ;
@@ -57,10 +67,27 @@ let prettierFormat;
57
67
// Rule Definition
58
68
// ------------------------------------------------------------------------------
59
69
70
+ /**
71
+ * @param {number[] } lineIndexes
72
+ * @param {number } offset
73
+ * @returns {Location }
74
+ */
75
+ function getLocFromOffset ( lineIndexes , offset ) {
76
+ const [ lineStart , line ] = lineIndexes . reduce ( ( acc , lineStart , lineNo ) => lineStart < offset ? [ lineStart , lineNo ] : acc , [ - 1 , - 1 ] ) ;
77
+ if ( line < 0 ) {
78
+ const line = Math . max ( 0 , lineIndexes . length - 1 ) ;
79
+ const column = offset - Math . max ( 0 , lineIndexes [ line ] ) ;
80
+ return { line, column, offset }
81
+ }
82
+
83
+ const column = offset - lineStart ;
84
+ return { line, column, offset } ;
85
+ }
86
+
60
87
/**
61
88
* Reports a difference.
62
89
*
63
- * @param {Rule. RuleContext } context - The ESLint rule context.
90
+ * @param {RuleContext } context - The ESLint rule context.
64
91
* @param {Difference } difference - The difference object.
65
92
* @returns {void }
66
93
*/
@@ -71,8 +98,14 @@ function reportDifference(context, difference) {
71
98
// `context.getSourceCode()` was deprecated in ESLint v8.40.0 and replaced
72
99
// with the `sourceCode` property.
73
100
// TODO: Only use property when our eslint peerDependency is >=8.40.0.
101
+ const sourceCode = context . sourceCode ?? context . getSourceCode ( ) ;
102
+ if ( ! ( 'text' in sourceCode ) ) {
103
+ throw new Error ( 'prettier only supports textual source code' ) ;
104
+ }
105
+
106
+ const lineIndexes = [ ...sourceCode . text . matchAll ( / \n / g) ] . map ( match => match . index ) ;
74
107
const [ start , end ] = range . map ( index =>
75
- ( context . sourceCode ?? context . getSourceCode ( ) ) . getLocFromIndex ( index ) ,
108
+ getLocFromOffset ( lineIndexes , index )
76
109
) ;
77
110
78
111
context . report ( {
@@ -90,7 +123,7 @@ function reportDifference(context, difference) {
90
123
// Module Definition
91
124
// ------------------------------------------------------------------------------
92
125
93
- /** @type {ESLint.Plugin } */
126
+ /** @satisfies {ESLint.Plugin } */
94
127
const eslintPluginPrettier = {
95
128
meta : { name, version } ,
96
129
configs : {
@@ -168,7 +201,7 @@ const eslintPluginPrettier = {
168
201
const source = sourceCode . text ;
169
202
170
203
return {
171
- Program ( node ) {
204
+ [ sourceCode . ast . type ] ( node ) {
172
205
if ( ! prettierFormat ) {
173
206
// Prettier is expensive to load, so only load it if needed.
174
207
prettierFormat = /** @type {PrettierFormat } */ (
@@ -251,7 +284,7 @@ const eslintPluginPrettier = {
251
284
252
285
for ( const difference of differences ) {
253
286
reportDifference (
254
- /** @type {Rule.RuleContext } */ ( context ) ,
287
+ /** @type {Rule.RuleContext } */ ( context ) ,
255
288
difference ,
256
289
) ;
257
290
}
0 commit comments