close: #7338close: #7344
The `SymbolFlags::Export` is Initially used to solve `ExportSpecifier` that is not `IdentifierReference` that causes we cannot determine whether a Binding is not used everywhere by `Semantic`.
Since #3820 this problem is solved, so we don't need `SymbolFlags::Export` no longer. Also, removing this can help us easier to pass the `Semantic` check in `Transformer`
Realized we can get the source type from the AST.
The next PR will introduce `unambiguous` to `SourceType` and directly set `Program::source_type` to either `script` or `module`.
Closes#5177
While making this, I noticed an uncaught parse error for accessors: accessors cannot be optional. I'll add a fix for this in an up-stack PR.
Previously `ScopeTree::get_child_ids` and `ScopeTree::get_child_ids_mut` returned an `Option`. Instead return the unwrapped value, in line with other methods e.g. `get_flags`.
> Re-creation of #4427 due to rebasing issues. Original attempt: #642
-----
Third time's the charm?
Each time I attempt this rule, I find a bunch of bugs in `Semantic`, and I expect this attempt to be no different. Expect sidecar issues+PRs stemming from this PR here.
## Not Supported
These are cases supported in the original eslint rule, but that I'm intentionally deciding not to support
- export comments in scripts
```js
/* exported a */ var a;
```
- global comments
```js
/* global a */ var a;
```
## Behavior Changes
These are intentional deviations from the original rule's behavior:
- logical re-assignments are not considered usages
```js
// passes in eslint/no-unused-vars, fails in this implementation
let a = 0; a ||= 1;
let b = 0; b &&= 2;
let c = undefined; c ??= []
```
## Known Limitations
- Lint rules do not have babel or tsconfig information, meaning we can't determine if `React` imports are being used or not. The relevant tsconfig settings here are `jsx`, `jsxPragma`, and `jsxFragmentName`. To accommodate this, all imports to symbols named `React` or `h` are ignored in JSX files.
- References to symbols used in JSDoc `{@link}` tags are not created, so symbols that are only used in doc comments will be reported as unused. See: #4443
- `.vue` files are skipped completely, since variables can be used in templates in ways we cannot detect
> note: `.d.ts` files are skipped as well.
## Todo
- [x] Skip unused TS enum members on used enums
- [x] Skip unused parameters followed by used variables in object/array spreads
- [x] Re-assignments to array/object spreads do not respect `destructuredArrayIgnorePattern` (related to: https://github.com/oxc-project/oxc/issues/4435)
- [x] #4493
- [x] References inside a nested scope are not considered usages (#4447)
- [x] Port over typescript-eslint test cases _(wip, they've been copied and I'm slowly enabling them)_
- [x] Handle constructor properties
```ts
class Foo {
constructor(public a) {} // `a` should be allowed
}
```
- [x] Read references in sequence expressions (that are not in the last position) should not count as a usage
```js
let a = 0; let b = (a++, 0); console.log(b)
```
> Honestly, is anyone even writing code like this?
- [x] function overload signatures should not be reported
- [x] Named functions returned from other functions get incorrectly reported as unused (found by @camc314)
```js
function foo() {
return function bar() { }
}
Foo()()
```
- [x] false positive for TS modules within ambient modules
```ts
declare global {
// incorrectly marked as unused
namespace jest { }
}
```
## Blockers
- https://github.com/oxc-project/oxc/issues/4436
- https://github.com/oxc-project/oxc/issues/4437
- #4446
- #4447
- #4494
- #4495
## Non-Blocking Issues
- #4443
- #4475 (prevents checks on exported symbols from namespaces)
The code changes in `builder.rs` optimize the export flag check in the `SemanticBuilder` implementation. Instead of setting the export flag to `true` for all cases except `ExportDefaultDeclarationKind::ClassDeclaration(ref class)`, the flag is now set to `true` only for `ExportDefaultDeclarationKind::ClassDeclaration` and `false` for all other cases. This change improves the efficiency of the export flag check.
> Part of #4445
Fixes a bug where non-exported functions and variables inside of
exported TS namespaces were being flagged with `SymbolFlags::Export`
```ts
export namespace Foo {
// incorrectly flagged as exported
function foo() { }
}
```
close: #3969close: #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.
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.
Reverts oxc-project/oxc#3972
@DonIsaac As it turns out we can't have lifetimes on these structures because semantic data is exposed to downstream users to use freely, detached from the ast and allocator.