Commit Graph

1582 Commits

Author SHA1 Message Date
Dunqing 0e1e79dc6b fix(transformer/typescript): remove properties with definite assignment assertion (#12713)
close: https://github.com/rolldown/tsdown/issues/399

Here is a [TypeScript Playground](https://www.typescriptlang.org/play/?#code/KYDwDg9gTgLgBAYwDYEMDOa4FkCeBhVDOAbwCg44A7FAW2AEIAuONGKAS0oHNyXQmWbTjwC+pUrgLo0AOjBQIMRTjDAZ1OnAC8cAOQAvABYpuaE7on5Cs+YuWqZaUNr00USYBaA), which shows the expected output.
2025-08-02 11:12:43 +00:00
Cameron e836e552f3 fix(parser): prevent panic when parsing invalid extends clause (#12551)
fixes #12546
2025-08-01 16:19:30 +08:00
camc314 ce5876d5b5 fix(parser): validate inner expression of type assertions in assignment targets (#12614)
fixes #12612
2025-08-01 04:42:56 +00:00
Boshen f46818ad70 feat(minifier): remove unused class expression (#12618)
Also improved removable of unused class declaration.

closes #11454
2025-07-30 12:29:03 +00:00
Yuji Sugiura 9bf6ed5cce test(coverage/typescript): Update 2331-2400 error codes handling (#12606)
Part of #11582
2025-07-30 14:29:09 +08:00
Boshen fe9c8e14b1 fix(minifier): do not remove non-plain empty functions (#12573)
Do not remove empty function calls if the function is async or generator or args can cause type error.

From test262:

```js
function fn({}) {}

assert.throws(TypeError, function() {
  fn(null);
});
```
2025-07-28 12:54:43 +00:00
leaysgur 75d592f8ce test(coverage/typescript): Update 2000-2330 error codes handling (#12510)
Part of #11582

---

> Negative Passed: 1415/4400 (32.16%)

Now it's over 30%. ↗️
2025-07-25 12:28:34 +00:00
overlookmotel 5a7e72abb5 refactor(semantic)!: AstNodes::program return &Program not Option<&Program> (#12515)
#12193 made it so semantic analysis is run on all files (inc. `.d.ts`), so now `AstNodes::program` now always returns `Some`.

We always unwrap the value returned by `AstNodes::program`, so move the `unwrap` into the method itself.
2025-07-25 12:06:25 +00:00
Boshen b877039e43 feat(minifier): inline const variables that are only used once (#12488)
Just to get the infrastructure ready.

Other "inline"s are more complicated due to TDZ.
2025-07-24 08:08:10 +00:00
Dunqing 7c2d2c664e fix(transformer/top-level-statements): should not inject statements after non-import statement (#12463)
* close https://github.com/oxc-project/oxc/issues/12460

Injecting top-level statements after the last import statement is unsound because once there is an import statement in the last line, it would be broken if other code relies on the injected statements. Learn more to see the following example.

I suppose the reason we did this is that we had a test case that misled us. I overrode that test with the expected output.

For example:

Input:

```js
import { observer } from 'mobx-react-lite'
import { useFoo } from './useFoo'

export const BazComponent = observer(function BazComponent_() {
  const foo = useFoo()
  return (
    <>
      {foo}
      {bar}
    </>
  )
})

import { bar } from './bar'
```

Before output:
```js
import { observer } from "mobx-react-lite";
import { useFoo } from "./useFoo";
export const BazComponent = _s(observer(_c = _s(function BazComponent_() {
        _s();
        const foo = useFoo();
        return /* @__PURE__ */ _jsxs(_Fragment, { children: [foo, bar] });
}, "useFoo{foo}", false, function() {
        return [useFoo];
})), "useFoo{foo}", false, function() {
        return [useFoo];
});
_c2 = BazComponent;
import { bar } from "./bar";
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
var _s = $RefreshSig$();
var _c, _c2;
$RefreshReg$(_c, "BazComponent$observer");
$RefreshReg$(_c2, "BazComponent");

```

After output:

```js
import { observer } from "mobx-react-lite";
import { useFoo } from "./useFoo";
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
var _s = $RefreshSig$();
export const BazComponent = _s(observer(_c = _s(function BazComponent_() {
        _s();
        const foo = useFoo();
        return /* @__PURE__ */ _jsxs(_Fragment, { children: [foo, bar] });
}, "useFoo{foo}", false, function() {
        return [useFoo];
})), "useFoo{foo}", false, function() {
        return [useFoo];
});
_c2 = BazComponent;
import { bar } from "./bar";
var _c, _c2;
$RefreshReg$(_c, "BazComponent$observer");
$RefreshReg$(_c2, "BazComponent");
```

The difference is that `import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; var _s = $RefreshSig$();` has injected after `import { useFoo } from "./useFoo";`
2025-07-24 00:58:59 +00:00
Dunqing dcb245ce4c fix(transformer/typescript): incorrect evaluation of TemplateLiteral in enum (#12456)
* close https://github.com/rolldown/rolldown/issues/5386
2025-07-23 04:21:13 +00:00
leaysgur 0a6da98aef test(coverage/typescript): Update 4xxx error codes handling (#12459)
Part of #11582
2025-07-23 04:12:23 +00:00
Dunqing 986c48e2a9 fix(transformer/decorator): transformed decorators should be injected after class-properties has run (#12418)
* close https://github.com/rolldown/rolldown/issues/5374

Example:

Input:
```ts
function myPropertyDecorator() {
  return (target: any, propertyKey: number) => {
    console.log(target.constructor.modelName, propertyKey);
  };
}

class Test {
  public static modelName = 'Test';

  @myPropertyDecorator()
  public myProperty = 1;
}

const instance = new Test();

export default instance;
```

Output diff:
```diff
function myPropertyDecorator() {
        return (target, propertyKey) => {
                console.log(target.constructor.modelName, propertyKey);
        };
}
class Test {
        constructor() {
                babelHelpers.defineProperty(this, "myProperty", 1);
        }
}
-babelHelpers.decorate([myPropertyDecorator()], Test.prototype, "myProperty", void 0);
-babelHelpers.defineProperty(Test, "modelName", "Test");
+babelHelpers.defineProperty(Test, "modelName", "Test");
+babelHelpers.decorate([myPropertyDecorator()], Test.prototype, "myProperty", void 0);

const instance = new Test();
export default instance;
```

The cause is that we transform class fields and decorators in two different plugins, and the decorator plugin should be transformed first, and then run the class-properties plugin, because class-properties might erase some decorator information. However, this cause transformed decorators injected before transformed class fields.

This PR fixes this problem by collecting all transformed decorators that wait for injection, and injecting them in batch after the `class-properties` plugin has run.
2025-07-21 15:14:41 +00:00
Dunqing c4a2d79252 fix(transformer/typescript): should remove abstract field early (#12417)
* close https://github.com/rolldown/rolldown/issues/5326

Regression introduced by #12212. The transform execution shift causes the bug because the `class-properties` plugin always assumes that all fields accessed can be transformed. However, the prior change breaks the assumption.

This PR reverts some changes to remove the ts-only field early, which respects that `class-properties` assumption
2025-07-21 06:40:24 +00:00
Yuji Sugiura b492458a76 test(coverage/typescript): Update 5xxx error codes handling (#12385)
Part of #11582
2025-07-18 16:39:12 +08:00
camc314 6fa23ad24e test(semantic): add failing tests for arguments and eval use in strict mode (#12298) 2025-07-16 07:49:38 +00:00
camc314 089f7b10a3 fix(semantic): allow arguments/eval as name of TSTypeAliasDeclaration, TSInterfaceDeclaration (#12291)
this stack should fix #12286
2025-07-16 07:49:37 +00:00
camc314 1bfd44feba fix(semantic): allow arguments/eval as spread argument name inside TSMethodSignature, TSFunctionType (#12290) 2025-07-16 07:49:37 +00:00
camc314 a740f3f3e8 fix(semantic): allow arguments/eval as argument name inside TSMethodSignature (#12289) 2025-07-16 07:49:37 +00:00
leaysgur a257c0188b test(coverage/typescript): Update 6xxx error codes handling (#12311)
Part of #11582
2025-07-16 02:44:17 +00:00
camc314 e82f758ff9 fix(semantic): allow arguments/eval as argument name inside TSFunctionType (#12288) 2025-07-16 01:45:12 +00:00
leaysgur 099f4f8eb2 test(coverage/typescript): Exclude more non-testable units (#12159)
Part of #11582

The filter logic added in the previous PR was not complete, so I fixed it.
Also added more non-testable case.

~~For `parser_typescript.snap`, 2 "Expect Syntax Error" entries are newly reported, but they will be handled in the future task.~~
2025-07-15 02:20:24 +00:00
camc314 2a1e805d55 fix(semantic): allow assigning to eval and arguments in ambient context (#12208)
https://github.com/microsoft/typescript/blob/7f802bbca25634c6bffe316de75771274f1d9b1d/src/compiler/binder.ts#L2670

https://www.typescriptlang.org/play/?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXxADcoIAKASgC55CctgBueAemfgHkBpAKFElgQp02PPFgBzZAFsQqDAGcK1WvSasOPPtDhI0mXPkSkiJaqmkAjEDAA0YmJJlz5Zy9arxzUqzDVsuvODagnoi+OKkAN4mEHYS0rIKAL7U0cQQrt7WcQ4Jzpk+SR5ePn7wAKIwMDgwgfw6QvqiABakANoxOY6J8gC61G0l2Z5uML3Fo2WV1TBAA
2025-07-14 19:15:23 +00:00
camc314 c995fe23f1 feat(semantic): build semantic for .d.ts files (#12193)
fixes #12134
2025-07-14 13:27:19 +00:00
Boshen 9b14fbcd4f feat(ast): add ThisExpression to TSTypeName (#12156)
part of #12042

Aligned with estree: https://github.com/typescript-eslint/typescript-eslint/blob/5c5e3d5c3853ab613e06be0d77a40e970017b3fc/packages/ast-spec/src/unions/EntityName.ts#L5
2025-07-13 01:43:57 +00:00
Dunqing 23c5951d26 fix(transformer/legacy-decorator): decorated fields with the declare modifier are not transformed (#12212)
Input: 
```ts
class DeclareFields {
  @dec declare name: string;
  @dec declare output: number;
}
```

Before output:
```ts
class DeclareFields {}
```

After output:
```ts
class DeclareFields {}

babelHelpers.decorate([dec], DeclareFields.prototype, "name", void 0);
babelHelpers.decorate([dec], DeclareFields.prototype, "output", void 0);
```


The `declare` fields with decorators should be transformed, but they
would be removed in the typescript plugin before legacy decorators
transform them, so this PR is to adjust the transform order and allow
`declare` fields can be transformed
2025-07-12 09:52:13 +08:00
Dunqing e095e99cb9 fix(semantic): panics when function is the part of IfStatement (#12190)
close: #10015

Also, removed weird SymbolId!
2025-07-11 14:33:06 +00:00
Ulrich Stark 228cff5418 refactor(semantic,linter): assert that Program is always the first node (#12123)
Follow on to #12087

> We might be able to improve perf of AstNodes::ancestor_ids a little by
using a custom iterator, instead of std::iter::successors.
> Also, node_id == NodeId::DUMMY would be a cheaper check than parent_id
== node_id. The NodeId of Program in practice is always NodeId::DUMMY
(0), but we don't have a static guarantee of that at present. But we
could get that guarantee by adding assert!(self.parent_ids.is_empty())
to the top of AstNodes::add_program_node (or maybe just debug_assert!).
> @overlookmotel in
https://github.com/oxc-project/oxc/pull/12087#issuecomment-3041419201

My changes:
- added constant NodeId::ROOT (same value as NodeId::DUMMY, but leads to
more intuitive code)
- added asserts in `add_program_node` that nodes are empty and node kind
that's being added is Program
- ancestor_kinds and ancestors now build upon ancestor_ids, making
std::iter::successors implementation obsolete
- make AstNodeParentIter simpler by iterating over node ids and by
making use of previous assertions of `add_program_node`
- remove root, root_node and root_node_mut functions and replace their
use with either new program function or NodeId::ROOT

Results in general much less code, especially less boilerplate code in
the linter around getting the program node. Also might hopefully yield
some small benchmark improvements.

Edit:
Only very minor if not zero improvements on the linter benchmarks :(

I also noticed while working on this that the ancestor iterator methods
where documented as "The first node produced by this iterator is the
first parent of the node pointed to by node_id". That statement was
incorrect because all the iterators didn't yield the parent of node_id,
but node_id itself as first item. I updated the documentation of these
methods to correctly reflect their implementation.
2025-07-08 11:35:47 +01:00
Boshen 8b30a5bbd6 feat(codegen)!: introduce CommentOptions (#12114)
Control printing of comments more precisely via more options:

The logic change here is that jsdoc is no longer part of annotation
comments.

```rust
pub struct CommentOptions {
    /// Print normal comments that do not have special meanings.
    ///
    /// At present only statement level comments are printed.
    ///
    /// Default is `true`.
    pub normal: bool,

    /// Print jsdoc comments.
    ///
    /// * jsdoc: `/** jsdoc */`
    ///
    /// Default is `true`.
    pub jsdoc: bool,

    /// Print annotation comments.
    ///
    /// * pure: `/* #__PURE__ */` and `/* #__NO_SIDE_EFFECTS__ */`
    /// * webpack: `/* webpackChunkName */`
    /// * vite: `/* @vite-ignore */`
    /// * coverage: `v8 ignore`, `c8 ignore`, `node:coverage`, `istanbul ignore`
    ///
    /// Default is `true`.
    pub annotation: bool,

    /// Print legal comments.
    ///
    /// * starts with `//!` or `/*!`.
    /// * contains `/* @license */` or `/* @preserve */`
    ///
    /// Default is [LegalComment::Inline].
    pub legal: LegalComment,
}
```

closes #12030
related https://github.com/rolldown/tsdown/issues/357
2025-07-07 08:57:59 +00:00
leaysgur 4ac9500e28 test(coverage/typescript): Update 7xxx error codes handling (#12067)
Part of #11582

- Expand error codes as usual
- Excluded invalid test unit like this
  - https://github.com/microsoft/TypeScript/blob/833a8d492c728d606454865e8c0fee84842f9f10/tests/cases/compiler/extendsUntypedModule.ts
2025-07-04 13:55:43 +00:00
camchenry 6d865afde2 fix(parser): allow extends this.B syntax (#12038)
Syntactically, this is valid. It is only an error when you get to type checking. The error code itself can be handled as part of https://github.com/oxc-project/oxc/issues/11582, but this fixes an issue where we emitted an error for a case that should definitely be valid, as pointed out in the file itself.
2025-07-03 07:12:29 +00:00
Dunqing 07e14a40fe refactor(semantic): remove redundant code handling reference flags (#12043)
This PR is a follow-up to #11990. After `AstKind::TSTypeName` has been removed, a lot of prior handling of the kind can be removed. The semantic snapshot changes are expected, caused by #12042.
2025-07-03 04:26:07 +00:00
Yuji Sugiura 7a54493fa8 test(coverage/typescript): Update 8xxx error codes handling (#12034)
Part of #11582
2025-07-02 21:27:13 +08:00
overlookmotel 754f01d79a refactor(ast/estree): move start and end fields to last (#12012)
Related to #10307.

Re-arrange fields in ESTree AST, so `start` and `end` are last, instead of first.

Also bump `acorn-test262` submodule to include https://github.com/oxc-project/acorn-test262/pull/54, which rearranges the fields in test snapshots.
2025-07-01 17:32:06 +00:00
Boshen b446a66fe7 feat(parser): report duplicate private / protected / public modifier (#11996)
closes #11712
2025-07-01 14:13:46 +00:00
leaysgur bcd5813f14 test(coverage/typescript): Update 9xxx, 17xxx error codes handling (#11989)
Part of #11582
2025-07-01 03:07:50 +00:00
leaysgur 543b8f4fd0 test(coverage/typescript): Update TS18xxx error codes handling (#11933)
Part of #11582
2025-06-27 09:42:58 +00:00
leaysgur d7a6db8845 refactor(coverage/typescript): Use regex to capture TSxxxx error codes (#11932)
Part of #11582

I found that consecutive `CRLF`s can appear anywhere, so changing to the robust regex just in case.
2025-06-27 09:34:11 +00:00
leaysgur 1e7076feb7 refactor(coverage/typescript): Do not check NON_SUPPORETED_ERROR_CODES in semantic_typescript tests (#11902)
Follow up #11858, take 2 from #11875 .
2025-06-25 14:17:06 +00:00
camc314 6c9c580989 fix(parser): panic when parsing interface with missing implements (#11898) 2025-06-25 12:42:32 +00:00
camc314 404cb14409 fix(semantic): remove needless ts type param empty check (#11899)
we already check this in the parser, we don't need to check in semantic as well

https://github.com/oxc-project/oxc/blob/8c341a2699022a7e8c70107604d93a77a8afa529/crates/oxc_parser/src/diagnostics.rs#L410-L413
2025-06-25 12:42:32 +00:00
Boshen 066c4c4719 fix(parser): do not produce AST for incorrect rest parameter position (#11894)
closes #11863
2025-06-25 19:35:10 +08:00
Bacary Bruno Bodian 9a2548ae9d feat(napi/parser)!: add range option (#11728)
Part of #10307. Add `range` option to `oxc-parser`, to add `range` property to nodes in ESTree AST.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
2025-06-24 02:23:27 +01:00
Yuji Sugiura 70749bb20e refactor(coverage/parser_typescript): Improve should_fail check by extracting diagnostic codes from .errors.txt (#11858)
Part of #11582 

- 👉🏻 Check error codes in coverage tests
- Fill more error codes 
- Dump currently reviewed error codes somewhere
2025-06-23 15:53:17 +08:00
Don Isaac 4ad86ff14c feat(sema/check): check for reserved type names (#11694)
It may make sense to move some or all of this to `oxc_parser` since
switching over token `Kind` is much faster than string comparisons.
2025-06-18 13:15:28 +08:00
Don Isaac 8c341a2699 feat(sema/check): ts setters cannot have initializers (#11695) 2025-06-18 12:53:56 +08:00
overlookmotel 6feab7e748 fix(ast/estree): remove custom serializer for MethodDefinition key field (#11763)
Remove the custom ESTree serializer for `MethodDefinition`'s `key` field. This serializer was required to replicate a bug in TS-ESLint, which they've now fixed. This fixes the test case which was broken by #11762.
2025-06-16 21:37:42 +00:00
overlookmotel ea30fff17f test(ast/estree): bump acorn-test262 submodule (#11762)
Bump `acorn-test262` submodule, which bumps `@typescript-eslint/parser`. Latest version of TS-ESLint contains fixes for bugs which I reported. Currently this breaks 1 conformance test - will fix in following PR.
2025-06-16 21:37:42 +00:00
Ulrich Stark 563684aa1f feat(parser): emit diagnostic for modifiers on static block (#11727) 2025-06-16 09:49:25 +08:00
Boshen 8fb53b61a5 feat(parser): forbid declare on class getter and setter (#11717)
part of #11713
2025-06-15 03:41:15 +00:00