Commit graph

471 commits

Author SHA1 Message Date
Boshen
e78cba6464 refactor(minifier): ast passes infrastructure (#4625)
After studying google closure compiler, I'm leaning towards a multi-ast-pass infrastructure for the minifier.

This is one of the few places where we are going to trade maintainability over performance, given the goal of the minifier is compression size not performance.

All of the terminologies and separation of concerns are aligned with google closure compiler.

Infrastructure of `terser` and `esbuild` are not suitable for us to study nor pursuit. Their code are so tightly coupled - I failed to comprehend any of them every time I try to walk through a piece of optmization. Google closure compiler despite being written in Java, it's actually the most readable minifier out there.

To improve performance between ast passes, I envision a change detection system over a portion of the code.

The benchmark will demonstrate the performance regression of running 5 ast passes instead of 2.

To complete this PR, I need to figure out "fix-point" and order of these ast passes.
2024-08-04 11:58:39 +00:00
Boshen
a40a217de4 fix(parser): parse assert keyword in TSImportAttributes (#4610)
closes #4601
2024-08-04 01:41:31 +00:00
Boshen
a558492bf9 feat(codegen): implement BinaryExpressionVisitor (#4548)
part of https://github.com/oxc-project/backlog/issues/58

`monitor-oxc` run: https://github.com/oxc-project/monitor-oxc/actions/runs/10179047831
binary expression stack length tally using `counts` in top 100 npm packages from monitor-oxc:

```
29772 counts
(  1)    17652 (59.3%, 59.3%): 0
(  2)     5772 (19.4%, 78.7%): 1
(  3)     3204 (10.8%, 89.4%): 2
(  4)     1276 ( 4.3%, 93.7%): 3
(  5)      616 ( 2.1%, 95.8%): 4
(  6)      308 ( 1.0%, 96.8%): 5
(  7)      202 ( 0.7%, 97.5%): 6
(  8)      168 ( 0.6%, 98.1%): 7
(  9)      114 ( 0.4%, 98.5%): 9
( 10)       90 ( 0.3%, 98.8%): 8
( 11)       84 ( 0.3%, 99.0%): 13
( 12)       58 ( 0.2%, 99.2%): 10
( 13)       48 ( 0.2%, 99.4%): 12
( 14)       32 ( 0.1%, 99.5%): 11
( 15)       20 ( 0.1%, 99.6%): 134
( 16)       16 ( 0.1%, 99.6%): 18
( 17)       16 ( 0.1%, 99.7%): 20
( 18)       12 ( 0.0%, 99.7%): 19
( 19)       12 ( 0.0%, 99.8%): 35
( 20)       12 ( 0.0%, 99.8%): 51
( 21)       10 ( 0.0%, 99.8%): 15
( 22)        6 ( 0.0%, 99.9%): 17
( 23)        6 ( 0.0%, 99.9%): 21
( 24)        6 ( 0.0%, 99.9%): 45
( 25)        4 ( 0.0%, 99.9%): 14
( 26)        4 ( 0.0%, 99.9%): 26
( 27)        4 ( 0.0%, 99.9%): 53
( 28)        2 ( 0.0%, 99.9%): 172
( 29)        2 ( 0.0%, 99.9%): 214
( 30)        2 ( 0.0%,100.0%): 22
( 31)        2 ( 0.0%,100.0%): 27
( 32)        2 ( 0.0%,100.0%): 28
( 33)        2 ( 0.0%,100.0%): 29
( 34)        2 ( 0.0%,100.0%): 31
( 35)        2 ( 0.0%,100.0%): 36
( 36)        2 ( 0.0%,100.0%): 46
( 37)        2 ( 0.0%,100.0%): 55
```
2024-07-31 12:44:19 +00:00
DonIsaac
d5c4b190aa fix(parser): fix enum member parsing (#4543)
Closes #4449
2024-07-30 10:43:09 +00:00
Boshen
35654e665c feat(codegen): align operator precedence with esbuild (#4509)
closes #4339
2024-07-28 11:48:51 +00:00
Boshen
6a94e3f573 fix(codegen): fixes for esbuild test cases (#4503) 2024-07-28 08:57:15 +00:00
Don Isaac
77bd5f102c
fix(semantic): use correct span for namespace symbols (#4448)
Before:
```ts
    namespace N {}
// ---------------
```

After:
```ts
    namespace N {}
//            -
```

Found while working on #4427
2024-07-25 09:43:06 +08:00
Dunqing
7cd53f3897 refactor(semantic): var hoisting (#4379)
close: #4323

This PR refactors the var hoisting logic to avoid inserting the same symbol into every scope that can be hosted.
2024-07-25 00:55:02 +00:00
Boshen
3d88f20cbb
fix(codegen): print shorthand for all { x } variants (#4374)
closes #4340
2024-07-21 19:54:21 +08:00
DonIsaac
a2eabe1f4b refactor(parser): use error codes for ts diagnostics (#4335)
Part of #4333
2024-07-18 16:09:25 +00:00
Dunqing
9badac030d fix(semantic): avoid var hosting insert the var variable to the CatchClause scope (#4337)
related: #4192 #4323

I will figure it out #4323 later
2024-07-18 02:52:14 +00:00
Dunqing
a88d588a07 feat(semantic): add ReferenceFlags::TSTypeQuery to indicate referenced by TSTypeQuery (#4317)
`ReferenceFlags::TSTypeQuery` can be used to help us insist on whether the reference is referenced by the type or not.
2024-07-17 09:52:57 +00:00
Dunqing
351ecf2707 fix(semantic): incorrect resolve references for TSTypeQuery (#4310)
```ts
type A = typeof Foo
                ^^^ Only allow reference to value symbol
```

I have verified the changed snapshot. That's correct
2024-07-17 03:33:00 +00:00
Dunqing
af4dc0112e feat(ast): align ts ast scope with typescript (#4253)
close: #3969
close: #2023

We need to add scope according to [this](d8086f14b6/src/compiler/binder.ts (L3883-L3962)). There are still some ASTs that need to be added to the scope.

---

Context from @Boshen:

Before this whole journey of fixing symbols and scopes I asked @Dunqing to debug through binder.ts via a debugger to fully understand how it does resolution.

We then agreed to align the implementation so that when a problem occurs, we can debug through both implementations and find where our problem is.

tsc doesn't have a specification, so we need to align with the reference implementation instead.
2024-07-17 02:50:47 +00:00
Boshen
107e57019c feat(coverage): run multi-file typescript tests (#4256)
The code is really ugly because I didn't anticipate multi-test files from typescript when I started writing the runner :-(
2024-07-16 06:15:04 +00:00
lucab
9a87e41332 fix(parser): avoid crashing on invalid const modifier (#4267)
Followup on https://github.com/oxc-project/oxc/pull/3977, fixing one of the crashes at https://github.com/oxc-project/oxc/pull/3977.
2024-07-15 11:37:31 +00:00
Dunqing
ace4f1ff77 refactor(semantic): update the order of visit_function and Visit fields in the builder to be consistent (#4248)
Same as #4195
2024-07-14 11:39:15 +00:00
Boshen
83bd40db4e
chore: turn off doctest for all [[bin]] 2024-07-14 16:55:19 +08:00
Boshen
e167ef79c6 fix(codegen): print parenthesis properly (#4245)
`TSParenthesizedType` handles parenthesis in ts types.

It should be considered a bug if parenthesis is not printed correctly after this PR.
2024-07-14 04:13:10 +00:00
Dunqing
dc2b3c44fb refactor(semantic): add strict mode in scope flags for class definitions (#4156)
related: https://github.com/oxc-project/oxc/issues/4142#issuecomment-2219125356

Although we called `enter_node(Class)`, that doesn't mean we're in the `class` scope. It causes our must to visit decorators before `enter_node`.

Let's look at this case. It causes a syntax error if we don't visit decorators before `enter_node`
```js
// This file was procedurally generated from the following sources:
// - src/decorator/decorator-call-expr-identifier-reference-yield.case
// - src/decorator/syntax/valid/cls-expr-decorators-valid-syntax.template
/*---
description: Decorator @ DecoratorCallExpression (Valid syntax for decorator on class expression)
esid: prod-ClassExpression
features: [class, decorators]
flags: [generated, noStrict]
info: |
    ClassExpression[Yield, Await] :
      DecoratorList[?Yield, ?Await]opt class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await]

    DecoratorList[Yield, Await] :
      DecoratorList[?Yield, ?Await]opt Decorator[?Yield, ?Await]

    Decorator[Yield, Await] :
      @ DecoratorMemberExpression[?Yield, ?Await]
      @ DecoratorParenthesizedExpression[?Yield, ?Await]
      @ DecoratorCallExpression[?Yield, ?Await]

    ...

    DecoratorCallExpression[Yield, Await] :
      DecoratorMemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

    DecoratorMemberExpression[Yield, Await] :
      IdentifierReference[?Yield, ?Await]
      DecoratorMemberExpression[?Yield, ?Await] . IdentifierName
      DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier

    IdentifierReference[Yield, Await] :
      [~Yield] yield
      ...

---*/
function decorator() {
  return () => {};
}
var yield = decorator;

var C = @yield() class {};

```
Errors:
```shell
  × The keyword 'yield' is reserved
    ╭─[language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js:45:2]
 44 │
 45 │ @yield() class C {}
    ·  ─────
    ╰────
```

The changed code makes more sense. Only if we call `enter_scope` for class, the flags will contain `StrictMode`. Also, we can get the exact `flags` of the `scope` in the `class` at the transformer

For example:

```
class A {
   B() {
       // Before: flags is `Function`
      //  After: flags is `Function | StrictMode`
   }
}
```

The regression tests will be fixed in follow-up PRs
2024-07-14 03:35:12 +00:00
Dunqing
20cdb1fe0a feat(semantic): align class scope with typescript (#4195)
```ts
class Klass <T>   extends Root       <R>                   {}
//    ^^^^^ ^^^           ^^^^       ^^^                   ^^
//    id type_paramter super_class super_type_parameters  body
```
I reorder fields according to the order above

The class scope is not defined in the spec. But we need to create a scope for `class` to store `TypeParamters`
2024-07-14 03:19:30 +00:00
Boshen
c65198fa15 fix(codegen): choose the right quote for jsx attribute string (#4236) 2024-07-12 17:30:24 +00:00
Boshen
be82c286d6 fix(codegen): print JSXAttributeValue::StringLiteral directly (#4231)
jsx attribute string is interpreted as is without escaping.

The transformer is responsible for converting it to plain js string.
2024-07-12 16:17:23 +00:00
Dunqing
92ee77487f feat(semantic): add ScopeFlags::CatchClause for use in CatchClause (#4205) 2024-07-12 03:47:07 +00:00
rzvxa
aab7aaaa06 refactor(ast/visit): fire node events as the outermost one. (#4203)
I'm going to be AFK today(till about 9 PM UTC). Meanwhile, I Didn't want to be a blocker so here we go.
It would fix the #4200 merge if you guys find it in the correct order otherwise feel free to close it.
2024-07-12 03:27:59 +00:00
Boshen
83c2c62f7b feat(codegen): add option for choosing quotes; remove slow choose_quot method (#4219) 2024-07-12 03:08:22 +00:00
IWANABETHATGUY
1c117eb20d
fix: avoid print extra semicolon after accessor property (#4199)
## Before
```js
export default class Foo { @x @y accessor #aDef = 1 }
```
**output** 
```bash
Original:
export default class Foo { @x @y accessor #aDef = 1 }


Printed:
export default class Foo {
        accessor #aDef=1;;
}

```
2024-07-11 20:16:02 +08:00
Dunqing
bbe5dede07 refactor(semantic): set current_scope_id to scope_id in enter_scope (#4193)
close: #4170
2024-07-11 08:45:35 +00:00
Dunqing
7f1adddaf0 refactor(semantic): correct scope in CatchClause (#4192)
close: #4186

CatchClause has two scopes. The first one is `CatchClause`, which will add a `CatchParameter` to it. The second one is `Block`, which will add binding that declares in the current block scope.

The spec has a syntax error about `CatchParameter`
- It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the LexicallyDeclaredNames of Block.
2024-07-11 08:45:30 +00:00
Boshen
ca0b4fa08a refactor(tasks): clean up test files and remove libs.txt (#4172) 2024-07-10 17:38:06 +00:00
DonIsaac
4a656c3a18 fix(lexer): incorrect lexing of large hex/octal/binary literals (#4072)
Closes #3347. Implementation follows the approach described by @overlookmotel [here](https://github.com/oxc-project/oxc/issues/3347#issuecomment-2119004288).
2024-07-10 16:39:10 +00:00
Boshen
28eeee0f71 fix(parser): fix asi error diagnostic pointing at invalid text causing crash (#4163) 2024-07-10 14:45:10 +00:00
Luca Bruno
5731e3957f
refactor(ast)!: store span details inside comment struct (#4132)
This tweaks `Comment` definition in order to internally store the start
and end position of its span.

Closes: https://github.com/oxc-project/oxc/issues/4069
2024-07-09 23:23:43 +08:00
DonIsaac
2f53bdf72d feat(semantic): check for abstract ClassElements in non-abstract classes (#4127)
feat(semantic): check for abstract ClassElements in non-abstract classes

chore: update coverage snapshots
2024-07-09 03:35:32 +00:00
DonIsaac
3a0f2aa7ef feat(parser): check for illegal modifiers in modules and namespaces (#4126) 2024-07-09 02:54:06 +00:00
Don Isaac
c4ee9f8ec6
feat(semantic): check for abstract initializations and implementations (#4125) 2024-07-08 17:30:16 -04:00
Don Isaac
0f026089d1
fix(semantic): bind TSImportEqualsDeclarations (#4100)
Closes #4091
2024-07-08 14:03:47 +08:00
DonIsaac
e386b62331 feat(semantic): check for invalid type import assignments (#4097)
Adds checks to `TSImportEqualsDeclaration` for invalid use of `import type` modifier.

```ts
import { Foo } from './foo'
namespace Bar {
  export class Baz {}
}

import type A = Foo.Baz;        // not allowed
import type B = Bar.Baz;        // not allowed
import type C = require('./c'); // allowed
```
2024-07-08 03:14:22 +00:00
Boshen
6e5447e5d5
chore(coverage): add test for huge binary expression and nested if statements (#4084)
relates https://github.com/oxc-project/backlog/issues/58
2024-07-08 00:15:26 +08:00
Boshen
aaac2d8775
fix(codegen): preserve parentheses from AST instead calculating from operator precedence (#4055)
…operator precedence

Calculating from operator precedence is currently unsafe and will result
incorrect semantics.
2024-07-05 14:01:17 +08:00
Boshen
243c9f35b0 refactor(parser): use function instead of trait to parse list with rest element (#4028)
closes #3887
2024-07-02 13:43:14 +00:00
Boshen
1dacb1fc5b
refactor(parser): use function instead of trait to parse delimited lists (#4014)
relates #3887

The rest of the list parsing trait implementations involves ... parsing
`rest`, which I'll refactor in another PR.
2024-07-02 14:47:56 +08:00
Boshen
23038ad8f8 fix(codegen): print TSFunctionType inside TSTypeAssertion (#3999) 2024-07-01 14:44:35 +00:00
DonIsaac
63f36daae0 feat(parser): parse modifiers with parse_modifiers (take 2) (#3977)
Same as #3948, with fixes for bugs found by @Boshen.
2024-06-30 03:46:34 +00:00
Boshen
14bc31ee74
Revert "feat(parser): parse modifiers with parse_modifiers (#3948)"
This reverts commit 7b38bde073.
2024-06-29 14:16:26 +08:00
DonIsaac
7b38bde073 feat(parser): parse modifiers with parse_modifiers (#3948)
Closes #3929
2024-06-29 05:29:47 +00:00
Dunqing
51e54f902c fix(codegen): should print TSModuleDeclarationKind instead of just module (#3957) 2024-06-29 05:24:36 +00:00
underfin
9e8709f06e
fix(sourcemap): should add tokens for unordered span (#3941)
close: https://github.com/oxc-project/oxc/issues/3843
2024-06-27 20:24:22 +08:00
Boshen
275349a9fe fix(parser): parse function type parameter name accessor (#3926)
fixes #3910
2024-06-26 13:34:24 +00:00
Boshen
3db2553dc2 refactor(parser): improve parsing of TypeScript type arguments (#3923) 2024-06-26 07:16:18 +00:00