mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
codex/parser-grouped-expression-allocation
154 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
baf022d74d |
refactor(ast)!: remove old AstBuilder methods (#24563)
Closes the migration tracked in #23043. The new builder API (methods on the AST types themselves) has been in place for a while, all Oxc crates are migrated, and every crate which uses `AstBuilder` already enables `disable_old_builder` in its tests. The module docs said "after a few weeks, we will remove `AstBuilder`'s own methods entirely" — this does that. ## What's removed - `crates/oxc_ast/src/generated/ast_builder.rs` and `builder/methods.rs` — `AstBuilder`'s own node and primitive constructors. - `AstBuilderGenerator`, which produced the former. - The `disable_old_builder` Cargo feature, plus the dev-dependency hacks it required across 33 manifests. Eight crates depended on `oxc_ast` *purely* to turn the feature on; those deps and their `cargo-shear` ignore entries are gone too. ## One thing worth reviewing `AstBuilderGenerator` owned the `#[builder(default)]` / `#[builder(skip)]` attr registration that `BuilderMethodsGenerator` only *reads* — its doc comment said as much. Deleting it naively would have silently dropped `skip`/`default` handling for the 12 AST types using those attrs, so `attrs()` and `parse_attr()` move to `BuilderMethodsGenerator`. The evidence this was faithful: after regenerating, `builder_methods.rs` and every other generated file are **byte-identical**. The only generated change in the diff is the deletion. ## Breaking changes - `AstBuilder`'s own methods are gone. Use the AST type methods: `Statement::new_expression_statement(span, expr, &builder)` instead of `builder.statement_expression(span, expr)`. - `AstBuilder` is no longer `Copy`/`Clone`, and its `allocator` field is private — use the `allocator` method from `GetAllocator`. - `AstBuilder` and `NONE` are no longer re-exported from the crate root; import them from `oxc_ast::builder`. (The `disable_old_builder` feature already gated these off, so nothing in-tree used the root path.) - The `disable_old_builder` feature no longer exists — remove it from any manifest that sets it. A migration note covering all of the above is in `crates/oxc_ast/src/builder/mod.rs`. --- Implemented with AI assistance (Claude Code); design, review, and verification driven by the author per the repo AI-usage policy. |
||
|
|
161d2f1b16 |
refactor(linter): migrate JS-only visitors to VisitJs (#24530)
Migrate 33 JS-only `Visit` implementors in `oxc_linter` (plus the 3 in `tasks/rulegen`) to `VisitJs` (#24499). Part of #24317; transformer/minifier half in #24532. Behavior is unchanged — all 1169 rule tests pass with identical snapshots. Together with #24532: `oxlint` −129.4 KiB (−0.94%) stripped, `oxc_transform` napi −16.2 KiB (−0.46%). ## Why each visitor can switch A visitor is safe on `VisitJs` when its hooks cannot observe anything inside the pruned type grammar. The three ways that holds here: the hooked node kinds are value-space-only (`return`, `throw`, `await`, calls, real functions — none exist inside `TSType`), the visitor already skipped type space via hand-written `visit_ts_*` stubs, or its type inspection is by direct field access rather than walking. | Visitor | File (`crates/oxc_linter/src/`) | Why equivalent | |---|---|---| | `ReturnStatementFinder` | `rules/eslint/array_callback_return/return_checker.rs` | Hooks only `visit_return_statement`; `return` cannot occur in type grammar. | | `ComplexityVisitor` | `rules/eslint/complexity.rs` | All scoring hooks are value-space; the one explicit walk into property type annotations is deleted — valid type grammar contains no complexity-scoring constructs (no `?:`/`&&`/`?.`/default params). | | `StatementCounter` | `rules/eslint/max_statements.rs` | Counts statements via function/class/static-block body hooks; type declarations contain no statements. | | `YieldBeforeLoopExitFinder` | `rules/eslint/no_constant_condition.rs` | Hooks only `visit_yield_expression`; `yield` cannot occur in type grammar. | | `LoopFunctionCollector` | `rules/eslint/no_loop_func.rs` | Hooks `visit_function`/`visit_arrow_function_expression`; those nodes never appear in type grammar (`TSFunctionType` is a distinct node). | | `ReturnStatementFinder` | `rules/eslint/no_promise_executor_return.rs` | `return`-statement hook only. | | `ThrowFinder` | `rules/eslint/preserve_caught_error.rs` | Hooks only `visit_throw_statement`; `throw` cannot occur in type grammar. | | `AwaitFinder` | `rules/eslint/require_await.rs` | Hooks `visit_await_expression`/`visit_for_of_statement`; `await`/`for await` are runtime-only. | | `RequireCallScanner` | `rules/import/newline_after_import.rs` | Matches `require(...)` calls; calls cannot occur in valid type grammar. | | `ResolveFinder` | `rules/promise/no_multiple_resolved.rs` | `leave_node` records only value-space kinds (new/import/yield/member); its `visit_call_expression` doesn't descend. | | `ReturnWrapFinder` | `rules/promise/no_return_wrap.rs` | `return`-statement hook only. | | `AssertionVisitor` | `rules/shared/jest_vitest/expect_expect.rs` | Call/if/block hooks hunting assertion calls; none can fire in type space. | | `HookScanner`, `BodyScanner` | `rules/shared/jest_vitest/prefer_expect_assertions.rs` | Call + loop/function-body hooks; `expect.hasAssertions()` calls and loops cannot occur in types. | | `CallLikeExpressionVisitor` | `rules/shared/jest_vitest/prefer_mock_return_shorthand.rs` | call/new/tagged-template/import hooks — value-space only. (Sibling `IdentifierCollectorVisitor` stays on `Visit`: it collects identifiers, which do leak through type space.) | | `PromiseExpectScanner` | `rules/shared/jest_vitest/valid_expect_in_promise.rs` | call/await hooks. (Sibling `IdentifierFinder` stays on `Visit` for the same reason as above.) | | `AwaitDetector`, `ExposeAfterAwaitVisitor` | `rules/vue/no_expose_after_await.rs` | await/call hooks. | | `LifecycleAfterAwaitVisitor` | `rules/vue/no_lifecycle_after_await.rs` | await/call hooks. | | `WatchAfterAwaitVisitor` | `rules/vue/no_watch_after_await.rs` | await/expression-statement hooks. | | `ReturnFinder` | `rules/vue/require_direct_export.rs` | `return`-statement hook only. | | `ReturnVisitor` | `rules/vue/return_in_emits_validator.rs` | function/arrow depth tracking + return hook; none fire for `TSFunctionType`. | | `DefineOptionsChecker` | `rules/vue/valid_define_options.rs` | Matches `defineOptions()` calls; reads `type_arguments` by field access, not by walking. | | `LocalReferenceChecker` | `rules/vue/valid_define_options.rs` | Already skipped type space via a hand-written `visit_ts_type` stub ("`as X`/`typeof str` are statically resolvable") — `VisitJs` subsumes it; stub deleted. | | `ExhaustiveDepsVisitor` | `rules/react/exhaustive_deps.rs` | Already skipped type space via 4 noop `visit_ts_*` stubs (deleted). The `visit_ts_type_query` stub shows `typeof x` deps were deliberately not collected — `VisitJs` preserves exactly that. | | `ComponentFinder` | `rules/react/no_multi_comp.rs` | Component-defining hooks (class/function/call/object-property/assignment) are all value-space kinds. | | `MayThrowBeforeHook` | `rules/react/rules_of_hooks.rs` | `enter_node` treats only Call/New/Member kinds as may-throw; type annotations are erased at runtime and cannot throw. | | `ConstructorAssignmentCollector` | `rules/typescript/class_literal_property_style.rs` | Assignment-expression hook; assignments cannot occur in type grammar. | | `ReturnStatementChecker` | `rules/typescript/explicit_function_return_type.rs` | `return`-statement hook only. | | `ExplicitTypesChecker` | `rules/typescript/explicit_module_boundary_types.rs` | Inspects types by direct field access (`.return_type.is_none()`, `is_const_type_reference()`), never by walking; its 3 cast overrides survive on `VisitJs`. The deleted walk into `new` type args could only produce spurious "missing argument type" reports from function-typed type arguments. | | `AssignmentVisitor` | `rules/typescript/no_unnecessary_parameter_property_assignment.rs` | Assignment hook; RHS casts are unwrapped via `get_inner_expression`, not walker descent. | | `JsxFinder` | `utils/react.rs` | JSX/createElement hooks; JSX cannot occur in type grammar. All consumers pass value-space function bodies. | | `ThisExpressionFinder` | `utils/this_expression.rs` | The `this` type is `TSThisType`, which never fires `visit_this_expression`; the only leak path is a `typeof this.X` qualified name, invalid at the entry scopes its two consumers scan, and nested functions are already cut off by the `visit_function` stub. | | `TestCase`, `State`, `RuleConfig` | `tasks/rulegen/src/main.rs` | Extract value-space data (test `code` strings, schema object literals) via manual recursion/structural matching; `as`/`satisfies` wrappers are unwrapped with `get_inner_expression`, and `VisitJs` still walks those. | Left on `Visit` (results would change): `consistent_function_scoping`, `branches_sharing_code`, `prefer_arrow_callback`, `object_shorthand`, `class_methods_use_this`, the two jest identifier collectors above — their identifier/`this` hooks fire inside type space today (`typeof this`, type references) and that input feeds reports or autofixes. Also `no_loop_func`'s `NestedFunctionFinder`/`UnsafeReferenceFinder`, which share a `V: Visit<'a>` generic driver with one of them. --- 🤖 This PR was written with the assistance of Claude Code (Claude Fable 5). |
||
|
|
66e1a25c0e |
chore(all): fix clippy::manual_assert_eq (#24351)
|
||
|
|
87841eebfd |
chore(all): fix clippy::useless_borrows_in_formatting (#24347)
|
||
|
|
85a6853e0b |
fix(tasks): enable disable_old_builder Cargo feature for oxc_ast crate for all tasks (#23885)
Part of #23043. We don't enable `oxc_ast`'s `disable_old_builder` Cargo feature in any of our published crates, or crates that are depended on by published crates. Tasks are private to the repo, so enable this feature on them, to ensure no usage of legacy `AstBuilder` methods sneak in during the transition period before we delete these methods. |
||
|
|
e2aa77dd10 |
fix(rulegen): escape Rust keywords in config fields (#23794)
fixes #23634 When valid Rust identifiers are generated for rule configurations that match reserved keywords, we convert it to the`r#`... form |
||
|
|
d1f18cda21 |
refactor(all): import arena Box and Vec as ArenaBox / ArenaVec (#23747)
Pure refactor. Use `ArenaBox` and `ArenaVec` everywhere for the arena-allocated types from `oxc_allocator`, instead of plain `Box` and `Vec`. This disambiguates when `Vec` is `oxc_allocator::Vec` and when it's `std::vec::Vec`, making code clearer to follow. Previously it was easy to confuse the two, and such confusion led to UB in `Traverse` (fixed in #23745). Ditto other arena types - `ArenaHashMap`, `ArenaHashSet`, `ArenaStringBuilder`. The only exceptions are: 1. Inside `oxc_allocator` crate itself. 2. AST type definitions. 3. Generated code (migrated separately in #23749). |
||
|
|
777f02ae10 |
refactor(diagnostics)!: return a Diagnostics type instead of Vec<OxcDiagnostic> (#23217)
## Summary Introduces `oxc_diagnostics::Diagnostics` — a `Vec<OxcDiagnostic>` newtype that knows the difference between errors and warnings — and makes it the standard diagnostics return value across oxc. - **New type**: `Diagnostics` with `has_errors()`, `has_warnings()`, `errors()`, `warnings()`, plus `Vec`-like ergonomics (Deref, `IntoIterator`, `Extend`, `From`/`Into<Vec>`) so most call sites are unchanged. - **Return types**: `ParserReturn`, `SemanticBuilderReturn`, `IsolatedDeclarationsReturn`, the React Compiler `TransformResult`/`LintResult`, and `TransformerReturn` now expose `diagnostics: Diagnostics` instead of `errors: Vec<OxcDiagnostic>` (the React Compiler's separate `errors`/`warnings` are merged into one severity-tagged list). - **Behaviour**: a React Compiler **error** now stops the transform (no output), while **warnings** flow through and the transform continues. `compile()` aborts codegen only when `diagnostics.has_errors()` — warnings alone no longer abort (previously any diagnostic did). ## Breaking change Consumers reading `*.errors` on these return values must read `*.diagnostics`. React Compiler consumers that read `.errors`/`.warnings` separately should use `diagnostics.has_errors()` / `diagnostics.errors()` / `diagnostics.warnings()`. Parser/semantic/isolated-declarations fatality is otherwise unchanged. Builds on the React Compiler transform feature (#23201). 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
d09ccc9a7b |
chore(linter): Add info and short_description fields to declare_oxc_lint! macro. (#22511)
Simplified redo of #22295. Calling this a chore because I don't think it warrants mention in the changelog for now as this is just basic scaffolding changes, but we can mark it as a feature if preferred. AI Disclosure: generated with Claude Code, reviewed by me. The `short_description` field will be a one-sentence summary of the rule that can be used in documentation, and especially the rules list on the website. The idea would be to enable the rules list to include the short description as a subtitle under each rule, similar to this: <img width="1120" height="618" alt="image" src="https://github.com/user-attachments/assets/ff9e4d63-b61f-474e-9455-d3567c96d51c" /> The rule macros will now look like this: ```rs declare_oxc_lint!( /// Longer rule description here. MyRule, eslint, nursery, pending, config = MyRule, version = "next", info { short_description = "FIXME: One-sentence description of the rule.", }, ); ``` We could do `info = {` here instead of `info {`, up to the reviewers. I'll move `version` into the `info` field in a subsequent PR. I didn't do it here because I wanted to keep this simple and avoid problems of merge conflicts with the release tomorrow. The `info` field was suggested by camchenry to avoid continuing to bloat the size of the rule meta struct / rules enum file. In a subsequent PR I'll add the short_description to most rules using the same script as I used in #22295. Again, just keeping this simple / avoiding merge conflicts. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
72b6e236f8 | chore(rulegen): sort template imports (#22793) | ||
|
|
28749f003d | fix(tasks/rulegen): use minimal raw string delimiters (#22766) | ||
|
|
a26c437268 |
fix(linter/rulegen): handle Flow type parse errors gracefully in rule generator (#21794)
`just new-jsx-a11y-rule <name>` panics because `eslint-plugin-jsx-a11y` uses Flow type annotations, which the Oxc parser can't handle, causing parse errors that hit `assert!(ret.errors.is_empty())` (introduced in #15865). ## Changes - **`tasks/rulegen/src/main.rs`**: Replace two `assert!(ret.errors.is_empty())` calls — one for test file parsing, one for rule source file parsing — with `eprintln!` warnings that allow execution to continue with the partial AST. The tool can still extract test cases and rule config from a partially-parsed AST, so this restores pre-#15865 behavior while surfacing parse issues to the user: ``` Warning: 3 parse error(s) in rule source file (possibly due to Flow types). Attempting to extract rule config anyway. ``` --------- Signed-off-by: Connor Shea <2977353+connorshea@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: connorshea <2977353+connorshea@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Cameron <cameron.clark@hey.com> |
||
|
|
00089f2524 |
feat(tasks/linter): set rulegen version to next in template (#21370)
- follow up to #21363 by setting `version = "next"` in the rulegen template for newly scaffolded lint rules - update the rulegen template snapshot to match |
||
|
|
7ce45cbc08 |
test(linter): update the rulegen test path for vue rules. (#20096)
All eslint-plugin-vue tests were moved. See https://github.com/vuejs/eslint-plugin-vue/commit/b5d8f141a4aeba1e1c363be2042a4da680159ecb#diff-ed2e8d689a406c52dde510ab3fdf139e22e8a24154b51bc7f2025eefe961d58c |
||
|
|
bfbbc821b7 |
refactor(linter): Update the rulegen code to replace leading tabs with spaces in code snippets. (#19426)
This fixes problems where tests end up with mixed indentation in the generated test cases. AI Disclosure: Generated with Claude Code. Tested by me, ran over every unicorn rule in the codebase to ensure nothing weird changed. (catch-error-name generates invalid code, but that's true on main as well) |
||
|
|
456442a399 |
chore(rulegen): Minor updates to the rulegen template. (#19116)
Clarify some of the TODOs in the rulegen template to make them easier to understand. Syntax correctness in the example code is not actually enforced anymore, so remove mention of it. |
||
|
|
04a2871033 |
fix(linter): fix rulegen tool broken after #18076 (#18338)
## Summary - Remove obsolete `declare_all_lint_rules!` macro handling from `add_rules_entry` - the macro was removed in #18076 - Fix `find_unsupported_rule` to respect the specified plugin instead of matching any plugin's rule with the same name ## Test plan - [x] `cargo test -p rulegen` passes - [x] `cargo run -p rulegen dot-notation` now correctly creates `eslint/dot-notation` instead of failing with `vue/dot-notation` unsupported error Closes #18322 🤖 Generated with [Claude Code](https://claude.ai/claude-code) |
||
|
|
23aad439b7 |
refactor(rulegen): Update the rulegen template to error on an invalid config (#18115)
New rules created with this tooling will now be generated to error when the config is invalid, rather than falling back to a default config. Also use `serde` attributes for deserialization, and ensure we set `default` for serde. Also prefer to use `serde` over schemars in the template. |
||
|
|
6be97f9512 |
feat(rulegen): Error upon generating an unsupported rule with rulegen (#18051)
Fix #18045. To avoid any contributors trying to generate rules that are not possible/that we don't want, don't want to waste people's time if we can avoid it. Examples: ``` connorshea@Connors-MacBook-Pro oxc % just new-n-rule no-hide-core-modules cargo run -p rulegen no-hide-core-modules n Compiling rulegen v0.0.0 (/Users/connorshea/code/oxc/tasks/rulegen) Finished `dev` profile [unoptimized] target(s) in 1.61s Running `target/debug/rulegen no-hide-core-modules n` Error: This rule is either not planned or not possible to implement in Oxlint. The rule 'n/no-hide-core-modules' will not be implemented for the following reason: > This rule is deprecated in eslint-plugin-n for being inherently incorrect, no need for us to implement it. error: Recipe `new-rule` failed on line 157 with exit code 1 ``` ``` connorshea@Connors-MacBook-Pro oxc % just new-rule no-dupe-args cargo run -p rulegen no-dupe-args eslint Finished `dev` profile [unoptimized] target(s) in 0.21s Running `target/debug/rulegen no-dupe-args eslint` Error: This rule is either not planned or not possible to implement in Oxlint. The rule 'eslint/no-dupe-args' will not be implemented for the following reason: > Superseded by strict mode. error: Recipe `new-rule` failed on line 157 with exit code 1 ``` And generating a valid rule like `just new-react-rule no-multi-comp` still works: ``` Reading test file from https://raw.githubusercontent.com/jsx-eslint/eslint-plugin-react/master/tests/lib/rules/no-multi-comp.js File parsed and 16 pass cases, 20 fail cases are found Reading rule source file from https://raw.githubusercontent.com/jsx-eslint/eslint-plugin-react/master/lib/rules/no-multi-comp.js Rule config parsed. Saved file to crates/oxc_linter/src/rules/react/no_multi_comp.rs Formatted rule file Updated crates/oxc_linter/src/rules.rs Generating RuleRunner impl... ``` |
||
|
|
fc80b40d51 |
feat(rulegen): Improve rulegen output and add tests (#17899)
Simple changes cut out of #17620, to fix some minor issues with the rulegen code. Basically, just improves consistency in the code output by the rulegen tool: - Replaces tabs in the test cases with spaces, previously we inserted tabs for indentation and that lead to weird differences in the code. - Reduce unnecessary usage of `r#"` escaping that resulted in clippy warnings about unnecessary escaping when generating some rules (this doesn't fix _all_ problems here, but it fixes a lot of them). - Adds tests I've used a script I wrote to regenerate every ESLint rule in the repo and gone through them to make sure this doesn't break anything, and I believe this is a safe change. |
||
|
|
df57f98222 |
fix(rulegen): Avoid printing a useless None in the fixer tuple for rules with no config option tests. (#17904)
I tested this with `just update-rule-tests unicode-bom` (which generates tests with config options) and `just update-rule-tests no-useless-rename` (which has no config options for the fix tests), both work properly. Previously, we would always write the fixer tests as a 3-tuple, and that's basically pointless. |
||
|
|
d9cbb2e2c9 |
chore(rulegen): Add an empty line between fix and Tester. (#17895)
This was bothering me, so now it's fixed. |
||
|
|
624a7209d3 |
feat(rulegen): add --update-tests flag to update only test block in existing rules (#17669)
This allows updating test cases from upstream without overwriting the rule implementation. Useful for PR validation workflows. |
||
|
|
794bedc2b4 |
chore(rulegen): Fix the vue rule/test paths. (#17625)
These technically still worked, but it's basically a fluke that they did. The trailing `/` results in pulling a URL with two slashes lol Noticed this from the logs while running the command: ``` Reading rule source file from https://raw.githubusercontent.com/vuejs/eslint-plugin-vue/master/lib/rules//require-direct-export.js ``` |
||
|
|
901eef6b5d |
refactor(linter): update Rule::from_configuration to return a Result (#17479)
Built on top of #17478. Based on the changes I experimented with in #17199, and the suggestion given by camc in that PR. AI Disclosure: This was done almost entirely via find+replace and manual updates to fix individual rules. I did use AI for the change in 0abc9814d3b9e44c59dcd042ef65f446a556d1a3 since I had trouble figuring out a solution for that. It may be easier to review this by going through it commit-by-commit. Ran ecosystem CI on this branch and it looks like it works fine, no new regressions https://github.com/oxc-project/oxc-ecosystem-ci/actions/runs/20590908980 --------- Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
fd57ec3112 |
chore(rulegen): Improve the rule template and config json handling (#17117)
The rule configs often came out weird previously, and now the config objects in the tests look a bit less bad for generated rules :)
Done with help from Copilot + Claude Opus.
Also run `just fmt` after generating a rule, to avoid some problems with the sort order of defined rules by default, and update the template.txt to use some common patterns.
Example generated rule:
<details>
<summary>Before</summary>
```rs
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
AstNode,
context::LintContext,
fixer::{RuleFix, RuleFixer},
rule::Rule,
};
fn explicit_member_accessibility_diagnostic(span: Span) -> OxcDiagnostic {
// See <https://oxc.rs/docs/contribute/linter/adding-rules.html#diagnostics> for details
OxcDiagnostic::warn("Should be an imperative statement about what is wrong")
.with_help("Should be a command-like statement that tells the user how to fix the issue")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct ExplicitMemberAccessibility;
// See <https://github.com/oxc-project/oxc/issues/6050> for documentation details.
declare_oxc_lint!(
/// ### What it does
///
/// Briefly describe the rule's purpose.
///
/// ### Why is this bad?
///
/// Explain why violating this rule is problematic.
///
/// ### Examples
///
/// Examples of **incorrect** code for this rule:
/// ```ts
/// FIXME: Tests will fail if examples are missing or syntactically incorrect.
/// ```
///
/// Examples of **correct** code for this rule:
/// ```ts
/// FIXME: Tests will fail if examples are missing or syntactically incorrect.
/// ```
ExplicitMemberAccessibility,
typescript,
nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style`
// See <https://oxc.rs/docs/contribute/linter.html#rule-category> for details
pending, // TODO: describe fix capabilities. Remove if no fix can be done,
// keep at 'pending' if you think one could be added but don't know how.
// Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion'
);
impl Rule for ExplicitMemberAccessibility {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
(
"
class Test {
public constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
public constructor(private readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
public constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(protected foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(public foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(private readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
protected name: string;
private x: number;
public getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public 'foo-bar'?: string;
}
",
None,
),
(
"
class Test {
public constructor({ x, y }: { x: number; y: number }) {}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
protected name: string;
protected foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
name: string;
foo?: string;
getX() {
return this.x;
}
get fooName(): string {
return this.foo + ' ' + this.name;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
private set internalValue(value: number) {
this.x = value;
}
public square(): number {
return this.x * this.x;
}
}
",
Some(
serde_json::json!([{ "overrides": { "accessors": "off", "constructors": "off" } }]),
),
),
(
"
class Test {
private x: number;
public constructor(x: number) {
this.x = x;
}
public get internalValue() {
return this.x;
}
public set internalValue(value: number) {
this.x = value;
}
public square(): number {
return this.x * this.x;
}
half(): number {
return this.x / 2;
}
}
",
Some(serde_json::json!([{ "overrides": { "methods": "off" } }])),
),
(
"
class Test {
constructor(private x: number) {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
constructor(public x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
constructor(public foo: number) {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
public static getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
get getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "off" } }])),
),
(
"
class Test {
private x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "explicit" } }])),
),
(
"
class Test {
x = 2;
private x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "no-public" } }])),
),
(
"
class Test {
#foo = 1;
#bar() {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
private accessor foo = 1;
}
",
None,
),
(
"
abstract class Test {
private abstract accessor foo: number;
}
",
None,
),
];
let fail = vec![
(
"
export class XXXX {
public constructor(readonly value: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "explicit", }, }, ]),
),
),
(
"
export class WithParameterProperty {
public constructor(readonly value: string) {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
export class XXXX {
public constructor(readonly samosa: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "constructors": "explicit", "parameterProperties": "explicit", }, }, ]),
),
),
(
"
class Test {
public constructor(readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
x: number;
public getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
private x: number;
getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
x?: number;
getX?() {
return this.x;
}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
protected name: string;
public foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public x: number;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
set internalValue(value: number) {
this.x = value;
}
}
",
Some(serde_json::json!([{ "overrides": { "constructors": "no-public" } }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
set internalValue(value: number) {
this.x = value;
}
}
",
None,
),
(
"
class Test {
constructor(public x: number) {}
public foo(): string {
return 'foo';
}
}
",
Some(
serde_json::json!([ { "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public x: number) {}
}
",
None,
),
(
"
class Test {
constructor(public readonly x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "explicit" }, }, ]),
),
),
(
"
class Test {
public x = 2;
private x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public x: any[]) {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
public /*public*/constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
@public
public foo() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
@public
public foo;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
public foo = '';
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
constructor(public/* Hi there */ readonly foo) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public /* */ constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public 'foo' = 1;
public 'foo foo' = 2;
public 'bar'() {}
public 'bar bar'() {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
abstract class SomeClass {
abstract method(): string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
public abstract method(): string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
abstract class SomeClass {
abstract x: string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
public abstract x: string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class SomeClass {
accessor foo = 1;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
abstract accessor foo: string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class DecoratedClass {
constructor(@foo @bar() readonly arg: string) {}
@foo @bar() x: string;
@foo @bar() getX() {
return this.x;
}
@foo
@bar()
get y() {
return this.x;
}
@foo @bar() set z(@foo @bar() value: x) {
this.x = x;
}
}
",
None,
),
(
"
abstract class SomeClass {
abstract ['computed-method-name'](): string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
];
let fix = vec![
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
"
class Test {
protected name: string;
protected foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
protected name: string;
public foo?: string;
getX() {
return this.x;
}
}
",
"
class Test {
protected name: string;
foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public x: number;
public getX() {
return this.x;
}
}
",
"
class Test {
x: number;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
constructor(public readonly x: number) {}
}
",
"
class Test {
constructor(readonly x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public x = 2;
private x = 2;
}
",
"
class Test {
x = 2;
private x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "no-public" }, }, ]),
),
),
(
"
class Test {
public /*public*/constructor(private foo: string) {}
}
",
"
class Test {
/*public*/constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
@public
public foo() {}
}
",
"
class Test {
@public
foo() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
@public
public foo;
}
",
"
class Test {
@public
foo;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
public foo = '';
}
",
"
class Test {
foo = '';
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class Test {
constructor(public/* Hi there */ readonly foo) {}
}
",
"
class Test {
constructor(/* Hi there */ readonly foo) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public readonly foo: string) {}
}
",
"
class Test {
constructor(readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public constructor() {}
}
",
"
class EnsureWhiteSPaceSpan {
constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public /* */ constructor() {}
}
",
"
class EnsureWhiteSPaceSpan {
/* */ constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public 'foo' = 1;
public 'foo foo' = 2;
public 'bar'() {}
public 'bar bar'() {}
}
",
"
class Test {
'foo' = 1;
'foo foo' = 2;
'bar'() {}
'bar bar'() {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
abstract class SomeClass {
public abstract method(): string;
}
",
"
abstract class SomeClass {
abstract method(): string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
abstract class SomeClass {
public abstract x: string;
}
",
"
abstract class SomeClass {
abstract x: string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
];
Tester::new(ExplicitMemberAccessibility::NAME, ExplicitMemberAccessibility::PLUGIN, pass, fail)
.expect_fix(fix)
.test_and_snapshot();
}
```
</details>
<details>
<summary>After</summary>
```rs
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
AstNode,
context::LintContext,
fixer::{RuleFix, RuleFixer},
rule::Rule,
};
fn explicit_member_accessibility_diagnostic(span: Span) -> OxcDiagnostic {
// See <https://oxc.rs/docs/contribute/linter/adding-rules.html#diagnostics> for details
OxcDiagnostic::warn("Should be an imperative statement about what is wrong.")
.with_help("Should be a command-like statement that tells the user how to fix the issue.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct ExplicitMemberAccessibility;
// See <https://github.com/oxc-project/oxc/issues/6050> for documentation details.
declare_oxc_lint!(
/// ### What it does
///
/// Briefly describe the rule's purpose.
///
/// ### Why is this bad?
///
/// Explain why violating this rule is problematic.
///
/// ### Examples
///
/// Examples of **incorrect** code for this rule:
/// ```ts
/// FIXME: Tests will fail if examples are missing or syntactically incorrect.
/// ```
///
/// Examples of **correct** code for this rule:
/// ```ts
/// FIXME: Tests will fail if examples are missing or syntactically incorrect.
/// ```
ExplicitMemberAccessibility,
typescript,
nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style`
// See <https://oxc.rs/docs/contribute/linter.html#rule-category> for details
pending, // TODO: describe fix capabilities. Remove if no fix can be done,
// keep at 'pending' if you think one could be added but don't know how.
// Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion'
);
impl Rule for ExplicitMemberAccessibility {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
(
"
class Test {
public constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
public constructor(private readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
public constructor(private foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(protected foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(public foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
public constructor(private readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
protected name: string;
private x: number;
public getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public 'foo-bar'?: string;
}
",
None,
),
(
"
class Test {
public constructor({ x, y }: { x: number; y: number }) {}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
protected name: string;
protected foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
name: string;
foo?: string;
getX() {
return this.x;
}
get fooName(): string {
return this.foo + ' ' + this.name;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
private set internalValue(value: number) {
this.x = value;
}
public square(): number {
return this.x * this.x;
}
}
",
Some(
serde_json::json!([{ "overrides": { "accessors": "off", "constructors": "off" } }]),
),
),
(
"
class Test {
private x: number;
public constructor(x: number) {
this.x = x;
}
public get internalValue() {
return this.x;
}
public set internalValue(value: number) {
this.x = value;
}
public square(): number {
return this.x * this.x;
}
half(): number {
return this.x / 2;
}
}
",
Some(serde_json::json!([{ "overrides": { "methods": "off" } }])),
),
(
"
class Test {
constructor(private x: number) {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
constructor(public x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "off" }, }, ]),
),
),
(
"
class Test {
constructor(public foo: number) {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
public static getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
get getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "ignoredMethodNames": ["getX"] }])),
),
(
"
class Test {
x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "off" } }])),
),
(
"
class Test {
private x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "explicit" } }])),
),
(
"
class Test {
x = 2;
private x = 2;
}
",
Some(serde_json::json!([{ "overrides": { "properties": "no-public" } }])),
),
(
"
class Test {
#foo = 1;
#bar() {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
private accessor foo = 1;
}
",
None,
),
(
"
abstract class Test {
private abstract accessor foo: number;
}
",
None,
),
];
let fail = vec![
(
"
export class XXXX {
public constructor(readonly value: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "explicit", }, }, ]),
),
),
(
"
export class WithParameterProperty {
public constructor(readonly value: string) {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
export class XXXX {
public constructor(readonly samosa: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "constructors": "explicit", "parameterProperties": "explicit", }, }, ]),
),
),
(
"
class Test {
public constructor(readonly foo: string) {}
}
",
Some(
serde_json::json!([ { "accessibility": "explicit", "overrides": { "parameterProperties": "explicit" }, }, ]),
),
),
(
"
class Test {
x: number;
public getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
private x: number;
getX() {
return this.x;
}
}
",
None,
),
(
"
class Test {
x?: number;
getX?() {
return this.x;
}
}
",
None,
),
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
protected name: string;
public foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public x: number;
public getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
set internalValue(value: number) {
this.x = value;
}
}
",
Some(serde_json::json!([{ "overrides": { "constructors": "no-public" } }])),
),
(
"
class Test {
private x: number;
constructor(x: number) {
this.x = x;
}
get internalValue() {
return this.x;
}
set internalValue(value: number) {
this.x = value;
}
}
",
None,
),
(
"
class Test {
constructor(public x: number) {}
public foo(): string {
return 'foo';
}
}
",
Some(
serde_json::json!([ { "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public x: number) {}
}
",
None,
),
(
"
class Test {
constructor(public readonly x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "explicit" }, }, ]),
),
),
(
"
class Test {
public x = 2;
private x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public x: any[]) {}
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class Test {
public /*public*/constructor(private foo: string) {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
@public
public foo() {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
@public
public foo;
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
public foo = '';
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
constructor(public/* Hi there */ readonly foo) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public readonly foo: string) {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class EnsureWhiteSPaceSpan {
public constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public /* */ constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public 'foo' = 1;
public 'foo foo' = 2;
public 'bar'() {}
public 'bar bar'() {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
abstract class SomeClass {
abstract method(): string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
public abstract method(): string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
abstract class SomeClass {
abstract x: string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
public abstract x: string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class SomeClass {
accessor foo = 1;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
abstract class SomeClass {
abstract accessor foo: string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
(
"
class DecoratedClass {
constructor(@foo @bar() readonly arg: string) {}
@foo @bar() x: string;
@foo @bar() getX() {
return this.x;
}
@foo
@bar()
get y() {
return this.x;
}
@foo @bar() set z(@foo @bar() value: x) {
this.x = x;
}
}
",
None,
),
(
"
abstract class SomeClass {
abstract ['computed-method-name'](): string;
}
",
Some(serde_json::json!([{ "accessibility": "explicit" }])),
),
];
let fix = vec![
(
"
class Test {
protected name: string;
protected foo?: string;
public getX() {
return this.x;
}
}
",
"
class Test {
protected name: string;
protected foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
protected name: string;
public foo?: string;
getX() {
return this.x;
}
}
",
"
class Test {
protected name: string;
foo?: string;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
public x: number;
public getX() {
return this.x;
}
}
",
"
class Test {
x: number;
getX() {
return this.x;
}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
class Test {
constructor(public readonly x: number) {}
}
",
"
class Test {
constructor(readonly x: number) {}
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public x = 2;
private x = 2;
}
",
"
class Test {
x = 2;
private x = 2;
}
",
Some(
serde_json::json!([ { "accessibility": "off", "overrides": { "properties": "no-public" }, }, ]),
),
),
(
"
class Test {
public /*public*/constructor(private foo: string) {}
}
",
"
class Test {
/*public*/constructor(private foo: string) {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
@public
public foo() {}
}
",
"
class Test {
@public
foo() {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
@public
public foo;
}
",
"
class Test {
@public
foo;
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
public foo = '';
}
",
"
class Test {
foo = '';
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class Test {
constructor(public/* Hi there */ readonly foo) {}
}
",
"
class Test {
constructor(/* Hi there */ readonly foo) {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
constructor(public readonly foo: string) {}
}
",
"
class Test {
constructor(readonly foo: string) {}
}
",
Some(serde_json::json!([ { "accessibility": "no-public", }, ])),
),
(
"
class EnsureWhiteSPaceSpan {
public constructor() {}
}
",
"
class EnsureWhiteSPaceSpan {
constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class EnsureWhiteSPaceSpan {
public /* */ constructor() {}
}
",
"
class EnsureWhiteSPaceSpan {
/* */ constructor() {}
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
class Test {
public 'foo' = 1;
public 'foo foo' = 2;
public 'bar'() {}
public 'bar bar'() {}
}
",
"
class Test {
'foo' = 1;
'foo foo' = 2;
'bar'() {}
'bar bar'() {}
}
",
Some(serde_json::json!([{ "accessibility": "no-public" }])),
),
(
"
abstract class SomeClass {
public abstract method(): string;
}
",
"
abstract class SomeClass {
abstract method(): string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
(
"
abstract class SomeClass {
public abstract x: string;
}
",
"
abstract class SomeClass {
abstract x: string;
}
",
Some(
serde_json::json!([ { "accessibility": "no-public", "overrides": { "parameterProperties": "no-public" }, }, ]),
),
),
];
Tester::new(ExplicitMemberAccessibility::NAME, ExplicitMemberAccessibility::PLUGIN, pass, fail)
.expect_fix(fix)
.test_and_snapshot();
}
```
</details>
|
||
|
|
dece1faf59 |
chore(linter): Update the GitHub URL for the vitest eslint plugin repo. (#16941)
This needed to be updated in a few different places. |
||
|
|
09ca386422 |
chore(linter): remove unused builtin regex plugin (#16493)
Closes #11439 6 months after adding opening the eslint plugin regex issue, and adding support for regex rules in rule gen, we have implemented none of the regex rule. Given this, and the fact that these rules can be implemented via JS plugins, it makes a the most sense to remove support for this plugin. cc @connorshea |
||
|
|
b3d6f45d37 |
test(all): check parse errors existence (#15865)
Added `assert!(ret.errors.is_empty());` in many places so that invalid inputs are caught properly. |
||
|
|
c417564c4b |
chore(deps): update dependency rust to v1.91.0 (#15163)
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.90.0` -> `1.91.0` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.91.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1910-2025-10-30) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.90.0...1.91.0) \========================== <a id="1.91.0-Language"></a> ## Language - [Lower pattern bindings in the order they're written and base drop order on primary bindings' order](https://redirect.github.com/rust-lang/rust/pull/143764) - [Stabilize declaration of C-style variadic functions for `sysv64`, `win64`, `efiapi`, and `aapcs` ABIs](https://redirect.github.com/rust-lang/rust/pull/144066). This brings these ABIs in line with the C ABI: variadic functions can be declared in extern blocks but not defined. - [Add `dangling_pointers_from_locals` lint to warn against dangling pointers from local variables](https://redirect.github.com/rust-lang/rust/pull/144322) - [Upgrade `semicolon_in_expressions_from_macros` from warn to deny](https://redirect.github.com/rust-lang/rust/pull/144369) - [Stabilize LoongArch32 inline assembly](https://redirect.github.com/rust-lang/rust/pull/144402) - [Add warn-by-default `integer_to_ptr_transmutes` lint against integer-to-pointer transmutes](https://redirect.github.com/rust-lang/rust/pull/144531) - [Stabilize `sse4a` and `tbm` target features](https://redirect.github.com/rust-lang/rust/pull/144542) - [Add `target_env = "macabi"` and `target_env = "sim"` cfgs](https://redirect.github.com/rust-lang/rust/pull/139451) as replacements for the `target_abi` cfgs with the same values. <a id="1.91.0-Compiler"></a> ## Compiler - [Don't warn on never-to-any `as` casts as unreachable](https://redirect.github.com/rust-lang/rust/pull/144804) <a id="1.91.0-Platform-Support"></a> ## Platform Support - [Promote `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` to Tier 2 with host tools.](https://redirect.github.com/rust-lang/rust/pull/143031) Note: llvm-tools and MSI installers are missing but will be added in future releases. - [Promote `aarch64-pc-windows-msvc` to Tier 1](https://redirect.github.com/rust-lang/rust/pull/145682) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. [platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html <a id="1.91.0-Libraries"></a> ## Libraries - [Print thread ID in panic message](https://redirect.github.com/rust-lang/rust/pull/115746) - [Fix overly restrictive lifetime in `core::panic::Location::file` return type](https://redirect.github.com/rust-lang/rust/pull/132087) - [Guarantee parameter order for `_by()` variants of `min` / `max`/ `minmax` in `std::cmp`](https://redirect.github.com/rust-lang/rust/pull/139357) - [Document assumptions about `Clone` and `Eq` traits](https://redirect.github.com/rust-lang/rust/pull/144330/) - [`std::thread`: Return error if setting thread stack size fails](https://redirect.github.com/rust-lang/rust/pull/144210) This used to panic within the standard library. <a id="1.91.0-Stabilized-APIs"></a> ## Stabilized APIs - [`Path::file_prefix`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.file_prefix) - [`AtomicPtr::fetch_ptr_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_add) - [`AtomicPtr::fetch_ptr_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_sub) - [`AtomicPtr::fetch_byte_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_add) - [`AtomicPtr::fetch_byte_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_sub) - [`AtomicPtr::fetch_or`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_or) - [`AtomicPtr::fetch_and`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and) - [`AtomicPtr::fetch_xor`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_xor) - [`{integer}::strict_add`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add) - [`{integer}::strict_sub`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub) - [`{integer}::strict_mul`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_mul) - [`{integer}::strict_div`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div) - [`{integer}::strict_div_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div_euclid) - [`{integer}::strict_rem`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem) - [`{integer}::strict_rem_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem_euclid) - [`{integer}::strict_neg`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_neg) - [`{integer}::strict_shl`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shl) - [`{integer}::strict_shr`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shr) - [`{integer}::strict_pow`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_pow) - [`i{N}::strict_add_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_add_unsigned) - [`i{N}::strict_sub_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_sub_unsigned) - [`i{N}::strict_abs`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_abs) - [`u{N}::strict_add_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add_signed) - [`u{N}::strict_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub_signed) - [`PanicHookInfo::payload_as_str`](https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload_as_str) - [`core::iter::chain`](https://doc.rust-lang.org/stable/core/iter/fn.chain.html) - [`u{N}::checked_signed_diff`](https://doc.rust-lang.org/stable/std/primitive.u16.html#method.checked_signed_diff) - [`core::array::repeat`](https://doc.rust-lang.org/stable/core/array/fn.repeat.html) - [`PathBuf::add_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.add_extension) - [`PathBuf::with_added_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.with_added_extension) - [`Duration::from_mins`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_mins) - [`Duration::from_hours`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_hours) - [`impl PartialEq<str> for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3Cstr%3E-for-PathBuf) - [`impl PartialEq<String> for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf) - [`impl PartialEq<str> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path) - [`impl PartialEq<String> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path) - [`impl PartialEq<PathBuf> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String) - [`impl PartialEq<Path> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String) - [`impl PartialEq<PathBuf> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str) - [`impl PartialEq<Path> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPath%3E-for-str) - [`Ipv4Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.from_octets) - [`Ipv6Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_octets) - [`Ipv6Addr::from_segments`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_segments) - [`impl<T> Default for Pin<Box<T>> where Box<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CBox%3CT%3E%3E) - [`impl<T> Default for Pin<Rc<T>> where Rc<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CRc%3CT%3E%3E) - [`impl<T> Default for Pin<Arc<T>> where Arc<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CArc%3CT%3E%3E) - [`Cell::as_array_of_cells`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.as_array_of_cells) - [`u{N}::carrying_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_add) - [`u{N}::borrowing_sub`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.borrowing_sub) - [`u{N}::carrying_mul`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul) - [`u{N}::carrying_mul_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul_add) - [`BTreeMap::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.extract_if) - [`BTreeSet::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.extract_if) - [`impl Debug for windows::ffi::EncodeWide<'_>`](https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-Debug-for-EncodeWide%3C'_%3E) - [`str::ceil_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.ceil_char_boundary) - [`str::floor_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.floor_char_boundary) - [`impl Sum for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum-for-Saturating%3Cu32%3E) - [`impl Sum<&Self> for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E) - [`impl Product for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product-for-Saturating%3Cu32%3E) - [`impl Product<&Self> for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E) These previously stable APIs are now stable in const contexts: - [`<[T; N]>::each_ref`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_ref) - [`<[T; N]>::each_mut`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut) - [`OsString::new`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.new) - [`PathBuf::new`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.new) - [`TypeId::of`](https://doc.rust-lang.org/stable/std/any/struct.TypeId.html#method.of) - [`ptr::with_exposed_provenance`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance.html) - [`ptr::with_exposed_provenance_mut`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance_mut.html) <a id="1.91.0-Cargo"></a> ## Cargo - 🎉 Stabilize `build.build-dir`. This config sets the directory where intermediate build artifacts are stored. These artifacts are produced by Cargo and rustc during the build process. End users usually won't need to interact with them, and the layout inside `build-dir` is an implementation detail that may change without notice. ([config doc](https://doc.rust-lang.org/stable/cargo/reference/config.html#buildbuild-dir)) ([build cache doc](https://doc.rust-lang.org/stable/cargo/reference/build-cache.html)) [#​15833](https://redirect.github.com/rust-lang/cargo/pull/15833) [#​15840](https://redirect.github.com/rust-lang/cargo/pull/15840) - The `--target` flag and the `build.target` configuration can now take literal `"host-tuple"` string, which will internally be substituted by the host machine's target triple. [#​15838](https://redirect.github.com/rust-lang/cargo/pull/15838) [#​16003](https://redirect.github.com/rust-lang/cargo/pull/16003) [#​16032](https://redirect.github.com/rust-lang/cargo/pull/16032) <a id="1.91.0-Rustdoc"></a> ## Rustdoc - [In search results, rank doc aliases lower than non-alias items with the same name](https://redirect.github.com/rust-lang/rust/pull/145100) - [Raw pointers now work in type-based search like references](https://redirect.github.com/rust-lang/rust/pull/145731). This means you can now search for things like `*const u8 ->`, and additionally functions that take or return raw pointers will now display their signature properly in search results. <a id="1.91.0-Compatibility-Notes"></a> ## Compatibility Notes - [Always require coroutine captures to be drop-live](https://redirect.github.com/rust-lang/rust/pull/144156) - [Apple: Always pass SDK root when linking with `cc`, and pass it via `SDKROOT` env var](https://redirect.github.com/rust-lang/rust/pull/131477). This should fix linking issues with `rustc` running inside Xcode. Libraries in `/usr/local/lib` may no longer be linked automatically, if you develop or use a crate that relies on this, you should explicitly set `cargo::rustc-link-search=/usr/local/lib` in a `build.rs` script. - [Relaxed bounds in associated type bound position like in `TraitRef<AssocTy: ?Sized>` are now correctly forbidden](https://redirect.github.com/rust-lang/rust/pull/135331) - [Add unstable `#[sanitize(xyz = "on|off")]` built-in attribute that shadows procedural macros with the same name](https://redirect.github.com/rust-lang/rust/pull/142681) - [Fix the drop checker being more permissive for bindings declared with let-else](https://redirect.github.com/rust-lang/rust/pull/143028) - [Be more strict when parsing attributes, erroring on many invalid attributes](https://redirect.github.com/rust-lang/rust/pull/144689) - [Error on invalid `#[should_panic]` attributes](https://redirect.github.com/rust-lang/rust/pull/143808) - [Error on invalid `#[link]` attributes](https://redirect.github.com/rust-lang/rust/pull/143193) - [Mark all deprecation lints in name resolution as deny-by-default and also report in dependencies](https://redirect.github.com/rust-lang/rust/pull/143929) - The lint `semicolon_in_expressions_from_macros`, for `macro_rules!` macros in expression position that expand to end in a semicolon (`;`), is now deny-by-default. It was already warn-by-default, and a future compatibility warning (FCW) that warned even in dependencies. This lint will become a hard error in the future. - [Trait impl modifiers (e.g., `unsafe`, `!`, `default`) in inherent impls are no longer syntactically valid](https://redirect.github.com/rust-lang/rust/pull/144386) - [Start reporting future breakage for `ill_formed_attribute_input` in dependencies](https://redirect.github.com/rust-lang/rust/pull/144544) - [Restrict the scope of temporaries created by the macros `pin!`, `format_args!`, `write!`, and `writeln!` in `if let` scrutinees in Rust Edition 2024.](https://redirect.github.com/rust-lang/rust/pull/145342) This applies [Rust Edition 2024's `if let` temporary scope rules](https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html) to these temporaries, which previously could live past the `if` expression regardless of Edition. - [Invalid numeric literal suffixes in tuple indexing, tuple struct indexing, and struct field name positions are now correctly rejected](https://redirect.github.com/rust-lang/rust/pull/145463) - [Closures marked with the keyword `static` are now syntactically invalid](https://redirect.github.com/rust-lang/rust/pull/145604) - [Shebangs inside `--cfg` and `--check-cfg` arguments are no longer allowed](https://redirect.github.com/rust-lang/rust/pull/146211) - [Add future incompatibility lint for temporary lifetime shortening in Rust 1.92](https://redirect.github.com/rust-lang/rust/pull/147056) Cargo compatibility notes: - `cargo publish` no longer keeps `.crate` tarballs as final build artifacts when `build.build-dir` is set. These tarballs were previously included due to an oversight and are now treated as intermediate artifacts. To get `.crate` tarballs as final artifacts, use `cargo package`. In a future version, this change will apply regardless of `build.build-dir`. [#​15910](https://redirect.github.com/rust-lang/cargo/pull/15910) - Adjust Cargo messages to match rustc diagnostic style. This changes some of the terminal colors used by Cargo messages. [#​15928](https://redirect.github.com/rust-lang/cargo/pull/15928) - Tools and projects relying on the [internal details of Cargo's `build-dir`](https://doc.rust-lang.org/cargo/reference/build-cache.html) may not work for users changing their `build-dir` layout. For those doing so, we'd recommend proactively testing these cases particularly as we are considering changing the default location of the `build-dir` in the future ([cargo#16147](https://redirect.github.com/rust-lang/cargo/issues/16147)). If you can't migrate off of Cargo's internal details, we'd like to learn more about your use case as we prepare to change the layout of the `build-dir` ([cargo#15010](https://redirect.github.com/rust-lang/cargo/issues/15010)). <a id="1.91.0-Internal-Changes"></a> ## Internal Changes These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Update to LLVM 21](https://redirect.github.com/rust-lang/rust/pull/143684) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNTkuNCIsInVwZGF0ZWRJblZlciI6IjQxLjE1OS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> |
||
|
|
d65fd527d1 |
fix(rulegen): update template to include comma after 'pending'. (#15000)
Otherwise you end up with syntax errors when there are config options to generate. |
||
|
|
b13c4bddbb | feat(rulegen): add function to generate RuleRunner implementation; (#14549) | ||
|
|
3bb5a33645 | fix(rulegen): improve rule insertion logic for lint rules (#14548) | ||
|
|
41b0d3544d |
fix(tasks/rulegen): trim quotes from filename (#14283)
All rule generation for `vue` would result into testfiles like:
```
Some(PathBuf::from("'test.vue'")),
```
but it should be:
```
Some(PathBuf::from("test.vue")),
```
|
||
|
|
b794af1924 |
feat(rulegen): add config struct (#13320)
Parses the meta.schema field of the eslint rule to code generate the structs and enums needed for the rule. It also adds the derive attributes so that documentation code generation can read the struct shape and `from_configuration` can easily deserialize. Improvements that I would prefer to tackle for follow up PRs: - Resolve the schema value in javascript (a la `tasks/lint_rules` package), then parse in rust - Parse other parts of the json schema for validation, like `minItems` and `maximum`, and use a validation crate in `from_configuration` - Support json schema constants like `true`, number literals like `1` and `null` - Support other json schema concepts like `allOf`, `not`, `patternProperties`, `additionalProperties`, and others - Support migrating existing rules to this new format - Use configs in `oxlintrc.json` schema generation for lsps to validate in the editor --------- Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
e7b26cab41 |
fix(rulegen): strip comments from config (#13163)
Rule generation created invalid rust due to comments inside the configuration object. Additionally, the format was being called asynchronously which was causing errors to show up after the command finished and interrupted the shell prompt. This PR fixes both of these issues by stripping the comments from the configuration object before converting it to a JSON literal and waiting for format to finish so that errors will pop up before the command finishes. |
||
|
|
e28c491be5 |
refactor(tasks/rulegen): panic if RuleKind is unmatched (#12947)
|
||
|
|
84794ebdbf |
refactor(all): enable collapsible_if lint (#12902)
|
||
|
|
bf2129e102 |
fix(rulegen): tests with backslash should be raw string literals (#12854)
Needed to fix some test cases: <img width="1253" height="145" alt="grafik" src="https://github.com/user-attachments/assets/7119b11b-07e5-4cf4-9b29-a6dbb7659b65" /> https://github.com/oxc-project/oxc/pull/12835 |
||
|
|
d3604f9d9f |
chore(rulegen): add new-vue-rule just command (#12543)
|
||
|
|
c68b607d84 |
refactor(ast): rename TemplateLiteral::quasi to TemplateLiteral::single_quasi (#12266)
The method name `quasi` is hard to realize that this method will return a `Some` when there is a only single quasi in this `TemplateLiteral`, so rename to `single_quasi` to match what the implementation does. |
||
|
|
e78d06423c | chore(tasks): add regexp infra to rulegen scripts (#11444) | ||
|
|
12543f1e75 |
feat(rulegen): skip adding rule to rules.rs if exists (#11304)
|
||
|
|
f524552e06 | chore(deps): update dependency rust to v1.87.0 (#11063) | ||
|
|
5dd8c10595 |
fix(rulegen): use get_inner_expression for getting rules (#10269)
|
||
|
|
fa0e455b10 |
perf(cfg, diagnostics, lexer, syntax, tasks): remove write! macro where unnecessary (#10236)
Same as #10230, for small changes to various crates. Replace usages of `write!` macro with either `fmt.write_str(...)` for static strings or `Display::fmt` / `Debug::fmt` for other values, where it's not being used to concatenate multiple values. `Formatter::write_str` is more performant, as it avoids various checks. `Display::fmt` / `Debug::fmt` may also perform a little better in some cases, and will be equivalent in others. But in all cases it should be better for compile times, due to avoiding macro expansion and trait resolution. |
||
|
|
a788a64649 |
chore(deps): update dependency rust to v1.86.0 (#10196)
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.85.1` -> `1.86.0` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.86.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1860-2025-04-03) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.85.1...1.86.0) \========================== <a id="1.86.0-Language"></a> ## Language - [Stabilize upcasting trait objects to supertraits.](https://redirect.github.com/rust-lang/rust/pull/134367) - [Allow safe functions to be marked with the `#[target_feature]` attribute.](https://redirect.github.com/rust-lang/rust/pull/134090) - [The `missing_abi` lint now warns-by-default.](https://redirect.github.com/rust-lang/rust/pull/132397) - Rust now lints about double negations, to catch cases that might have intended to be a prefix decrement operator (`--x`) as written in other languages. This was previously a clippy lint, `clippy::double_neg`, and is [now available directly in Rust as `double_negations`.](https://redirect.github.com/rust-lang/rust/pull/126604) - [More pointers are now detected as definitely not-null based on their alignment in const eval.](https://redirect.github.com/rust-lang/rust/pull/133700) - [Empty `repr()` attribute applied to invalid items are now correctly rejected.](https://redirect.github.com/rust-lang/rust/pull/133925) - [Inner attributes `#![test]` and `#![rustfmt::skip]` are no longer accepted in more places than intended.](https://redirect.github.com/rust-lang/rust/pull/134276) <a id="1.86.0-Compiler"></a> ## Compiler - [Debug-assert that raw pointers are non-null on access.](https://redirect.github.com/rust-lang/rust/pull/134424) - [Change `-O` to mean `-C opt-level=3` instead of `-C opt-level=2` to match Cargo's defaults.](https://redirect.github.com/rust-lang/rust/pull/135439) - [Fix emission of `overflowing_literals` under certain macro environments.](https://redirect.github.com/rust-lang/rust/pull/136393) <a id="1.86.0-Platform-Support"></a> ## Platform Support - [Replace `i686-unknown-redox` target with `i586-unknown-redox`.](https://redirect.github.com/rust-lang/rust/pull/136698) - [Increase baseline CPU of `i686-unknown-hurd-gnu` to Pentium 4.](https://redirect.github.com/rust-lang/rust/pull/136700) - New tier 3 targets: - [`{aarch64-unknown,x86_64-pc}-nto-qnx710_iosock`](https://redirect.github.com/rust-lang/rust/pull/133631). For supporting Neutrino QNX 7.1 with `io-socket` network stack. - [`{aarch64-unknown,x86_64-pc}-nto-qnx800`](https://redirect.github.com/rust-lang/rust/pull/133631). For supporting Neutrino QNX 8.0 (`no_std`-only). - [`{x86_64,i686}-win7-windows-gnu`](https://redirect.github.com/rust-lang/rust/pull/134609). Intended for backwards compatibility with Windows 7. `{x86_64,i686}-win7-windows-msvc` are the Windows MSVC counterparts that already exist as Tier 3 targets. - [`amdgcn-amd-amdhsa`](https://redirect.github.com/rust-lang/rust/pull/134740). - [`x86_64-pc-cygwin`](https://redirect.github.com/rust-lang/rust/pull/134999). - [`{mips,mipsel}-mti-none-elf`](https://redirect.github.com/rust-lang/rust/pull/135074). Initial bare-metal support. - [`m68k-unknown-none-elf`](https://redirect.github.com/rust-lang/rust/pull/135085). - [`armv7a-nuttx-{eabi,eabihf}`, `aarch64-unknown-nuttx`, and `thumbv7a-nuttx-{eabi,eabihf}`](https://redirect.github.com/rust-lang/rust/pull/135757). Refer to Rust's \[platform support page]\[platform-support-doc] for more information on Rust's tiered platform support. <a id="1.86.0-Libraries"></a> ## Libraries - The type of `FromBytesWithNulError` in `CStr::from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError>` was [changed from an opaque struct to an enum](https://redirect.github.com/rust-lang/rust/pull/134143), allowing users to examine why the conversion failed. - [Remove `RustcDecodable` and `RustcEncodable`.](https://redirect.github.com/rust-lang/rust/pull/134272) - [Deprecate libtest's `--logfile` option.](https://redirect.github.com/rust-lang/rust/pull/134283) - [On recent versions of Windows, `std::fs::remove_file` will now remove read-only files.](https://redirect.github.com/rust-lang/rust/pull/134679) <a id="1.86.0-Stabilized-APIs"></a> ## Stabilized APIs - [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down) - [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up) - [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut) - [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut) - [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html) - [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut) - [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut) - [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones) - [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if) - [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait) - [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force) - [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait) These APIs are now stable in const contexts: - [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html) - [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut) - [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position) - [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary) - [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at) - [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked) - [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut) - [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked) <a id="1.86.0-Cargo"></a> ## Cargo - [When merging, replace rather than combine configuration keys that refer to a program path and its arguments.](https://redirect.github.com/rust-lang/cargo/pull/15066/) - [Error if both `--package` and `--workspace` are passed but the requested package is missing.](https://redirect.github.com/rust-lang/cargo/pull/15071/) This was previously silently ignored, which was considered a bug since missing packages should be reported. - [Deprecate the token argument in `cargo login` to avoid shell history leaks.](https://redirect.github.com/rust-lang/cargo/pull/15057/) - [Simplify the implementation of `SourceID` comparisons.](https://redirect.github.com/rust-lang/cargo/pull/14980/) This may potentially change behavior if the canonicalized URL compares differently in alternative registries. <a id="1.86.0-Rustdoc"></a> ## Rustdoc - [Add a sans-serif font setting.](https://redirect.github.com/rust-lang/rust/pull/133636) <a id="1.86.0-Compatibility-Notes"></a> ## Compatibility Notes - [The `wasm_c_abi` future compatibility warning is now a hard error.](https://redirect.github.com/rust-lang/rust/pull/133951) Users of `wasm-bindgen` should upgrade to at least version 0.2.89, otherwise compilation will fail. - [Remove long-deprecated no-op attributes `#![no_start]` and `#![crate_id]`.](https://redirect.github.com/rust-lang/rust/pull/134300) - [The future incompatibility lint `cenum_impl_drop_cast` has been made into a hard error.](https://redirect.github.com/rust-lang/rust/pull/135964) This means it is now an error to cast a field-less enum to an integer if the enum implements `Drop`. - [SSE2 is now required for "i686" 32-bit x86 hard-float targets; disabling it causes a warning that will become a hard error eventually.](https://redirect.github.com/rust-lang/rust/pull/137037) To compile for pre-SSE2 32-bit x86, use a "i586" target instead. <a id="1.86.0-Internal-Changes"></a> ## Internal Changes These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Build the rustc on AArch64 Linux with ThinLTO + PGO.](https://redirect.github.com/rust-lang/rust/pull/133807) The ARM 64-bit compiler (AArch64) on Linux is now optimized with ThinLTO and PGO, similar to the optimizations we have already performed for the x86-64 compiler on Linux. This should make it up to 30% faster. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMjcuMyIsInVwZGF0ZWRJblZlciI6IjM5LjIyNy4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> |
||
|
|
6432707052 |
refactor(rust): use lazy-regex (#10004)
|
||
|
|
5fbf8a550e |
chore(linter): update new rule template (#9712)
Related to #6050 Update the linter rule documentation template to further standardize the content of new rule documentation. |
||
|
|
85d49e3951 |
fix(rulegen): make finding end of module also work on windows (#9579)
``` > just new-ts-rule class-literal-property-style Reading test file from https://raw.githubusercontent.com/typescript-eslint/typescript-eslint/main/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts File parsed and 31 pass cases, 19 fail cases are found Saved test file to "crates/oxc_linter/src/rules/typescript\\class_literal_property_style.rs" failed to add class-literal-property-style to rules file: failed to find end of 'mod typescript' module in crates/oxc_linter/src/rules.rs ``` Running rulegen on Windows fails because it can't find the end of the correct module in crates\oxc_linter\src\rules.rs because it treats "}\n" as the end but on Windows it would be "}\r\n". Replacing the parameter of find with '}' would fix the rulegen tool for Windows users while still behaving the same for all other users. |