Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion .github/workflows/types-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,40 @@ jobs:
working-directory: eslint-js
run: npm run build:types --workspace eslint-visitor-keys

eslint_json:
name: Types (@eslint/json)
runs-on: ubuntu-latest
steps:
- name: Checkout eslint
uses: actions/checkout@v4
with:
path: eslint

- name: Checkout @eslint/json
uses: actions/checkout@v4
with:
repository: eslint/json
path: json

- uses: actions/setup-node@v4
with:
node-version: "lts/*"

- name: Install Packages (eslint)
working-directory: eslint
run: npm install

- name: Install Packages (neostandard)
working-directory: json
run: |
npm install
npm run build
npm install ../eslint

- name: Run TSC
working-directory: json
run: npm run test:types

are-the-types-wrong:
name: Are the types wrong?
runs-on: ubuntu-latest
Expand Down Expand Up @@ -176,4 +210,4 @@ jobs:

- name: Check validity of type definitions
working-directory: ${{ matrix.package.directory }}
run: npm run lint:types
run: npm run lint:types
124 changes: 64 additions & 60 deletions lib/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,41 @@
*/

import * as ESTree from "estree";
import { Language } from "@eslint/core";
import type {
RuleVisitor,
TextSourceCode,
Language,
SourceRange,
TraversalStep,
LanguageOptions as GenericLanguageOptions,
RuleDefinition,
RuleContext as CoreRuleContext
} from "@eslint/core";
import { JSONSchema4 } from "json-schema";
import { LegacyESLint } from "./use-at-your-own-risk.js";

/*
* Need to extend the `RuleContext` interface to include the
* deprecated methods that have not yet been removed.
* TODO: Remove in v10.0.0.
*/
declare module "@eslint/core" {
interface RuleContext {

/** @deprecated Use `sourceCode.getAncestors()` instead */
getAncestors(): ESTree.Node[];

/** @deprecated Use `sourceCode.getDeclaredVariables()` instead */
getDeclaredVariables(node: ESTree.Node): Scope.Variable[];

/** @deprecated Use `sourceCode.getScope()` instead */
getScope(): Scope.Scope;

/** @deprecated Use `sourceCode.markVariableAsUsed()` instead */
markVariableAsUsed(name: string): boolean;
}
}

export namespace AST {
type TokenType =
| "Boolean"
Expand Down Expand Up @@ -149,7 +180,12 @@ export namespace Scope {

// #region SourceCode

export class SourceCode {
export class SourceCode implements TextSourceCode<{
LangOptions: Linter.LanguageOptions;
RootNode: AST.Program;
SyntaxElementWithLoc: AST.Token | ESTree.Node;
ConfigNode: ESTree.Comment;
}> {
text: string;
ast: AST.Program;
lines: string[];
Expand All @@ -163,6 +199,9 @@ export class SourceCode {

static splitLines(text: string): string[];

getLoc(syntaxElement: AST.Token | ESTree.Node): ESTree.SourceLocation;
getRange(syntaxElement: AST.Token | ESTree.Node): SourceRange;

getText(node?: ESTree.Node, beforeCount?: number, afterCount?: number): string;

getLines(): string[];
Expand Down Expand Up @@ -238,6 +277,8 @@ export class SourceCode {
): boolean;

markVariableAsUsed(name: string, refNode?: ESTree.Node): boolean;

traverse(): Iterable<TraversalStep>;
}

export namespace SourceCode {
Expand Down Expand Up @@ -507,21 +548,25 @@ export namespace SourceCode {
// #endregion

export namespace Rule {
interface RuleModule {
create(context: RuleContext): RuleListener;
meta?: RuleMetaData | undefined;
}

type RuleModule = RuleDefinition<{
LangOptions: Linter.LanguageOptions,
Code: SourceCode,
RuleOptions: any[],
Visitor: NodeListener,
Node: ESTree.Node,
MessageIds: string,
ExtRuleDocs: {}
}>;

type NodeTypes = ESTree.Node["type"];
interface NodeListener {
interface NodeListener extends RuleVisitor {
ArrayExpression?: ((node: ESTree.ArrayExpression & NodeParentExtension) => void) | undefined;
"ArrayExpression:exit"?: ((node: ESTree.ArrayExpression & NodeParentExtension) => void) | undefined;
ArrayPattern?: ((node: ESTree.ArrayPattern & NodeParentExtension) => void) | undefined;
"ArrayPattern:exit"?: ((node: ESTree.ArrayPattern & NodeParentExtension) => void) | undefined;
ArrowFunctionExpression?: ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void) | undefined;
"ArrowFunctionExpression:exit"?:
| ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void)
| undefined;
"ArrowFunctionExpression:exit"?: ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void) | undefined;
AssignmentExpression?: ((node: ESTree.AssignmentExpression & NodeParentExtension) => void) | undefined;
"AssignmentExpression:exit"?: ((node: ESTree.AssignmentExpression & NodeParentExtension) => void) | undefined;
AssignmentPattern?: ((node: ESTree.AssignmentPattern & NodeParentExtension) => void) | undefined;
Expand Down Expand Up @@ -559,13 +604,9 @@ export namespace Rule {
ExportAllDeclaration?: ((node: ESTree.ExportAllDeclaration & NodeParentExtension) => void) | undefined;
"ExportAllDeclaration:exit"?: ((node: ESTree.ExportAllDeclaration & NodeParentExtension) => void) | undefined;
ExportDefaultDeclaration?: ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void) | undefined;
"ExportDefaultDeclaration:exit"?:
| ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void)
| undefined;
"ExportDefaultDeclaration:exit"?: ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void) | undefined;
ExportNamedDeclaration?: ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void) | undefined;
"ExportNamedDeclaration:exit"?:
| ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void)
| undefined;
"ExportNamedDeclaration:exit"?: ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void) | undefined;
ExportSpecifier?: ((node: ESTree.ExportSpecifier & NodeParentExtension) => void) | undefined;
"ExportSpecifier:exit"?: ((node: ESTree.ExportSpecifier & NodeParentExtension) => void) | undefined;
ExpressionStatement?: ((node: ESTree.ExpressionStatement & NodeParentExtension) => void) | undefined;
Expand All @@ -587,15 +628,11 @@ export namespace Rule {
ImportDeclaration?: ((node: ESTree.ImportDeclaration & NodeParentExtension) => void) | undefined;
"ImportDeclaration:exit"?: ((node: ESTree.ImportDeclaration & NodeParentExtension) => void) | undefined;
ImportDefaultSpecifier?: ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void) | undefined;
"ImportDefaultSpecifier:exit"?:
| ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void)
| undefined;
"ImportDefaultSpecifier:exit"?: ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void) | undefined;
ImportExpression?: ((node: ESTree.ImportExpression & NodeParentExtension) => void) | undefined;
"ImportExpression:exit"?: ((node: ESTree.ImportExpression & NodeParentExtension) => void) | undefined;
ImportNamespaceSpecifier?: ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void) | undefined;
"ImportNamespaceSpecifier:exit"?:
| ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void)
| undefined;
"ImportNamespaceSpecifier:exit"?: ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void) | undefined;
ImportSpecifier?: ((node: ESTree.ImportSpecifier & NodeParentExtension) => void) | undefined;
"ImportSpecifier:exit"?: ((node: ESTree.ImportSpecifier & NodeParentExtension) => void) | undefined;
LabeledStatement?: ((node: ESTree.LabeledStatement & NodeParentExtension) => void) | undefined;
Expand Down Expand Up @@ -641,9 +678,7 @@ export namespace Rule {
SwitchStatement?: ((node: ESTree.SwitchStatement & NodeParentExtension) => void) | undefined;
"SwitchStatement:exit"?: ((node: ESTree.SwitchStatement & NodeParentExtension) => void) | undefined;
TaggedTemplateExpression?: ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void) | undefined;
"TaggedTemplateExpression:exit"?:
| ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void)
| undefined;
"TaggedTemplateExpression:exit"?: ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void) | undefined;
TemplateElement?: ((node: ESTree.TemplateElement & NodeParentExtension) => void) | undefined;
"TemplateElement:exit"?: ((node: ESTree.TemplateElement & NodeParentExtension) => void) | undefined;
TemplateLiteral?: ((node: ESTree.TemplateLiteral & NodeParentExtension) => void) | undefined;
Expand Down Expand Up @@ -765,39 +800,8 @@ export namespace Rule {
hasSuggestions?: boolean | undefined;
}

