Commit graph

5796 commits

Author SHA1 Message Date
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
oxc-bot
7f0e27afd9
release(crates): v0.30.1 (#6016)
## [0.30.1] - 2024-09-24

### Features

- 5c323a2 minifier: Loop compressor passes (#6013) (Boshen)

### Bug Fixes

- 9ca202a codegen: Preserve newlines between comments (#6014) (Boshen)
- 4a99372 codegen: Print jsdoc comments for `TSEnumMember`s (#6007)
(camc314)
- 97a2c41 isolated-declarations: False positive for class private getter
with non-inferrable return type (#5987) (michaelm)

### Performance

- 2b17003 linter, prettier, diagnostics: Use `FxHashMap` instead of
`std::collections::HashMap` (#5993) (camchenry)
- 7b90d79 transformer: `SparseStack` always keep minimum 1 entry (#5962)
(overlookmotel)
- 28fe80a transformer: Logical assignment operator transform use
`SparseStack` (#5960) (overlookmotel)
- 9f7d4b7 transformer: Exponentiation operator transform use
`SparseStack` (#5959) (overlookmotel)
- 5dc0154 transformer: Nullish coalescing operator transform use
`SparseStack` (#5942) (overlookmotel)
- 618e89e transformer: Arrow function transform: reduce stack memory
usage (#5940) (overlookmotel)

### Documentation

- 5a0d17c ast: Document more AST nodes (#6000) (DonIsaac)
- 18371dd oxc: Include feature-guarded modules in docs.rs (#6012)
(DonIsaac)
- 1abfe8f semantic: Document `SymbolTable` (#5998) (DonIsaac)
- f5eee72 semantic: Correct docs for `Reference` (#5992) (overlookmotel)
- 860f108 transformer: Add to arrow functions transform docs (#5989)
(overlookmotel)

### Refactor

- 0a2f687 minifier: Move dce conditional expression to `RemoveDeadCode`
(#5971) (Boshen)
- f02bf51 transformer: Arrow function transform: remove unnecessary
assertion (#6002) (overlookmotel)

---------

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 14:03:03 +08:00
Boshen
9ca202a01e fix(codegen): preserve newlines between comments (#6014)
fixes #6010
2024-09-24 05:14:02 +00:00
Boshen
5c323a2105 feat(minifier): loop compressor passes (#6013) 2024-09-24 03:09:35 +00:00
DonIsaac
18371dda3d docs(oxc): include feature-guarded modules in docs.rs (#6012) 2024-09-24 02:42:00 +00:00
DonIsaac
c77cd24fec chore(oxc): include all features in all feature (#6011) 2024-09-24 02:41:59 +00:00
camc314
4a99372c14 fix(codegen): print jsdoc comments for TSEnumMembers (#6007)
closes #6006

Boshen/Dunqing please feel free to take over this PR. it's a bit outside what i normally work on. 🙂
2024-09-24 01:12:57 +00:00
camchenry
5ae3f364e9 perf(linter): no-fallthrough: Use string matching instead of Regex for default comment pattern (#6008)
Profiling has shown this rule to be a consistent slow point, and in particular, the Regex construction is slow.

<img width="1323" alt="Screenshot 2024-09-23 at 7 12 58 PM" src="https://github.com/user-attachments/assets/1d9b367d-eeda-4b19-b0a3-463e54ac4334">

This PR improves the situation in two ways:

1. A `Regex` is only constructed when there is a custom comment pattern (which is likely the minority of cases)
2. For the default comment pattern (when no custom pattern is passed), we now use a simple string matcher function, instead of a full-blown regex matcher. I believe this should be faster since it involves much less work, though can still allocate a `String`.
2024-09-24 01:06:00 +00:00
DonIsaac
5a0d17c9aa docs(ast): document more AST nodes (#6000) 2024-09-23 23:19:43 +00:00
DonIsaac
1abfe8f02c docs(semantic): document SymbolTable (#5998)
Re-creation of #5978, per @overlookmotel's request
2024-09-23 23:19:41 +00:00
camchenry
02d5637dbc perf(ast-tools): use FxHashMap over std::collections::HashMap (#5997) 2024-09-23 18:28:54 +00:00
overlookmotel
f02bf516cf refactor(transformer): arrow function transform: remove unnecessary assertion (#6002)
This assertion was required previously for soundness, but now `SparseStack::pop` makes it impossible for `self.this_var_stack.len()` to be 0. Being exactly 1 is not a safety invariant, only that it's not 0.
2024-09-23 18:05:31 +00:00
camchenry
2b17003e0b perf(linter, prettier, diagnostics): use FxHashMap instead of std::collections::HashMap (#5993)
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`.
2024-09-23 16:29:05 +00:00
camchenry
b240b42eb9 fix(rulegen): handle raw string literals correctly (#5991)
Currently, we are not handling raw string literals correctly and just translating them as normal Rust string literals, which causes compile errors and also misses some cases. This PR updates it so that we detect usage of `String.raw` and translate it as a Rust raw string literal.

Before:

<img width="867" alt="Screenshot 2024-09-23 at 10 02 21 AM" src="https://github.com/user-attachments/assets/7c042537-d6c2-4141-a119-0ed846bce59d">

After:

<img width="832" alt="Screenshot 2024-09-23 at 10 01 27 AM" src="https://github.com/user-attachments/assets/759f6647-a675-42eb-b39d-c0e88f689536">
2024-09-23 16:24:19 +00:00
Boshen
4771492b6a fix(linter): fix import/no_cycle with ignoreTypes (#5995)
related https://github.com/toeverything/AFFiNE/issues/7580

`iter().all` produces `true` on an empty list.
2024-09-23 15:10:53 +00:00
overlookmotel
f5eee723fa docs(semantic): correct docs for Reference (#5992)
Correct docs. `JSXIdentifier` no longer has a reference.
2024-09-23 14:48:19 +00:00
Boshen
0a2f68756f refactor(minifier): move dce conditional expression to RemoveDeadCode (#5971)
This is aligned to closure compiler
2024-09-23 10:22:00 +00:00
overlookmotel
860f108a75 docs(transformer): add to arrow functions transform docs (#5989)
Add details of `spec` option and shorten example.
2024-09-23 09:49:39 +00:00
overlookmotel
7b90d794d1 perf(transformer): SparseStack always keep minimum 1 entry (#5962)
Optimize `SparseStack` (which was introduced in #5940). Initialize it with a single entry, and ensure the stack is never emptied. This makes `take`, `get_or_init` and `get_mut_or_init` methods infallible, since there is always an entry on the stack to read.
2024-09-23 07:52:47 +00:00