• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { JSONSchema4 } from '../json-schema';
2import { ParserServices, TSESTree } from '../ts-estree';
3import { AST } from './AST';
4import { Linter } from './Linter';
5import { Scope } from './Scope';
6import { SourceCode } from './SourceCode';
7
8interface RuleMetaDataDocs {
9  /**
10   * The general category the rule falls within
11   */
12  category:
13    | 'Best Practices'
14    | 'Stylistic Issues'
15    | 'Variables'
16    | 'Possible Errors';
17  /**
18   * Concise description of the rule
19   */
20  description: string;
21  /**
22   * The recommendation level for the rule.
23   * Used by the build tools to generate the recommended config.
24   * Set to false to not include it as a recommendation
25   */
26  recommended: 'error' | 'warn' | false;
27  /**
28   * The URL of the rule's docs
29   */
30  url: string;
31  /**
32   * Specifies whether the rule can return suggestions.
33   */
34  suggestion?: boolean;
35  /**
36   * Does the rule require us to create a full TypeScript Program in order for it
37   * to type-check code. This is only used for documentation purposes.
38   */
39  requiresTypeChecking?: boolean;
40  /**
41   * Does the rule extend (or is it based off of) an ESLint code rule?
42   * Alternately accepts the name of the base rule, in case the rule has been renamed.
43   * This is only used for documentation purposes.
44   */
45  extendsBaseRule?: boolean | string;
46}
47interface RuleMetaData<TMessageIds extends string> {
48  /**
49   * True if the rule is deprecated, false otherwise
50   */
51  deprecated?: boolean;
52  /**
53   * Documentation for the rule, unnecessary for custom rules/plugins
54   */
55  docs?: RuleMetaDataDocs;
56  /**
57   * The fixer category. Omit if there is no fixer
58   */
59  fixable?: 'code' | 'whitespace';
60  /**
61   * A map of messages which the rule can report.
62   * The key is the messageId, and the string is the parameterised error string.
63   * See: https://eslint.org/docs/developer-guide/working-with-rules#messageids
64   */
65  messages: Record<TMessageIds, string>;
66  /**
67   * The type of rule.
68   * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve.
69   * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn’t changed.
70   * - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren’t specified in the AST.
71   */
72  type: 'suggestion' | 'problem' | 'layout';
73  /**
74   * The name of the rule this rule was replaced by, if it was deprecated.
75   */
76  replacedBy?: string[];
77  /**
78   * The options schema. Supply an empty array if there are no options.
79   */
80  schema: JSONSchema4 | JSONSchema4[];
81}
82
83interface RuleFix {
84  range: AST.Range;
85  text: string;
86}
87
88interface RuleFixer {
89  insertTextAfter(
90    nodeOrToken: TSESTree.Node | TSESTree.Token,
91    text: string,
92  ): RuleFix;
93
94  insertTextAfterRange(range: AST.Range, text: string): RuleFix;
95
96  insertTextBefore(
97    nodeOrToken: TSESTree.Node | TSESTree.Token,
98    text: string,
99  ): RuleFix;
100
101  insertTextBeforeRange(range: AST.Range, text: string): RuleFix;
102
103  remove(nodeOrToken: TSESTree.Node | TSESTree.Token): RuleFix;
104
105  removeRange(range: AST.Range): RuleFix;
106
107  replaceText(
108    nodeOrToken: TSESTree.Node | TSESTree.Token,
109    text: string,
110  ): RuleFix;
111
112  replaceTextRange(range: AST.Range, text: string): RuleFix;
113}
114
115type ReportFixFunction = (
116  fixer: RuleFixer,
117) => null | RuleFix | RuleFix[] | IterableIterator<RuleFix>;
118type ReportSuggestionArray<TMessageIds extends string> = ReportDescriptorBase<
119  TMessageIds
120>[];
121
122interface ReportDescriptorBase<TMessageIds extends string> {
123  /**
124   * The parameters for the message string associated with `messageId`.
125   */
126  readonly data?: Readonly<Record<string, unknown>>;
127  /**
128   * The fixer function.
129   */
130  readonly fix?: ReportFixFunction | null;
131  /**
132   * The messageId which is being reported.
133   */
134  readonly messageId: TMessageIds;
135
136  // we disallow this because it's much better to use messageIds for reusable errors that are easily testable
137  // readonly desc?: string;
138}
139interface ReportDescriptorWithSuggestion<TMessageIds extends string>
140  extends ReportDescriptorBase<TMessageIds> {
141  /**
142   * 6.7's Suggestions API
143   */
144  readonly suggest?: Readonly<ReportSuggestionArray<TMessageIds>> | null;
145}
146
147interface ReportDescriptorNodeOptionalLoc {
148  /**
149   * The Node or AST Token which the report is being attached to
150   */
151  readonly node: TSESTree.Node | TSESTree.Comment | TSESTree.Token;
152  /**
153   * An override of the location of the report
154   */
155  readonly loc?:
156    | Readonly<TSESTree.SourceLocation>
157    | Readonly<TSESTree.LineAndColumnData>;
158}
159interface ReportDescriptorLocOnly {
160  /**
161   * An override of the location of the report
162   */
163  loc: Readonly<TSESTree.SourceLocation> | Readonly<TSESTree.LineAndColumnData>;
164}
165type ReportDescriptor<
166  TMessageIds extends string
167> = ReportDescriptorWithSuggestion<TMessageIds> &
168  (ReportDescriptorNodeOptionalLoc | ReportDescriptorLocOnly);
169
170interface RuleContext<
171  TMessageIds extends string,
172  TOptions extends readonly unknown[]
173> {
174  /**
175   * The rule ID.
176   */
177  id: string;
178  /**
179   * An array of the configured options for this rule.
180   * This array does not include the rule severity.
181   */
182  options: TOptions;
183  /**
184   * The name of the parser from configuration.
185   */
186  parserPath: string;
187  /**
188   * The parser options configured for this run
189   */
190  parserOptions: Linter.ParserOptions;
191  /**
192   * An object containing parser-provided services for rules
193   */
194  parserServices?: ParserServices;
195  /**
196   * The shared settings from configuration.
197   * We do not have any shared settings in this plugin.
198   */
199  settings: Record<string, unknown>;
200
201  /**
202   * Returns an array of the ancestors of the currently-traversed node, starting at
203   * the root of the AST and continuing through the direct parent of the current node.
204   * This array does not include the currently-traversed node itself.
205   */
206  getAncestors(): TSESTree.Node[];
207
208  /**
209   * Returns a list of variables declared by the given node.
210   * This information can be used to track references to variables.
211   */
212  getDeclaredVariables(node: TSESTree.Node): Scope.Variable[];
213
214  /**
215   * Returns the filename associated with the source.
216   */
217  getFilename(): string;
218
219  /**
220   * Returns the scope of the currently-traversed node.
221   * This information can be used track references to variables.
222   */
223  getScope(): Scope.Scope;
224
225  /**
226   * Returns a SourceCode object that you can use to work with the source that
227   * was passed to ESLint.
228   */
229  getSourceCode(): Readonly<SourceCode>;
230
231  /**
232   * Marks a variable with the given name in the current scope as used.
233   * This affects the no-unused-vars rule.
234   */
235  markVariableAsUsed(name: string): boolean;
236
237  /**
238   * Reports a problem in the code.
239   */
240  report(descriptor: ReportDescriptor<TMessageIds>): void;
241}
242
243// This isn't the correct signature, but it makes it easier to do custom unions within reusable listeners
244// never will break someone's code unless they specifically type the function argument
245type RuleFunction<T extends TSESTree.BaseNode = never> = (node: T) => void;
246
247interface RuleListener {
248  [nodeSelector: string]: RuleFunction | undefined;
249  ArrayExpression?: RuleFunction<TSESTree.ArrayExpression>;
250  ArrayPattern?: RuleFunction<TSESTree.ArrayPattern>;
251  ArrowFunctionExpression?: RuleFunction<TSESTree.ArrowFunctionExpression>;
252  AssignmentPattern?: RuleFunction<TSESTree.AssignmentPattern>;
253  AssignmentExpression?: RuleFunction<TSESTree.AssignmentExpression>;
254  AwaitExpression?: RuleFunction<TSESTree.AwaitExpression>;
255  BigIntLiteral?: RuleFunction<TSESTree.BigIntLiteral>;
256  BinaryExpression?: RuleFunction<TSESTree.BinaryExpression>;
257  BlockStatement?: RuleFunction<TSESTree.BlockStatement>;
258  BreakStatement?: RuleFunction<TSESTree.BreakStatement>;
259  CallExpression?: RuleFunction<TSESTree.CallExpression>;
260  CatchClause?: RuleFunction<TSESTree.CatchClause>;
261  ChainExpression?: RuleFunction<TSESTree.ChainExpression>;
262  ClassBody?: RuleFunction<TSESTree.ClassBody>;
263  ClassDeclaration?: RuleFunction<TSESTree.ClassDeclaration>;
264  ClassExpression?: RuleFunction<TSESTree.ClassExpression>;
265  ClassProperty?: RuleFunction<TSESTree.ClassProperty>;
266  Comment?: RuleFunction<TSESTree.Comment>;
267  ConditionalExpression?: RuleFunction<TSESTree.ConditionalExpression>;
268  ContinueStatement?: RuleFunction<TSESTree.ContinueStatement>;
269  DebuggerStatement?: RuleFunction<TSESTree.DebuggerStatement>;
270  Decorator?: RuleFunction<TSESTree.Decorator>;
271  DoWhileStatement?: RuleFunction<TSESTree.DoWhileStatement>;
272  EmptyStatement?: RuleFunction<TSESTree.EmptyStatement>;
273  ExportAllDeclaration?: RuleFunction<TSESTree.ExportAllDeclaration>;
274  ExportDefaultDeclaration?: RuleFunction<TSESTree.ExportDefaultDeclaration>;
275  ExportNamedDeclaration?: RuleFunction<TSESTree.ExportNamedDeclaration>;
276  ExportSpecifier?: RuleFunction<TSESTree.ExportSpecifier>;
277  ExpressionStatement?: RuleFunction<TSESTree.ExpressionStatement>;
278  ForInStatement?: RuleFunction<TSESTree.ForInStatement>;
279  ForOfStatement?: RuleFunction<TSESTree.ForOfStatement>;
280  ForStatement?: RuleFunction<TSESTree.ForStatement>;
281  FunctionDeclaration?: RuleFunction<TSESTree.FunctionDeclaration>;
282  FunctionExpression?: RuleFunction<TSESTree.FunctionExpression>;
283  Identifier?: RuleFunction<TSESTree.Identifier>;
284  IfStatement?: RuleFunction<TSESTree.IfStatement>;
285  ImportDeclaration?: RuleFunction<TSESTree.ImportDeclaration>;
286  ImportDefaultSpecifier?: RuleFunction<TSESTree.ImportDefaultSpecifier>;
287  ImportExpression?: RuleFunction<TSESTree.ImportExpression>;
288  ImportNamespaceSpecifier?: RuleFunction<TSESTree.ImportNamespaceSpecifier>;
289  ImportSpecifier?: RuleFunction<TSESTree.ImportSpecifier>;
290  JSXAttribute?: RuleFunction<TSESTree.JSXAttribute>;
291  JSXClosingElement?: RuleFunction<TSESTree.JSXClosingElement>;
292  JSXClosingFragment?: RuleFunction<TSESTree.JSXClosingFragment>;
293  JSXElement?: RuleFunction<TSESTree.JSXElement>;
294  JSXEmptyExpression?: RuleFunction<TSESTree.JSXEmptyExpression>;
295  JSXExpressionContainer?: RuleFunction<TSESTree.JSXExpressionContainer>;
296  JSXFragment?: RuleFunction<TSESTree.JSXFragment>;
297  JSXIdentifier?: RuleFunction<TSESTree.JSXIdentifier>;
298  JSXMemberExpression?: RuleFunction<TSESTree.JSXMemberExpression>;
299  JSXOpeningElement?: RuleFunction<TSESTree.JSXOpeningElement>;
300  JSXOpeningFragment?: RuleFunction<TSESTree.JSXOpeningFragment>;
301  JSXSpreadAttribute?: RuleFunction<TSESTree.JSXSpreadAttribute>;
302  JSXSpreadChild?: RuleFunction<TSESTree.JSXSpreadChild>;
303  JSXText?: RuleFunction<TSESTree.JSXText>;
304  LabeledStatement?: RuleFunction<TSESTree.LabeledStatement>;
305  Literal?: RuleFunction<TSESTree.Literal>;
306  LogicalExpression?: RuleFunction<TSESTree.LogicalExpression>;
307  MemberExpression?: RuleFunction<TSESTree.MemberExpression>;
308  MetaProperty?: RuleFunction<TSESTree.MetaProperty>;
309  MethodDefinition?: RuleFunction<TSESTree.MethodDefinition>;
310  NewExpression?: RuleFunction<TSESTree.NewExpression>;
311  ObjectExpression?: RuleFunction<TSESTree.ObjectExpression>;
312  ObjectPattern?: RuleFunction<TSESTree.ObjectPattern>;
313  Program?: RuleFunction<TSESTree.Program>;
314  Property?: RuleFunction<TSESTree.Property>;
315  RestElement?: RuleFunction<TSESTree.RestElement>;
316  ReturnStatement?: RuleFunction<TSESTree.ReturnStatement>;
317  SequenceExpression?: RuleFunction<TSESTree.SequenceExpression>;
318  SpreadElement?: RuleFunction<TSESTree.SpreadElement>;
319  Super?: RuleFunction<TSESTree.Super>;
320  SwitchCase?: RuleFunction<TSESTree.SwitchCase>;
321  SwitchStatement?: RuleFunction<TSESTree.SwitchStatement>;
322  TaggedTemplateExpression?: RuleFunction<TSESTree.TaggedTemplateExpression>;
323  TemplateElement?: RuleFunction<TSESTree.TemplateElement>;
324  TemplateLiteral?: RuleFunction<TSESTree.TemplateLiteral>;
325  ThisExpression?: RuleFunction<TSESTree.ThisExpression>;
326  ThrowStatement?: RuleFunction<TSESTree.ThrowStatement>;
327  Token?: RuleFunction<TSESTree.Token>;
328  TryStatement?: RuleFunction<TSESTree.TryStatement>;
329  TSAbstractClassProperty?: RuleFunction<TSESTree.TSAbstractClassProperty>;
330  TSAbstractKeyword?: RuleFunction<TSESTree.TSAbstractKeyword>;
331  TSAbstractMethodDefinition?: RuleFunction<
332    TSESTree.TSAbstractMethodDefinition
333  >;
334  TSAnyKeyword?: RuleFunction<TSESTree.TSAnyKeyword>;
335  TSArrayType?: RuleFunction<TSESTree.TSArrayType>;
336  TSAsExpression?: RuleFunction<TSESTree.TSAsExpression>;
337  TSAsyncKeyword?: RuleFunction<TSESTree.TSAsyncKeyword>;
338  TSBigIntKeyword?: RuleFunction<TSESTree.TSBigIntKeyword>;
339  TSBooleanKeyword?: RuleFunction<TSESTree.TSBooleanKeyword>;
340  TSCallSignatureDeclaration?: RuleFunction<
341    TSESTree.TSCallSignatureDeclaration
342  >;
343  TSClassImplements?: RuleFunction<TSESTree.TSClassImplements>;
344  TSConditionalType?: RuleFunction<TSESTree.TSConditionalType>;
345  TSConstructorType?: RuleFunction<TSESTree.TSConstructorType>;
346  TSConstructSignatureDeclaration?: RuleFunction<
347    TSESTree.TSConstructSignatureDeclaration
348  >;
349  TSDeclareKeyword?: RuleFunction<TSESTree.TSDeclareKeyword>;
350  TSDeclareFunction?: RuleFunction<TSESTree.TSDeclareFunction>;
351  TSEmptyBodyFunctionExpression?: RuleFunction<
352    TSESTree.TSEmptyBodyFunctionExpression
353  >;
354  TSEnumDeclaration?: RuleFunction<TSESTree.TSEnumDeclaration>;
355  TSEnumMember?: RuleFunction<TSESTree.TSEnumMember>;
356  TSExportAssignment?: RuleFunction<TSESTree.TSExportAssignment>;
357  TSExportKeyword?: RuleFunction<TSESTree.TSExportKeyword>;
358  TSExternalModuleReference?: RuleFunction<TSESTree.TSExternalModuleReference>;
359  TSFunctionType?: RuleFunction<TSESTree.TSFunctionType>;
360  TSImportEqualsDeclaration?: RuleFunction<TSESTree.TSImportEqualsDeclaration>;
361  TSImportType?: RuleFunction<TSESTree.TSImportType>;
362  TSIndexedAccessType?: RuleFunction<TSESTree.TSIndexedAccessType>;
363  TSIndexSignature?: RuleFunction<TSESTree.TSIndexSignature>;
364  TSInferType?: RuleFunction<TSESTree.TSInferType>;
365  TSInterfaceBody?: RuleFunction<TSESTree.TSInterfaceBody>;
366  TSInterfaceDeclaration?: RuleFunction<TSESTree.TSInterfaceDeclaration>;
367  TSInterfaceHeritage?: RuleFunction<TSESTree.TSInterfaceHeritage>;
368  TSIntersectionType?: RuleFunction<TSESTree.TSIntersectionType>;
369  TSLiteralType?: RuleFunction<TSESTree.TSLiteralType>;
370  TSMappedType?: RuleFunction<TSESTree.TSMappedType>;
371  TSMethodSignature?: RuleFunction<TSESTree.TSMethodSignature>;
372  TSModuleBlock?: RuleFunction<TSESTree.TSModuleBlock>;
373  TSModuleDeclaration?: RuleFunction<TSESTree.TSModuleDeclaration>;
374  TSNamespaceExportDeclaration?: RuleFunction<
375    TSESTree.TSNamespaceExportDeclaration
376  >;
377  TSNeverKeyword?: RuleFunction<TSESTree.TSNeverKeyword>;
378  TSNonNullExpression?: RuleFunction<TSESTree.TSNonNullExpression>;
379  TSNullKeyword?: RuleFunction<TSESTree.TSNullKeyword>;
380  TSNumberKeyword?: RuleFunction<TSESTree.TSNumberKeyword>;
381  TSObjectKeyword?: RuleFunction<TSESTree.TSObjectKeyword>;
382  TSOptionalType?: RuleFunction<TSESTree.TSOptionalType>;
383  TSParameterProperty?: RuleFunction<TSESTree.TSParameterProperty>;
384  TSParenthesizedType?: RuleFunction<TSESTree.TSParenthesizedType>;
385  TSPrivateKeyword?: RuleFunction<TSESTree.TSPrivateKeyword>;
386  TSPropertySignature?: RuleFunction<TSESTree.TSPropertySignature>;
387  TSProtectedKeyword?: RuleFunction<TSESTree.TSProtectedKeyword>;
388  TSPublicKeyword?: RuleFunction<TSESTree.TSPublicKeyword>;
389  TSQualifiedName?: RuleFunction<TSESTree.TSQualifiedName>;
390  TSReadonlyKeyword?: RuleFunction<TSESTree.TSReadonlyKeyword>;
391  TSRestType?: RuleFunction<TSESTree.TSRestType>;
392  TSStaticKeyword?: RuleFunction<TSESTree.TSStaticKeyword>;
393  TSStringKeyword?: RuleFunction<TSESTree.TSStringKeyword>;
394  TSSymbolKeyword?: RuleFunction<TSESTree.TSSymbolKeyword>;
395  TSThisType?: RuleFunction<TSESTree.TSThisType>;
396  TSTupleType?: RuleFunction<TSESTree.TSTupleType>;
397  TSTypeAliasDeclaration?: RuleFunction<TSESTree.TSTypeAliasDeclaration>;
398  TSTypeAnnotation?: RuleFunction<TSESTree.TSTypeAnnotation>;
399  TSTypeAssertion?: RuleFunction<TSESTree.TSTypeAssertion>;
400  TSTypeLiteral?: RuleFunction<TSESTree.TSTypeLiteral>;
401  TSTypeOperator?: RuleFunction<TSESTree.TSTypeOperator>;
402  TSTypeParameter?: RuleFunction<TSESTree.TSTypeParameter>;
403  TSTypeParameterDeclaration?: RuleFunction<
404    TSESTree.TSTypeParameterDeclaration
405  >;
406  TSTypeParameterInstantiation?: RuleFunction<
407    TSESTree.TSTypeParameterInstantiation
408  >;
409  TSTypePredicate?: RuleFunction<TSESTree.TSTypePredicate>;
410  TSTypeQuery?: RuleFunction<TSESTree.TSTypeQuery>;
411  TSTypeReference?: RuleFunction<TSESTree.TSTypeReference>;
412  TSUndefinedKeyword?: RuleFunction<TSESTree.TSUndefinedKeyword>;
413  TSUnionType?: RuleFunction<TSESTree.TSUnionType>;
414  TSUnknownKeyword?: RuleFunction<TSESTree.TSUnknownKeyword>;
415  TSVoidKeyword?: RuleFunction<TSESTree.TSVoidKeyword>;
416  UnaryExpression?: RuleFunction<TSESTree.UnaryExpression>;
417  UpdateExpression?: RuleFunction<TSESTree.UpdateExpression>;
418  VariableDeclaration?: RuleFunction<TSESTree.VariableDeclaration>;
419  VariableDeclarator?: RuleFunction<TSESTree.VariableDeclarator>;
420  WhileStatement?: RuleFunction<TSESTree.WhileStatement>;
421  WithStatement?: RuleFunction<TSESTree.WithStatement>;
422  YieldExpression?: RuleFunction<TSESTree.YieldExpression>;
423}
424
425interface RuleModule<
426  TMessageIds extends string,
427  TOptions extends readonly unknown[],
428  // for extending base rules
429  TRuleListener extends RuleListener = RuleListener
430> {
431  /**
432   * Metadata about the rule
433   */
434  meta: RuleMetaData<TMessageIds>;
435
436  /**
437   * Function which returns an object with methods that ESLint calls to “visit”
438   * nodes while traversing the abstract syntax tree.
439   */
440  create(context: Readonly<RuleContext<TMessageIds, TOptions>>): TRuleListener;
441}
442
443type RuleCreateFunction = (
444  context: Readonly<RuleContext<never, unknown[]>>,
445) => RuleListener;
446
447export {
448  ReportDescriptor,
449  ReportFixFunction,
450  ReportSuggestionArray,
451  RuleContext,
452  RuleCreateFunction,
453  RuleFix,
454  RuleFixer,
455  RuleFunction,
456  RuleListener,
457  RuleMetaData,
458  RuleMetaDataDocs,
459  RuleModule,
460};
461