Commit graph

1798 commits

Author SHA1 Message Date
msdlisper
a36813405b
refactor(linter): perfect the scope linter (#2092)
perfect the scope linter for #1141
2024-01-20 10:46:35 +08:00
Boshen
2f5afff9bd
fix(parser): fix crash on TSTemplateLiteralType in function return position (#2089)
```
interface Helpers {
  inspect(): `~~~~\n${string}\n~~~~`;
}
```
2024-01-19 23:14:05 +08:00
Dunqing
721a869b6e
feat(linter): improve no_redeclare rule implementation (#2084) 2024-01-19 20:10:06 +08:00
Boshen
a9e2158362
Update README 2024-01-19 18:39:07 +08:00
Yuji Sugiura
2f1e1e2e46
feat/tasks: expose linter RULES and use it for listing (#2083)
Part of #2020 , follow up of #2081 .
2024-01-19 16:45:00 +08:00
Dunqing
b5b2ef34af
feat(transformer/typescript): improve function parameters name (#2079) 2024-01-19 13:50:10 +08:00
Dunqing
7711f7abaf
feat(transformer/typescript): support only_remove_type_imports option (#2077) 2024-01-18 23:25:31 +08:00
Dunqing
f5bf5dece1
feat(transformer/typescript): support transform exported TSModuleBlock (#2076) 2024-01-18 23:20:26 +08:00
Dunqing
56ca8b6dfe
feat(transformer/typescript): support transform namespace (#2075) 2024-01-18 23:15:28 +08:00
Dunqing
2e78b918d1
refactor(transformer/typescript): move the ExportNamedDeclaration logic to its function (#2074) 2024-01-18 21:28:48 +08:00
overlookmotel
0e32618664
refactor(parser): combine token kinds for skipped tokens (#2072)
Small optimization to the lexer.

Whitespace, line breaks, and comments are all skipped by
`read_next_token()`.

At present there's a different `Kind` for each, and `read_next_token()`
decides whether to skip with `matches!(kind, Kind::WhiteSpace |
Kind::NewLine | Kind::Comment | Kind::MultiLineComment)`.

These `Kind`s are used for no other purpose, so there seems little
reason to differentiate them.

This PR combines them all into `Kind::Skip`, so then the test of whether
to skip is reduced to `kind == Kind::Skip`.

Only produces ~0.3% performance bump on parser benchmarks. But, why
not?...
2024-01-18 21:14:12 +08:00
Valerii Smirnov
d7ecd21801
fix(linter): eslint-plugin-import no-named-as-default-member rule (#2071)
Fixed false positives and early return @mysteryven 
#1988

64de6e9265 (r1453429430)
2024-01-18 09:32:40 +08:00
Wenzhe Wang
29dc5e69ff
fix(codegen): add parenthesis in binary expression by precedence (#2067)
related ESBuild code:
f5f8ff895c/internal/js_printer/js_printer.go (L3348-L3371)
2024-01-17 23:01:42 +08:00
Dunqing
b89e84cc2d
feat(transformer/typescript): keep imports if import specifiers is empty (#2058) 2024-01-17 16:14:31 +08:00
Dunqing
24ac957660
fix(semantic): incorrect reference flag (#2057) 2024-01-17 16:08:31 +08:00
Dunqing
3413bb3884
feat(transformer/typescript): remove type-related exports (#2056) 2024-01-17 16:04:30 +08:00
Dunqing
95d741abd6
feat(transformer/typescript): remove type only imports/exports correctly (#2055) 2024-01-17 15:58:04 +08:00
overlookmotel
8d5f5b8a49
refactor(parser): macro for ASCII byte handlers (#2066)
As discussed on #2046, it wasn't ideal to have `unsafe {
lexer.consume_ascii_char() }` in every byte handler. It also wasn't
great to have a safe function `consume_ascii_char()` which could cause
UB if called incorrectly (so wasn't really safe at all).

This PR achieves the same objective of #2046, but using a macro to
define byte handlers for ASCII chars, which builds in the assertion that
next char is guaranteed to be ASCII.

Before #2046:

```rs
const SPS: ByteHandler = |lexer| {
  lexer.consume_char();
  Kind::WhiteSpace
};
```

After this PR:

```rs
ascii_byte_handler!(SPS(lexer) {
  lexer.consume_char();
  Kind::WhiteSpace
});
```

i.e. The body of the handlers are unchanged from how they were before
https://github.com/oxc-project/oxc/pull/2046.

This expands to:

```rs
const SPS: ByteHandler = |lexer| {
  unsafe {
    let s = lexer.current.chars.as_str();
    assert_unchecked!(!s.is_empty());
    assert_unchecked!(s.as_bytes()[0] < 128);
  }
  lexer.consume_char();
  Kind::WhiteSpace
};
```

But due to the assertions the macro inserts, `consume_char()` is now
optimized for ASCII characters, and reduces to a single instruction. So
the `consume_ascii_char()` function introduced by #2046 is unnecessary,
and can be removed again.

The "boundary of unsafe" is moved to a new function `handle_byte()`
which `read_next_token()` calls. `read_next_token()` is responsible for
upholding the safety invariants, which include ensuring that
`ascii_byte_handler!()` macro is not being misused (that last part is
strictly speaking a bit of a cheat, but...).

I am not a fan of macros, as they're not great for readability. But in
this case I don't think it's *too* bad, because:

1. The macro is well-documented.
2. It's not too clever (only one syntax is accepted).
3. It's used repetitively in a clear pattern, and once you've understood
one, you understand them all.

What do you think? Does this strike a reasonable balance between
readability and safety?
2024-01-17 15:29:15 +08:00
Bradley Farias
18a58d472b
feat(minifier): handle more expressions for side effects (#2062)
Eventually these should return effects rather than a bool since some can
be moved around and ignored. For now, keep it similar to previous code.
2024-01-17 11:22:02 +08:00
Boshen
3faa2aa2a8
fix(linter): s/consistent-type-export/consistent-type-exports (#2065) 2024-01-17 11:03:43 +08:00
Boshen
f514410427
refactor(linter): move LintSettings to its own file (#2052) 2024-01-16 17:23:55 +08:00
Boshen
ae4e714713
refactor(linter): remove the LintSettings parameter from LintContext::new. (#2051) 2024-01-16 17:17:46 +08:00
Boshen
9e06bd7797
feat(linter): remove the --timings feature (#2049)
For a various reasons:

This features bloats the code size.

We have many tools for profiling in Rust (as compared to ESLint where the feature came from),
so a built-in feature is not really needed anymore.

ESLint needed `--timings` because it needs to monitor plugins.
We control all our code so we don't need this.
2024-01-16 14:21:04 +08:00
Boshen
f4132976e9
chore: say good bye to ezno (#2048)
ezno has decided to focus on its own compiler for 2024,
we part away but we still collaborate and share knowledge together.
2024-01-16 13:53:54 +08:00
overlookmotel
408acb90e6
refactor(parser): lexer handle unicode without branch (#2039)
As suggested by @strager in
https://github.com/oxc-project/oxc/pull/2025#pullrequestreview-1820273832,
this PR adds `BYTE_HANDLERS` for first bytes of unicode characters.

This removes a branch from `read_next_token()` and produces a +1%
speed-up on parser benchmarks.
2024-01-16 13:14:22 +08:00
overlookmotel
66a7a68f9f
perf(parser): lexer byte handlers consume ASCII chars faster (#2046)
In the lexer, most `BYTE_HANDLER`s immediately consume the current char
with `lexer.consume_char()`.

Byte handlers are only called if there's a certain value (or range of
values) for the next char. This is their entire purpose. So in all cases
we know for sure that we're not at EOF, and that the next char is a
single-byte ASCII character.

The compiler, however, doesn't seem to be able to "see through" the
`BYTE_HANDLERS[byte](self)` call and understand these invariants. So it
produces very verbose ASM for `lexer.consume_char()`.

This PR replaces `lexer.consume_char()` in the byte handlers with an
unsafe `lexer.consume_ascii_char()` which skips on to next char with a
single `inc` instruction.

The difference in codegen can be seen here:
https://godbolt.org/z/1ha3cr9W5 (compare the 2 x
`core::ops::function::FnOnce::call_once` handlers).

Downside is that this does introduce a lot of unsafe blocks, but in my
opinion they're all pretty trivial to validate.

---------

Co-authored-by: Boshen <boshenc@gmail.com>
2024-01-16 12:31:45 +08:00
Boshen
09c7570560
ci: use miri to detect memory leak for the parser (#2037)
We'll merge this and then eventually turn it on as a nightly check, it's
a manual run for now.
2024-01-15 15:11:02 +00:00
Valerii Smirnov
c60c31521e
feat(linter): eslint-plugin-import no-named-as-default-member rule (#1988)
- Docs:
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-named-as-default-member.md
- Code:
https://github.com/import-js/eslint-plugin-import/blob/main/src/rules/no-named-as-default-member.js
- Tests:
https://github.com/import-js/eslint-plugin-import/blob/main/tests/src/rules/no-named-as-default-member.js
2024-01-15 11:03:04 +00:00
dependabot[bot]
21909fa962
chore(deps): bump the dependencies group with 3 updates (#2033) 2024-01-15 15:31:32 +08:00
Boshen
3b40fbdbac
fix(linter): false positive for filename_case where filename doesn't have a proper casing (#2032) 2024-01-15 14:36:48 +08:00
Boshen
68606c4d6d
fix(linter): keep rules disabled if the rule is not enabled in the config (#2031)
relates #1969
2024-01-15 05:32:51 +00:00
Bradley Farias
3490111c56
Commutative undefined minify (#2003)
this should probably be squashed, i'm not familiar with code commit
norms here. we can expand a bunch of the commutative compressions later.

---------

Co-authored-by: Boshen <boshenc@gmail.com>
2024-01-15 02:51:53 +00:00
Yuto Yoshino
530d1bea56
feat(linter): eslint-plugin-jsx-a11y no-redundant-roles rule (#1981)
Part of: https://github.com/oxc-project/oxc/issues/1141

Based on:
- doc: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-redundant-roles.md
- code: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/rules/no-redundant-roles.js
- test: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/__tests__/src/rules/no-redundant-roles-test.js
2024-01-14 21:03:58 +00:00
overlookmotel
b4d76f0b0d
refactor(parser): remove noop code (#2028)
This PR removes some code from the lexer which doesn't do anything.
2024-01-14 23:48:35 +08:00
keita hino
198f0e5d73
feat(linter): eslint-plugin-jsx-a11y aria-activedescendant-has-tabindex (#2012)
Part of: #1141

Based on:
- docs: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-activedescendant-has-tabindex.md
- code: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/rules/aria-activedescendant-has-tabindex.js
- test: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js
2024-01-14 11:34:07 +00:00
overlookmotel
60a927d8f5
perf(parser): lexer match byte not char (#2025)
2 related changes to lexer's `read_next_token()`:

1. Hint to branch predictor that unicode identifiers and non-standard
whitespace are rare by marking that branch `#[cold]`.

2. The branch is on whether next character is ASCII or not. This check
only requires reading 1 byte, as ASCII characters are always single byte
in UTF8. So only do the work of getting a `char` in the cold path, once
it's established that character is not ASCII and this work is required.
2024-01-14 18:50:11 +08:00
kaykdm
a356918d83
feat(linter): eslint-plugin-next: no-document-import-in-page (#1997)
Part of: https://github.com/oxc-project/oxc/issues/1929

Based on:
- https://github.com/vercel/next.js/blob/canary/packages/eslint-plugin-next/src/rules/no-document-import-in-page.ts
-  https://nextjs.org/docs/messages/no-document-import-in-page

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
2024-01-13 17:52:47 +00:00
kaykdm
c70a065191
feat(linter): eslint-plugin-next: no-head-element (#2006)
Part of: https://github.com/oxc-project/oxc/issues/1929

Based on:

- code: https://github.com/vercel/next.js/blob/canary/packages/eslint-plugin-next/src/rules/no-head-element.ts
- test: https://github.com/vercel/next.js/blob/canary/test/unit/eslint-plugin-next/no-head-element.test.ts
- doc: https://nextjs.org/docs/messages/no-head-element

---------

Co-authored-by: Cameron Clark <cameron.clark@hey.com>
2024-01-13 17:47:32 +00:00
kaykdm
8f0f824a6a
feat(linter): eslint-plugin-next: no-typos (#1978)
Part of: https://github.com/oxc-project/oxc/issues/1929

Based on:
https://github.com/vercel/next.js/blob/canary/packages/eslint-plugin-next/src/rules/no-typos.ts
2024-01-13 17:42:11 +00:00
Dunqing
ac4b3a4f8d
feat(ast): visit TSTypeQuery (#2021)
```ts
type Bar = typeof Foo;
```
2024-01-14 00:38:18 +08:00
magic-akari
9b77d0e6e6
fix(prettier): Correctly print export declaration (#2014)
Before this PR:
<img width="912" alt="image"
src="https://github.com/oxc-project/oxc/assets/7829098/78605f25-3320-4bed-8a31-3ffa7604cdc7">

https://oxc-project.github.io/oxc/playground/?code=3YCAAICUgICAgICAgICyHorESipoTXBToMuz4zZHvH%2B4MPS3Y6F%2FfvvogA%3D%3D
2024-01-13 21:26:33 +08:00
Dunqing
6c7f983de5
feat(transformer/typescript): remove export specifier that import_kind is type (#2015) 2024-01-13 21:25:59 +08:00
magic-akari
869643b03b
fix(prettier): Correctly format call expression arguments (#2018) 2024-01-13 21:25:26 +08:00
Yuji Sugiura
04540f749d
feat(linter): eslint-plugin-jsx-a11y click-events-have-key-events (#1976)
( #1974  was lost due to mishandling. 🙈 )

Part of #1141 

### Refs
-
4c7e7815c1/docs/rules/click-events-have-key-events.md
-
4c7e7815c1/src/rules/click-events-have-key-events.js
-
4c7e7815c1/__tests__/src/rules/click-events-have-key-events-test.js

---------

Co-authored-by: Boshen <boshenc@gmail.com>
2024-01-13 09:27:26 +00:00
Dunqing
ead4e8df1f
feat(transformer/typescript): remove import if only have type reference (#2001) 2024-01-13 08:52:14 +00:00
Boshen
b386177af2
refactor(linter): move away from tuples for test cases (#2011)
closes #1956
2024-01-13 16:23:16 +08:00
Boshen
1886a5b838
perf(parser): reduce Token size from 16 to 12 bytes (#2010)
I also had to change how the string for private identifiers are built,
otherwise they will always be allocated.
2024-01-13 12:42:39 +08:00
overlookmotel
6996948825
refactor(parser): remove extraneous code from regex parsing (#2008)
This PR removes some code in parsing regexp flags which is extraneous:

```rs
if !ch.is_ascii_lowercase() {
  self.error(diagnostics::RegExpFlag(ch, self.current_offset()));
  continue;
}
```

Which is followed by:

```rs
let flag = if let Ok(flag) = RegExpFlags::try_from(ch) {
  flag
} else {
  self.error(diagnostics::RegExpFlag(ch, self.current_offset()));
  continue;
};
```

`!ch.is_ascii_lowercase()` is equivalent to `ch < 'a' || ch > 'z'`. The
compiler implements `RegExpFlags::try_from(ch)` as `ch < 'd' || ch >
'y'` and then a jump table. So `ch.is_ascii_lowercase()` does nothing
that `RegExpFlags::try_from(ch)` doesn't do already.

https://godbolt.org/z/51GPPY9nx

(this PR built on top of #2007 for ease)
2024-01-13 02:34:05 +00:00
Cameron
107a32ea48
fix(linter): fix false positive for erasing-op in 0/0 case (#2009) 2024-01-13 10:32:26 +08:00
overlookmotel
712e99cf9b
fix(parser): restore regex flag parsing (#2007)
As discussed in
https://github.com/oxc-project/oxc/pull/1999#issuecomment-1888916383,
this PR restores some of regex parsing behavior to as it was prior to
#1926.
2024-01-13 03:19:33 +08:00