Using `FxHashMap` is faster than `HashMap` in many cases, especially for hashing-heavy workloads. This change improves the performance of the linter, prettier, and diagnostics crates by using `FxHashMap` instead of `std::collections::HashMap`.
- part of https://github.com/oxc-project/oxc/issues/5416
This pull request includes significant improvements to the `no_hex_escape` rule in the `oxc_linter` crate. The changes enhance the detection and replacement of hexadecimal escapes within regular expressions by introducing a more comprehensive AST traversal.
- Implemented a new `visit_terms` function and its helper functions to traverse the regex AST and apply checks on individual terms.
- Introduced the `check_character` function to replace hexadecimal escapes with Unicode escapes within regex patterns.
- Updated snapshots to reflect the new diagnostic messages and replacements for hexadecimal escapes in regex patterns.
- part of https://github.com/oxc-project/oxc/issues/5416
Uses the parsed regular expression patterns for detecting empty character classes. This is more robust than the handwritten pattern matching from before and allows us to provide more accurate diagnostics and actually point to the empty character class in the literal.
## What This PR does
Adds a new `oxc-security/api-key` rule that scans for hard-coded API keys.
It is broken up into "secret rules", where each one is responsible for finding a different kind of key. It is architecturally identical to how lint rules themselves. This PR also includes the first of these rules, for AWS access key IDs.
Logic and rules are based on [keyhunter](https://github.com/Donisaac/keyhunter). I've licensed that repo under GNU GPLv3, but it's my code and I can do what I want with it 😈 (read: I'm fine with it being MIT for oxc).
This PR is a complete feature in its own right, but does not represent the end of this work. See https://github.com/oxc-project/backlog/issues/116 to track overall progress.
- part of https://github.com/oxc-project/oxc/issues/5416
Replaces the handwritten regex parsing logic with the `oxc_regular_expression` parser, which should be more accurate and enables support for unicode sets.
- part of https://github.com/oxc-project/oxc/issues/5416
Use the `oxc_regular_expression` parser to make these checks more robust. a few snapshots are updated because they now output more accurate diagnostics based on the regex AST. for example, `/ ?/` now correctly only highlights two spaces rather than three (because the last one is part of a quantifier)
- part of https://github.com/oxc-project/oxc/issues/5416
This change enhances the accuracy of the `prefer_string_starts_ends_with` rule by using the parsed regex patterns for analysis. It allows for more precise detection of patterns that can be replaced with `startsWith()` and `endsWith()` methods, reducing false positives and improving the overall effectiveness of the linter.
### What changed?
- Replaced the simple string-based regex analysis with a more robust AST-based approach.
- Removed the `is_simple_string` function as it's no longer needed.
- part of https://github.com/oxc-project/oxc/issues/479
The bulk of this rule is closely based on the logic from the original ESLint rule. One major difference between this implementation and the original though is the lack of a tokenizer. ESLint uses a proper tokenizer to find identifers, parentheses, brackets, and other tokens. For this rule, I opted to just manually search for the characters we might expect to find. I'm not sure how this will hold up in the real world, I expect it could lead to some missing cases potentially, but it at least works for all of the given test cases.
This will replace `OxlintOptions` in an upstream PR. This also adds `plugins` to
`Oxlintrc`. This field gets respected by the builder, but not by
`OxlintOptions`.
hypothesis: profiling shows that Regex creation takes a decent amount of time. the `regex` crate uses `aho-corasick` internally for string matching, which is all we need in some cases. in theory, we could save time by using the lib directly and not needing the full regex syntax.
- part of https://github.com/oxc-project/oxc/issues/479
This implements the `no-extend-native` rule from the ESLint core
ruleset. This was translated based on the rule source code from the
ESLint codebase. That means some oddity, such as treating any
capitalized identifier (like `Math`) as a global object, is preserved.
So even though `Math.prototype` doesn't exist in reality, we still
report it as an error. This is probably okay given that such code
doesn't make sense anyway.
Cleans diagnostic messages and help texts for (almost) all remaining rules.
There were two rules I couldn' find good replacements for.
I also made some logical improvements to a few rules, and added `pending` fixers
to others.
This rule is enabled by default in typescript-eslint's recommended config, so we
should enable it by default too. I checked this change with `oxlint-ecosystem-ci` locally and saw no problems.
This PR also improves diagnostic messages for this rule.
## What This PR Does
Each time a lint rule is run on a file, it will now store diagnostics in a
shared vec instead of having its own list. This is done by moving `diagnostics`
from `LintContext` to `ContextHost`.
The motivating line of code can be found in `Linter::run` in
`oxc_linter/src/lib.rs#145`
```rust
rules.into_iter().flat_map(|(_, ctx)| ctx.into_message()).collect::<Vec<_>>()
```
Each `LintContext` allocates a new vec, and pushes diagnostics into it. After
all run-related methods have been run, a new vec is created and those
diagnostics are copied into it. This is `O(n+1)` allocations and `O(n)` copies,
not to mention that allocations for the original vecs cannot be re-used since
those vecs aren't dropped until after the new one is created.
- Part of https://github.com/oxc-project/oxc/issues/1022
This implements the [recommended rule
`no-danger-with-children`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md)
from the `eslint-plugin-react` package.
This rule proved to be a little bit trickier to implement than I
anticipated, as it required searching up through all of the scopes
recursively in order to resolve object properties. This would be easier
with something like a type-check system, but this will work for now.
(Sidenote: this is my first real attempt at Rust programming in ~5
years, so any feedback on making this more idiomatic is welcome.)
> Related to #5770
## What This PR Does
Moves state that is constant over a linted file out of `LintContext` and into a shared `ContextHost` struct, turning `LintContext` into a [flyweight](https://en.wikipedia.org/wiki/Flyweight_pattern).
This brings `LintContext` from 144 bytes down to 96. `Linter::run` iterates over `(rule, ctx)` pairs in a very tight loop, and each rule instance gets its own clone of `ctx`. A smaller `LintContext` means better cache locality and a smaller heap allocation for this vec. I'm hoping to eventually get it small enough to fit in a single cache line.
I made a PR a while ago that did something similar to this one, but instead of using an `Rc`, each `LintContext` stored a read-only reference. This added an extra lifetime parameter, making it slightly unwieldy, but I saw up to 15%/25% perf improvements on local benchmarks. I'll dig around for it and add a link shortly.
### Architecture

----

This is to fix the cases mentioned in the comment section of #5365.
In short, it will report these as PASS test cases:
```js
let inner;
function foo1() {
inner = function() {}
}
function foo2() {
inner = function() {}
}
```
```js
let inner;
function outer() {
inner = function() {}
}
```
And report these below as FAIL test cases:
```js
let inner;
function foo1() {
inner = function smth() {}
}
function foo2() {
inner = function bar() {}
}
```
```js
let inner;
function outer() {
inner = function inner() {}
}
```
The case below was already done in #5312 but mentioned in #5365. It is a
FAIL case as well:
```js
function outer() {
const inner = function inner() {}
}
```
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Don Isaac <donald.isaac@gmail.com>
…t_function_return_type rule
This PR fixes an issue where the Bitwise AND (&) operator was mistakenly
used in a conditional statement, instead of the Logical AND (&&)
operator.
- part of https://github.com/oxc-project/oxc/issues/479
This PR implements the `no-plusplus` rule and is more-or-less a direct
port of the ESLint version of the rule.
---------
Co-authored-by: Don Isaac <donald.isaac@gmail.com>
This PR adds the `eslint/sort-keys` implementation as part of #479
Note: two tests are commented out. I was not able to model this behavior
properly. I would be happy to have some assistance there.