Commit graph

7114 commits

Author SHA1 Message Date
overlookmotel
85aff19514 perf(transformer): introduce Stack (#6093)
`Stack` is a stack structure, optimized for fast push/pop and reading/writing the last entry on the stack. The difference from `NonEmptyStack` is that it can be empty.

This has a different trade-off vs `NonEmptyStack`:

* `Stack::new` does not allocate (`NonEmptyStack` does).
* `Stack::last` and `Stack::last_mut` are fallible and contain a branch (those methods on `NonEmptyStack` are branchless and infallible).

`Stack` is only the better choice if:
1. You want `new()` not to allocate. or
2. Creating initial value for `NonEmptyStack::new()` is expensive.

Use `Stack` as one of the backing stores in `SparseStack`.
2024-09-27 04:28:54 +00:00
overlookmotel
ad4ef31f9f perf(transformer): introduce NonEmptyStack (#6092)
`NonEmptyStack` is a stack structure, optimized for fast push/pop and reading/writing the last entry on the stack. By always having 1 at least one entry, `last` and `last_mut` can be made branchless and extremely cheap (only 1 CPU op).

Use `NonEmptyStack` as one of the backing stores in `SparseStack`.
2024-09-27 04:28:53 +00:00
overlookmotel
1399d2ce1f refactor(transformer): move SparseStack definition into folder (#6091)
Pure refactor. Just move file into a separate directory.
2024-09-27 04:28:53 +00:00
overlookmotel
6bd29ddc9e refactor(transformer): add more debug assertions (#6090)
Test stacks are in expected state at end of traversal.
2024-09-27 04:28:52 +00:00
overlookmotel
c90b9bfb6d refactor(transformer): rename SparseStack methods (#6089)
Pure refactor. Just rename methods.
2024-09-27 04:28:51 +00:00
DonIsaac
bd8f7867eb fix(linter): rule and generic filters do not re-configure existing rules (#6087)
Continuation of #6085.
2024-09-27 03:39:01 +00:00
DonIsaac
c5cdb4c615 fix(linter): disable all rules in a plugin when that plugin gets turned off (#6086)
Fixes a bug where rules for a plugin are still added to the linter after that plugin gets disabled.

```rust
// `linter` still has typescript-eslint rules. This PR fixes that.
let linter = LinterBuilder::default()
  .and_plugins(LintPlugins::TYPESCRIPT, false)
  .build();
```
2024-09-27 02:22:27 +00:00
DonIsaac
6c855affa3 fix(linter): only write fix results if source code has changed (#6096)
Closes #6061.

Read [this reply](https://github.com/oxc-project/oxc/issues/6061#issuecomment-2378226722) for context.
2024-09-27 02:14:27 +00:00
michaelm
418ae25f3d
fix(isolated-declarations): Report uninferrable types in arrays (#6084) 2024-09-27 07:31:22 +08:00
DonIsaac
87595286ce fix(linter): category filters not re-configuring already-enabled rules (#6085)
> AI generated because I'm busy
### TL;DR

Enhanced LinterBuilder functionality and improved rule configuration handling.

### What changed?

- Made `rules` field in `LinterBuilder` public within the crate.
- Added a `plugins()` method to `LinterBuilder` to access lint plugins.
- Improved rule configuration logic in `configure_rules` method to update existing rules' severity.
- Added comprehensive test cases for `LinterBuilder` functionality.
- Implemented `Borrow<RuleEnum>` for `RuleWithSeverity` to improve rule lookup efficiency.

### How to test?

1. Run the newly added test cases in the `test` module of `builder.rs`.
2. Verify that all tests pass, including:
   - Default builder configuration
   - Empty builder configuration
   - Rule filtering and severity changes
   - Plugin configuration and rule interactions

### Why make this change?

These changes improve the flexibility and robustness of the linter configuration process:

1. Allowing access to the `rules` field enables more advanced customization options.
2. The new `plugins()` method provides better visibility into configured plugins.
3. Updating existing rules' severity ensures consistent behavior when reconfiguring rules.
4. Comprehensive tests ensure the reliability of the `LinterBuilder` functionality.
5. Implementing `Borrow<RuleEnum>` for `RuleWithSeverity` optimizes rule lookup operations.

These enhancements contribute to a more maintainable and efficient linter system.
2024-09-26 20:18:18 +00:00
DonIsaac
55949ebd88 test(linter): add OxlintRules::override_rules tests (#6081)
wrote these while working on better understanding this method in prep for the `LinterBuilder` migration.
2024-09-26 19:40:26 +00:00
DonIsaac
1a6923a891 test(linter): add filter parsing test cases (#6080)
I also deleted some commented-out-code I forgot to remove in a previous PR
2024-09-26 17:15:19 +00:00
Dunqing
6b7d3ed613 perf(isolated-declarations): should clone transformed AST rather than original AST (#6078)
close: #6074
Performance regression introduced by https://github.com/oxc-project/oxc/pull/5909. After this PR we back to the fold pattern again
2024-09-26 15:50:27 +00:00
Dunqing
cca433f84a feat(codegen): print vite / webpack special comments (#6021)
Related: https://github.com/oxc-project/oxc/issues/1046#issuecomment-2347345319
Close: #6024
2024-09-26 15:19:31 +00:00
overlookmotel
efabfc8dac docs(semantic): improve doc comments on Reference methods (#6076) 2024-09-26 12:22:31 +00:00
camc314
c2616f7fa1 fix(linter): fix panic in fixer for oxc/only-used-in-recursion (#6070)
closes #6068
2024-09-26 10:50:49 +00:00
Boshen
01b9c4bedc fix(npm/oxlint): make bin/oxc_language_server an executable (#6066)
closes #6064
2024-09-26 06:02:01 +00:00
camchenry
8d026e1dd9 feat(regular_expression): implement GetSpan for RegExp AST nodes (#6056)
To make it easier to get the `Span` for some node in the Regex AST, I've implemented the `GetSpan` trait for all necessary structs.
2024-09-26 05:51:35 +00:00
Dunqing
60c52ba2b9 feat(ast): allow passing span to void_0 method (#6065)
unblock #6021

Keep the original expression's `span` to insert comments correctly. Have tested in #6021 and it worked
2024-09-26 05:46:40 +00:00
camchenry
77647931e4 feat(regular_expression): implement visitor pattern trait for regex AST (#6055)
- resolves https://github.com/oxc-project/oxc/issues/5977
- supersedes https://github.com/oxc-project/oxc/pull/5951

To facilitate easier traversal of the Regex AST, this PR defines a `Visit` trait with default implementations that will walk the entirety of the Regex AST. Methods in the `Visit` trait can be overridden with custom implementations to do things like analyzing only certain nodes in a regular expression, which will be useful for regex-related `oxc_linter` rules.

In the future, we should consider automatically generating this code as it is very repetitive, but for now a handwritten visitor is sufficient.
2024-09-26 05:04:46 +00:00
DonIsaac
3da3845f24 fix(linter): malformed snippets in eslint/for-direction docs (#6060) 2024-09-25 21:47:38 +00:00
dalaoshu
a4fdf1bc49
docs(linter): improve docs for promise rules (#6051) 2024-09-25 08:33:07 -04:00
DonIsaac
b1af73db81 fix(semantic): do not create a global symbol for declare global {} (#6040)
Re-creation of #6004 to unblock it from down-stack PRs. @Boshen has already reviewed the previous PR and determined this to be correct behavior.
2024-09-25 08:46:00 +00:00
overlookmotel
a4cec7585e test(transformer): enable tests (#6032)
`oxc_transformer` crate has some tests, but they were disabled.
2024-09-25 06:31:46 +00:00
Dunqing
fe696f0dec refactor(codegen): simplify printing annotation comments (#6027)
Simplify printing annotation comments, reusing the architecture of printing JSDoc.
2024-09-25 06:27:18 +00:00
DonIsaac
f866781f49 feat(semantic): check for type annotations on left side of for..in and for..of iterators (#6043) 2024-09-25 02:51:17 +00:00
DonIsaac
8b2e9aa744 feat(semantic): check for JSDoc types in TS type annotations (#6042)
Closes #5982
2024-09-25 02:35:59 +00:00
DonIsaac
93575cd09e test(semantic): add comprehensive regression test suite (#5976)
# What This PR Does

Enhance's `oxc_semantic`'s integration tests with a regression test suite that ensures semantic's contract guarantees hold over all test cases in typescript-eslint's scope snapshot tests. Each test case checks a separate assumption and runs independently from other test cases.

This PR sets up the code infrastructure for this test suite and adds two test cases to start us off:
1. Reflexivity tests for `IdentifierReference` and `Reference`
2. Symbol declaration reflexivity tests between declarations in `SymbolTable` and their corresponding node in the AST.

Please refer to the doc comments for each of these tests for an in-depth explanation.

## Aren't our existing tests sufficient?
`oxc_semantic` is currently tested directly via
1. scope snapshot tests, ported from `typescript-eslint`
2. Hand-written tests using `SemanticTester` in `tests/integration`

And indirectly via

3. Conformance test suite over Test262/TypeScript/Babel
4. Linter snapshot tests

Shouldn't this be sufficient? I argue not, for two reasons:

## 1. Clarify Contract Ambiguity

When using `Semantic`, I often find myself asking these questions?
* Does `semantic.symbols().get_declaration(id)` point to a `BindingIdentifer`/`BindingPattern` or the declaration that holds an identifier/pattern?
* Will a `Reference`'s `node_id` point me to an `IdentifierReference` or the expression/statement that is holding an `IdentifierReference`?
* When will `BindingIdentifier`'s `symbol_id` get populated? can we guarantee that after semantic analysis it will never be `None`?
* What actually _is_ the node covered by `semantic.symbols().get_span(id)`? This one really messed me up, and resulted in me creating #4739.
* What scope does `Function::scope_id` point to? The one where the function is declared? The one created by its body? The one created by the type annotations but before the function body? Or something else entirely?

**These test cases are meant to answer such questions and guarnatee those answers as test cases**. No other existing testing solution currently upholds such promises: they only tell us if code expecting one answer or another produces an unexpected result. However, those parts of the codebase could always be adjusted to conform to new `Semantic` behavior, meaning no contract guarantees are actually upheld.

## 2. Existing Tests Do Not Test The Same Behavior

I'll cover each above listed test case one-by-one:

1. For starters, these tests only cover scopes. Additionally, they only tell us **how behavior has changed**, not that **behavior is now incorrect**.
2. These _do_ generally cover the same behaviors, but **are not comprehensive and are difficult to maintain**. These are unit tests that should be used hand-in-hand with this new test suite.
3. The most relevant tests here are for the parser. However, these tests **only tell us if a syntax/parse error was produced**, and tell us nothing about the validity of `Semantic`.
4. Relying on lint rule's output is a a mediiocre proxy of `Semantic`'s behavior at best. They can tell us if changes to `Semantic` break assumptions made by lint rules, but they do not tell us if **those assumptions are the ones we want to uphold to external crates consuming `Semantic`.
2024-09-25 02:24:57 +00:00
DonIsaac
3099709dcd docs(allocator): document oxc_allocator crate (#6037)
Part of #5870
2024-09-25 02:16:32 +00:00
DonIsaac
d60ceb4a0b docs(oxc): add README.md and crate-level docs (#6035) 2024-09-25 02:16:31 +00:00
camchenry
c047d423b1 fix(linter): no-useless-escape: do not crash on backslash character (#6048)
Fixes https://github.com/oxc-project/oxc/issues/6046

Unlike other escape sequences such as `/\w/`, this is not actually parsed as a single character: `/\c/` so we incorrectly try to get the character before the backslash, which doesn't exist.
2024-09-24 23:25:49 +00:00
camchenry
58d333a533 test(linter): add more test cases for disable directives (#6047)
- related to https://github.com/oxc-project/oxc/issues/6041
- follow-up to https://github.com/oxc-project/oxc/pull/6045

While working on the original PR, I noticed that we didn't have any pathological test cases yet for disable directives. I've added some more complex test cases here to ensure we don't regress the disable/enable behavior in the future.
2024-09-24 23:20:47 +00:00
camchenry
6f76ebe302 fix(linter): ignore invalid or partial disable directives (#6045)
- closes https://github.com/oxc-project/oxc/issues/6041

We were not ignoring cases where the directive was invalid, now we do.
2024-09-24 21:24:34 +00:00
Alexander S.
f8464a3953
perf(linter): no-magic-numbers remove redudant checks in is_array_index (#6033)
- there can not be an `UnaryExpression` as a `parent_kind`, when the
`ast_kind` is `NumericLiteral`,
  `InternConfig::from` prevents it from happending
- `NumericLiteral` can not be negative or else they would be passed as
`UnaryExpression`
2024-09-24 14:46:56 -04:00
camchenry
09a24cd9f1 fix(linter): fix false positives for generics in no-unexpected-multiline (#6039)
- follow-up to https://github.com/oxc-project/oxc/pull/6031
2024-09-24 18:10:01 +00:00
camchenry
1f92d61097 refactor(linter): jest/prefer-hooks-in-order: improve diagnostic messages (#6036)
In the previous PR, I added an additional span that allows us to actually point to the prior hook function that the hook should be moved above. I've updated the error messages to hopefully be a little bit more helpful in explaining what to do.
2024-09-24 17:51:10 +00:00
camchenry
c16ae6038e perf(linter): jest/prefer-hooks-in-order: rewrite rule to allocate less and iterate fewer times (#6030)
Profiling this in a single-threaded run showed this rule to be relatively slow compared to other rules:

<img width="907" alt="image" src="https://github.com/user-attachments/assets/789cdc1f-d1ce-4d4a-bfa3-5882bd92cfc4">

The profile shows that a lot of time is spent doing pushes on `Vec`:
<img width="896" alt="image" src="https://github.com/user-attachments/assets/cde361d7-091d-42db-abc2-76a0c8a7fa44">

I believe this is because we were essentially duplicating the entirety of `ctx.nodes()`, and then iterating over it again for the actual rule.

I addressed this by:

- We no longer store any nodes (we only store the previous hook span + order), which saves many allocations.
- We only iterate over the nodes once and store the previous hook function in a per-scope hash map. This should be faster since we now only do `n` iterations, instead of `2n` iterations.

Benchmarking on the `microsoft/vscode` repository shows that this is probably faster (by up to ~3%), and probably not any slower:

<img width="992" alt="Screenshot 2024-09-24 at 12 06 32 PM" src="https://github.com/user-attachments/assets/ab916464-1b50-48e1-a65d-f9b3a4b4607d">

The snapshot change in this PR is due to slightly different ordering, I think, but it appears to be the same diagnostics overall.
2024-09-24 17:51:09 +00:00
DonIsaac
d05fd20906 fix(linter): newline in type parameters causing false positive in no-unexpected-multiline (#6031)
Fixes a bug in `eslint/no-unexpected-multiline` where newlines in
function call type parameters triggered a false positive. For example:

```ts
const foo = bar<{
    a: string
    b: number
}>();
```
2024-09-24 16:14:06 +00:00
Boshen
21cdb784d6 docs(linter): fix incorrect "bad" example in only-used-in-recursion (#6029)
closes #4811
2024-09-24 14:47:41 +00:00
Boshen
e0a895962d fix(minifier): compute void number as undefined (#6028) 2024-09-24 14:39:44 +00:00
oxc-bot
539751cd13
release(oxlint): v0.9.8 (#6025)
## [0.9.8] - 2024-09-24

### Bug Fixes

- e3c8a12 linter: Fix panic in sort-keys (#6017) (Boshen)
- 4771492 linter: Fix `import/no_cycle` with `ignoreTypes` (#5995)
(Boshen)

### Performance

- 5ae3f36 linter: `no-fallthrough`: Use string matching instead of Regex
for default comment pattern (#6008) (camchenry)
- 2b17003 linter, prettier, diagnostics: Use `FxHashMap` instead of
`std::collections::HashMap` (#5993) (camchenry)

---------

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-09-24 19:43:11 +08:00
Cam McHenry
65d8f9e8fe
perf(linter, ast-tools, coverage): Use FxHashSet instead of std::collections::HashSet (#6001) 2024-09-24 19:29:08 +08:00
Boshen
28da77195b feat(transformer): do not transform ** with bigint literals (#6023)
part of #5822

They will produce runtime errors.
2024-09-24 10:33:02 +00:00
Boshen
2b380c8f15 refactor(transformer): remove unsued self.ctx (#6022)
They are remnants from our past code.
2024-09-24 10:14:04 +00:00
Boshen
0658576718 fix(paresr): do not report missing initializer error in ambient context (#6020)
closes #5958
2024-09-24 09:04:09 +00:00
Cam McHenry
0c9dee1eda
chore(oxc): ban std::collections::HashMap in favor of FxHashMap (#5996)
Co-authored-by: camchenry <1514176+camchenry@users.noreply.github.com>
2024-09-24 16:41:36 +08:00
Boshen
c8682e9fcb fix(semantic,codegen,transformer): handle definite ! operator in variable declarator (#6019)
closes #5999
2024-09-24 08:32:05 +00:00
Boshen
a88504cefb fix(diagnostics): check for terminal when displaying links (#6018)
fixes #5819
2024-09-24 07:18:07 +00:00
Boshen
e3c8a12c0d fix(linter): fix panic in sort-keys (#6017)
closes #5773
2024-09-24 06:51:38 +00:00
Dunqing
1fc80d1bba refactor(ast): move all ts ast related impl methods to ast_impl (#6015) 2024-09-24 06:07:37 +00:00