interface RuleContext {
id: string;
options: any[];
settings: { [name: string]: any };
parserPath: string | undefined;
languageOptions: Linter.LanguageOptions;
parserOptions: Linter.ParserOptions;
cwd: string;
filename: string;
physicalFilename: string;
sourceCode: SourceCode;

getAncestors(): ESTree.Node[];

getDeclaredVariables(node: ESTree.Node): Scope.Variable[];

/** @deprecated Use property `filename` directly instead */
getFilename(): string;

/** @deprecated Use property `physicalFilename` directly instead */
getPhysicalFilename(): string;

/** @deprecated Use property `cwd` directly instead */
getCwd(): string;

getScope(): Scope.Scope;

/** @deprecated Use property `sourceCode` directly instead */
getSourceCode(): SourceCode;

markVariableAsUsed(name: string): boolean;

report(descriptor: ReportDescriptor): void;
interface RuleContext extends CoreRuleContext {
// report(descriptor: ReportDescriptor): void;
}

type ReportFixer = (fixer: RuleFixer) => null | Fix | IterableIterator<Fix> | Fix[];
Expand Down Expand Up @@ -1325,7 +1329,7 @@ export namespace Linter {
[name: string]: GlobalConf;
}

interface LanguageOptions {
interface LanguageOptions extends GenericLanguageOptions {
/**
* The version of ECMAScript to support. May be any year (i.e., 2022) or
* version (i.e., 5). Set to "latest" for the most recent supported version.
Expand Down Expand Up @@ -1469,7 +1473,7 @@ export namespace ESLint {
environments?: Record<string, Environment> | undefined;
languages?: Record<string, Language> | undefined;
processors?: Record<string, Linter.Processor> | undefined;
rules?: Record<string, Rule.RuleModule> | undefined;
rules?: Record<string, RuleDefinition> | undefined;
}

type FixType = "directive" | "problem" | "suggestion" | "layout";
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.10.0",
"@eslint/core": "^0.11.0",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "9.19.0",
"@eslint/plugin-kit": "^0.2.5",
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/types/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ rule = {
context.markVariableAsUsed("foo");

context.report({ message: "foo", node: AST });
context.report({ message: "foo", loc: { line: 0, column: 0 } });
context.report({ message: "foo", loc: { start: {line: 0, column: 0}, end: { line: 1, column: 1 } } });
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appeared to be an error in the current types, as loc should have start and end properties.

context.report({ message: "foo", node: AST, data: { foo: "bar" } });
context.report({ message: "foo", node: AST, fix: () => null });
context.report({ message: "foo", node: AST, fix: ruleFixer => ruleFixer.replaceText(AST, "foo") });
Expand Down