mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-15 06:39:17 +00:00
feat(ast)!: introduce ExportDeclaration, ExportFromDeclaration (#25095)
## Summary
Split the overloaded Rust `ExportNamedDeclaration` into syntax-specific AST nodes:
- `ExportDeclaration` for exported declarations
- `ExportNamedDeclaration` for local exports
- `ExportFromDeclaration` for re-exports
## Breaking Change
The Rust AST changes from:
```rust
pub struct ExportNamedDeclaration<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub declaration: Option<Declaration<'a>>,
pub specifiers: Vec<'a, ExportSpecifier<'a>>,
pub source: Option<StringLiteral<'a>>,
pub export_kind: ImportOrExportKind,
pub with_clause: Option<Box<'a, WithClause<'a>>>,
}
pub enum ModuleDeclaration<'a> {
// ...
ExportNamedDeclaration(Box<'a, ExportNamedDeclaration<'a>>),
// ...
}
```
to:
```rust
pub struct ExportDeclaration<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub declaration: Declaration<'a>,
}
pub struct ExportNamedDeclaration<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub specifiers: Vec<'a, ExportSpecifier<'a>>,
pub export_kind: ImportOrExportKind,
}
pub struct ExportFromDeclaration<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub specifiers: Vec<'a, ExportSpecifier<'a>>,
pub source: StringLiteral<'a>,
pub export_kind: ImportOrExportKind,
pub with_clause: Option<Box<'a, WithClause<'a>>>,
}
pub enum ModuleDeclaration<'a> {
// ...
ExportDeclaration(Box<'a, ExportDeclaration<'a>>),
ExportNamedDeclaration(Box<'a, ExportNamedDeclaration<'a>>),
ExportFromDeclaration(Box<'a, ExportFromDeclaration<'a>>),
// ...
}
```
## Why?
The previous node represented three distinct syntax forms through optional and mutually exclusive fields:
```text
export const value = 1; -> ExportDeclaration
export { value }; -> ExportNamedDeclaration
export { value } from "mod"; -> ExportFromDeclaration
```
This allowed invalid combinations such as declarations with specifiers or sources, and import attributes without a source. The new nodes make these states unrepresentable and remove repeated `declaration`/`source` branching from consumers.
## How to migrate
Match the syntax-specific `ModuleDeclaration`, `Statement`, or `AstKind` variant instead of inspecting optional fields. Generated builders, visitors, traversal ancestors, and formatter wrappers now expose corresponding APIs for all three nodes.
Common field migrations:
| Previous representation | New representation |
| --- | --- |
| `declaration: Some(declaration)` | `ExportDeclaration { declaration }` |
| `declaration.as_ref()` | `&export.declaration` |
| `source.is_none()` for local exports | Match `ExportNamedDeclaration` |
| `source: Some(source)` | `ExportFromDeclaration { source }` |
| `source.as_ref().unwrap()` | `&export.source` |
| `with_clause` | Only available on `ExportFromDeclaration` |
| Stored `export_kind` on exported declarations | `ExportDeclaration::export_kind()` |
| `ExportNamedDeclaration::boxed_plain_declaration(...)` | `ExportDeclaration::boxed(...)` |
| `ExportNamedDeclaration::boxed(..., None, specifiers, None, ...)` | `ExportNamedDeclaration::boxed(..., specifiers, ...)` |
| `ExportNamedDeclaration::boxed(..., None, specifiers, Some(source), ...)` | `ExportFromDeclaration::boxed(..., specifiers, source, ...)` |
closes https://github.com/oxc-project/backlog/issues/219
This commit is contained in:
1 parent
dda5636004
commit
1bdedd11ca
146 files changed
+4991
-3437
No files matched your search
@@ -1524,10 +1524,14 @@ function deserializeStatement(pos) {
|
||||
case 66:
|
||||
return deserializeBoxExportDefaultDeclaration(pos + 8);
|
||||
case 67:
|
||||
return deserializeBoxExportNamedDeclaration(pos + 8);
|
||||
return deserializeBoxExportDeclaration(pos + 8);
|
||||
case 68:
|
||||
return deserializeBoxTSExportAssignment(pos + 8);
|
||||
return deserializeBoxExportNamedDeclaration(pos + 8);
|
||||
case 69:
|
||||
return deserializeBoxExportFromDeclaration(pos + 8);
|
||||
case 70:
|
||||
return deserializeBoxTSExportAssignment(pos + 8);
|
||||
case 71:
|
||||
return deserializeBoxTSNamespaceExportDeclaration(pos + 8);
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for Statement`);
|
||||
@@ -3099,7 +3103,58 @@ function deserializeImportAttributeKey(pos) {
|
||||
}
|
||||
}
|
||||
|
||||
function deserializeExportDeclaration(pos) {
|
||||
let start,
|
||||
end,
|
||||
previousParent = parent,
|
||||
node = (parent = {
|
||||
__proto__: NodeProto,
|
||||
type: "ExportNamedDeclaration",
|
||||
declaration: null,
|
||||
specifiers: [],
|
||||
source: null,
|
||||
exportKind: null,
|
||||
attributes: [],
|
||||
start: (start = deserializeI32(pos)),
|
||||
end: (end = deserializeI32(pos + 4)),
|
||||
range: [start, end],
|
||||
parent,
|
||||
}),
|
||||
declaration = deserializeDeclaration(pos + 16);
|
||||
node.declaration = declaration;
|
||||
node.exportKind =
|
||||
declaration.declare === true ||
|
||||
declaration.type === "TSTypeAliasDeclaration" ||
|
||||
declaration.type === "TSInterfaceDeclaration"
|
||||
? "type"
|
||||
: "value";
|
||||
parent = previousParent;
|
||||
return node;
|
||||
}
|
||||
|
||||
function deserializeExportNamedDeclaration(pos) {
|
||||
let start,
|
||||
end,
|
||||
previousParent = parent,
|
||||
node = (parent = {
|
||||
__proto__: NodeProto,
|
||||
type: "ExportNamedDeclaration",
|
||||
declaration: null,
|
||||
specifiers: null,
|
||||
source: null,
|
||||
exportKind: deserializeImportOrExportKind(pos + 12),
|
||||
attributes: [],
|
||||
start: (start = deserializeI32(pos)),
|
||||
end: (end = deserializeI32(pos + 4)),
|
||||
range: [start, end],
|
||||
parent,
|
||||
});
|
||||
node.specifiers = deserializeVecExportSpecifier(pos + 16);
|
||||
parent = previousParent;
|
||||
return node;
|
||||
}
|
||||
|
||||
function deserializeExportFromDeclaration(pos) {
|
||||
let start,
|
||||
end,
|
||||
previousParent = parent,
|
||||
@@ -3116,10 +3171,9 @@ function deserializeExportNamedDeclaration(pos) {
|
||||
range: [start, end],
|
||||
parent,
|
||||
}),
|
||||
withClause = deserializeOptionBoxWithClause(pos + 104);
|
||||
node.declaration = deserializeOptionDeclaration(pos + 16);
|
||||
node.specifiers = deserializeVecExportSpecifier(pos + 32);
|
||||
node.source = deserializeOptionStringLiteral(pos + 56);
|
||||
withClause = deserializeOptionBoxWithClause(pos + 88);
|
||||
node.specifiers = deserializeVecExportSpecifier(pos + 16);
|
||||
node.source = deserializeStringLiteral(pos + 40);
|
||||
node.attributes = withClause === null ? [] : withClause.attributes;
|
||||
parent = previousParent;
|
||||
return node;
|
||||
@@ -6727,10 +6781,18 @@ function deserializeBoxExportDefaultDeclaration(pos) {
|
||||
return deserializeExportDefaultDeclaration(int32[pos >> 2]);
|
||||
}
|
||||
|
||||
function deserializeBoxExportDeclaration(pos) {
|
||||
return deserializeExportDeclaration(int32[pos >> 2]);
|
||||
}
|
||||
|
||||
function deserializeBoxExportNamedDeclaration(pos) {
|
||||
return deserializeExportNamedDeclaration(int32[pos >> 2]);
|
||||
}
|
||||
|
||||
function deserializeBoxExportFromDeclaration(pos) {
|
||||
return deserializeExportFromDeclaration(int32[pos >> 2]);
|
||||
}
|
||||
|
||||
function deserializeBoxTSExportAssignment(pos) {
|
||||
return deserializeTSExportAssignment(int32[pos >> 2]);
|
||||
}
|
||||
@@ -6795,10 +6857,6 @@ function deserializeVecImportAttribute(pos) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function deserializeOptionDeclaration(pos) {
|
||||
return uint8[pos] === 31 ? null : deserializeDeclaration(pos);
|
||||
}
|
||||
|
||||
function deserializeVecExportSpecifier(pos) {
|
||||
let arr = [],
|
||||
pos32 = pos >> 2;
|
||||
@@ -6811,10 +6869,6 @@ function deserializeVecExportSpecifier(pos) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function deserializeOptionStringLiteral(pos) {
|
||||
return uint8[pos + 12] === 2 ? null : deserializeStringLiteral(pos);
|
||||
}
|
||||
|
||||
function deserializeOptionModuleExportName(pos) {
|
||||
return uint8[pos] === 255 ? null : deserializeModuleExportName(pos);
|
||||
}
|
||||
|
||||
@@ -2401,8 +2401,7 @@ pub struct StaticBlock<'a> {
|
||||
/// import bar from 'bar';
|
||||
/// import * as baz from 'baz';
|
||||
///
|
||||
/// // Not a ModuleDeclaration
|
||||
/// export const a = 5;
|
||||
/// export const a = 5; // ExportDeclaration
|
||||
///
|
||||
/// const b = 6;
|
||||
///
|
||||
@@ -2424,14 +2423,17 @@ pub enum ModuleDeclaration<'a> {
|
||||
ExportAllDeclaration(Box<'a, ExportAllDeclaration<'a>>) = 65,
|
||||
/// `export default 5;`
|
||||
ExportDefaultDeclaration(Box<'a, ExportDefaultDeclaration<'a>>) = 66,
|
||||
/// `export {five} from './numbers.js';`
|
||||
/// `export const five = 5;`
|
||||
ExportDeclaration(Box<'a, ExportDeclaration<'a>>) = 67,
|
||||
/// `export {six, seven};`
|
||||
ExportNamedDeclaration(Box<'a, ExportNamedDeclaration<'a>>) = 67,
|
||||
ExportNamedDeclaration(Box<'a, ExportNamedDeclaration<'a>>) = 68,
|
||||
/// `export {five} from './numbers.js';`
|
||||
ExportFromDeclaration(Box<'a, ExportFromDeclaration<'a>>) = 69,
|
||||
|
||||
/// `export = 5;`
|
||||
TSExportAssignment(Box<'a, TSExportAssignment<'a>>) = 68,
|
||||
TSExportAssignment(Box<'a, TSExportAssignment<'a>>) = 70,
|
||||
/// `export as namespace React;`
|
||||
TSNamespaceExportDeclaration(Box<'a, TSNamespaceExportDeclaration<'a>>) = 69,
|
||||
TSNamespaceExportDeclaration(Box<'a, TSNamespaceExportDeclaration<'a>>) = 71,
|
||||
}
|
||||
|
||||
#[ast]
|
||||
@@ -2669,32 +2671,104 @@ pub enum ImportAttributeKey<'a> {
|
||||
StringLiteral(StringLiteral<'a>) = 1,
|
||||
}
|
||||
|
||||
/// Named Export Declaration
|
||||
/// Exported declaration.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ts
|
||||
/// export const foo = 1;
|
||||
/// export interface Bar {}
|
||||
/// ```
|
||||
#[ast(visit)]
|
||||
#[derive(Debug)]
|
||||
#[generate_derive(CloneIn, Dummy, ReplaceWith, TakeIn)]
|
||||
#[generate_derive(ContentEq, ESTree, GetSpan, GetSpanMut, UnstableAddress)]
|
||||
#[estree(
|
||||
rename = "ExportNamedDeclaration",
|
||||
ts_alias = "ExportNamedDeclaration",
|
||||
add_ts_def = "
|
||||
interface ExportNamedDeclaration extends Span {
|
||||
type: 'ExportNamedDeclaration';
|
||||
declaration: Declaration | null;
|
||||
specifiers: Array<ExportSpecifier>;
|
||||
source: StringLiteral | null;
|
||||
exportKind?: ImportOrExportKind;
|
||||
attributes: Array<ImportAttribute>;
|
||||
parent/* IF !LINTER */?/* END IF */: Node;
|
||||
}
|
||||
",
|
||||
add_fields(
|
||||
specifiers = EmptyArray,
|
||||
source = Null,
|
||||
exportKind = ExportDeclarationExportKind,
|
||||
attributes = EmptyArray,
|
||||
),
|
||||
field_order(declaration, specifiers, source, exportKind, attributes, span),
|
||||
)]
|
||||
pub struct ExportDeclaration<'a> {
|
||||
pub node_id: Cell<NodeId>,
|
||||
pub span: Span,
|
||||
pub declaration: Declaration<'a>,
|
||||
}
|
||||
|
||||
/// Local named export declaration.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ts
|
||||
/// // ________ specifiers
|
||||
/// export { Foo, Bar };
|
||||
/// export type { Baz } from 'baz';
|
||||
/// // ^^^^ ^^^^^
|
||||
/// // export_kind source
|
||||
/// export type { Baz };
|
||||
/// // ^^^^
|
||||
/// // export_kind
|
||||
/// ```
|
||||
#[ast(visit)]
|
||||
#[derive(Debug)]
|
||||
#[generate_derive(CloneIn, Dummy, ReplaceWith, TakeIn)]
|
||||
#[generate_derive(ContentEq, ESTree, GetSpan, GetSpanMut, UnstableAddress)]
|
||||
#[estree(
|
||||
rename = "ExportNamedDeclaration",
|
||||
ts_alias = "ExportNamedDeclaration",
|
||||
add_fields(declaration = Null, source = Null, attributes = EmptyArray),
|
||||
field_order(declaration, specifiers, source, export_kind, attributes, span),
|
||||
)]
|
||||
pub struct ExportNamedDeclaration<'a> {
|
||||
pub node_id: Cell<NodeId>,
|
||||
pub span: Span,
|
||||
pub declaration: Option<Declaration<'a>>,
|
||||
pub specifiers: Vec<'a, ExportSpecifier<'a>>,
|
||||
pub source: Option<StringLiteral<'a>>,
|
||||
/// `export type { foo }`
|
||||
#[ts]
|
||||
pub export_kind: ImportOrExportKind,
|
||||
}
|
||||
|
||||
/// Named re-export declaration.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ts
|
||||
/// export { Foo, Bar } from 'module';
|
||||
/// export type { Baz } from 'baz';
|
||||
/// ```
|
||||
#[ast(visit)]
|
||||
#[derive(Debug)]
|
||||
#[generate_derive(CloneIn, Dummy, ReplaceWith, TakeIn)]
|
||||
#[generate_derive(ContentEq, ESTree, GetSpan, GetSpanMut, UnstableAddress)]
|
||||
#[estree(
|
||||
rename = "ExportNamedDeclaration",
|
||||
ts_alias = "ExportNamedDeclaration",
|
||||
add_fields(declaration = Null),
|
||||
field_order(declaration, specifiers, source, export_kind, with_clause, span),
|
||||
)]
|
||||
pub struct ExportFromDeclaration<'a> {
|
||||
pub node_id: Cell<NodeId>,
|
||||
pub span: Span,
|
||||
pub specifiers: Vec<'a, ExportSpecifier<'a>>,
|
||||
pub source: StringLiteral<'a>,
|
||||
/// `export type { foo } from 'module'`
|
||||
#[ts]
|
||||
pub export_kind: ImportOrExportKind,
|
||||
/// Some(vec![]) for empty assertion
|
||||
#[estree(rename = "attributes", via = ExportNamedDeclarationWithClause)]
|
||||
#[estree(rename = "attributes", via = ExportFromDeclarationWithClause)]
|
||||
pub with_clause: Option<Box<'a, WithClause<'a>>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1902,7 +1902,9 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
match self {
|
||||
ModuleDeclaration::ImportDeclaration(_) => false,
|
||||
ModuleDeclaration::ExportDefaultDeclaration(decl) => decl.is_typescript_syntax(),
|
||||
ModuleDeclaration::ExportDeclaration(decl) => decl.is_typescript_syntax(),
|
||||
ModuleDeclaration::ExportNamedDeclaration(decl) => decl.is_typescript_syntax(),
|
||||
ModuleDeclaration::ExportFromDeclaration(decl) => decl.is_typescript_syntax(),
|
||||
ModuleDeclaration::ExportAllDeclaration(decl) => decl.is_typescript_syntax(),
|
||||
ModuleDeclaration::TSNamespaceExportDeclaration(_)
|
||||
| ModuleDeclaration::TSExportAssignment(_) => true,
|
||||
@@ -1920,7 +1922,9 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
self,
|
||||
Self::ExportAllDeclaration(_)
|
||||
| Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::ExportFromDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_)
|
||||
)
|
||||
@@ -1942,8 +1946,10 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
match self {
|
||||
Self::ImportDeclaration(decl) => Some(&decl.source),
|
||||
Self::ExportAllDeclaration(decl) => Some(&decl.source),
|
||||
Self::ExportNamedDeclaration(decl) => decl.source.as_ref(),
|
||||
Self::ExportFromDeclaration(decl) => Some(&decl.source),
|
||||
Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_) => None,
|
||||
}
|
||||
@@ -1960,8 +1966,10 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
match self {
|
||||
Self::ImportDeclaration(decl) => decl.with_clause.as_deref(),
|
||||
Self::ExportAllDeclaration(decl) => decl.with_clause.as_deref(),
|
||||
Self::ExportNamedDeclaration(decl) => decl.with_clause.as_deref(),
|
||||
Self::ExportFromDeclaration(decl) => decl.with_clause.as_deref(),
|
||||
Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_) => None,
|
||||
}
|
||||
@@ -2009,11 +2017,34 @@ impl<'a> ImportAttributeKey<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportNamedDeclaration<'_> {
|
||||
/// Returns `true` if this export declaration uses any TypeScript syntax (such as `type` or `declare`).
|
||||
impl ExportDeclaration<'_> {
|
||||
/// Returns the export kind derived from the wrapped declaration.
|
||||
#[inline]
|
||||
pub fn export_kind(&self) -> ImportOrExportKind {
|
||||
if self.declaration.declare() || self.declaration.is_type() {
|
||||
ImportOrExportKind::Type
|
||||
} else {
|
||||
ImportOrExportKind::Value
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this export declaration uses any TypeScript syntax.
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
self.export_kind == ImportOrExportKind::Type
|
||||
|| self.declaration.as_ref().is_some_and(Declaration::is_typescript_syntax)
|
||||
self.declaration.is_typescript_syntax()
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportNamedDeclaration<'_> {
|
||||
/// Returns `true` if this is a TypeScript type-only export.
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
self.export_kind.is_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportFromDeclaration<'_> {
|
||||
/// Returns `true` if this is a TypeScript type-only re-export.
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
self.export_kind.is_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,9 @@ impl<'a> AstKind<'a> {
|
||||
match self {
|
||||
Self::ImportDeclaration(decl) => Some(ModuleDeclarationKind::Import(decl)),
|
||||
Self::ExportAllDeclaration(decl) => Some(ModuleDeclarationKind::ExportAll(decl)),
|
||||
Self::ExportDeclaration(decl) => Some(ModuleDeclarationKind::Export(decl)),
|
||||
Self::ExportNamedDeclaration(decl) => Some(ModuleDeclarationKind::ExportNamed(decl)),
|
||||
Self::ExportFromDeclaration(decl) => Some(ModuleDeclarationKind::ExportFrom(decl)),
|
||||
Self::ExportDefaultDeclaration(decl) => {
|
||||
Some(ModuleDeclarationKind::ExportDefault(decl))
|
||||
}
|
||||
@@ -515,7 +517,9 @@ impl AstKind<'_> {
|
||||
Self::ImportNamespaceSpecifier(_) => "ImportNamespaceSpecifier".into(),
|
||||
Self::ImportAttribute(_) => "ImportAttribute".into(),
|
||||
Self::ExportDefaultDeclaration(_) => "ExportDefaultDeclaration".into(),
|
||||
Self::ExportDeclaration(_) => "ExportDeclaration".into(),
|
||||
Self::ExportNamedDeclaration(_) => "ExportNamedDeclaration".into(),
|
||||
Self::ExportFromDeclaration(_) => "ExportFromDeclaration".into(),
|
||||
Self::ExportAllDeclaration(_) => "ExportAllDeclaration".into(),
|
||||
Self::WithClause(_) => "WithClause".into(),
|
||||
Self::JSXOpeningElement(_) => "JSXOpeningElement".into(),
|
||||
@@ -773,8 +777,12 @@ pub enum ModuleDeclarationKind<'a> {
|
||||
Import(&'a ImportDeclaration<'a>),
|
||||
/// An export all declaration like `export * from 'foo'`
|
||||
ExportAll(&'a ExportAllDeclaration<'a>),
|
||||
/// An exported declaration like `export const foo = 1`
|
||||
Export(&'a ExportDeclaration<'a>),
|
||||
/// A named export declaration like `export { foo, bar }`
|
||||
ExportNamed(&'a ExportNamedDeclaration<'a>),
|
||||
/// A named re-export declaration like `export { foo } from 'bar'`
|
||||
ExportFrom(&'a ExportFromDeclaration<'a>),
|
||||
/// A default export declaration like `export default foo`
|
||||
ExportDefault(&'a ExportDefaultDeclaration<'a>),
|
||||
/// A TypeScript export assignment like `export = foo`
|
||||
@@ -789,7 +797,9 @@ impl ModuleDeclarationKind<'_> {
|
||||
matches!(
|
||||
self,
|
||||
Self::ExportAll(_)
|
||||
| Self::Export(_)
|
||||
| Self::ExportNamed(_)
|
||||
| Self::ExportFrom(_)
|
||||
| Self::ExportDefault(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExport(_)
|
||||
@@ -802,7 +812,9 @@ impl GetSpan for ModuleDeclarationKind<'_> {
|
||||
match self {
|
||||
Self::Import(decl) => decl.span,
|
||||
Self::ExportAll(decl) => decl.span,
|
||||
Self::Export(decl) => decl.span,
|
||||
Self::ExportNamed(decl) => decl.span,
|
||||
Self::ExportFrom(decl) => decl.span,
|
||||
Self::ExportDefault(decl) => decl.span,
|
||||
Self::TSExportAssignment(decl) => decl.span,
|
||||
Self::TSNamespaceExport(decl) => decl.span,
|
||||
@@ -816,7 +828,9 @@ impl GetAddress for ModuleDeclarationKind<'_> {
|
||||
match *self {
|
||||
Self::Import(decl) => decl.unstable_address(),
|
||||
Self::ExportAll(decl) => decl.unstable_address(),
|
||||
Self::Export(decl) => decl.unstable_address(),
|
||||
Self::ExportNamed(decl) => decl.unstable_address(),
|
||||
Self::ExportFrom(decl) => decl.unstable_address(),
|
||||
Self::ExportDefault(decl) => decl.unstable_address(),
|
||||
Self::TSExportAssignment(decl) => decl.unstable_address(),
|
||||
Self::TSNamespaceExport(decl) => decl.unstable_address(),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
use std::{alloc::Layout, mem::MaybeUninit, slice, str};
|
||||
|
||||
use oxc_allocator::{Allocator, ArenaBox, ArenaVec, GetAllocator, IntoIn};
|
||||
use oxc_allocator::{Allocator, ArenaBox, GetAllocator};
|
||||
use oxc_span::{SPAN, Span};
|
||||
use oxc_str::Str;
|
||||
use oxc_syntax::{number::NumberBase, operator::UnaryOperator, scope::ScopeId};
|
||||
@@ -177,61 +177,6 @@ impl<'a> Function<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExportNamedDeclaration<'a> {
|
||||
/// Build an [`ExportNamedDeclaration`] with no modifiers, containing a set of
|
||||
/// [exported symbol names](ExportSpecifier), and store it in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
#[inline]
|
||||
pub fn boxed_plain<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
specifiers: V1,
|
||||
source: Option<StringLiteral<'a>>,
|
||||
builder: &B,
|
||||
) -> ArenaBox<'a, Self>
|
||||
where
|
||||
V1: IntoIn<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
{
|
||||
let builder = builder.builder();
|
||||
ExportNamedDeclaration::boxed(
|
||||
span,
|
||||
None,
|
||||
specifiers,
|
||||
source,
|
||||
ImportOrExportKind::Value,
|
||||
None,
|
||||
builder,
|
||||
)
|
||||
}
|
||||
|
||||
/// Build an [`ExportNamedDeclaration`] with no modifiers, wrapping a [`Declaration`],
|
||||
/// and store it in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
#[inline]
|
||||
pub fn boxed_plain_declaration<B: GetAstBuilder<'a>>(
|
||||
span: Span,
|
||||
declaration: Declaration<'a>,
|
||||
builder: &B,
|
||||
) -> ArenaBox<'a, Self> {
|
||||
let builder = builder.builder();
|
||||
ExportNamedDeclaration::boxed(
|
||||
span,
|
||||
Some(declaration),
|
||||
[],
|
||||
None,
|
||||
ImportOrExportKind::Value,
|
||||
None,
|
||||
builder,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TemplateElement<'a> {
|
||||
/// Build a [`TemplateElement`], escaping special characters in the raw value.
|
||||
///
|
||||
|
||||
@@ -909,16 +909,30 @@ const _: () = {
|
||||
assert!(size_of::<ImportAttributeKey>() == 56);
|
||||
assert!(align_of::<ImportAttributeKey>() == 8);
|
||||
|
||||
// Padding: 4 bytes
|
||||
assert!(size_of::<ExportDeclaration>() == 32);
|
||||
assert!(align_of::<ExportDeclaration>() == 8);
|
||||
assert!(offset_of!(ExportDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportDeclaration, declaration) == 16);
|
||||
|
||||
// Padding: 3 bytes
|
||||
assert!(size_of::<ExportNamedDeclaration>() == 112);
|
||||
assert!(size_of::<ExportNamedDeclaration>() == 40);
|
||||
assert!(align_of::<ExportNamedDeclaration>() == 8);
|
||||
assert!(offset_of!(ExportNamedDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportNamedDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportNamedDeclaration, export_kind) == 12);
|
||||
assert!(offset_of!(ExportNamedDeclaration, declaration) == 16);
|
||||
assert!(offset_of!(ExportNamedDeclaration, specifiers) == 32);
|
||||
assert!(offset_of!(ExportNamedDeclaration, source) == 56);
|
||||
assert!(offset_of!(ExportNamedDeclaration, with_clause) == 104);
|
||||
assert!(offset_of!(ExportNamedDeclaration, specifiers) == 16);
|
||||
|
||||
// Padding: 3 bytes
|
||||
assert!(size_of::<ExportFromDeclaration>() == 96);
|
||||
assert!(align_of::<ExportFromDeclaration>() == 8);
|
||||
assert!(offset_of!(ExportFromDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportFromDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportFromDeclaration, export_kind) == 12);
|
||||
assert!(offset_of!(ExportFromDeclaration, specifiers) == 16);
|
||||
assert!(offset_of!(ExportFromDeclaration, source) == 40);
|
||||
assert!(offset_of!(ExportFromDeclaration, with_clause) == 88);
|
||||
|
||||
// Padding: 4 bytes
|
||||
assert!(size_of::<ExportDefaultDeclaration>() == 32);
|
||||
@@ -2726,16 +2740,30 @@ const _: () = if cfg!(target_family = "wasm") || align_of::<u64>() == 8 {
|
||||
assert!(size_of::<ImportAttributeKey>() == 36);
|
||||
assert!(align_of::<ImportAttributeKey>() == 4);
|
||||
|
||||
// Padding: 0 bytes
|
||||
assert!(size_of::<ExportDeclaration>() == 20);
|
||||
assert!(align_of::<ExportDeclaration>() == 4);
|
||||
assert!(offset_of!(ExportDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportDeclaration, declaration) == 12);
|
||||
|
||||
// Padding: 3 bytes
|
||||
assert!(size_of::<ExportNamedDeclaration>() == 76);
|
||||
assert!(size_of::<ExportNamedDeclaration>() == 32);
|
||||
assert!(align_of::<ExportNamedDeclaration>() == 4);
|
||||
assert!(offset_of!(ExportNamedDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportNamedDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportNamedDeclaration, export_kind) == 12);
|
||||
assert!(offset_of!(ExportNamedDeclaration, declaration) == 16);
|
||||
assert!(offset_of!(ExportNamedDeclaration, specifiers) == 24);
|
||||
assert!(offset_of!(ExportNamedDeclaration, source) == 40);
|
||||
assert!(offset_of!(ExportNamedDeclaration, with_clause) == 72);
|
||||
assert!(offset_of!(ExportNamedDeclaration, specifiers) == 16);
|
||||
|
||||
// Padding: 3 bytes
|
||||
assert!(size_of::<ExportFromDeclaration>() == 68);
|
||||
assert!(align_of::<ExportFromDeclaration>() == 4);
|
||||
assert!(offset_of!(ExportFromDeclaration, span) == 0);
|
||||
assert!(offset_of!(ExportFromDeclaration, node_id) == 8);
|
||||
assert!(offset_of!(ExportFromDeclaration, export_kind) == 12);
|
||||
assert!(offset_of!(ExportFromDeclaration, specifiers) == 16);
|
||||
assert!(offset_of!(ExportFromDeclaration, source) == 32);
|
||||
assert!(offset_of!(ExportFromDeclaration, with_clause) == 64);
|
||||
|
||||
// Padding: 0 bytes
|
||||
assert!(size_of::<ExportDefaultDeclaration>() == 20);
|
||||
|
||||
@@ -9452,25 +9452,35 @@ impl<'a> Statement<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Build a [`Statement::ExportDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
#[inline]
|
||||
pub fn new_export_declaration<B: GetAstBuilder<'a>>(
|
||||
span: Span,
|
||||
declaration: Declaration<'a>,
|
||||
builder: &B,
|
||||
) -> Self {
|
||||
Self::ExportDeclaration(ExportDeclaration::boxed(span, declaration, builder.builder()))
|
||||
}
|
||||
|
||||
/// Build a [`Statement::ExportNamedDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportNamedDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo }`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new_export_named_declaration<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
declaration: Option<Declaration<'a>>,
|
||||
specifiers: V1,
|
||||
source: Option<StringLiteral<'a>>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
@@ -9478,7 +9488,36 @@ impl<'a> Statement<'a> {
|
||||
{
|
||||
Self::ExportNamedDeclaration(ExportNamedDeclaration::boxed(
|
||||
span,
|
||||
declaration,
|
||||
specifiers,
|
||||
export_kind,
|
||||
builder.builder(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Build a [`Statement::ExportFromDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportFromDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo } from 'module'`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new_export_from_declaration<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
specifiers: V1,
|
||||
source: StringLiteral<'a>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
V1: IntoIn<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
{
|
||||
Self::ExportFromDeclaration(ExportFromDeclaration::boxed(
|
||||
span,
|
||||
specifiers,
|
||||
source,
|
||||
export_kind,
|
||||
@@ -16264,25 +16303,35 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Build a [`ModuleDeclaration::ExportDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
#[inline]
|
||||
pub fn new_export_declaration<B: GetAstBuilder<'a>>(
|
||||
span: Span,
|
||||
declaration: Declaration<'a>,
|
||||
builder: &B,
|
||||
) -> Self {
|
||||
Self::ExportDeclaration(ExportDeclaration::boxed(span, declaration, builder.builder()))
|
||||
}
|
||||
|
||||
/// Build a [`ModuleDeclaration::ExportNamedDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportNamedDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo }`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new_export_named_declaration<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
declaration: Option<Declaration<'a>>,
|
||||
specifiers: V1,
|
||||
source: Option<StringLiteral<'a>>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
@@ -16290,7 +16339,36 @@ impl<'a> ModuleDeclaration<'a> {
|
||||
{
|
||||
Self::ExportNamedDeclaration(ExportNamedDeclaration::boxed(
|
||||
span,
|
||||
declaration,
|
||||
specifiers,
|
||||
export_kind,
|
||||
builder.builder(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Build a [`ModuleDeclaration::ExportFromDeclaration`].
|
||||
///
|
||||
/// This node contains an [`ExportFromDeclaration`] that will be stored in the memory arena.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo } from 'module'`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new_export_from_declaration<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
specifiers: V1,
|
||||
source: StringLiteral<'a>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
V1: IntoIn<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
{
|
||||
Self::ExportFromDeclaration(ExportFromDeclaration::boxed(
|
||||
span,
|
||||
specifiers,
|
||||
source,
|
||||
export_kind,
|
||||
@@ -16884,6 +16962,44 @@ impl<'a> ImportAttributeKey<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExportDeclaration<'a> {
|
||||
/// Build an [`ExportDeclaration`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena,
|
||||
/// use [`ExportDeclaration::boxed`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
#[inline]
|
||||
pub fn new<B: GetAstBuilder<'a>>(
|
||||
span: Span,
|
||||
declaration: Declaration<'a>,
|
||||
builder: &B,
|
||||
) -> Self {
|
||||
let builder = builder.builder();
|
||||
ExportDeclaration { node_id: Cell::new(builder.node_id()), span, declaration }
|
||||
}
|
||||
|
||||
/// Build an [`ExportDeclaration`], and store it in the memory arena.
|
||||
///
|
||||
/// Returns a [`Box`](ArenaBox) containing the newly-allocated node.
|
||||
/// If you want a stack-allocated node, use [`ExportDeclaration::new`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
#[inline]
|
||||
pub fn boxed<B: GetAstBuilder<'a>>(
|
||||
span: Span,
|
||||
declaration: Declaration<'a>,
|
||||
builder: &B,
|
||||
) -> ArenaBox<'a, Self> {
|
||||
let builder = builder.builder();
|
||||
ArenaBox::new_in(Self::new(span, declaration, builder), &builder.allocator())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExportNamedDeclaration<'a> {
|
||||
/// Build an [`ExportNamedDeclaration`].
|
||||
///
|
||||
@@ -16892,19 +17008,13 @@ impl<'a> ExportNamedDeclaration<'a> {
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo }`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
declaration: Option<Declaration<'a>>,
|
||||
specifiers: V1,
|
||||
source: Option<StringLiteral<'a>>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
@@ -16914,11 +17024,8 @@ impl<'a> ExportNamedDeclaration<'a> {
|
||||
ExportNamedDeclaration {
|
||||
node_id: Cell::new(builder.node_id()),
|
||||
span,
|
||||
declaration,
|
||||
specifiers: specifiers.into_in(builder.allocator()),
|
||||
source,
|
||||
export_kind,
|
||||
with_clause,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16929,17 +17036,74 @@ impl<'a> ExportNamedDeclaration<'a> {
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `declaration`
|
||||
/// * `specifiers`
|
||||
/// * `export_kind`: `export type { foo }`
|
||||
#[inline]
|
||||
pub fn boxed<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
specifiers: V1,
|
||||
export_kind: ImportOrExportKind,
|
||||
builder: &B,
|
||||
) -> ArenaBox<'a, Self>
|
||||
where
|
||||
V1: IntoIn<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
{
|
||||
let builder = builder.builder();
|
||||
ArenaBox::new_in(Self::new(span, specifiers, export_kind, builder), &builder.allocator())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExportFromDeclaration<'a> {
|
||||
/// Build an [`ExportFromDeclaration`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena,
|
||||
/// use [`ExportFromDeclaration::boxed`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo }`
|
||||
/// * `export_kind`: `export type { foo } from 'module'`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn new<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
specifiers: V1,
|
||||
source: StringLiteral<'a>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
) -> Self
|
||||
where
|
||||
V1: IntoIn<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
{
|
||||
let builder = builder.builder();
|
||||
ExportFromDeclaration {
|
||||
node_id: Cell::new(builder.node_id()),
|
||||
span,
|
||||
specifiers: specifiers.into_in(builder.allocator()),
|
||||
source,
|
||||
export_kind,
|
||||
with_clause,
|
||||
}
|
||||
}
|
||||
|
||||
/// Build an [`ExportFromDeclaration`], and store it in the memory arena.
|
||||
///
|
||||
/// Returns a [`Box`](ArenaBox) containing the newly-allocated node.
|
||||
/// If you want a stack-allocated node, use [`ExportFromDeclaration::new`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// * `span`: The [`Span`] covering this node
|
||||
/// * `specifiers`
|
||||
/// * `source`
|
||||
/// * `export_kind`: `export type { foo } from 'module'`
|
||||
/// * `with_clause`: Some(vec![]) for empty assertion
|
||||
#[inline]
|
||||
pub fn boxed<B: GetAstBuilder<'a>, V1>(
|
||||
span: Span,
|
||||
declaration: Option<Declaration<'a>>,
|
||||
specifiers: V1,
|
||||
source: Option<StringLiteral<'a>>,
|
||||
source: StringLiteral<'a>,
|
||||
export_kind: ImportOrExportKind,
|
||||
with_clause: Option<ArenaBox<'a, WithClause<'a>>>,
|
||||
builder: &B,
|
||||
@@ -16949,7 +17113,7 @@ impl<'a> ExportNamedDeclaration<'a> {
|
||||
{
|
||||
let builder = builder.builder();
|
||||
ArenaBox::new_in(
|
||||
Self::new(span, declaration, specifiers, source, export_kind, with_clause, builder),
|
||||
Self::new(span, specifiers, source, export_kind, with_clause, builder),
|
||||
&builder.allocator(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use oxc_syntax::node::NodeId;
|
||||
use crate::ast::*;
|
||||
|
||||
/// The largest integer value that can be mapped to an `AstType`/`AstKind` enum variant.
|
||||
pub const AST_TYPE_MAX: u8 = 188;
|
||||
pub const AST_TYPE_MAX: u8 = 190;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
@@ -103,105 +103,107 @@ pub enum AstType {
|
||||
ImportNamespaceSpecifier = 87,
|
||||
WithClause = 88,
|
||||
ImportAttribute = 89,
|
||||
ExportNamedDeclaration = 90,
|
||||
ExportDefaultDeclaration = 91,
|
||||
ExportAllDeclaration = 92,
|
||||
ExportSpecifier = 93,
|
||||
V8IntrinsicExpression = 94,
|
||||
BooleanLiteral = 95,
|
||||
NullLiteral = 96,
|
||||
NumericLiteral = 97,
|
||||
StringLiteral = 98,
|
||||
BigIntLiteral = 99,
|
||||
RegExpLiteral = 100,
|
||||
JSXElement = 101,
|
||||
JSXOpeningElement = 102,
|
||||
JSXClosingElement = 103,
|
||||
JSXFragment = 104,
|
||||
JSXOpeningFragment = 105,
|
||||
JSXClosingFragment = 106,
|
||||
JSXNamespacedName = 107,
|
||||
JSXMemberExpression = 108,
|
||||
JSXExpressionContainer = 109,
|
||||
JSXEmptyExpression = 110,
|
||||
JSXAttribute = 111,
|
||||
JSXSpreadAttribute = 112,
|
||||
JSXIdentifier = 113,
|
||||
JSXSpreadChild = 114,
|
||||
JSXText = 115,
|
||||
TSThisParameter = 116,
|
||||
TSEnumDeclaration = 117,
|
||||
TSEnumBody = 118,
|
||||
TSEnumMember = 119,
|
||||
TSTypeAnnotation = 120,
|
||||
TSLiteralType = 121,
|
||||
TSConditionalType = 122,
|
||||
TSUnionType = 123,
|
||||
TSIntersectionType = 124,
|
||||
TSParenthesizedType = 125,
|
||||
TSTypeOperator = 126,
|
||||
TSArrayType = 127,
|
||||
TSIndexedAccessType = 128,
|
||||
TSTupleType = 129,
|
||||
TSNamedTupleMember = 130,
|
||||
TSOptionalType = 131,
|
||||
TSRestType = 132,
|
||||
TSAnyKeyword = 133,
|
||||
TSStringKeyword = 134,
|
||||
TSBooleanKeyword = 135,
|
||||
TSNumberKeyword = 136,
|
||||
TSNeverKeyword = 137,
|
||||
TSIntrinsicKeyword = 138,
|
||||
TSUnknownKeyword = 139,
|
||||
TSNullKeyword = 140,
|
||||
TSUndefinedKeyword = 141,
|
||||
TSVoidKeyword = 142,
|
||||
TSSymbolKeyword = 143,
|
||||
TSThisType = 144,
|
||||
TSObjectKeyword = 145,
|
||||
TSBigIntKeyword = 146,
|
||||
TSTypeReference = 147,
|
||||
TSQualifiedName = 148,
|
||||
TSTypeParameterInstantiation = 149,
|
||||
TSTypeParameter = 150,
|
||||
TSTypeParameterDeclaration = 151,
|
||||
TSTypeAliasDeclaration = 152,
|
||||
TSClassImplements = 153,
|
||||
TSInterfaceDeclaration = 154,
|
||||
TSInterfaceBody = 155,
|
||||
TSPropertySignature = 156,
|
||||
TSIndexSignature = 157,
|
||||
TSCallSignatureDeclaration = 158,
|
||||
TSMethodSignature = 159,
|
||||
TSConstructSignatureDeclaration = 160,
|
||||
TSIndexSignatureName = 161,
|
||||
TSInterfaceHeritage = 162,
|
||||
TSTypePredicate = 163,
|
||||
TSModuleDeclaration = 164,
|
||||
TSGlobalDeclaration = 165,
|
||||
TSModuleBlock = 166,
|
||||
TSTypeLiteral = 167,
|
||||
TSInferType = 168,
|
||||
TSTypeQuery = 169,
|
||||
TSImportType = 170,
|
||||
TSImportTypeQualifiedName = 171,
|
||||
TSFunctionType = 172,
|
||||
TSConstructorType = 173,
|
||||
TSMappedType = 174,
|
||||
TSTemplateLiteralType = 175,
|
||||
TSAsExpression = 176,
|
||||
TSSatisfiesExpression = 177,
|
||||
TSTypeAssertion = 178,
|
||||
TSImportEqualsDeclaration = 179,
|
||||
TSExternalModuleReference = 180,
|
||||
TSNonNullExpression = 181,
|
||||
Decorator = 182,
|
||||
TSExportAssignment = 183,
|
||||
TSNamespaceExportDeclaration = 184,
|
||||
TSInstantiationExpression = 185,
|
||||
JSDocNullableType = 186,
|
||||
JSDocNonNullableType = 187,
|
||||
JSDocUnknownType = 188,
|
||||
ExportDeclaration = 90,
|
||||
ExportNamedDeclaration = 91,
|
||||
ExportFromDeclaration = 92,
|
||||
ExportDefaultDeclaration = 93,
|
||||
ExportAllDeclaration = 94,
|
||||
ExportSpecifier = 95,
|
||||
V8IntrinsicExpression = 96,
|
||||
BooleanLiteral = 97,
|
||||
NullLiteral = 98,
|
||||
NumericLiteral = 99,
|
||||
StringLiteral = 100,
|
||||
BigIntLiteral = 101,
|
||||
RegExpLiteral = 102,
|
||||
JSXElement = 103,
|
||||
JSXOpeningElement = 104,
|
||||
JSXClosingElement = 105,
|
||||
JSXFragment = 106,
|
||||
JSXOpeningFragment = 107,
|
||||
JSXClosingFragment = 108,
|
||||
JSXNamespacedName = 109,
|
||||
JSXMemberExpression = 110,
|
||||
JSXExpressionContainer = 111,
|
||||
JSXEmptyExpression = 112,
|
||||
JSXAttribute = 113,
|
||||
JSXSpreadAttribute = 114,
|
||||
JSXIdentifier = 115,
|
||||
JSXSpreadChild = 116,
|
||||
JSXText = 117,
|
||||
TSThisParameter = 118,
|
||||
TSEnumDeclaration = 119,
|
||||
TSEnumBody = 120,
|
||||
TSEnumMember = 121,
|
||||
TSTypeAnnotation = 122,
|
||||
TSLiteralType = 123,
|
||||
TSConditionalType = 124,
|
||||
TSUnionType = 125,
|
||||
TSIntersectionType = 126,
|
||||
TSParenthesizedType = 127,
|
||||
TSTypeOperator = 128,
|
||||
TSArrayType = 129,
|
||||
TSIndexedAccessType = 130,
|
||||
TSTupleType = 131,
|
||||
TSNamedTupleMember = 132,
|
||||
TSOptionalType = 133,
|
||||
TSRestType = 134,
|
||||
TSAnyKeyword = 135,
|
||||
TSStringKeyword = 136,
|
||||
TSBooleanKeyword = 137,
|
||||
TSNumberKeyword = 138,
|
||||
TSNeverKeyword = 139,
|
||||
TSIntrinsicKeyword = 140,
|
||||
TSUnknownKeyword = 141,
|
||||
TSNullKeyword = 142,
|
||||
TSUndefinedKeyword = 143,
|
||||
TSVoidKeyword = 144,
|
||||
TSSymbolKeyword = 145,
|
||||
TSThisType = 146,
|
||||
TSObjectKeyword = 147,
|
||||
TSBigIntKeyword = 148,
|
||||
TSTypeReference = 149,
|
||||
TSQualifiedName = 150,
|
||||
TSTypeParameterInstantiation = 151,
|
||||
TSTypeParameter = 152,
|
||||
TSTypeParameterDeclaration = 153,
|
||||
TSTypeAliasDeclaration = 154,
|
||||
TSClassImplements = 155,
|
||||
TSInterfaceDeclaration = 156,
|
||||
TSInterfaceBody = 157,
|
||||
TSPropertySignature = 158,
|
||||
TSIndexSignature = 159,
|
||||
TSCallSignatureDeclaration = 160,
|
||||
TSMethodSignature = 161,
|
||||
TSConstructSignatureDeclaration = 162,
|
||||
TSIndexSignatureName = 163,
|
||||
TSInterfaceHeritage = 164,
|
||||
TSTypePredicate = 165,
|
||||
TSModuleDeclaration = 166,
|
||||
TSGlobalDeclaration = 167,
|
||||
TSModuleBlock = 168,
|
||||
TSTypeLiteral = 169,
|
||||
TSInferType = 170,
|
||||
TSTypeQuery = 171,
|
||||
TSImportType = 172,
|
||||
TSImportTypeQualifiedName = 173,
|
||||
TSFunctionType = 174,
|
||||
TSConstructorType = 175,
|
||||
TSMappedType = 176,
|
||||
TSTemplateLiteralType = 177,
|
||||
TSAsExpression = 178,
|
||||
TSSatisfiesExpression = 179,
|
||||
TSTypeAssertion = 180,
|
||||
TSImportEqualsDeclaration = 181,
|
||||
TSExternalModuleReference = 182,
|
||||
TSNonNullExpression = 183,
|
||||
Decorator = 184,
|
||||
TSExportAssignment = 185,
|
||||
TSNamespaceExportDeclaration = 186,
|
||||
TSInstantiationExpression = 187,
|
||||
JSDocNullableType = 188,
|
||||
JSDocNonNullableType = 189,
|
||||
JSDocUnknownType = 190,
|
||||
}
|
||||
|
||||
/// Untyped AST Node Kind
|
||||
@@ -306,7 +308,9 @@ pub enum AstKind<'a> {
|
||||
AstType::ImportNamespaceSpecifier as u8,
|
||||
WithClause(&'a WithClause<'a>) = AstType::WithClause as u8,
|
||||
ImportAttribute(&'a ImportAttribute<'a>) = AstType::ImportAttribute as u8,
|
||||
ExportDeclaration(&'a ExportDeclaration<'a>) = AstType::ExportDeclaration as u8,
|
||||
ExportNamedDeclaration(&'a ExportNamedDeclaration<'a>) = AstType::ExportNamedDeclaration as u8,
|
||||
ExportFromDeclaration(&'a ExportFromDeclaration<'a>) = AstType::ExportFromDeclaration as u8,
|
||||
ExportDefaultDeclaration(&'a ExportDefaultDeclaration<'a>) =
|
||||
AstType::ExportDefaultDeclaration as u8,
|
||||
ExportAllDeclaration(&'a ExportAllDeclaration<'a>) = AstType::ExportAllDeclaration as u8,
|
||||
@@ -513,7 +517,9 @@ impl AstKind<'_> {
|
||||
Self::ImportNamespaceSpecifier(it) => it.node_id(),
|
||||
Self::WithClause(it) => it.node_id(),
|
||||
Self::ImportAttribute(it) => it.node_id(),
|
||||
Self::ExportDeclaration(it) => it.node_id(),
|
||||
Self::ExportNamedDeclaration(it) => it.node_id(),
|
||||
Self::ExportFromDeclaration(it) => it.node_id(),
|
||||
Self::ExportDefaultDeclaration(it) => it.node_id(),
|
||||
Self::ExportAllDeclaration(it) => it.node_id(),
|
||||
Self::ExportSpecifier(it) => it.node_id(),
|
||||
@@ -710,7 +716,9 @@ impl AstKind<'_> {
|
||||
Self::ImportNamespaceSpecifier(it) => it.set_node_id(node_id),
|
||||
Self::WithClause(it) => it.set_node_id(node_id),
|
||||
Self::ImportAttribute(it) => it.set_node_id(node_id),
|
||||
Self::ExportDeclaration(it) => it.set_node_id(node_id),
|
||||
Self::ExportNamedDeclaration(it) => it.set_node_id(node_id),
|
||||
Self::ExportFromDeclaration(it) => it.set_node_id(node_id),
|
||||
Self::ExportDefaultDeclaration(it) => it.set_node_id(node_id),
|
||||
Self::ExportAllDeclaration(it) => it.set_node_id(node_id),
|
||||
Self::ExportSpecifier(it) => it.set_node_id(node_id),
|
||||
@@ -909,7 +917,9 @@ impl GetSpan for AstKind<'_> {
|
||||
Self::ImportNamespaceSpecifier(it) => it.span(),
|
||||
Self::WithClause(it) => it.span(),
|
||||
Self::ImportAttribute(it) => it.span(),
|
||||
Self::ExportDeclaration(it) => it.span(),
|
||||
Self::ExportNamedDeclaration(it) => it.span(),
|
||||
Self::ExportFromDeclaration(it) => it.span(),
|
||||
Self::ExportDefaultDeclaration(it) => it.span(),
|
||||
Self::ExportAllDeclaration(it) => it.span(),
|
||||
Self::ExportSpecifier(it) => it.span(),
|
||||
@@ -1109,7 +1119,9 @@ impl GetAddress for AstKind<'_> {
|
||||
Self::ImportNamespaceSpecifier(it) => it.unstable_address(),
|
||||
Self::WithClause(it) => it.unstable_address(),
|
||||
Self::ImportAttribute(it) => it.unstable_address(),
|
||||
Self::ExportDeclaration(it) => it.unstable_address(),
|
||||
Self::ExportNamedDeclaration(it) => it.unstable_address(),
|
||||
Self::ExportFromDeclaration(it) => it.unstable_address(),
|
||||
Self::ExportDefaultDeclaration(it) => it.unstable_address(),
|
||||
Self::ExportAllDeclaration(it) => it.unstable_address(),
|
||||
Self::ExportSpecifier(it) => it.unstable_address(),
|
||||
@@ -1667,11 +1679,21 @@ impl<'a> AstKind<'a> {
|
||||
if let Self::ImportAttribute(v) = self { Some(v) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_export_declaration(self) -> Option<&'a ExportDeclaration<'a>> {
|
||||
if let Self::ExportDeclaration(v) = self { Some(v) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_export_named_declaration(self) -> Option<&'a ExportNamedDeclaration<'a>> {
|
||||
if let Self::ExportNamedDeclaration(v) = self { Some(v) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_export_from_declaration(self) -> Option<&'a ExportFromDeclaration<'a>> {
|
||||
if let Self::ExportFromDeclaration(v) = self { Some(v) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_export_default_declaration(self) -> Option<&'a ExportDefaultDeclaration<'a>> {
|
||||
if let Self::ExportDefaultDeclaration(v) = self { Some(v) } else { None }
|
||||
|
||||
@@ -1414,7 +1414,9 @@ impl<'new_alloc> CloneIn<'new_alloc> for Statement<'_> {
|
||||
Self::ImportDeclaration(_)
|
||||
| Self::ExportAllDeclaration(_)
|
||||
| Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::ExportFromDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_) => Statement::from(CloneIn::clone_in_impl(
|
||||
self.to_module_declaration(),
|
||||
@@ -2672,9 +2674,15 @@ impl<'new_alloc> CloneIn<'new_alloc> for ModuleDeclaration<'_> {
|
||||
Self::ExportDefaultDeclaration(it) => ModuleDeclaration::ExportDefaultDeclaration(
|
||||
CloneIn::clone_in_impl(it, with_semantic_ids, allocator),
|
||||
),
|
||||
Self::ExportDeclaration(it) => ModuleDeclaration::ExportDeclaration(
|
||||
CloneIn::clone_in_impl(it, with_semantic_ids, allocator),
|
||||
),
|
||||
Self::ExportNamedDeclaration(it) => ModuleDeclaration::ExportNamedDeclaration(
|
||||
CloneIn::clone_in_impl(it, with_semantic_ids, allocator),
|
||||
),
|
||||
Self::ExportFromDeclaration(it) => ModuleDeclaration::ExportFromDeclaration(
|
||||
CloneIn::clone_in_impl(it, with_semantic_ids, allocator),
|
||||
),
|
||||
Self::TSExportAssignment(it) => ModuleDeclaration::TSExportAssignment(
|
||||
CloneIn::clone_in_impl(it, with_semantic_ids, allocator),
|
||||
),
|
||||
@@ -2932,6 +2940,22 @@ impl<'new_alloc> CloneIn<'new_alloc> for ImportAttributeKey<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'new_alloc> CloneIn<'new_alloc> for ExportDeclaration<'_> {
|
||||
type Cloned = ExportDeclaration<'new_alloc>;
|
||||
|
||||
fn clone_in_impl(
|
||||
&self,
|
||||
with_semantic_ids: CloneInSemanticIds,
|
||||
allocator: &'new_alloc Allocator,
|
||||
) -> Self::Cloned {
|
||||
ExportDeclaration {
|
||||
node_id: CloneIn::clone_in_impl(&self.node_id, with_semantic_ids, allocator),
|
||||
span: CloneIn::clone_in_impl(&self.span, with_semantic_ids, allocator),
|
||||
declaration: CloneIn::clone_in_impl(&self.declaration, with_semantic_ids, allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'new_alloc> CloneIn<'new_alloc> for ExportNamedDeclaration<'_> {
|
||||
type Cloned = ExportNamedDeclaration<'new_alloc>;
|
||||
|
||||
@@ -2943,7 +2967,23 @@ impl<'new_alloc> CloneIn<'new_alloc> for ExportNamedDeclaration<'_> {
|
||||
ExportNamedDeclaration {
|
||||
node_id: CloneIn::clone_in_impl(&self.node_id, with_semantic_ids, allocator),
|
||||
span: CloneIn::clone_in_impl(&self.span, with_semantic_ids, allocator),
|
||||
declaration: CloneIn::clone_in_impl(&self.declaration, with_semantic_ids, allocator),
|
||||
specifiers: CloneIn::clone_in_impl(&self.specifiers, with_semantic_ids, allocator),
|
||||
export_kind: CloneIn::clone_in_impl(&self.export_kind, with_semantic_ids, allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'new_alloc> CloneIn<'new_alloc> for ExportFromDeclaration<'_> {
|
||||
type Cloned = ExportFromDeclaration<'new_alloc>;
|
||||
|
||||
fn clone_in_impl(
|
||||
&self,
|
||||
with_semantic_ids: CloneInSemanticIds,
|
||||
allocator: &'new_alloc Allocator,
|
||||
) -> Self::Cloned {
|
||||
ExportFromDeclaration {
|
||||
node_id: CloneIn::clone_in_impl(&self.node_id, with_semantic_ids, allocator),
|
||||
span: CloneIn::clone_in_impl(&self.span, with_semantic_ids, allocator),
|
||||
specifiers: CloneIn::clone_in_impl(&self.specifiers, with_semantic_ids, allocator),
|
||||
source: CloneIn::clone_in_impl(&self.source, with_semantic_ids, allocator),
|
||||
export_kind: CloneIn::clone_in_impl(&self.export_kind, with_semantic_ids, allocator),
|
||||
|
||||
@@ -707,7 +707,9 @@ impl ContentEq for Statement<'_> {
|
||||
(Self::ExportDefaultDeclaration(a), Self::ExportDefaultDeclaration(b)) => {
|
||||
a.content_eq(b)
|
||||
}
|
||||
(Self::ExportDeclaration(a), Self::ExportDeclaration(b)) => a.content_eq(b),
|
||||
(Self::ExportNamedDeclaration(a), Self::ExportNamedDeclaration(b)) => a.content_eq(b),
|
||||
(Self::ExportFromDeclaration(a), Self::ExportFromDeclaration(b)) => a.content_eq(b),
|
||||
(Self::TSExportAssignment(a), Self::TSExportAssignment(b)) => a.content_eq(b),
|
||||
(Self::TSNamespaceExportDeclaration(a), Self::TSNamespaceExportDeclaration(b)) => {
|
||||
a.content_eq(b)
|
||||
@@ -1303,7 +1305,9 @@ impl ContentEq for ModuleDeclaration<'_> {
|
||||
(Self::ExportDefaultDeclaration(a), Self::ExportDefaultDeclaration(b)) => {
|
||||
a.content_eq(b)
|
||||
}
|
||||
(Self::ExportDeclaration(a), Self::ExportDeclaration(b)) => a.content_eq(b),
|
||||
(Self::ExportNamedDeclaration(a), Self::ExportNamedDeclaration(b)) => a.content_eq(b),
|
||||
(Self::ExportFromDeclaration(a), Self::ExportFromDeclaration(b)) => a.content_eq(b),
|
||||
(Self::TSExportAssignment(a), Self::TSExportAssignment(b)) => a.content_eq(b),
|
||||
(Self::TSNamespaceExportDeclaration(a), Self::TSNamespaceExportDeclaration(b)) => {
|
||||
a.content_eq(b)
|
||||
@@ -1421,10 +1425,22 @@ impl ContentEq for ImportAttributeKey<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ContentEq for ExportNamedDeclaration<'_> {
|
||||
impl ContentEq for ExportDeclaration<'_> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.declaration, &other.declaration)
|
||||
&& ContentEq::content_eq(&self.specifiers, &other.specifiers)
|
||||
}
|
||||
}
|
||||
|
||||
impl ContentEq for ExportNamedDeclaration<'_> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.specifiers, &other.specifiers)
|
||||
&& ContentEq::content_eq(&self.export_kind, &other.export_kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl ContentEq for ExportFromDeclaration<'_> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.specifiers, &other.specifiers)
|
||||
&& ContentEq::content_eq(&self.source, &other.source)
|
||||
&& ContentEq::content_eq(&self.export_kind, &other.export_kind)
|
||||
&& ContentEq::content_eq(&self.with_clause, &other.with_clause)
|
||||
|
||||
@@ -1466,9 +1466,9 @@ impl<'a> Dummy<'a> for StaticBlock<'a> {
|
||||
impl<'a> Dummy<'a> for ModuleDeclaration<'a> {
|
||||
/// Create a dummy [`ModuleDeclaration`].
|
||||
///
|
||||
/// Has cost of making 2 allocations (48 bytes).
|
||||
/// Has cost of making 1 allocation (40 bytes).
|
||||
fn dummy(allocator: &'a Allocator) -> Self {
|
||||
Self::ExportDefaultDeclaration(Dummy::dummy(allocator))
|
||||
Self::ExportNamedDeclaration(Dummy::dummy(allocator))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1643,6 +1643,19 @@ impl<'a> Dummy<'a> for ImportAttributeKey<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Dummy<'a> for ExportDeclaration<'a> {
|
||||
/// Create a dummy [`ExportDeclaration`].
|
||||
///
|
||||
/// Has cost of making 1 allocation (40 bytes).
|
||||
fn dummy(allocator: &'a Allocator) -> Self {
|
||||
Self {
|
||||
node_id: Dummy::dummy(allocator),
|
||||
span: Dummy::dummy(allocator),
|
||||
declaration: Dummy::dummy(allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Dummy<'a> for ExportNamedDeclaration<'a> {
|
||||
/// Create a dummy [`ExportNamedDeclaration`].
|
||||
///
|
||||
@@ -1651,7 +1664,20 @@ impl<'a> Dummy<'a> for ExportNamedDeclaration<'a> {
|
||||
Self {
|
||||
node_id: Dummy::dummy(allocator),
|
||||
span: Dummy::dummy(allocator),
|
||||
declaration: Dummy::dummy(allocator),
|
||||
specifiers: Dummy::dummy(allocator),
|
||||
export_kind: Dummy::dummy(allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Dummy<'a> for ExportFromDeclaration<'a> {
|
||||
/// Create a dummy [`ExportFromDeclaration`].
|
||||
///
|
||||
/// Does not allocate any data into arena.
|
||||
fn dummy(allocator: &'a Allocator) -> Self {
|
||||
Self {
|
||||
node_id: Dummy::dummy(allocator),
|
||||
span: Dummy::dummy(allocator),
|
||||
specifiers: Dummy::dummy(allocator),
|
||||
source: Dummy::dummy(allocator),
|
||||
export_kind: Dummy::dummy(allocator),
|
||||
|
||||
@@ -831,7 +831,9 @@ impl ESTree for Statement<'_> {
|
||||
Self::ImportDeclaration(_)
|
||||
| Self::ExportAllDeclaration(_)
|
||||
| Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::ExportFromDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_) => {
|
||||
self.to_module_declaration().serialize(serializer)
|
||||
@@ -1600,7 +1602,9 @@ impl ESTree for ModuleDeclaration<'_> {
|
||||
Self::ImportDeclaration(it) => it.serialize(serializer),
|
||||
Self::ExportAllDeclaration(it) => it.serialize(serializer),
|
||||
Self::ExportDefaultDeclaration(it) => it.serialize(serializer),
|
||||
Self::ExportDeclaration(it) => it.serialize(serializer),
|
||||
Self::ExportNamedDeclaration(it) => it.serialize(serializer),
|
||||
Self::ExportFromDeclaration(it) => it.serialize(serializer),
|
||||
Self::TSExportAssignment(it) => it.serialize(serializer),
|
||||
Self::TSNamespaceExportDeclaration(it) => it.serialize(serializer),
|
||||
}
|
||||
@@ -1750,17 +1754,48 @@ impl ESTree for ImportAttributeKey<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ESTree for ExportNamedDeclaration<'_> {
|
||||
impl ESTree for ExportDeclaration<'_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
let mut state = serializer.serialize_struct();
|
||||
state.serialize_field("type", &JsonSafeString("ExportNamedDeclaration"));
|
||||
state.serialize_field("declaration", &self.declaration);
|
||||
state.serialize_field("specifiers", &crate::serialize::basic::EmptyArray(self));
|
||||
state.serialize_field("source", &crate::serialize::basic::Null(self));
|
||||
state.serialize_ts_field(
|
||||
"exportKind",
|
||||
&crate::serialize::js::ExportDeclarationExportKind(self),
|
||||
);
|
||||
state.serialize_field("attributes", &crate::serialize::basic::EmptyArray(self));
|
||||
state.serialize_span(self.span);
|
||||
state.end();
|
||||
}
|
||||
}
|
||||
|
||||
impl ESTree for ExportNamedDeclaration<'_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
let mut state = serializer.serialize_struct();
|
||||
state.serialize_field("type", &JsonSafeString("ExportNamedDeclaration"));
|
||||
state.serialize_field("declaration", &crate::serialize::basic::Null(self));
|
||||
state.serialize_field("specifiers", &self.specifiers);
|
||||
state.serialize_field("source", &crate::serialize::basic::Null(self));
|
||||
state.serialize_ts_field("exportKind", &self.export_kind);
|
||||
state.serialize_field("attributes", &crate::serialize::basic::EmptyArray(self));
|
||||
state.serialize_span(self.span);
|
||||
state.end();
|
||||
}
|
||||
}
|
||||
|
||||
impl ESTree for ExportFromDeclaration<'_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
let mut state = serializer.serialize_struct();
|
||||
state.serialize_field("type", &JsonSafeString("ExportNamedDeclaration"));
|
||||
state.serialize_field("declaration", &crate::serialize::basic::Null(self));
|
||||
state.serialize_field("specifiers", &self.specifiers);
|
||||
state.serialize_field("source", &self.source);
|
||||
state.serialize_ts_field("exportKind", &self.export_kind);
|
||||
state.serialize_field(
|
||||
"attributes",
|
||||
&crate::serialize::js::ExportNamedDeclarationWithClause(self),
|
||||
&crate::serialize::js::ExportFromDeclarationWithClause(self),
|
||||
);
|
||||
state.serialize_span(self.span);
|
||||
state.end();
|
||||
|
||||
@@ -321,7 +321,9 @@ impl GetAddress for Statement<'_> {
|
||||
Self::ImportDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportAllDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportDefaultDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportNamedDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportFromDeclaration(it) => GetAddress::address(it),
|
||||
Self::TSExportAssignment(it) => GetAddress::address(it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetAddress::address(it),
|
||||
}
|
||||
@@ -509,7 +511,9 @@ impl GetAddress for ModuleDeclaration<'_> {
|
||||
Self::ImportDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportAllDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportDefaultDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportNamedDeclaration(it) => GetAddress::address(it),
|
||||
Self::ExportFromDeclaration(it) => GetAddress::address(it),
|
||||
Self::TSExportAssignment(it) => GetAddress::address(it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetAddress::address(it),
|
||||
}
|
||||
|
||||
@@ -625,7 +625,9 @@ impl GetSpan for Statement<'_> {
|
||||
Self::ImportDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportAllDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportDefaultDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportNamedDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportFromDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::TSExportAssignment(it) => GetSpan::span(&**it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetSpan::span(&**it),
|
||||
}
|
||||
@@ -1100,7 +1102,9 @@ impl GetSpan for ModuleDeclaration<'_> {
|
||||
Self::ImportDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportAllDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportDefaultDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportNamedDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::ExportFromDeclaration(it) => GetSpan::span(&**it),
|
||||
Self::TSExportAssignment(it) => GetSpan::span(&**it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetSpan::span(&**it),
|
||||
}
|
||||
@@ -1182,6 +1186,13 @@ impl GetSpan for ImportAttributeKey<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpan for ExportDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpan for ExportNamedDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
@@ -1189,6 +1200,13 @@ impl GetSpan for ExportNamedDeclaration<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpan for ExportFromDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpan for ExportDefaultDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
|
||||
@@ -624,7 +624,9 @@ impl GetSpanMut for Statement<'_> {
|
||||
Self::ImportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportAllDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportDefaultDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportNamedDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportFromDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::TSExportAssignment(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
}
|
||||
@@ -1099,7 +1101,9 @@ impl GetSpanMut for ModuleDeclaration<'_> {
|
||||
Self::ImportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportAllDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportDefaultDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportNamedDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::ExportFromDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::TSExportAssignment(it) => GetSpanMut::span_mut(&mut **it),
|
||||
Self::TSNamespaceExportDeclaration(it) => GetSpanMut::span_mut(&mut **it),
|
||||
}
|
||||
@@ -1181,6 +1185,13 @@ impl GetSpanMut for ImportAttributeKey<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpanMut for ExportDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
&mut self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpanMut for ExportNamedDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
@@ -1188,6 +1199,13 @@ impl GetSpanMut for ExportNamedDeclaration<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpanMut for ExportFromDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
&mut self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl GetSpanMut for ExportDefaultDeclaration<'_> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
|
||||
@@ -234,8 +234,12 @@ impl<'a> ReplaceWith<'a> for ImportAttribute<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ImportAttributeKey<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ExportDeclaration<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ExportNamedDeclaration<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ExportFromDeclaration<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ExportDefaultDeclaration<'a> {}
|
||||
|
||||
impl<'a> ReplaceWith<'a> for ExportAllDeclaration<'a> {}
|
||||
|
||||
@@ -236,8 +236,12 @@ impl<'a> TakeIn<'a> for ImportAttribute<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ImportAttributeKey<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ExportDeclaration<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ExportNamedDeclaration<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ExportFromDeclaration<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ExportDefaultDeclaration<'a> {}
|
||||
|
||||
impl<'a> TakeIn<'a> for ExportAllDeclaration<'a> {}
|
||||
|
||||
@@ -188,8 +188,12 @@ impl UnstableAddress for WithClause<'_> {}
|
||||
|
||||
impl UnstableAddress for ImportAttribute<'_> {}
|
||||
|
||||
impl UnstableAddress for ExportDeclaration<'_> {}
|
||||
|
||||
impl UnstableAddress for ExportNamedDeclaration<'_> {}
|
||||
|
||||
impl UnstableAddress for ExportFromDeclaration<'_> {}
|
||||
|
||||
impl UnstableAddress for ExportDefaultDeclaration<'_> {}
|
||||
|
||||
impl UnstableAddress for ExportAllDeclaration<'_> {}
|
||||
|
||||
@@ -1685,6 +1685,22 @@ impl ImportAttribute<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportDeclaration<'_> {
|
||||
/// Get [`NodeId`] of [`ExportDeclaration`].
|
||||
///
|
||||
/// Only use this method on a post-semantic AST where [`NodeId`]s are always defined.
|
||||
#[inline]
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.node_id.get()
|
||||
}
|
||||
|
||||
/// Set [`NodeId`] of [`ExportDeclaration`].
|
||||
#[inline]
|
||||
pub fn set_node_id(&self, node_id: NodeId) {
|
||||
self.node_id.set(node_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportNamedDeclaration<'_> {
|
||||
/// Get [`NodeId`] of [`ExportNamedDeclaration`].
|
||||
///
|
||||
@@ -1701,6 +1717,22 @@ impl ExportNamedDeclaration<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportFromDeclaration<'_> {
|
||||
/// Get [`NodeId`] of [`ExportFromDeclaration`].
|
||||
///
|
||||
/// Only use this method on a post-semantic AST where [`NodeId`]s are always defined.
|
||||
#[inline]
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.node_id.get()
|
||||
}
|
||||
|
||||
/// Set [`NodeId`] of [`ExportFromDeclaration`].
|
||||
#[inline]
|
||||
pub fn set_node_id(&self, node_id: NodeId) {
|
||||
self.node_id.set(node_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl ExportDefaultDeclaration<'_> {
|
||||
/// Get [`NodeId`] of [`ExportDefaultDeclaration`].
|
||||
///
|
||||
@@ -3853,7 +3885,9 @@ impl Statement<'_> {
|
||||
Self::ImportDeclaration(it) => it.node_id(),
|
||||
Self::ExportAllDeclaration(it) => it.node_id(),
|
||||
Self::ExportDefaultDeclaration(it) => it.node_id(),
|
||||
Self::ExportDeclaration(it) => it.node_id(),
|
||||
Self::ExportNamedDeclaration(it) => it.node_id(),
|
||||
Self::ExportFromDeclaration(it) => it.node_id(),
|
||||
Self::TSExportAssignment(it) => it.node_id(),
|
||||
Self::TSNamespaceExportDeclaration(it) => it.node_id(),
|
||||
}
|
||||
@@ -4048,7 +4082,9 @@ impl ModuleDeclaration<'_> {
|
||||
Self::ImportDeclaration(it) => it.node_id(),
|
||||
Self::ExportAllDeclaration(it) => it.node_id(),
|
||||
Self::ExportDefaultDeclaration(it) => it.node_id(),
|
||||
Self::ExportDeclaration(it) => it.node_id(),
|
||||
Self::ExportNamedDeclaration(it) => it.node_id(),
|
||||
Self::ExportFromDeclaration(it) => it.node_id(),
|
||||
Self::TSExportAssignment(it) => it.node_id(),
|
||||
Self::TSNamespaceExportDeclaration(it) => it.node_id(),
|
||||
}
|
||||
|
||||
@@ -2766,7 +2766,9 @@ impl<'a> Statement<'a> {
|
||||
Self::ImportDeclaration(_)
|
||||
| Self::ExportAllDeclaration(_)
|
||||
| Self::ExportDefaultDeclaration(_)
|
||||
| Self::ExportDeclaration(_)
|
||||
| Self::ExportNamedDeclaration(_)
|
||||
| Self::ExportFromDeclaration(_)
|
||||
| Self::TSExportAssignment(_)
|
||||
| Self::TSNamespaceExportDeclaration(_)
|
||||
)
|
||||
@@ -2866,9 +2868,11 @@ impl<'a> TryFrom<Statement<'a>> for ModuleDeclaration<'a> {
|
||||
Statement::ExportDefaultDeclaration(o) => {
|
||||
Ok(ModuleDeclaration::ExportDefaultDeclaration(o))
|
||||
}
|
||||
Statement::ExportDeclaration(o) => Ok(ModuleDeclaration::ExportDeclaration(o)),
|
||||
Statement::ExportNamedDeclaration(o) => {
|
||||
Ok(ModuleDeclaration::ExportNamedDeclaration(o))
|
||||
}
|
||||
Statement::ExportFromDeclaration(o) => Ok(ModuleDeclaration::ExportFromDeclaration(o)),
|
||||
Statement::TSExportAssignment(o) => Ok(ModuleDeclaration::TSExportAssignment(o)),
|
||||
Statement::TSNamespaceExportDeclaration(o) => {
|
||||
Ok(ModuleDeclaration::TSNamespaceExportDeclaration(o))
|
||||
@@ -2890,7 +2894,9 @@ impl<'a> From<ModuleDeclaration<'a>> for Statement<'a> {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(o) => {
|
||||
Statement::ExportDefaultDeclaration(o)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(o) => Statement::ExportDeclaration(o),
|
||||
ModuleDeclaration::ExportNamedDeclaration(o) => Statement::ExportNamedDeclaration(o),
|
||||
ModuleDeclaration::ExportFromDeclaration(o) => Statement::ExportFromDeclaration(o),
|
||||
ModuleDeclaration::TSExportAssignment(o) => Statement::TSExportAssignment(o),
|
||||
ModuleDeclaration::TSNamespaceExportDeclaration(o) => {
|
||||
Statement::TSNamespaceExportDeclaration(o)
|
||||
@@ -5612,7 +5618,9 @@ macro_rules! match_module_declaration {
|
||||
$ty::ImportDeclaration(_)
|
||||
| $ty::ExportAllDeclaration(_)
|
||||
| $ty::ExportDefaultDeclaration(_)
|
||||
| $ty::ExportDeclaration(_)
|
||||
| $ty::ExportNamedDeclaration(_)
|
||||
| $ty::ExportFromDeclaration(_)
|
||||
| $ty::TSExportAssignment(_)
|
||||
| $ty::TSNamespaceExportDeclaration(_)
|
||||
};
|
||||
|
||||
@@ -739,7 +739,7 @@ impl ESTree for ImportDeclarationSpecifiers<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
// Serializers for `with_clause` field of `ImportDeclaration`, `ExportNamedDeclaration`,
|
||||
// Serializers for `with_clause` field of `ImportDeclaration`, `ExportFromDeclaration`,
|
||||
// and `ExportAllDeclaration` (which are renamed to `attributes` in ESTree AST).
|
||||
//
|
||||
// Serialize only the `with_entries` field of `WithClause`, and serialize `None` as empty array (`[]`).
|
||||
@@ -775,9 +775,9 @@ impl ESTree for ImportDeclarationWithClause<'_, '_> {
|
||||
withClause === null ? [] : withClause.attributes
|
||||
"
|
||||
)]
|
||||
pub struct ExportNamedDeclarationWithClause<'a, 'b>(pub &'b ExportNamedDeclaration<'a>);
|
||||
pub struct ExportFromDeclarationWithClause<'a, 'b>(pub &'b ExportFromDeclaration<'a>);
|
||||
|
||||
impl ESTree for ExportNamedDeclarationWithClause<'_, '_> {
|
||||
impl ESTree for ExportFromDeclarationWithClause<'_, '_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
if let Some(with_clause) = &self.0.with_clause {
|
||||
with_clause.with_entries.serialize(serializer);
|
||||
@@ -787,6 +787,21 @@ impl ESTree for ExportNamedDeclarationWithClause<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializer for the derived `exportKind` field of [`ExportDeclaration`].
|
||||
#[ast_meta]
|
||||
#[estree(
|
||||
ts_type = "ImportOrExportKind",
|
||||
raw_deser = "(THIS.declaration.declare === true || THIS.declaration.type === 'TSTypeAliasDeclaration' || THIS.declaration.type === 'TSInterfaceDeclaration') ? 'type' : 'value'"
|
||||
)]
|
||||
#[ts]
|
||||
pub struct ExportDeclarationExportKind<'a, 'b>(pub &'b ExportDeclaration<'a>);
|
||||
|
||||
impl ESTree for ExportDeclarationExportKind<'_, '_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
self.0.export_kind().serialize(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
#[ast_meta]
|
||||
#[estree(
|
||||
ts_type = "Array<ImportAttribute>",
|
||||
|
||||
@@ -86,10 +86,10 @@ impl Program<'_> {
|
||||
/// from the `Program` start span.
|
||||
/// See <https://github.com/oxc-project/oxc/pull/10134> for more info.
|
||||
///
|
||||
/// Special case where first statement is an `ExportNamedDeclaration` or `ExportDefaultDeclaration`
|
||||
/// Special case where first statement is an `ExportDeclaration` or `ExportDefaultDeclaration`
|
||||
/// exporting a class with decorators, where one of the decorators is before `export`.
|
||||
/// In these cases, the span of the statement starts after the span of the decorators.
|
||||
/// e.g. `@dec export class C {}` - `ExportNamedDeclaration` span start is 5, `Decorator` span start is 0.
|
||||
/// e.g. `@dec export class C {}` - `ExportDeclaration` span start is 5, `Decorator` span start is 0.
|
||||
/// `Program` span start is 0 (not 5).
|
||||
#[ast_meta]
|
||||
#[estree(raw_deser = "
|
||||
@@ -189,8 +189,8 @@ fn get_ts_start_span(program: &Program<'_>) -> u32 {
|
||||
|
||||
let start = first_stmt.span().start;
|
||||
match first_stmt {
|
||||
Statement::ExportNamedDeclaration(decl) => {
|
||||
if let Some(Declaration::ClassDeclaration(class)) = &decl.declaration
|
||||
Statement::ExportDeclaration(decl) => {
|
||||
if let Declaration::ClassDeclaration(class) = &decl.declaration
|
||||
&& let Some(decorator) = class.decorators.first()
|
||||
{
|
||||
return cmp::min(start, decorator.span.start);
|
||||
|
||||
@@ -727,26 +727,40 @@ pub static INHERITED_ENUMS: [InheritedEnum; 9] = [
|
||||
is_boxed: true,
|
||||
discriminant: 66,
|
||||
},
|
||||
EnumVariant {
|
||||
name: "ExportDeclaration",
|
||||
inner_name: "ExportDeclaration",
|
||||
inner_has_lifetime: true,
|
||||
is_boxed: true,
|
||||
discriminant: 67,
|
||||
},
|
||||
EnumVariant {
|
||||
name: "ExportNamedDeclaration",
|
||||
inner_name: "ExportNamedDeclaration",
|
||||
inner_has_lifetime: true,
|
||||
is_boxed: true,
|
||||
discriminant: 67,
|
||||
discriminant: 68,
|
||||
},
|
||||
EnumVariant {
|
||||
name: "ExportFromDeclaration",
|
||||
inner_name: "ExportFromDeclaration",
|
||||
inner_has_lifetime: true,
|
||||
is_boxed: true,
|
||||
discriminant: 69,
|
||||
},
|
||||
EnumVariant {
|
||||
name: "TSExportAssignment",
|
||||
inner_name: "TSExportAssignment",
|
||||
inner_has_lifetime: true,
|
||||
is_boxed: true,
|
||||
discriminant: 68,
|
||||
discriminant: 70,
|
||||
},
|
||||
EnumVariant {
|
||||
name: "TSNamespaceExportDeclaration",
|
||||
inner_name: "TSNamespaceExportDeclaration",
|
||||
inner_has_lifetime: true,
|
||||
is_boxed: true,
|
||||
discriminant: 69,
|
||||
discriminant: 71,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -542,9 +542,21 @@ impl<'a> VisitMut<'a> for Utf8ToUtf16Converter<'_> {
|
||||
self.convert_offset(&mut it.span.end);
|
||||
}
|
||||
|
||||
fn visit_export_named_declaration(&mut self, it: &mut ExportNamedDeclaration<'a>) {
|
||||
fn visit_export_declaration(&mut self, it: &mut ExportDeclaration<'a>) {
|
||||
// Custom implementation
|
||||
self.convert_export_named_declaration(it);
|
||||
self.convert_export_declaration(it);
|
||||
}
|
||||
|
||||
fn visit_export_named_declaration(&mut self, it: &mut ExportNamedDeclaration<'a>) {
|
||||
self.convert_offset(&mut it.span.start);
|
||||
walk_mut::walk_export_named_declaration(self, it);
|
||||
self.convert_offset(&mut it.span.end);
|
||||
}
|
||||
|
||||
fn visit_export_from_declaration(&mut self, it: &mut ExportFromDeclaration<'a>) {
|
||||
self.convert_offset(&mut it.span.start);
|
||||
walk_mut::walk_export_from_declaration(self, it);
|
||||
self.convert_offset(&mut it.span.end);
|
||||
}
|
||||
|
||||
fn visit_export_default_declaration(&mut self, it: &mut ExportDefaultDeclaration<'a>) {
|
||||
|
||||
@@ -606,11 +606,21 @@ pub trait Visit<'a>: Sized {
|
||||
walk_import_attribute_key(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_declaration(&mut self, it: &ExportDeclaration<'a>) {
|
||||
walk_export_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_named_declaration(&mut self, it: &ExportNamedDeclaration<'a>) {
|
||||
walk_export_named_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_from_declaration(&mut self, it: &ExportFromDeclaration<'a>) {
|
||||
walk_export_from_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_default_declaration(&mut self, it: &ExportDefaultDeclaration<'a>) {
|
||||
walk_export_default_declaration(self, it);
|
||||
@@ -2698,9 +2708,13 @@ pub mod walk {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(it) => {
|
||||
visitor.visit_export_default_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(it) => visitor.visit_export_declaration(it),
|
||||
ModuleDeclaration::ExportNamedDeclaration(it) => {
|
||||
visitor.visit_export_named_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(it) => {
|
||||
visitor.visit_export_from_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(it) => visitor.visit_ts_export_assignment(it),
|
||||
ModuleDeclaration::TSNamespaceExportDeclaration(it) => {
|
||||
visitor.visit_ts_namespace_export_declaration(it)
|
||||
@@ -2833,6 +2847,15 @@ pub mod walk {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_declaration<'a, V: Visit<'a>>(visitor: &mut V, it: &ExportDeclaration<'a>) {
|
||||
let kind = AstKind::ExportDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
visitor.visit_declaration(&it.declaration);
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_named_declaration<'a, V: Visit<'a>>(
|
||||
visitor: &mut V,
|
||||
@@ -2841,13 +2864,20 @@ pub mod walk {
|
||||
let kind = AstKind::ExportNamedDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
if let Some(declaration) = &it.declaration {
|
||||
visitor.visit_declaration(declaration);
|
||||
}
|
||||
visitor.visit_export_specifiers(&it.specifiers);
|
||||
if let Some(source) = &it.source {
|
||||
visitor.visit_string_literal(source);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_from_declaration<'a, V: Visit<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &ExportFromDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstKind::ExportFromDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
visitor.visit_export_specifiers(&it.specifiers);
|
||||
visitor.visit_string_literal(&it.source);
|
||||
if let Some(with_clause) = &it.with_clause {
|
||||
visitor.visit_with_clause(with_clause);
|
||||
}
|
||||
|
||||
@@ -633,11 +633,21 @@ pub trait VisitJs<'a>: Sized {
|
||||
walk_import_attribute_key(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_declaration(&mut self, it: &ExportDeclaration<'a>) {
|
||||
walk_export_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_named_declaration(&mut self, it: &ExportNamedDeclaration<'a>) {
|
||||
walk_export_named_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_from_declaration(&mut self, it: &ExportFromDeclaration<'a>) {
|
||||
walk_export_from_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_default_declaration(&mut self, it: &ExportDefaultDeclaration<'a>) {
|
||||
walk_export_default_declaration(self, it);
|
||||
@@ -2336,7 +2346,6 @@ pub mod walk_js {
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_module_declaration<'a, V: VisitJs<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &ModuleDeclaration<'a>,
|
||||
@@ -2348,9 +2357,13 @@ pub mod walk_js {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(it) => {
|
||||
visitor.visit_export_default_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(it) => visitor.visit_export_declaration(it),
|
||||
ModuleDeclaration::ExportNamedDeclaration(it) => {
|
||||
visitor.visit_export_named_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(it) => {
|
||||
visitor.visit_export_from_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(it) => visitor.visit_ts_export_assignment(it),
|
||||
_ => {}
|
||||
}
|
||||
@@ -2481,6 +2494,18 @@ pub mod walk_js {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_declaration<'a, V: VisitJs<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &ExportDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstKind::ExportDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
visitor.visit_declaration(&it.declaration);
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_named_declaration<'a, V: VisitJs<'a>>(
|
||||
visitor: &mut V,
|
||||
@@ -2489,13 +2514,20 @@ pub mod walk_js {
|
||||
let kind = AstKind::ExportNamedDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
if let Some(declaration) = &it.declaration {
|
||||
visitor.visit_declaration(declaration);
|
||||
}
|
||||
visitor.visit_export_specifiers(&it.specifiers);
|
||||
if let Some(source) = &it.source {
|
||||
visitor.visit_string_literal(source);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_from_declaration<'a, V: VisitJs<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &ExportFromDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstKind::ExportFromDeclaration(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&it.span);
|
||||
visitor.visit_export_specifiers(&it.specifiers);
|
||||
visitor.visit_string_literal(&it.source);
|
||||
if let Some(with_clause) = &it.with_clause {
|
||||
visitor.visit_with_clause(with_clause);
|
||||
}
|
||||
|
||||
@@ -625,11 +625,21 @@ pub trait VisitJsMut<'a>: Sized {
|
||||
walk_import_attribute_key(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_declaration(&mut self, it: &mut ExportDeclaration<'a>) {
|
||||
walk_export_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_named_declaration(&mut self, it: &mut ExportNamedDeclaration<'a>) {
|
||||
walk_export_named_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_from_declaration(&mut self, it: &mut ExportFromDeclaration<'a>) {
|
||||
walk_export_from_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_default_declaration(&mut self, it: &mut ExportDefaultDeclaration<'a>) {
|
||||
walk_export_default_declaration(self, it);
|
||||
@@ -2438,7 +2448,6 @@ pub mod walk_js_mut {
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_module_declaration<'a, V: VisitJsMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut ModuleDeclaration<'a>,
|
||||
@@ -2450,9 +2459,13 @@ pub mod walk_js_mut {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(it) => {
|
||||
visitor.visit_export_default_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(it) => visitor.visit_export_declaration(it),
|
||||
ModuleDeclaration::ExportNamedDeclaration(it) => {
|
||||
visitor.visit_export_named_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(it) => {
|
||||
visitor.visit_export_from_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(it) => visitor.visit_ts_export_assignment(it),
|
||||
_ => {}
|
||||
}
|
||||
@@ -2595,6 +2608,18 @@ pub mod walk_js_mut {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_declaration<'a, V: VisitJsMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut ExportDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstType::ExportDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
visitor.visit_declaration(&mut it.declaration);
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_named_declaration<'a, V: VisitJsMut<'a>>(
|
||||
visitor: &mut V,
|
||||
@@ -2603,13 +2628,20 @@ pub mod walk_js_mut {
|
||||
let kind = AstType::ExportNamedDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
if let Some(declaration) = &mut it.declaration {
|
||||
visitor.visit_declaration(declaration);
|
||||
}
|
||||
visitor.visit_export_specifiers(&mut it.specifiers);
|
||||
if let Some(source) = &mut it.source {
|
||||
visitor.visit_string_literal(source);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_from_declaration<'a, V: VisitJsMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut ExportFromDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstType::ExportFromDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
visitor.visit_export_specifiers(&mut it.specifiers);
|
||||
visitor.visit_string_literal(&mut it.source);
|
||||
if let Some(with_clause) = &mut it.with_clause {
|
||||
visitor.visit_with_clause(with_clause);
|
||||
}
|
||||
|
||||
@@ -598,11 +598,21 @@ pub trait VisitMut<'a>: Sized {
|
||||
walk_import_attribute_key(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_declaration(&mut self, it: &mut ExportDeclaration<'a>) {
|
||||
walk_export_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_named_declaration(&mut self, it: &mut ExportNamedDeclaration<'a>) {
|
||||
walk_export_named_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_from_declaration(&mut self, it: &mut ExportFromDeclaration<'a>) {
|
||||
walk_export_from_declaration(self, it);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_default_declaration(&mut self, it: &mut ExportDefaultDeclaration<'a>) {
|
||||
walk_export_default_declaration(self, it);
|
||||
@@ -2798,9 +2808,13 @@ pub mod walk_mut {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(it) => {
|
||||
visitor.visit_export_default_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(it) => visitor.visit_export_declaration(it),
|
||||
ModuleDeclaration::ExportNamedDeclaration(it) => {
|
||||
visitor.visit_export_named_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(it) => {
|
||||
visitor.visit_export_from_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(it) => visitor.visit_ts_export_assignment(it),
|
||||
ModuleDeclaration::TSNamespaceExportDeclaration(it) => {
|
||||
visitor.visit_ts_namespace_export_declaration(it)
|
||||
@@ -2948,6 +2962,18 @@ pub mod walk_mut {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_declaration<'a, V: VisitMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut ExportDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstType::ExportDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
visitor.visit_declaration(&mut it.declaration);
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_named_declaration<'a, V: VisitMut<'a>>(
|
||||
visitor: &mut V,
|
||||
@@ -2956,13 +2982,20 @@ pub mod walk_mut {
|
||||
let kind = AstType::ExportNamedDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
if let Some(declaration) = &mut it.declaration {
|
||||
visitor.visit_declaration(declaration);
|
||||
}
|
||||
visitor.visit_export_specifiers(&mut it.specifiers);
|
||||
if let Some(source) = &mut it.source {
|
||||
visitor.visit_string_literal(source);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn walk_export_from_declaration<'a, V: VisitMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut ExportFromDeclaration<'a>,
|
||||
) {
|
||||
let kind = AstType::ExportFromDeclaration;
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_span(&mut it.span);
|
||||
visitor.visit_export_specifiers(&mut it.specifiers);
|
||||
visitor.visit_string_literal(&mut it.source);
|
||||
if let Some(with_clause) = &mut it.with_clause {
|
||||
visitor.visit_with_clause(with_clause);
|
||||
}
|
||||
|
||||
@@ -78,16 +78,13 @@ impl Utf8ToUtf16Converter<'_> {
|
||||
self.convert_offset(&mut prop.span.end);
|
||||
}
|
||||
|
||||
pub(crate) fn convert_export_named_declaration(
|
||||
&mut self,
|
||||
decl: &mut ExportNamedDeclaration<'_>,
|
||||
) {
|
||||
pub(crate) fn convert_export_declaration(&mut self, decl: &mut ExportDeclaration<'_>) {
|
||||
// Special case logic for `@dec export class C {}`
|
||||
if let Some(Declaration::ClassDeclaration(class)) = &mut decl.declaration {
|
||||
if let Declaration::ClassDeclaration(class) = &mut decl.declaration {
|
||||
self.convert_exported_class(class, &mut decl.span);
|
||||
} else {
|
||||
self.convert_offset(&mut decl.span.start);
|
||||
walk_mut::walk_export_named_declaration(self, decl);
|
||||
walk_mut::walk_export_declaration(self, decl);
|
||||
self.convert_offset(&mut decl.span.end);
|
||||
}
|
||||
}
|
||||
@@ -106,7 +103,7 @@ impl Utf8ToUtf16Converter<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit `ExportNamedDeclaration` or `ExportDefaultDeclaration` containing a `Class`.
|
||||
/// Visit `ExportDeclaration` or `ExportDefaultDeclaration` containing a `Class`.
|
||||
/// e.g. `export class C {}`, `export default class {}`
|
||||
///
|
||||
/// These need special handing because decorators before the `export` keyword
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Not;
|
||||
use cow_utils::CowUtils;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_span::GetSpan;
|
||||
use oxc_span::{GetSpan, Span};
|
||||
use oxc_syntax::{
|
||||
operator::UnaryOperator,
|
||||
precedence::{GetPrecedence, Precedence},
|
||||
@@ -152,7 +152,9 @@ impl Gen for Statement<'_> {
|
||||
Self::LabeledStatement(stmt) => stmt.print(p, ctx),
|
||||
Self::EmptyStatement(stmt) => stmt.print(p, ctx),
|
||||
Self::ImportDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::ExportDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::ExportNamedDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::ExportFromDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::ExportDefaultDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::ExportAllDeclaration(decl) => decl.print(p, ctx),
|
||||
Self::WithStatement(stmt) => stmt.print(p, ctx),
|
||||
@@ -1042,10 +1044,10 @@ impl Gen for ImportAttribute<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Gen for ExportNamedDeclaration<'_> {
|
||||
impl Gen for ExportDeclaration<'_> {
|
||||
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
|
||||
p.print_comments_at(self.span.start);
|
||||
if let Some(Declaration::FunctionDeclaration(func)) = &self.declaration
|
||||
if let Declaration::FunctionDeclaration(func) = &self.declaration
|
||||
&& func.pure
|
||||
&& p.options.print_annotation_comment()
|
||||
{
|
||||
@@ -1057,63 +1059,85 @@ impl Gen for ExportNamedDeclaration<'_> {
|
||||
p.print_indent();
|
||||
p.add_source_mapping(self.span);
|
||||
p.print_str("export");
|
||||
if let Some(decl) = &self.declaration {
|
||||
// A decorated class starts with `@`, so no space is needed after `export`.
|
||||
if matches!(decl, Declaration::ClassDeclaration(c) if !c.decorators.is_empty()) {
|
||||
p.print_soft_space();
|
||||
} else {
|
||||
p.print_hard_space();
|
||||
}
|
||||
match decl {
|
||||
Declaration::VariableDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::FunctionDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::ClassDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSModuleDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSGlobalDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSTypeAliasDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSInterfaceDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSEnumDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSImportEqualsDeclaration(decl) => decl.print(p, ctx),
|
||||
}
|
||||
if matches!(
|
||||
decl,
|
||||
Declaration::VariableDeclaration(_)
|
||||
| Declaration::TSTypeAliasDeclaration(_)
|
||||
| Declaration::TSImportEqualsDeclaration(_)
|
||||
) {
|
||||
p.print_semicolon_after_statement();
|
||||
} else {
|
||||
p.print_soft_newline();
|
||||
p.needs_semicolon = false;
|
||||
}
|
||||
} else {
|
||||
if self.export_kind.is_type() {
|
||||
p.print_hard_space();
|
||||
p.print_str("type");
|
||||
}
|
||||
let decl = &self.declaration;
|
||||
// A decorated class starts with `@`, so no space is needed after `export`.
|
||||
if matches!(decl, Declaration::ClassDeclaration(c) if !c.decorators.is_empty()) {
|
||||
p.print_soft_space();
|
||||
p.print_ascii_byte(b'{');
|
||||
if !self.specifiers.is_empty() {
|
||||
p.print_soft_space();
|
||||
p.print_list(&self.specifiers, ctx);
|
||||
p.print_soft_space();
|
||||
}
|
||||
p.print_ascii_byte(b'}');
|
||||
if let Some(source) = &self.source {
|
||||
p.print_soft_space();
|
||||
p.print_str("from");
|
||||
p.print_soft_space();
|
||||
p.print_string_literal(source, false);
|
||||
if let Some(with_clause) = &self.with_clause {
|
||||
p.print_soft_space();
|
||||
with_clause.print(p, ctx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.print_hard_space();
|
||||
}
|
||||
match decl {
|
||||
Declaration::VariableDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::FunctionDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::ClassDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSModuleDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSGlobalDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSTypeAliasDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSInterfaceDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSEnumDeclaration(decl) => decl.print(p, ctx),
|
||||
Declaration::TSImportEqualsDeclaration(decl) => decl.print(p, ctx),
|
||||
}
|
||||
if matches!(
|
||||
decl,
|
||||
Declaration::VariableDeclaration(_)
|
||||
| Declaration::TSTypeAliasDeclaration(_)
|
||||
| Declaration::TSImportEqualsDeclaration(_)
|
||||
) {
|
||||
p.print_semicolon_after_statement();
|
||||
} else {
|
||||
p.print_soft_newline();
|
||||
p.needs_semicolon = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Gen for ExportNamedDeclaration<'_> {
|
||||
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
|
||||
gen_export_specifiers(p, ctx, self.span, self.export_kind, &self.specifiers);
|
||||
p.print_semicolon_after_statement();
|
||||
}
|
||||
}
|
||||
|
||||
impl Gen for ExportFromDeclaration<'_> {
|
||||
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
|
||||
gen_export_specifiers(p, ctx, self.span, self.export_kind, &self.specifiers);
|
||||
p.print_soft_space();
|
||||
p.print_str("from");
|
||||
p.print_soft_space();
|
||||
p.print_string_literal(&self.source, false);
|
||||
if let Some(with_clause) = &self.with_clause {
|
||||
p.print_soft_space();
|
||||
with_clause.print(p, ctx);
|
||||
}
|
||||
p.print_semicolon_after_statement();
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_export_specifiers(
|
||||
p: &mut Codegen,
|
||||
ctx: Context,
|
||||
span: Span,
|
||||
export_kind: ImportOrExportKind,
|
||||
specifiers: &[ExportSpecifier<'_>],
|
||||
) {
|
||||
p.print_comments_at(span.start);
|
||||
p.print_indent();
|
||||
p.add_source_mapping(span);
|
||||
p.print_str("export");
|
||||
if export_kind.is_type() {
|
||||
p.print_hard_space();
|
||||
p.print_str("type");
|
||||
}
|
||||
p.print_soft_space();
|
||||
p.print_ascii_byte(b'{');
|
||||
if !specifiers.is_empty() {
|
||||
p.print_soft_space();
|
||||
p.print_list(specifiers, ctx);
|
||||
p.print_soft_space();
|
||||
}
|
||||
p.print_ascii_byte(b'}');
|
||||
}
|
||||
|
||||
impl Gen for TSExportAssignment<'_> {
|
||||
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
|
||||
p.print_indent();
|
||||
@@ -1223,7 +1247,7 @@ impl Gen for ExportDefaultDeclaration<'_> {
|
||||
&& func.pure
|
||||
&& p.options.print_annotation_comment()
|
||||
{
|
||||
// See [`ExportNamedDeclaration`] for the rationale.
|
||||
// See [`ExportDeclaration`] for the rationale.
|
||||
p.print_annotation_comment(self.span.start, AnnotationKind::NoSideEffects, true);
|
||||
}
|
||||
p.print_indent();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use oxc_ast::ast::{
|
||||
ArrayPattern, AssignmentPattern, BindingIdentifier, BindingPattern, BindingRestElement, Class,
|
||||
Declaration, ExportNamedDeclaration, FormalParameter, FormalParameters, Function,
|
||||
ImportDeclaration, ImportDeclarationSpecifier, ModuleDeclaration, ObjectPattern,
|
||||
VariableDeclaration,
|
||||
Declaration, ExportDeclaration, FormalParameter, FormalParameters, Function, ImportDeclaration,
|
||||
ImportDeclarationSpecifier, ModuleDeclaration, ObjectPattern, VariableDeclaration,
|
||||
};
|
||||
|
||||
/// [`BoundName`](https://tc39.es/ecma262/#sec-static-semantics-boundnames)
|
||||
@@ -133,7 +132,7 @@ impl<'a> BoundNames<'a> for ModuleDeclaration<'a> {
|
||||
fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
|
||||
match self {
|
||||
ModuleDeclaration::ImportDeclaration(decl) => decl.bound_names(f),
|
||||
ModuleDeclaration::ExportNamedDeclaration(decl) => decl.bound_names(f),
|
||||
ModuleDeclaration::ExportDeclaration(decl) => decl.bound_names(f),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -159,10 +158,8 @@ impl<'a> BoundNames<'a> for ImportDeclaration<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BoundNames<'a> for ExportNamedDeclaration<'a> {
|
||||
impl<'a> BoundNames<'a> for ExportDeclaration<'a> {
|
||||
fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
|
||||
if let Some(decl) = &self.declaration {
|
||||
decl.bound_names(f);
|
||||
}
|
||||
self.declaration.bound_names(f);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,9 @@ pub enum AstNodes<'a> {
|
||||
ImportNamespaceSpecifier(&'a AstNode<'a, ImportNamespaceSpecifier<'a>>),
|
||||
WithClause(&'a AstNode<'a, WithClause<'a>>),
|
||||
ImportAttribute(&'a AstNode<'a, ImportAttribute<'a>>),
|
||||
ExportDeclaration(&'a AstNode<'a, ExportDeclaration<'a>>),
|
||||
ExportNamedDeclaration(&'a AstNode<'a, ExportNamedDeclaration<'a>>),
|
||||
ExportFromDeclaration(&'a AstNode<'a, ExportFromDeclaration<'a>>),
|
||||
ExportDefaultDeclaration(&'a AstNode<'a, ExportDefaultDeclaration<'a>>),
|
||||
ExportAllDeclaration(&'a AstNode<'a, ExportAllDeclaration<'a>>),
|
||||
ExportSpecifier(&'a AstNode<'a, ExportSpecifier<'a>>),
|
||||
@@ -317,7 +319,9 @@ impl AstNodes<'_> {
|
||||
Self::ImportNamespaceSpecifier(n) => n.span(),
|
||||
Self::WithClause(n) => n.span(),
|
||||
Self::ImportAttribute(n) => n.span(),
|
||||
Self::ExportDeclaration(n) => n.span(),
|
||||
Self::ExportNamedDeclaration(n) => n.span(),
|
||||
Self::ExportFromDeclaration(n) => n.span(),
|
||||
Self::ExportDefaultDeclaration(n) => n.span(),
|
||||
Self::ExportAllDeclaration(n) => n.span(),
|
||||
Self::ExportSpecifier(n) => n.span(),
|
||||
@@ -517,7 +521,9 @@ impl AstNodes<'_> {
|
||||
Self::ImportNamespaceSpecifier(n) => n.parent(),
|
||||
Self::WithClause(n) => n.parent(),
|
||||
Self::ImportAttribute(n) => n.parent(),
|
||||
Self::ExportDeclaration(n) => n.parent(),
|
||||
Self::ExportNamedDeclaration(n) => n.parent(),
|
||||
Self::ExportFromDeclaration(n) => n.parent(),
|
||||
Self::ExportDefaultDeclaration(n) => n.parent(),
|
||||
Self::ExportAllDeclaration(n) => n.parent(),
|
||||
Self::ExportSpecifier(n) => n.parent(),
|
||||
@@ -712,7 +718,9 @@ impl AstNodes<'_> {
|
||||
Self::ImportNamespaceSpecifier(_) => "ImportNamespaceSpecifier",
|
||||
Self::WithClause(_) => "WithClause",
|
||||
Self::ImportAttribute(_) => "ImportAttribute",
|
||||
Self::ExportDeclaration(_) => "ExportDeclaration",
|
||||
Self::ExportNamedDeclaration(_) => "ExportNamedDeclaration",
|
||||
Self::ExportFromDeclaration(_) => "ExportFromDeclaration",
|
||||
Self::ExportDefaultDeclaration(_) => "ExportDefaultDeclaration",
|
||||
Self::ExportAllDeclaration(_) => "ExportAllDeclaration",
|
||||
Self::ExportSpecifier(_) => "ExportSpecifier",
|
||||
@@ -5509,6 +5517,14 @@ impl<'a> AstNode<'a, ModuleDeclaration<'a>> {
|
||||
following_span_start: self.following_span_start,
|
||||
}))
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(s) => {
|
||||
AstNodes::ExportDeclaration(self.allocator.alloc(AstNode {
|
||||
inner: s.as_ref(),
|
||||
parent,
|
||||
allocator: self.allocator,
|
||||
following_span_start: self.following_span_start,
|
||||
}))
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(s) => {
|
||||
AstNodes::ExportNamedDeclaration(self.allocator.alloc(AstNode {
|
||||
inner: s.as_ref(),
|
||||
@@ -5517,6 +5533,14 @@ impl<'a> AstNode<'a, ModuleDeclaration<'a>> {
|
||||
following_span_start: self.following_span_start,
|
||||
}))
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(s) => {
|
||||
AstNodes::ExportFromDeclaration(self.allocator.alloc(AstNode {
|
||||
inner: s.as_ref(),
|
||||
parent,
|
||||
allocator: self.allocator,
|
||||
following_span_start: self.following_span_start,
|
||||
}))
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(s) => {
|
||||
AstNodes::TSExportAssignment(self.allocator.alloc(AstNode {
|
||||
inner: s.as_ref(),
|
||||
@@ -5986,41 +6010,42 @@ impl<'a> AstNode<'a, ImportAttributeKey<'a>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AstNode<'a, ExportDeclaration<'a>> {
|
||||
#[inline]
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.inner.node_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declaration(&self) -> &AstNode<'a, Declaration<'a>> {
|
||||
let following_span_start = 0;
|
||||
self.allocator.alloc(AstNode {
|
||||
inner: &self.inner.declaration,
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn format_leading_comments(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
format_leading_comments(self.span()).fmt(f);
|
||||
}
|
||||
|
||||
pub fn format_trailing_comments(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
format_trailing_comments(self.parent.span(), self.inner.span(), self.following_span_start)
|
||||
.fmt(f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AstNode<'a, ExportNamedDeclaration<'a>> {
|
||||
#[inline]
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.inner.node_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declaration(&self) -> Option<&AstNode<'a, Declaration<'a>>> {
|
||||
let following_span_start = self
|
||||
.inner
|
||||
.specifiers
|
||||
.first()
|
||||
.map(|n| n.span().start)
|
||||
.or_else(|| self.inner.source.as_ref().map(|n| n.span().start))
|
||||
.or_else(|| self.inner.with_clause.as_deref().map(|n| n.span().start))
|
||||
.unwrap_or(0);
|
||||
self.allocator
|
||||
.alloc(self.inner.declaration.as_ref().map(|inner| AstNode {
|
||||
inner,
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportNamedDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
}))
|
||||
.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(&self) -> &AstNode<'a, ArenaVec<'a, ExportSpecifier<'a>>> {
|
||||
let following_span_start = self
|
||||
.inner
|
||||
.source
|
||||
.as_ref()
|
||||
.map(|n| n.span().start)
|
||||
.or_else(|| self.inner.with_clause.as_deref().map(|n| n.span().start))
|
||||
.unwrap_or(0);
|
||||
let following_span_start = 0;
|
||||
self.allocator.alloc(AstNode {
|
||||
inner: &self.inner.specifiers,
|
||||
allocator: self.allocator,
|
||||
@@ -6030,16 +6055,46 @@ impl<'a> AstNode<'a, ExportNamedDeclaration<'a>> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(&self) -> Option<&AstNode<'a, StringLiteral<'a>>> {
|
||||
pub fn export_kind(&self) -> ImportOrExportKind {
|
||||
self.inner.export_kind
|
||||
}
|
||||
|
||||
pub fn format_leading_comments(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
format_leading_comments(self.span()).fmt(f);
|
||||
}
|
||||
|
||||
pub fn format_trailing_comments(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
format_trailing_comments(self.parent.span(), self.inner.span(), self.following_span_start)
|
||||
.fmt(f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AstNode<'a, ExportFromDeclaration<'a>> {
|
||||
#[inline]
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.inner.node_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(&self) -> &AstNode<'a, ArenaVec<'a, ExportSpecifier<'a>>> {
|
||||
let following_span_start = self.inner.source.span().start;
|
||||
self.allocator.alloc(AstNode {
|
||||
inner: &self.inner.specifiers,
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportFromDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(&self) -> &AstNode<'a, StringLiteral<'a>> {
|
||||
let following_span_start = self.inner.with_clause.as_deref().map_or(0, |n| n.span().start);
|
||||
self.allocator
|
||||
.alloc(self.inner.source.as_ref().map(|inner| AstNode {
|
||||
inner,
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportNamedDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
}))
|
||||
.as_ref()
|
||||
self.allocator.alloc(AstNode {
|
||||
inner: &self.inner.source,
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportFromDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -6054,7 +6109,7 @@ impl<'a> AstNode<'a, ExportNamedDeclaration<'a>> {
|
||||
.alloc(self.inner.with_clause.as_ref().map(|inner| AstNode {
|
||||
inner: inner.as_ref(),
|
||||
allocator: self.allocator,
|
||||
parent: AstNodes::ExportNamedDeclaration(transmute_self(self)),
|
||||
parent: AstNodes::ExportFromDeclaration(transmute_self(self)),
|
||||
following_span_start,
|
||||
}))
|
||||
.as_ref()
|
||||
|
||||
@@ -2750,6 +2750,16 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ModuleDeclaration<'a>>
|
||||
})
|
||||
.fmt(f);
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(inner) => {
|
||||
allocator
|
||||
.alloc(AstNode::<ExportDeclaration> {
|
||||
inner,
|
||||
parent,
|
||||
allocator,
|
||||
following_span_start: self.following_span_start,
|
||||
})
|
||||
.fmt(f);
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(inner) => {
|
||||
allocator
|
||||
.alloc(AstNode::<ExportNamedDeclaration> {
|
||||
@@ -2760,6 +2770,16 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ModuleDeclaration<'a>>
|
||||
})
|
||||
.fmt(f);
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(inner) => {
|
||||
allocator
|
||||
.alloc(AstNode::<ExportFromDeclaration> {
|
||||
inner,
|
||||
parent,
|
||||
allocator,
|
||||
following_span_start: self.following_span_start,
|
||||
})
|
||||
.fmt(f);
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(inner) => {
|
||||
allocator
|
||||
.alloc(AstNode::<TSExportAssignment> {
|
||||
@@ -2965,6 +2985,19 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ImportAttributeKey<'a>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ExportDeclaration<'a>> {
|
||||
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let is_suppressed = f.comments().is_suppressed(self.span().start);
|
||||
if is_suppressed {
|
||||
self.format_leading_comments(f);
|
||||
FormatSuppressedNode(self.span()).fmt(f);
|
||||
self.format_trailing_comments(f);
|
||||
} else {
|
||||
self.write(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ExportNamedDeclaration<'a>> {
|
||||
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let is_suppressed = f.comments().is_suppressed(self.span().start);
|
||||
@@ -2978,6 +3011,19 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ExportNamedDeclaration<
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ExportFromDeclaration<'a>> {
|
||||
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let is_suppressed = f.comments().is_suppressed(self.span().start);
|
||||
if is_suppressed {
|
||||
self.format_leading_comments(f);
|
||||
FormatSuppressedNode(self.span()).fmt(f);
|
||||
self.format_trailing_comments(f);
|
||||
} else {
|
||||
self.write(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ExportDefaultDeclaration<'a>> {
|
||||
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let is_suppressed = f.comments().is_suppressed(self.span().start);
|
||||
|
||||
@@ -51,8 +51,8 @@ fn get_statement_span(stmt: &Statement<'_>) -> u32 {
|
||||
export.span.start
|
||||
}
|
||||
}
|
||||
Statement::ExportNamedDeclaration(export) => {
|
||||
if let Some(Declaration::ClassDeclaration(class)) = &export.declaration
|
||||
Statement::ExportDeclaration(export) => {
|
||||
if let Declaration::ClassDeclaration(class) = &export.declaration
|
||||
&& let Some(decorator) = class.decorators.first()
|
||||
{
|
||||
min(decorator.span.start, export.span.start)
|
||||
|
||||
@@ -290,7 +290,7 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatClass<'a, '_> {
|
||||
if self.is_expression()
|
||||
|| !matches!(
|
||||
self.parent(),
|
||||
AstNodes::ExportNamedDeclaration(_) | AstNodes::ExportDefaultDeclaration(_)
|
||||
AstNodes::ExportDeclaration(_) | AstNodes::ExportDefaultDeclaration(_)
|
||||
)
|
||||
{
|
||||
write!(f, decorators);
|
||||
|
||||
@@ -38,7 +38,7 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ArenaVec<'a, Decorator<
|
||||
AstNodes::FormalParameter(_) => {
|
||||
write!(f, should_expand_decorators(self, f).then_some(expand_parent()));
|
||||
}
|
||||
AstNodes::ExportNamedDeclaration(_) | AstNodes::ExportDefaultDeclaration(_) => {
|
||||
AstNodes::ExportDeclaration(_) | AstNodes::ExportDefaultDeclaration(_) => {
|
||||
write!(f, [hard_line_break()]);
|
||||
}
|
||||
_ => {
|
||||
|
||||
@@ -5,6 +5,7 @@ use oxc_span::GetSpan;
|
||||
use crate::{
|
||||
FormatTrailingCommas,
|
||||
ast_nodes::{AstNode, AstNodes},
|
||||
format_args,
|
||||
formatter::{
|
||||
JsFormatter,
|
||||
prelude::*,
|
||||
@@ -12,9 +13,7 @@ use crate::{
|
||||
trivia::{FormatLeadingComments, FormatTrailingComments},
|
||||
},
|
||||
print::{
|
||||
import_declaration::{
|
||||
format_import_and_export_source_with_clause, import_and_export_source_with_clause_end,
|
||||
},
|
||||
import_declaration::format_source_with_clause_and_semicolon,
|
||||
semicolon::{FormatContentWithSemicolon, OptionalSemicolon},
|
||||
},
|
||||
write,
|
||||
@@ -65,16 +64,65 @@ fn format_export_keyword_with_class_decorators<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the `kind { specifiers }` part of
|
||||
/// - `export { ... }`
|
||||
/// - and `export { ... } from "..."`
|
||||
///
|
||||
/// including the comments around the braces.
|
||||
fn format_export_specifiers_block<'a>(
|
||||
span: Span,
|
||||
export_kind: ImportOrExportKind,
|
||||
specifiers: &AstNode<'a, ArenaVec<'a, ExportSpecifier<'a>>>,
|
||||
f: &mut JsFormatter<'_, 'a>,
|
||||
) {
|
||||
let needs_space = f.options().bracket_spacing.value();
|
||||
if specifiers.is_empty() {
|
||||
let comments = f.context().comments().comments_before_character(span.start, b'{');
|
||||
let has_line_comment = comments.iter().any(|c| c.is_line());
|
||||
// Block comment example:
|
||||
// Input: `export /* comment */ {}`
|
||||
// Output: `export /* comment */ {}`
|
||||
//
|
||||
// Line comment example:
|
||||
// Input: `export // comment
|
||||
// {}`
|
||||
// Output: `export // comment
|
||||
// {}`
|
||||
if !comments.is_empty() {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
FormatTrailingComments::Comments(comments),
|
||||
has_line_comment.then_some(soft_line_break()),
|
||||
" "
|
||||
]
|
||||
);
|
||||
}
|
||||
write!(f, [export_kind, "{", format_dangling_comments(span).with_block_indent()]);
|
||||
} else if specifiers.len() == 1
|
||||
&& f.comments().comments_before_character(span.start, b'}').is_empty()
|
||||
{
|
||||
let space = maybe_space(needs_space).memoized();
|
||||
write!(f, [export_kind, "{", space, specifiers.first(), space]);
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
[export_kind, "{", group(&soft_block_indent_with_maybe_space(specifiers, needs_space))]
|
||||
);
|
||||
}
|
||||
write!(f, "}");
|
||||
}
|
||||
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ExportDefaultDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let declaration = self.declaration();
|
||||
format_export_keyword_with_class_decorators(
|
||||
self.span,
|
||||
"export default",
|
||||
self.declaration().as_ast_nodes(),
|
||||
declaration.as_ast_nodes(),
|
||||
f,
|
||||
);
|
||||
|
||||
let declaration = self.declaration();
|
||||
if declaration.is_expression() {
|
||||
write!(
|
||||
f,
|
||||
@@ -90,100 +138,62 @@ impl<'a> FormatWrite<'a> for AstNode<'a, ExportDefaultDeclaration<'a>> {
|
||||
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ExportAllDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let content = format_with(|f| {
|
||||
let prefix = format_with(|f| {
|
||||
write!(f, ["export", space(), self.export_kind(), "*", space()]);
|
||||
if let Some(name) = &self.exported() {
|
||||
write!(f, ["as", space(), name, space()]);
|
||||
}
|
||||
write!(f, ["from", space()]);
|
||||
|
||||
format_import_and_export_source_with_clause(self.source(), self.with_clause(), f);
|
||||
});
|
||||
let content_end =
|
||||
import_and_export_source_with_clause_end(self.source(), self.with_clause());
|
||||
write!(f, FormatContentWithSemicolon::new(&content, content_end, self.span.end));
|
||||
format_source_with_clause_and_semicolon(
|
||||
&prefix,
|
||||
self.source(),
|
||||
self.with_clause(),
|
||||
self.span.end,
|
||||
f,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ExportDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let declaration = self.declaration();
|
||||
format_export_keyword_with_class_decorators(
|
||||
self.span,
|
||||
"export",
|
||||
declaration.as_ast_nodes(),
|
||||
f,
|
||||
);
|
||||
write!(f, declaration);
|
||||
// No semicolon here: the declaration prints its own,
|
||||
// together with its trailing comments
|
||||
self.format_trailing_comments(f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ExportNamedDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let declaration = self.declaration();
|
||||
let export_kind = self.export_kind();
|
||||
let specifiers = self.specifiers();
|
||||
let source = self.source();
|
||||
self.format_leading_comments(f);
|
||||
write!(f, ["export", space()]);
|
||||
format_export_specifiers_block(self.span, self.export_kind(), self.specifiers(), f);
|
||||
write!(f, OptionalSemicolon);
|
||||
self.format_trailing_comments(f);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(decl) = declaration {
|
||||
format_export_keyword_with_class_decorators(
|
||||
self.span,
|
||||
"export",
|
||||
decl.as_ast_nodes(),
|
||||
f,
|
||||
);
|
||||
write!(f, decl);
|
||||
} else {
|
||||
self.format_leading_comments(f);
|
||||
write!(f, ["export", space()]);
|
||||
|
||||
let needs_space = f.options().bracket_spacing.value();
|
||||
if specifiers.is_empty() {
|
||||
let comments =
|
||||
f.context().comments().comments_before_character(self.span.start, b'{');
|
||||
let has_line_comment = comments.iter().any(|c| c.is_line());
|
||||
// Block comment example:
|
||||
// Input: `export /* comment */ {}`
|
||||
// Output: `export /* comment */ {}`
|
||||
//
|
||||
// Line comment example:
|
||||
// Input: `export // comment
|
||||
// {}`
|
||||
// Output: `export // comment
|
||||
// {}`
|
||||
if !comments.is_empty() {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
FormatTrailingComments::Comments(comments),
|
||||
has_line_comment.then_some(soft_line_break()),
|
||||
" "
|
||||
]
|
||||
);
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
[export_kind, "{", format_dangling_comments(self.span).with_block_indent()]
|
||||
);
|
||||
} else if specifiers.len() == 1
|
||||
&& f.comments().comments_before_character(self.span.start, b'}').is_empty()
|
||||
{
|
||||
let space = maybe_space(needs_space).memoized();
|
||||
write!(f, [export_kind, "{", space, specifiers.first(), space]);
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
export_kind,
|
||||
"{",
|
||||
group(&soft_block_indent_with_maybe_space(specifiers, needs_space))
|
||||
]
|
||||
);
|
||||
}
|
||||
write!(f, "}");
|
||||
|
||||
let with_clause = self.with_clause();
|
||||
if let Some(source) = source {
|
||||
let content = format_with(|f| {
|
||||
write!(f, [space(), "from", space()]);
|
||||
format_import_and_export_source_with_clause(source, with_clause, f);
|
||||
});
|
||||
let content_end = import_and_export_source_with_clause_end(source, with_clause);
|
||||
write!(f, FormatContentWithSemicolon::new(&content, content_end, self.span.end));
|
||||
} else {
|
||||
write!(f, OptionalSemicolon);
|
||||
}
|
||||
}
|
||||
// No semicolon when there is a declaration:
|
||||
// an exported variable declaration prints it itself, together with its trailing comments
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ExportFromDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
self.format_leading_comments(f);
|
||||
write!(f, ["export", space()]);
|
||||
format_export_specifiers_block(self.span, self.export_kind(), self.specifiers(), f);
|
||||
|
||||
format_source_with_clause_and_semicolon(
|
||||
&format_args!(space(), "from", space()),
|
||||
self.source(),
|
||||
self.with_clause(),
|
||||
self.span.end,
|
||||
f,
|
||||
);
|
||||
self.format_trailing_comments(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,34 +33,34 @@ impl<'a> Format<'a, JsFormatContext<'a>> for ImportPhase {
|
||||
}
|
||||
}
|
||||
|
||||
/// End position of the source + optional with-clause pair formatted by
|
||||
/// [`format_import_and_export_source_with_clause`].
|
||||
pub fn import_and_export_source_with_clause_end(
|
||||
source: &AstNode<'_, StringLiteral>,
|
||||
with_clause: Option<&AstNode<'_, WithClause>>,
|
||||
) -> u32 {
|
||||
with_clause.map_or(source.span.end, |with| with.span.end)
|
||||
}
|
||||
|
||||
pub fn format_import_and_export_source_with_clause<'a>(
|
||||
/// Formats `prefix` followed by the module source and its optional with-clause,
|
||||
/// then the semicolon, moving a same-line trailing comment behind it.
|
||||
pub fn format_source_with_clause_and_semicolon<'a>(
|
||||
prefix: &impl Format<'a, JsFormatContext<'a>>,
|
||||
source: &AstNode<'a, StringLiteral>,
|
||||
with_clause: Option<&AstNode<'a, WithClause>>,
|
||||
span_end: u32,
|
||||
f: &mut JsFormatter<'_, 'a>,
|
||||
) {
|
||||
source.fmt(f);
|
||||
let content = format_with(|f| {
|
||||
prefix.fmt(f);
|
||||
source.fmt(f);
|
||||
|
||||
if let Some(with_clause) = with_clause {
|
||||
if f.comments().has_comment_before(with_clause.span.start) {
|
||||
write!(f, [space()]);
|
||||
if let Some(with_clause) = with_clause {
|
||||
if f.comments().has_comment_before(with_clause.span.start) {
|
||||
write!(f, [space()]);
|
||||
}
|
||||
|
||||
write!(f, [with_clause]);
|
||||
}
|
||||
|
||||
write!(f, [with_clause]);
|
||||
}
|
||||
});
|
||||
let content_end = with_clause.map_or(source.span.end, |with| with.span.end);
|
||||
write!(f, FormatContentWithSemicolon::new(&content, content_end, span_end));
|
||||
}
|
||||
|
||||
impl<'a> FormatWrite<'a> for AstNode<'a, ImportDeclaration<'a>> {
|
||||
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
|
||||
let content = format_with(|f| {
|
||||
let prefix = format_with(|f| {
|
||||
write!(f, ["import", space()]);
|
||||
if let Some(phase) = self.phase() {
|
||||
write!(f, phase);
|
||||
@@ -71,12 +71,16 @@ impl<'a> FormatWrite<'a> for AstNode<'a, ImportDeclaration<'a>> {
|
||||
if let Some(specifiers) = self.specifiers() {
|
||||
write!(f, [specifiers, space(), "from", space()]);
|
||||
}
|
||||
|
||||
format_import_and_export_source_with_clause(self.source(), self.with_clause(), f);
|
||||
});
|
||||
let content_end =
|
||||
import_and_export_source_with_clause_end(self.source(), self.with_clause());
|
||||
let decl = FormatContentWithSemicolon::new(&content, content_end, self.span.end);
|
||||
let decl = format_with(|f| {
|
||||
format_source_with_clause_and_semicolon(
|
||||
&prefix,
|
||||
self.source(),
|
||||
self.with_clause(),
|
||||
self.span.end,
|
||||
f,
|
||||
);
|
||||
});
|
||||
|
||||
if f.options().sort_imports.is_some() {
|
||||
write!(f, [labelled(LabelId::of(JsLabels::ImportDeclaration), &decl)]);
|
||||
|
||||
@@ -81,8 +81,8 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatStatementsWithImports<'a, '_>
|
||||
let span = match stmt.as_ref() {
|
||||
// `@decorator export class A {}`
|
||||
// Get the span of the decorator.
|
||||
Statement::ExportNamedDeclaration(export) => {
|
||||
if let Some(Declaration::ClassDeclaration(decl)) = &export.declaration
|
||||
Statement::ExportDeclaration(export) => {
|
||||
if let Declaration::ClassDeclaration(decl) = &export.declaration
|
||||
&& let Some(decorator) = decl.decorators.first()
|
||||
&& decorator.span().start < export.span.start
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, VariableDeclaration<'a>> {
|
||||
AstNodes::ForInStatement(stmt) => stmt.left().span() != self.span(),
|
||||
AstNodes::ForOfStatement(stmt) => stmt.left().span() != self.span(),
|
||||
// Everywhere else the declaration terminates itself, including `export const ...`,
|
||||
// whose `ExportNamedDeclaration` prints no semicolon of its own (see its `FormatWrite` implementation).
|
||||
// whose `ExportDeclaration` prints no semicolon of its own (see its `FormatWrite` implementation).
|
||||
_ => true,
|
||||
};
|
||||
|
||||
|
||||
@@ -294,20 +294,31 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
need_empty_export_marker = false;
|
||||
}
|
||||
|
||||
ModuleDeclaration::ExportNamedDeclaration(decl) => {
|
||||
if decl.declaration.is_none() {
|
||||
need_empty_export_marker = false;
|
||||
}
|
||||
if let Some(new_decl) = self.transform_export_named_declaration(decl) {
|
||||
self.scope.visit_export_named_declaration(&new_decl);
|
||||
ModuleDeclaration::ExportDeclaration(decl) => {
|
||||
if let Some(new_decl) = self.transform_export_declaration(decl) {
|
||||
self.scope.visit_export_declaration(&new_decl);
|
||||
transformed_stmts[idx] =
|
||||
Some(Statement::ExportNamedDeclaration(new_decl));
|
||||
Some(Statement::ExportDeclaration(new_decl));
|
||||
} else {
|
||||
// Declaration couldn't be transformed; preserve as-is
|
||||
transformed_stmts[idx] = Some(stmt.clone_in(self.allocator()));
|
||||
}
|
||||
transformed_count += 1;
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(decl) => {
|
||||
need_empty_export_marker = false;
|
||||
self.scope.visit_export_named_declaration(decl);
|
||||
transformed_stmts[idx] = Some(stmt.clone_in(self.allocator()));
|
||||
transformed_count += 1;
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(decl) => {
|
||||
let new_decl = self.transform_export_from_declaration(decl);
|
||||
need_empty_export_marker = false;
|
||||
self.scope.visit_export_from_declaration(&new_decl);
|
||||
transformed_stmts[idx] =
|
||||
Some(Statement::ExportFromDeclaration(new_decl));
|
||||
transformed_count += 1;
|
||||
}
|
||||
ModuleDeclaration::ImportDeclaration(_) => {
|
||||
// We must transform this in the end, because we need to know all references
|
||||
}
|
||||
@@ -434,15 +445,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
|
||||
if need_empty_export_marker {
|
||||
let kind = ImportOrExportKind::Value;
|
||||
new_stmts.push(Statement::new_export_named_declaration(
|
||||
SPAN,
|
||||
None,
|
||||
[],
|
||||
None,
|
||||
kind,
|
||||
None,
|
||||
self,
|
||||
));
|
||||
new_stmts.push(Statement::new_export_named_declaration(SPAN, [], kind, self));
|
||||
} else if self.scope.is_ts_module_block() {
|
||||
// If we are in a module block and we don't need to add `export {}`, in that case we need to remove `export` keyword from all ExportNamedDeclaration
|
||||
// <https://github.com/microsoft/TypeScript/blob/a709f9899c2a544b6de65a0f2623ecbbe1394eab/src/compiler/transformers/declarations.ts#L1556-L1563>
|
||||
@@ -478,8 +481,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
}
|
||||
true
|
||||
}
|
||||
Statement::ExportNamedDeclaration(decl) => {
|
||||
if let Some(Declaration::FunctionDeclaration(func)) = &decl.declaration {
|
||||
Statement::ExportDeclaration(decl) => {
|
||||
if let Declaration::FunctionDeclaration(func) = &decl.declaration {
|
||||
let name: Str<'a> = func
|
||||
.id
|
||||
.as_ref()
|
||||
@@ -530,9 +533,9 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
let TSModuleDeclarationName::Identifier(ident) = &decl.id else { return };
|
||||
let Some(TSModuleDeclarationBody::TSModuleBlock(block)) = &decl.body else { return };
|
||||
for stmt in &block.body {
|
||||
let Statement::ExportNamedDeclaration(decl) = stmt else { continue };
|
||||
let Statement::ExportDeclaration(decl) = stmt else { continue };
|
||||
match &decl.declaration {
|
||||
Some(Declaration::VariableDeclaration(var)) => {
|
||||
Declaration::VariableDeclaration(var) => {
|
||||
for declarator in &var.declarations {
|
||||
if let Some(name) = declarator.id.get_identifier_name() {
|
||||
assignable_properties
|
||||
@@ -542,7 +545,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Declaration::FunctionDeclaration(func)) => {
|
||||
Declaration::FunctionDeclaration(func) => {
|
||||
if let Some(name) = func.name() {
|
||||
assignable_properties
|
||||
.entry(ident.name.as_str())
|
||||
@@ -550,7 +553,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
.insert(name.into());
|
||||
}
|
||||
}
|
||||
Some(Declaration::ClassDeclaration(cls)) => {
|
||||
Declaration::ClassDeclaration(cls) => {
|
||||
if let Some(id) = cls.id.as_ref() {
|
||||
assignable_properties
|
||||
.entry(ident.name.as_str())
|
||||
@@ -558,7 +561,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
.insert(id.name.into());
|
||||
}
|
||||
}
|
||||
Some(Declaration::TSEnumDeclaration(decl)) => {
|
||||
Declaration::TSEnumDeclaration(decl) => {
|
||||
assignable_properties
|
||||
.entry(ident.name.as_str())
|
||||
.or_default()
|
||||
@@ -574,15 +577,15 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
let mut can_expando_function_names = IdentHashSet::default();
|
||||
for stmt in stmts {
|
||||
match stmt {
|
||||
Statement::ExportNamedDeclaration(decl) => match decl.declaration.as_ref() {
|
||||
Some(Declaration::FunctionDeclaration(func)) => {
|
||||
Statement::ExportDeclaration(decl) => match &decl.declaration {
|
||||
Declaration::FunctionDeclaration(func) => {
|
||||
if func.body.is_some()
|
||||
&& let Some(id) = func.id.as_ref()
|
||||
{
|
||||
can_expando_function_names.insert(id.name);
|
||||
}
|
||||
}
|
||||
Some(Declaration::VariableDeclaration(decl)) => {
|
||||
Declaration::VariableDeclaration(decl) => {
|
||||
for declarator in &decl.declarations {
|
||||
if declarator.type_annotation.is_none()
|
||||
&& declarator.init.as_ref().is_some_and(Expression::is_function)
|
||||
@@ -592,7 +595,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Declaration::TSModuleDeclaration(decl)) => {
|
||||
Declaration::TSModuleDeclaration(decl) => {
|
||||
Self::collect_namespace_properties(
|
||||
decl,
|
||||
&mut assignable_properties_for_namespace,
|
||||
|
||||
@@ -13,31 +13,33 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
ExportAllDeclaration::boxed(
|
||||
prev_decl.span,
|
||||
prev_decl.exported.clone_in(self.allocator()),
|
||||
prev_decl.source.clone(),
|
||||
prev_decl.source.clone_in(self.allocator()),
|
||||
None,
|
||||
prev_decl.export_kind,
|
||||
self,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn transform_export_named_declaration(
|
||||
&mut self,
|
||||
prev_decl: &ExportNamedDeclaration<'a>,
|
||||
) -> Option<ArenaBox<'a, ExportNamedDeclaration<'a>>> {
|
||||
let declaration = match &prev_decl.declaration {
|
||||
Some(decl) => Some(self.transform_declaration(decl, false)?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
Some(ExportNamedDeclaration::boxed(
|
||||
pub(crate) fn transform_export_from_declaration(
|
||||
&self,
|
||||
prev_decl: &ExportFromDeclaration<'a>,
|
||||
) -> ArenaBox<'a, ExportFromDeclaration<'a>> {
|
||||
ExportFromDeclaration::boxed(
|
||||
prev_decl.span,
|
||||
declaration,
|
||||
prev_decl.specifiers.clone_in(self.allocator()),
|
||||
prev_decl.source.clone(),
|
||||
prev_decl.source.clone_in(self.allocator()),
|
||||
prev_decl.export_kind,
|
||||
None,
|
||||
self,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn transform_export_declaration(
|
||||
&mut self,
|
||||
prev_decl: &ExportDeclaration<'a>,
|
||||
) -> Option<ArenaBox<'a, ExportDeclaration<'a>>> {
|
||||
let decl = self.transform_declaration(&prev_decl.declaration, false)?;
|
||||
Some(ExportDeclaration::boxed(prev_decl.span, decl, self))
|
||||
}
|
||||
|
||||
pub(crate) fn create_unique_name(&self, name: &str) -> Str<'a> {
|
||||
@@ -186,7 +188,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip export keyword from ExportNamedDeclaration
|
||||
/// Strip export keyword from ExportDeclaration
|
||||
///
|
||||
/// ```ts
|
||||
/// export const a = 1;
|
||||
@@ -199,12 +201,10 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
/// ```
|
||||
pub(crate) fn strip_export_keyword(stmts: &mut ArenaVec<'a, Statement<'a>>) {
|
||||
stmts.iter_mut().for_each(|stmt| {
|
||||
if let Statement::ExportNamedDeclaration(decl) = stmt
|
||||
&& decl.declaration.is_some()
|
||||
{
|
||||
if let Statement::ExportDeclaration(_) = stmt {
|
||||
stmt.replace_with(|stmt| {
|
||||
let Statement::ExportNamedDeclaration(decl) = stmt else { unreachable!() };
|
||||
Statement::from(decl.unbox().declaration.unwrap())
|
||||
let Statement::ExportDeclaration(decl) = stmt else { unreachable!() };
|
||||
Statement::from(decl.unbox().declaration)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -152,19 +152,20 @@ impl<'a> Visit<'a> for ScopeTree<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_export_declaration(&mut self, decl: &ExportDeclaration<'a>) {
|
||||
walk_declaration(self, &decl.declaration);
|
||||
}
|
||||
|
||||
fn visit_export_named_declaration(&mut self, decl: &ExportNamedDeclaration<'a>) {
|
||||
if let Some(declaration) = &decl.declaration {
|
||||
walk_declaration(self, declaration);
|
||||
} else if decl.source.is_none() {
|
||||
// export { ... }
|
||||
for specifier in &decl.specifiers {
|
||||
if let Some(name) = specifier.local.identifier_name() {
|
||||
self.add_reference(name.into(), KindFlags::All);
|
||||
}
|
||||
for specifier in &decl.specifiers {
|
||||
if let Some(name) = specifier.local.identifier_name() {
|
||||
self.add_reference(name.into(), KindFlags::All);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_export_from_declaration(&mut self, _decl: &ExportFromDeclaration<'a>) {}
|
||||
|
||||
fn visit_export_default_declaration(&mut self, decl: &ExportDefaultDeclaration<'a>) {
|
||||
if let ExportDefaultDeclarationKind::Identifier(ident) = &decl.declaration {
|
||||
self.add_reference(ident.name.into(), KindFlags::All);
|
||||
|
||||
@@ -194,8 +194,10 @@ fn should_attach_jsdoc(kind: &AstKind) -> bool {
|
||||
| AstKind::Decorator(_)
|
||||
|
||||
| AstKind::ExportAllDeclaration(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExportDefaultDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportFromDeclaration(_)
|
||||
| AstKind::ImportDeclaration(_)
|
||||
|
||||
// Maybe JSX, TS related kinds should be added?
|
||||
|
||||
+17
-7
@@ -128,6 +128,7 @@ impl RuleRunner for crate::rules::import::no_empty_named_blocks::NoEmptyNamedBlo
|
||||
|
||||
impl RuleRunner for crate::rules::import::no_mutable_exports::NoMutableExports {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportDefaultDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
]));
|
||||
@@ -152,6 +153,8 @@ impl RuleRunner for crate::rules::import::no_named_default::NoNamedDefault {
|
||||
impl RuleRunner for crate::rules::import::no_named_export::NoNamedExport {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
]));
|
||||
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
|
||||
@@ -166,7 +169,7 @@ impl RuleRunner for crate::rules::import::no_nodejs_modules::NoNodejsModules {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::CallExpression,
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ImportDeclaration,
|
||||
AstType::ImportExpression,
|
||||
AstType::TSImportEqualsDeclaration,
|
||||
@@ -178,7 +181,7 @@ impl RuleRunner for crate::rules::import::no_relative_parent_imports::NoRelative
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::CallExpression,
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ImportDeclaration,
|
||||
AstType::ImportExpression,
|
||||
]));
|
||||
@@ -977,7 +980,9 @@ impl RuleRunner for crate::rules::eslint::no_regex_spaces::NoRegexSpaces {
|
||||
impl RuleRunner for crate::rules::eslint::no_restricted_exports::NoRestrictedExports {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportDefaultDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
]));
|
||||
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
|
||||
@@ -1264,6 +1269,7 @@ impl RuleRunner for crate::rules::eslint::no_useless_escape::NoUselessEscape {
|
||||
|
||||
impl RuleRunner for crate::rules::eslint::no_useless_rename::NoUselessRename {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ImportSpecifier,
|
||||
AstType::ObjectAssignmentTarget,
|
||||
@@ -1627,6 +1633,7 @@ impl RuleRunner
|
||||
for crate::rules::typescript::explicit_module_boundary_types::ExplicitModuleBoundaryTypes
|
||||
{
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportDefaultDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::TSExportAssignment,
|
||||
@@ -3065,7 +3072,7 @@ impl RuleRunner for crate::rules::unicorn::filename_case::FilenameCase {
|
||||
impl RuleRunner for crate::rules::unicorn::import_style::ImportStyle {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExpressionStatement,
|
||||
AstType::ImportDeclaration,
|
||||
AstType::ImportExpression,
|
||||
@@ -3318,6 +3325,8 @@ impl RuleRunner for crate::rules::unicorn::no_thenable::NoThenable {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::AssignmentExpression,
|
||||
AstType::CallExpression,
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::MethodDefinition,
|
||||
AstType::ObjectExpression,
|
||||
@@ -3689,7 +3698,7 @@ impl RuleRunner for crate::rules::unicorn::prefer_negative_index::PreferNegative
|
||||
impl RuleRunner for crate::rules::unicorn::prefer_node_protocol::PreferNodeProtocol {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::CallExpression,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ImportDeclaration,
|
||||
AstType::ImportExpression,
|
||||
AstType::TSImportEqualsDeclaration,
|
||||
@@ -3852,7 +3861,7 @@ impl RuleRunner for crate::rules::unicorn::require_array_join_separator::Require
|
||||
impl RuleRunner for crate::rules::unicorn::require_module_attributes::RequireModuleAttributes {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportAllDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ImportDeclaration,
|
||||
AstType::ImportExpression,
|
||||
]));
|
||||
@@ -3861,6 +3870,7 @@ impl RuleRunner for crate::rules::unicorn::require_module_attributes::RequireMod
|
||||
|
||||
impl RuleRunner for crate::rules::unicorn::require_module_specifiers::RequireModuleSpecifiers {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportFromDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ImportDeclaration,
|
||||
]));
|
||||
@@ -4273,8 +4283,8 @@ impl RuleRunner for crate::rules::oxc::no_rest_spread_properties::NoRestSpreadPr
|
||||
|
||||
impl RuleRunner for crate::rules::oxc::no_this_in_exported_function::NoThisInExportedFunction {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
|
||||
AstType::ExportDeclaration,
|
||||
AstType::ExportDefaultDeclaration,
|
||||
AstType::ExportNamedDeclaration,
|
||||
AstType::ExportSpecifier,
|
||||
]));
|
||||
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
|
||||
@@ -4412,7 +4422,7 @@ impl RuleRunner for crate::rules::nextjs::no_title_in_document_head::NoTitleInDo
|
||||
|
||||
impl RuleRunner for crate::rules::nextjs::no_typos::NoTypos {
|
||||
const NODE_TYPES: Option<&AstTypesBitset> =
|
||||
Some(&AstTypesBitset::from_types(&[AstType::ExportNamedDeclaration]));
|
||||
Some(&AstTypesBitset::from_types(&[AstType::ExportDeclaration]));
|
||||
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ declare_oxc_lint!(
|
||||
|
||||
fn is_ancestor_export_name_decl<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> bool {
|
||||
if let Some(export_decl_ancestor) = nth_outermost_paren_parent(node, ctx, 2)
|
||||
&& let AstKind::ExportNamedDeclaration(_) = export_decl_ancestor.kind()
|
||||
&& let AstKind::ExportDeclaration(_) = export_decl_ancestor.kind()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ impl FuncStyle {
|
||||
if *style != Style::Declaration {
|
||||
let should_diagnostic = match parent.kind() {
|
||||
AstKind::ExportDefaultDeclaration(_) => false,
|
||||
AstKind::ExportNamedDeclaration(_) => config.named_exports().is_none(),
|
||||
AstKind::ExportDeclaration(_) => config.named_exports().is_none(),
|
||||
_ => true,
|
||||
};
|
||||
if should_diagnostic {
|
||||
@@ -277,7 +277,7 @@ impl FuncStyle {
|
||||
}
|
||||
|
||||
if config.named_exports() == Some(&NamedExports::Expression)
|
||||
&& matches!(parent.kind(), AstKind::ExportNamedDeclaration(_))
|
||||
&& matches!(parent.kind(), AstKind::ExportDeclaration(_))
|
||||
{
|
||||
ctx.diagnostic(func_style_diagnostic(func.span, "expression"));
|
||||
}
|
||||
|
||||
@@ -294,8 +294,8 @@ fn export_specifier_identifier_should_skip(
|
||||
|
||||
matches!(
|
||||
ctx.nodes().parent_kind(specifier_node.id()),
|
||||
AstKind::ExportNamedDeclaration(declaration)
|
||||
if declaration.source.is_some() && specifier.local.span() == current_node.span()
|
||||
AstKind::ExportFromDeclaration(_)
|
||||
if specifier.local.span() == current_node.span()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ fn check_rule<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>, allow_namespaces: b
|
||||
// A declaration may be wrapped in `export`; look through it to find the real enclosing scope.
|
||||
let enclosing = if matches!(
|
||||
parent_kind,
|
||||
AstKind::ExportNamedDeclaration(_) | AstKind::ExportDefaultDeclaration(_)
|
||||
AstKind::ExportDeclaration(_) | AstKind::ExportDefaultDeclaration(_)
|
||||
) {
|
||||
ctx.nodes().parent_node(parent_node.id()).kind()
|
||||
} else {
|
||||
@@ -194,7 +194,7 @@ fn check_rule<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>, allow_namespaces: b
|
||||
AstKind::Program(_)
|
||||
| AstKind::FunctionBody(_)
|
||||
| AstKind::StaticBlock(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExportDefaultDeclaration(_)
|
||||
) {
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,10 @@ use serde::Deserialize;
|
||||
|
||||
use oxc_ast::{
|
||||
AstKind,
|
||||
ast::{Declaration, ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration},
|
||||
ast::{
|
||||
Declaration, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration,
|
||||
ExportFromDeclaration, ExportNamedDeclaration, ExportSpecifier,
|
||||
},
|
||||
};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
@@ -210,7 +213,9 @@ impl Rule for NoRestrictedExports {
|
||||
match node.kind() {
|
||||
AstKind::ExportAllDeclaration(export) => self.check_export_all(export, ctx),
|
||||
AstKind::ExportDefaultDeclaration(export) => self.check_export_default(export, ctx),
|
||||
AstKind::ExportDeclaration(export) => self.check_export_declaration(export, ctx),
|
||||
AstKind::ExportNamedDeclaration(export) => self.check_export_named(export, ctx),
|
||||
AstKind::ExportFromDeclaration(export) => self.check_export_from(export, ctx),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +248,21 @@ impl NoRestrictedExports {
|
||||
}
|
||||
|
||||
fn check_export_named(&self, export: &ExportNamedDeclaration, ctx: &LintContext) {
|
||||
let (named_exports, has_default_exports, local_specifiers) = export.specifiers.iter().fold(
|
||||
self.check_export_specifiers(export.span, &export.specifiers, false, ctx);
|
||||
}
|
||||
|
||||
fn check_export_from(&self, export: &ExportFromDeclaration, ctx: &LintContext) {
|
||||
self.check_export_specifiers(export.span, &export.specifiers, true, ctx);
|
||||
}
|
||||
|
||||
fn check_export_specifiers(
|
||||
&self,
|
||||
span: Span,
|
||||
specifiers: &[ExportSpecifier<'_>],
|
||||
has_source: bool,
|
||||
ctx: &LintContext,
|
||||
) {
|
||||
let (named_exports, has_default_exports, local_specifiers) = specifiers.iter().fold(
|
||||
(Vec::new(), false, Vec::new()),
|
||||
|(mut names, mut has_default, mut specifiers), spec| {
|
||||
names.push(spec.exported.name().into_string());
|
||||
@@ -261,41 +280,34 @@ impl NoRestrictedExports {
|
||||
},
|
||||
);
|
||||
|
||||
self.check_no_restricted_named_exports(ctx, export.span, named_exports);
|
||||
self.check_no_restricted_named_exports(ctx, span, named_exports);
|
||||
|
||||
if has_default_exports {
|
||||
self.check_no_restricted_named_default_exports(
|
||||
ctx,
|
||||
export.span,
|
||||
export.source.is_some(),
|
||||
local_specifiers,
|
||||
);
|
||||
self.check_no_restricted_named_default_exports(ctx, span, has_source, local_specifiers);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(declaration) = export.declaration.as_ref() {
|
||||
match declaration {
|
||||
Declaration::FunctionDeclaration(_) | Declaration::ClassDeclaration(_) => {
|
||||
if let Some(id) = declaration.id() {
|
||||
self.check_no_restricted_named_exports(
|
||||
ctx,
|
||||
export.span,
|
||||
std::iter::once(id.name.into_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
Declaration::VariableDeclaration(variable) => {
|
||||
fn check_export_declaration(&self, export: &ExportDeclaration, ctx: &LintContext) {
|
||||
match &export.declaration {
|
||||
Declaration::FunctionDeclaration(_) | Declaration::ClassDeclaration(_) => {
|
||||
if let Some(id) = export.declaration.id() {
|
||||
self.check_no_restricted_named_exports(
|
||||
ctx,
|
||||
export.span,
|
||||
variable.declarations.iter().flat_map(|d| {
|
||||
d.id.get_binding_identifiers()
|
||||
.into_iter()
|
||||
.map(|id| id.name.into_string())
|
||||
}),
|
||||
std::iter::once(id.name.into_string()),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Declaration::VariableDeclaration(variable) => {
|
||||
self.check_no_restricted_named_exports(
|
||||
ctx,
|
||||
export.span,
|
||||
variable.declarations.iter().flat_map(|d| {
|
||||
d.id.get_binding_identifiers().into_iter().map(|id| id.name.into_string())
|
||||
}),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -749,7 +749,7 @@ fn is_initializer_sentinel(kind: AstKind) -> bool {
|
||||
| AstKind::ArrowFunctionExpression(_)
|
||||
| AstKind::CatchClause(_)
|
||||
| AstKind::ImportDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,9 @@ fn is_ambient_namespace_without_explicit_exports(namespace: &TSModuleDeclaration
|
||||
stmt,
|
||||
Statement::ExportAllDeclaration(_)
|
||||
| Statement::ExportDefaultDeclaration(_)
|
||||
| Statement::ExportDeclaration(_)
|
||||
| Statement::ExportNamedDeclaration(_)
|
||||
| Statement::ExportFromDeclaration(_)
|
||||
| Statement::TSExportAssignment(_)
|
||||
)
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ impl Symbol<'_, '_> {
|
||||
fn in_export_node(&self) -> bool {
|
||||
for parent in self.nodes().ancestors(self.declaration_id()) {
|
||||
match parent.kind() {
|
||||
AstKind::ExportNamedDeclaration(_) | AstKind::ExportDefaultDeclaration(_) => {
|
||||
AstKind::ExportDeclaration(_) | AstKind::ExportDefaultDeclaration(_) => {
|
||||
return true;
|
||||
}
|
||||
AstKind::VariableDeclaration(_)
|
||||
|
||||
@@ -318,7 +318,9 @@ impl<'a> Symbol<'_, 'a> {
|
||||
| AstKind::TSGlobalDeclaration(_)
|
||||
| AstKind::VariableDeclaration(_)
|
||||
| AstKind::VariableDeclarator(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportFromDeclaration(_)
|
||||
| AstKind::ExportDefaultDeclaration(_)
|
||||
| AstKind::ExportAllDeclaration(_)
|
||||
| AstKind::Program(_)
|
||||
|
||||
@@ -439,7 +439,9 @@ where
|
||||
| AstKind::ArrowFunctionExpression(_)
|
||||
| AstKind::CatchClause(_)
|
||||
| AstKind::ImportDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_) => break,
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportFromDeclaration(_) => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +189,28 @@ impl Rule for NoUselessRename {
|
||||
}
|
||||
}
|
||||
}
|
||||
AstKind::ExportFromDeclaration(export_from_decl) => {
|
||||
if self.ignore_export {
|
||||
return;
|
||||
}
|
||||
for specifier in &export_from_decl.specifiers {
|
||||
if specifier.local.span() != specifier.exported.span()
|
||||
&& specifier.local.name() == specifier.exported.name()
|
||||
{
|
||||
ctx.diagnostic_with_fix(
|
||||
no_useless_rename_diagnostic(specifier.local.span()),
|
||||
|fixer| {
|
||||
let local_text = specifier
|
||||
.local
|
||||
.span()
|
||||
.source_text(ctx.source_text())
|
||||
.to_string();
|
||||
fixer.replace(specifier.span, local_text)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ impl Rule for VarsOnTop {
|
||||
let parent = ctx.nodes().parent_node(node.id());
|
||||
|
||||
match parent.kind() {
|
||||
AstKind::ExportNamedDeclaration(_) => {
|
||||
AstKind::ExportDeclaration(_) => {
|
||||
let grand_parent = ctx.nodes().parent_node(parent.id());
|
||||
if let AstKind::Program(grand_parent) = grand_parent.kind() {
|
||||
global_var_check(parent, grand_parent, ctx);
|
||||
@@ -143,8 +143,8 @@ fn is_variable_declaration(node: &Statement) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Statement::ExportNamedDeclaration(export) = node {
|
||||
return matches!(export.declaration, Some(Declaration::VariableDeclaration(_)));
|
||||
if let Statement::ExportDeclaration(export) = node {
|
||||
return matches!(export.declaration, Declaration::VariableDeclaration(_));
|
||||
}
|
||||
|
||||
false
|
||||
|
||||
@@ -74,8 +74,10 @@ fn is_exports_declaration(statement: &Statement) -> bool {
|
||||
matches!(
|
||||
declaration,
|
||||
ModuleDeclaration::ExportAllDeclaration(_)
|
||||
| ModuleDeclaration::ExportDeclaration(_)
|
||||
| ModuleDeclaration::ExportDefaultDeclaration(_)
|
||||
| ModuleDeclaration::ExportNamedDeclaration(_)
|
||||
| ModuleDeclaration::ExportFromDeclaration(_)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -75,28 +75,28 @@ impl Rule for GroupExports {
|
||||
|
||||
for node in semantic.nodes() {
|
||||
match node.kind() {
|
||||
AstKind::ExportNamedDeclaration(export_decl) => match export_decl.export_kind {
|
||||
AstKind::ExportFromDeclaration(export_decl) => match export_decl.export_kind {
|
||||
ImportOrExportKind::Value => {
|
||||
if let Some(source) = &export_decl.source {
|
||||
modules_source_record
|
||||
.entry(source.value.to_string())
|
||||
.or_default()
|
||||
.push(export_decl.span);
|
||||
} else {
|
||||
modules_nodes.push(export_decl.span);
|
||||
}
|
||||
modules_source_record
|
||||
.entry(export_decl.source.value.to_string())
|
||||
.or_default()
|
||||
.push(export_decl.span);
|
||||
}
|
||||
ImportOrExportKind::Type => {
|
||||
if let Some(source) = &export_decl.source {
|
||||
type_source_record
|
||||
.entry(source.value.to_string())
|
||||
.or_default()
|
||||
.push(export_decl.span);
|
||||
} else {
|
||||
type_nodes.push(export_decl.span);
|
||||
}
|
||||
type_source_record
|
||||
.entry(export_decl.source.value.to_string())
|
||||
.or_default()
|
||||
.push(export_decl.span);
|
||||
}
|
||||
},
|
||||
AstKind::ExportNamedDeclaration(export_decl) => match export_decl.export_kind {
|
||||
ImportOrExportKind::Value => modules_nodes.push(export_decl.span),
|
||||
ImportOrExportKind::Type => type_nodes.push(export_decl.span),
|
||||
},
|
||||
AstKind::ExportDeclaration(export_decl) => match export_decl.export_kind() {
|
||||
ImportOrExportKind::Value => modules_nodes.push(export_decl.span),
|
||||
ImportOrExportKind::Type => type_nodes.push(export_decl.span),
|
||||
},
|
||||
AstKind::AssignmentExpression(assignment_expr) => {
|
||||
let Some(member_expr) = assignment_expr.left.as_member_expression() else {
|
||||
continue;
|
||||
|
||||
@@ -485,14 +485,12 @@ fn first_decorator_start(stmt: &Statement<'_>) -> Option<u32> {
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
Statement::ExportNamedDeclaration(export_named) => {
|
||||
match export_named.declaration.as_ref() {
|
||||
Some(Declaration::ClassDeclaration(class)) => {
|
||||
class.decorators.first().map(|decorator| decorator.span.start)
|
||||
}
|
||||
_ => None,
|
||||
Statement::ExportDeclaration(export_decl) => match &export_decl.declaration {
|
||||
Declaration::ClassDeclaration(class) => {
|
||||
class.decorators.first().map(|decorator| decorator.span.start)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,32 +62,29 @@ declare_oxc_lint!(
|
||||
impl Rule for NoMutableExports {
|
||||
fn run<'a>(&self, node: &oxc_semantic::AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
match node.kind() {
|
||||
AstKind::ExportNamedDeclaration(export_name_decl) => {
|
||||
AstKind::ExportDeclaration(export_decl) => {
|
||||
// e.g. "export let a = 4;"
|
||||
if let Some(declaration) = &export_name_decl.declaration {
|
||||
let Declaration::VariableDeclaration(decl) = declaration else {
|
||||
return;
|
||||
};
|
||||
if matches!(
|
||||
decl.kind,
|
||||
VariableDeclarationKind::Var | VariableDeclarationKind::Let
|
||||
) {
|
||||
ctx.diagnostic(no_mutable_exports_diagnostic(decl.span, decl.kind));
|
||||
}
|
||||
} else if export_name_decl.source.is_none() {
|
||||
// e.g. "let a = 3; export { a }"
|
||||
for specifier in &export_name_decl.specifiers {
|
||||
if let ModuleExportName::IdentifierReference(ident) = &specifier.local {
|
||||
let Some(declaration) =
|
||||
get_reference_declaration(ident.reference_id(), ctx)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
ctx.diagnostic(no_mutable_exports_diagnostic(
|
||||
declaration.span,
|
||||
declaration.kind,
|
||||
));
|
||||
}
|
||||
let Declaration::VariableDeclaration(decl) = &export_decl.declaration else {
|
||||
return;
|
||||
};
|
||||
if matches!(decl.kind, VariableDeclarationKind::Var | VariableDeclarationKind::Let)
|
||||
{
|
||||
ctx.diagnostic(no_mutable_exports_diagnostic(decl.span, decl.kind));
|
||||
}
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(export_name_decl) => {
|
||||
// e.g. "let a = 3; export { a }"
|
||||
for specifier in &export_name_decl.specifiers {
|
||||
if let ModuleExportName::IdentifierReference(ident) = &specifier.local {
|
||||
let Some(declaration) =
|
||||
get_reference_declaration(ident.reference_id(), ctx)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
ctx.diagnostic(no_mutable_exports_diagnostic(
|
||||
declaration.span,
|
||||
declaration.kind,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ impl Rule for NoNamedExport {
|
||||
AstKind::ExportAllDeclaration(all_decl) => {
|
||||
ctx.diagnostic(no_named_export_diagnostic(all_decl.span));
|
||||
}
|
||||
AstKind::ExportDeclaration(export_decl) => {
|
||||
ctx.diagnostic(no_named_export_diagnostic(export_decl.span));
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(named_decl) => {
|
||||
let specifiers = &named_decl.specifiers;
|
||||
if specifiers.is_empty() {
|
||||
@@ -64,6 +67,15 @@ impl Rule for NoNamedExport {
|
||||
ctx.diagnostic(no_named_export_diagnostic(named_decl.span));
|
||||
}
|
||||
}
|
||||
AstKind::ExportFromDeclaration(from_decl)
|
||||
if from_decl.specifiers.is_empty()
|
||||
|| from_decl
|
||||
.specifiers
|
||||
.iter()
|
||||
.any(|specifier| specifier.exported.name() != "default") =>
|
||||
{
|
||||
ctx.diagnostic(no_named_export_diagnostic(from_decl.span));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,9 +107,7 @@ impl Rule for NoNodejsModules {
|
||||
call.common_js_require().map(|s| s.value)
|
||||
}
|
||||
AstKind::ImportDeclaration(import) => Some(import.source.value),
|
||||
AstKind::ExportNamedDeclaration(export) => {
|
||||
export.source.as_ref().map(|item| item.value)
|
||||
}
|
||||
AstKind::ExportFromDeclaration(export) => Some(export.source.value),
|
||||
AstKind::ExportAllDeclaration(export_all) => Some(export_all.source.value),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
@@ -61,11 +61,9 @@ impl Rule for NoRelativeParentImports {
|
||||
ctx.diagnostic(no_relative_parent_imports_diagnostic(import_decl.source.span));
|
||||
}
|
||||
// ESM export { } from '...'
|
||||
AstKind::ExportNamedDeclaration(export_decl) => {
|
||||
if let Some(source) = &export_decl.source
|
||||
&& is_parent_import(source.value.as_str())
|
||||
{
|
||||
ctx.diagnostic(no_relative_parent_imports_diagnostic(source.span));
|
||||
AstKind::ExportFromDeclaration(export_decl) => {
|
||||
if is_parent_import(export_decl.source.value.as_str()) {
|
||||
ctx.diagnostic(no_relative_parent_imports_diagnostic(export_decl.source.span));
|
||||
}
|
||||
}
|
||||
// ESM export * from '...'
|
||||
|
||||
@@ -77,10 +77,8 @@ impl Rule for NoTypos {
|
||||
}
|
||||
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
if let AstKind::ExportNamedDeclaration(en_decl) = node.kind()
|
||||
&& let Some(decl) = &en_decl.declaration
|
||||
{
|
||||
match decl {
|
||||
if let AstKind::ExportDeclaration(en_decl) = node.kind() {
|
||||
match &en_decl.declaration {
|
||||
Declaration::VariableDeclaration(decl) => {
|
||||
for decl in &decl.declarations {
|
||||
if let BindingPattern::BindingIdentifier(id) = &decl.id {
|
||||
|
||||
@@ -68,8 +68,8 @@ declare_oxc_lint!(
|
||||
impl Rule for NoThisInExportedFunction {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
match node.kind() {
|
||||
AstKind::ExportNamedDeclaration(export_decl) => {
|
||||
if let Some(Declaration::FunctionDeclaration(func)) = &export_decl.declaration {
|
||||
AstKind::ExportDeclaration(export_decl) => {
|
||||
if let Declaration::FunctionDeclaration(func) = &export_decl.declaration {
|
||||
check_function_for_this(func, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,10 @@ impl OnlyExportComponents {
|
||||
.any(|id| {
|
||||
matches!(
|
||||
nodes.get_node(id).kind(),
|
||||
AstKind::ExportDefaultDeclaration(_) | AstKind::ExportNamedDeclaration(_)
|
||||
AstKind::ExportDefaultDeclaration(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExportFromDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -285,10 +288,20 @@ impl OnlyExportComponents {
|
||||
}
|
||||
analysis.merge(result);
|
||||
}
|
||||
AstKind::ExportDeclaration(export_decl) => {
|
||||
let result = self.analyze_export_declaration(ctx, export_decl);
|
||||
analysis.merge(result);
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(export_named)
|
||||
if export_named.export_kind.is_value() =>
|
||||
{
|
||||
let result = self.analyze_export_named(ctx, export_named);
|
||||
let result = self.analyze_export_specifiers(&export_named.specifiers);
|
||||
analysis.merge(result);
|
||||
}
|
||||
AstKind::ExportFromDeclaration(export_from)
|
||||
if export_from.export_kind.is_value() =>
|
||||
{
|
||||
let result = self.analyze_export_specifiers(&export_from.specifiers);
|
||||
analysis.merge(result);
|
||||
}
|
||||
_ => {}
|
||||
@@ -436,82 +449,77 @@ impl OnlyExportComponents {
|
||||
analysis
|
||||
}
|
||||
|
||||
fn analyze_export_named(
|
||||
fn analyze_export_declaration(
|
||||
&self,
|
||||
ctx: &LintContext,
|
||||
export_named: &ExportNamedDeclaration,
|
||||
export_decl: &ExportDeclaration,
|
||||
) -> ExportAnalysis {
|
||||
let mut analysis = ExportAnalysis::default();
|
||||
if let Some(declaration) = &export_named.declaration {
|
||||
let exports = match declaration {
|
||||
Declaration::VariableDeclaration(var_decl) => var_decl
|
||||
.declarations
|
||||
.iter()
|
||||
.map(|declarator| match &declarator.id {
|
||||
BindingPattern::BindingIdentifier(binding_id) => {
|
||||
let is_func =
|
||||
self.can_be_react_function_component(declarator.init.as_ref());
|
||||
self.classify_export(
|
||||
binding_id.name.as_str(),
|
||||
binding_id.span,
|
||||
is_func,
|
||||
declarator.init.as_ref(),
|
||||
)
|
||||
}
|
||||
_ => ExportType::NonComponent(declarator.id.span()),
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
Declaration::FunctionDeclaration(func) => func.id.as_ref().map_or_else(
|
||||
|| {
|
||||
ctx.diagnostic(anonymous_components_diagnostic(func.span));
|
||||
vec![]
|
||||
},
|
||||
|id| vec![self.classify_export(id.name.as_str(), id.span, true, None)],
|
||||
),
|
||||
Declaration::ClassDeclaration(class) => class.id.as_ref().map_or(vec![], |id| {
|
||||
vec![if is_react_component_name(&id.name)
|
||||
&& Self::extends_react_component(class)
|
||||
{
|
||||
ExportType::ReactComponent
|
||||
} else {
|
||||
ExportType::NonComponent(id.span)
|
||||
}]
|
||||
}),
|
||||
Declaration::TSEnumDeclaration(ts_enum) => {
|
||||
vec![ExportType::NonComponent(ts_enum.id.span)]
|
||||
}
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
for export in exports {
|
||||
analysis.add_export(export);
|
||||
let exports = match &export_decl.declaration {
|
||||
Declaration::VariableDeclaration(var_decl) => var_decl
|
||||
.declarations
|
||||
.iter()
|
||||
.map(|declarator| match &declarator.id {
|
||||
BindingPattern::BindingIdentifier(binding_id) => {
|
||||
let is_func =
|
||||
self.can_be_react_function_component(declarator.init.as_ref());
|
||||
self.classify_export(
|
||||
binding_id.name.as_str(),
|
||||
binding_id.span,
|
||||
is_func,
|
||||
declarator.init.as_ref(),
|
||||
)
|
||||
}
|
||||
_ => ExportType::NonComponent(declarator.id.span()),
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
Declaration::FunctionDeclaration(func) => func.id.as_ref().map_or_else(
|
||||
|| {
|
||||
ctx.diagnostic(anonymous_components_diagnostic(func.span));
|
||||
vec![]
|
||||
},
|
||||
|id| vec![self.classify_export(id.name.as_str(), id.span, true, None)],
|
||||
),
|
||||
Declaration::ClassDeclaration(class) => class.id.as_ref().map_or(vec![], |id| {
|
||||
vec![if is_react_component_name(&id.name) && Self::extends_react_component(class) {
|
||||
ExportType::ReactComponent
|
||||
} else {
|
||||
ExportType::NonComponent(id.span)
|
||||
}]
|
||||
}),
|
||||
Declaration::TSEnumDeclaration(ts_enum) => {
|
||||
vec![ExportType::NonComponent(ts_enum.id.span)]
|
||||
}
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
for export in exports {
|
||||
analysis.add_export(export);
|
||||
}
|
||||
|
||||
let specifier_exports: Vec<ExportType> = export_named
|
||||
.specifiers
|
||||
.iter()
|
||||
.map(|export_spec| {
|
||||
let exported_name = match &export_spec.exported {
|
||||
ModuleExportName::IdentifierName(name) => Some(name.name.as_str()),
|
||||
ModuleExportName::IdentifierReference(ident) => Some(ident.name.as_str()),
|
||||
ModuleExportName::StringLiteral(_) => None,
|
||||
};
|
||||
analysis
|
||||
}
|
||||
|
||||
let local_name = export_spec.local.name();
|
||||
let span = export_spec.local.span();
|
||||
fn analyze_export_specifiers(&self, specifiers: &[ExportSpecifier]) -> ExportAnalysis {
|
||||
let mut analysis = ExportAnalysis::default();
|
||||
|
||||
if exported_name == Some("default") {
|
||||
self.classify_export(local_name.as_str(), span, false, None)
|
||||
} else if let Some(name) = exported_name {
|
||||
self.classify_export(name, span, false, None)
|
||||
} else {
|
||||
ExportType::NonComponent(span)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
for export_spec in specifiers {
|
||||
let exported_name = match &export_spec.exported {
|
||||
ModuleExportName::IdentifierName(name) => Some(name.name.as_str()),
|
||||
ModuleExportName::IdentifierReference(ident) => Some(ident.name.as_str()),
|
||||
ModuleExportName::StringLiteral(_) => None,
|
||||
};
|
||||
|
||||
for export in specifier_exports {
|
||||
let local_name = export_spec.local.name();
|
||||
let span = export_spec.local.span();
|
||||
|
||||
let export = if exported_name == Some("default") {
|
||||
self.classify_export(local_name.as_str(), span, false, None)
|
||||
} else if let Some(name) = exported_name {
|
||||
self.classify_export(name, span, false, None)
|
||||
} else {
|
||||
ExportType::NonComponent(span)
|
||||
};
|
||||
analysis.add_export(export);
|
||||
}
|
||||
|
||||
@@ -786,6 +794,8 @@ fn test() {
|
||||
("function Foo() {}; export default React.memo(Foo);", None),
|
||||
("function Foo() {}; export default React.memo(Foo) as typeof Foo;", None),
|
||||
("export type * from './module';", None),
|
||||
("export { Foo } from './mod';", None),
|
||||
("export type { Foo, helper } from './mod';", None),
|
||||
("type foo = string; export const Foo = () => null; export type { foo };", None),
|
||||
("export type foo = string; export const Foo = () => null;", None),
|
||||
(
|
||||
@@ -901,6 +911,7 @@ export function Button(props: PropsWithChildren): ReactNode {
|
||||
("export const foo = 4; export const Bar = () => {};", None),
|
||||
("export function Component() {}; export const Aa = 'a'", None),
|
||||
("const foo = 4; const Bar = () => {}; export { foo, Bar };", None),
|
||||
("export { Foo, helper } from './mod';", None),
|
||||
("export * from './foo';", None),
|
||||
("export default () => {};", None),
|
||||
("export default memo(() => {});", None),
|
||||
|
||||
@@ -206,8 +206,8 @@ impl GetMethod for ModuleDeclaration<'_> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(named_decl) => {
|
||||
if let Some(Declaration::FunctionDeclaration(func_decl)) = &named_decl.declaration {
|
||||
ModuleDeclaration::ExportDeclaration(export_decl) => {
|
||||
if let Declaration::FunctionDeclaration(func_decl) = &export_decl.declaration {
|
||||
return func_decl.id.as_ref().map(|id| Method {
|
||||
name: id.name.to_compact_str(),
|
||||
r#static: false,
|
||||
|
||||
@@ -181,20 +181,15 @@ impl Rule for ExplicitModuleBoundaryTypes {
|
||||
match node.kind() {
|
||||
// look for `export function foo() { ... }`, `export const foo = () => { ... }`,
|
||||
// etc.
|
||||
AstKind::ExportDeclaration(export) => {
|
||||
let mut checker = ExplicitTypesChecker::new(self, ctx);
|
||||
walk_js::walk_declaration(&mut checker, &export.declaration);
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(export) => {
|
||||
// export { foo } from 'bar';
|
||||
if export.source.is_some() {
|
||||
return;
|
||||
}
|
||||
if let Some(decl) = &export.declaration {
|
||||
let mut checker = ExplicitTypesChecker::new(self, ctx);
|
||||
walk_js::walk_declaration(&mut checker, decl);
|
||||
} else {
|
||||
let mut checker = ExplicitTypesChecker::new(self, ctx);
|
||||
for specifier in &export.specifiers {
|
||||
if let ModuleExportName::IdentifierReference(id) = &specifier.local {
|
||||
Self::run_on_identifier_reference(ctx, id, &mut checker);
|
||||
}
|
||||
let mut checker = ExplicitTypesChecker::new(self, ctx);
|
||||
for specifier in &export.specifiers {
|
||||
if let ModuleExportName::IdentifierReference(id) = &specifier.local {
|
||||
Self::run_on_identifier_reference(ctx, id, &mut checker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ impl Rule for NoExtraneousClass {
|
||||
if has_decorators {
|
||||
return fixer.noop();
|
||||
}
|
||||
if let AstKind::ExportNamedDeclaration(decl) =
|
||||
if let AstKind::ExportDeclaration(decl) =
|
||||
ctx.nodes().parent_kind(node.id())
|
||||
{
|
||||
fixer.delete(decl)
|
||||
|
||||
@@ -408,7 +408,7 @@ fn has_function_overload_signatures(
|
||||
ctx: &LintContext<'_>,
|
||||
) -> bool {
|
||||
let wrapper = match ctx.nodes().parent_kind(function_node.id()) {
|
||||
AstKind::ExportNamedDeclaration(_) => FunctionStatementWrapper::ExportNamed,
|
||||
AstKind::ExportDeclaration(_) => FunctionStatementWrapper::ExportNamed,
|
||||
AstKind::ExportDefaultDeclaration(_) => FunctionStatementWrapper::ExportDefault,
|
||||
_ => FunctionStatementWrapper::Plain,
|
||||
};
|
||||
@@ -474,8 +474,8 @@ fn statement_function_candidate<'a>(
|
||||
|
||||
if let Some(module_decl) = statement.as_module_declaration() {
|
||||
match module_decl {
|
||||
ModuleDeclaration::ExportNamedDeclaration(named_decl) => {
|
||||
if let Some(Declaration::FunctionDeclaration(function)) = &named_decl.declaration {
|
||||
ModuleDeclaration::ExportDeclaration(export_decl) => {
|
||||
if let Declaration::FunctionDeclaration(function) = &export_decl.declaration {
|
||||
return Some((function, FunctionStatementWrapper::ExportNamed));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ declare_oxc_lint!(
|
||||
impl Rule for NoUselessEmptyExport {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
let AstKind::ExportNamedDeclaration(decl) = node.kind() else { return };
|
||||
if decl.declaration.is_some() || !decl.specifiers.is_empty() {
|
||||
if !decl.specifiers.is_empty() {
|
||||
return;
|
||||
}
|
||||
let module_record = ctx.module_record();
|
||||
|
||||
@@ -151,7 +151,7 @@ fn check_member(member: &TSSignature, node: &AstNode<'_>, ctx: &LintContext<'_>)
|
||||
let mut is_parent_exported = false;
|
||||
let mut node_start = interface_decl.span.start;
|
||||
let mut node_end = interface_decl.span.end;
|
||||
if let AstKind::ExportNamedDeclaration(export_name_decl) =
|
||||
if let AstKind::ExportDeclaration(export_name_decl) =
|
||||
ctx.nodes().parent_kind(node.id())
|
||||
{
|
||||
is_parent_exported = true;
|
||||
|
||||
@@ -364,8 +364,8 @@ fn get_statement_overload<'a>(
|
||||
|
||||
let module_declaration = statement.as_module_declaration()?;
|
||||
match module_declaration {
|
||||
oxc_ast::ast::ModuleDeclaration::ExportNamedDeclaration(export_named) => {
|
||||
let Some(Declaration::FunctionDeclaration(function)) = &export_named.declaration else {
|
||||
oxc_ast::ast::ModuleDeclaration::ExportDeclaration(export_decl) => {
|
||||
let Declaration::FunctionDeclaration(function) = &export_decl.declaration else {
|
||||
return None;
|
||||
};
|
||||
if function.r#type != FunctionType::TSDeclareFunction {
|
||||
@@ -377,7 +377,7 @@ fn get_statement_overload<'a>(
|
||||
key,
|
||||
OverloadCandidate {
|
||||
signature: SignatureDefinition::Function(function),
|
||||
comment_target_start: export_named.span.start,
|
||||
comment_target_start: export_decl.span.start,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use oxc_ast::{
|
||||
AstKind,
|
||||
ast::{
|
||||
BinaryOperator, BindingPattern, CallExpression, ExportAllDeclaration,
|
||||
ExportNamedDeclaration, Expression, ImportDeclaration, ImportDeclarationSpecifier,
|
||||
ExportFromDeclaration, Expression, ImportDeclaration, ImportDeclarationSpecifier,
|
||||
ModuleExportName, VariableDeclarator,
|
||||
},
|
||||
};
|
||||
@@ -325,7 +325,7 @@ impl Rule for ImportStyle {
|
||||
AstKind::ExportAllDeclaration(export_decl) if self.check_export_from => {
|
||||
self.check_export_all_declaration(export_decl, ctx);
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(export_decl) if self.check_export_from => {
|
||||
AstKind::ExportFromDeclaration(export_decl) if self.check_export_from => {
|
||||
self.check_export_named_declaration(export_decl, ctx);
|
||||
}
|
||||
AstKind::ExpressionStatement(statement) if self.check_require => {
|
||||
@@ -375,14 +375,13 @@ impl ImportStyle {
|
||||
|
||||
fn check_export_named_declaration(
|
||||
&self,
|
||||
export_decl: &ExportNamedDeclaration<'_>,
|
||||
export_decl: &ExportFromDeclaration<'_>,
|
||||
ctx: &LintContext<'_>,
|
||||
) {
|
||||
let Some(source) = &export_decl.source else { return };
|
||||
let actual_styles = get_actual_export_declaration_styles(export_decl);
|
||||
self.report_if_needed(
|
||||
export_decl.span,
|
||||
source.value.as_str(),
|
||||
export_decl.source.value.as_str(),
|
||||
actual_styles,
|
||||
SourceKind::ModuleSyntax,
|
||||
ctx,
|
||||
@@ -494,7 +493,7 @@ fn get_actual_import_declaration_styles(import_decl: &ImportDeclaration<'_>) ->
|
||||
styles
|
||||
}
|
||||
|
||||
fn get_actual_export_declaration_styles(export_decl: &ExportNamedDeclaration<'_>) -> StyleSet {
|
||||
fn get_actual_export_declaration_styles(export_decl: &ExportFromDeclaration<'_>) -> StyleSet {
|
||||
if export_decl.specifiers.is_empty() {
|
||||
return StyleSet::unassigned();
|
||||
}
|
||||
|
||||
@@ -100,33 +100,41 @@ impl Rule for NoThenable {
|
||||
ctx.diagnostic(class(span));
|
||||
}
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(decl) => {
|
||||
AstKind::ExportDeclaration(decl) => {
|
||||
// check declaration
|
||||
if let Some(decl) = &decl.declaration {
|
||||
match decl {
|
||||
Declaration::VariableDeclaration(decl) => {
|
||||
for decl in &decl.declarations {
|
||||
check_binding_pattern(&decl.id, ctx);
|
||||
}
|
||||
let decl = &decl.declaration;
|
||||
match decl {
|
||||
Declaration::VariableDeclaration(decl) => {
|
||||
for decl in &decl.declarations {
|
||||
check_binding_pattern(&decl.id, ctx);
|
||||
}
|
||||
Declaration::FunctionDeclaration(decl) => {
|
||||
if let Some(bind) = decl.id.as_ref()
|
||||
&& bind.name == "then"
|
||||
{
|
||||
ctx.diagnostic(export(bind.span));
|
||||
}
|
||||
}
|
||||
Declaration::FunctionDeclaration(decl) => {
|
||||
if let Some(bind) = decl.id.as_ref()
|
||||
&& bind.name == "then"
|
||||
{
|
||||
ctx.diagnostic(export(bind.span));
|
||||
}
|
||||
Declaration::ClassDeclaration(decl) => {
|
||||
if let Some(bind) = decl.id.as_ref()
|
||||
&& bind.name == "then"
|
||||
{
|
||||
ctx.diagnostic(export(bind.span));
|
||||
}
|
||||
}
|
||||
Declaration::ClassDeclaration(decl) => {
|
||||
if let Some(bind) = decl.id.as_ref()
|
||||
&& bind.name == "then"
|
||||
{
|
||||
ctx.diagnostic(export(bind.span));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(decl) => {
|
||||
// check specifier
|
||||
for spec in &decl.specifiers {
|
||||
if spec.exported.name() == "then" {
|
||||
ctx.diagnostic(export(spec.exported.span()));
|
||||
}
|
||||
}
|
||||
// check specifier
|
||||
}
|
||||
AstKind::ExportFromDeclaration(decl) => {
|
||||
for spec in &decl.specifiers {
|
||||
if spec.exported.name() == "then" {
|
||||
ctx.diagnostic(export(spec.exported.span()));
|
||||
|
||||
@@ -151,10 +151,7 @@ impl Rule for PreferArrayFind {
|
||||
&& is_filter_call(call_expr)
|
||||
&& !matches!(
|
||||
ctx.nodes().ancestor_kinds(node.id()).nth(1),
|
||||
Some(
|
||||
AstKind::ExportDefaultDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
)
|
||||
Some(AstKind::ExportDefaultDeclaration(_) | AstKind::ExportDeclaration(_))
|
||||
)
|
||||
&& let Some(ident) = var_decl.id.get_binding_identifier()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ use serde::Deserialize;
|
||||
use oxc_ast::{
|
||||
AstKind,
|
||||
ast::{
|
||||
BindingPattern, ExportNamedDeclaration, ExportSpecifier, ImportAttributeKey,
|
||||
BindingPattern, ExportFromDeclaration, ExportSpecifier, ImportAttributeKey,
|
||||
ImportDeclaration, ImportDeclarationSpecifier, ImportOrExportKind, ModuleExportName,
|
||||
Statement, VariableDeclarationKind, VariableDeclarator, WithClause, WithClauseKeyword,
|
||||
},
|
||||
@@ -104,7 +104,7 @@ impl Rule for PreferExportFrom {
|
||||
return;
|
||||
}
|
||||
|
||||
let corresponding_export: Option<&ExportNamedDeclaration> =
|
||||
let corresponding_export: Option<&ExportFromDeclaration> =
|
||||
find_corresponding_export(ctx, import_decl);
|
||||
|
||||
let symbol_to_specifier_specs = Self::get_symbol_to_specifier(import_decl);
|
||||
@@ -144,7 +144,7 @@ impl PreferExportFrom {
|
||||
ctx: &LintContext<'a>,
|
||||
symbol_to_specifier: &FxIndexMap<SymbolId, SpecifierSpec<'a>>,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
re_export_decl: Option<&'a ExportNamedDeclaration<'a>>,
|
||||
re_export_decl: Option<&'a ExportFromDeclaration<'a>>,
|
||||
) {
|
||||
let (locally_used_specifiers, violations) =
|
||||
self.analyze_import_usage(ctx, symbol_to_specifier, import_decl);
|
||||
@@ -317,7 +317,7 @@ impl PreferExportFrom {
|
||||
if variable_declaration.kind == VariableDeclarationKind::Const
|
||||
&& matches!(
|
||||
ctx.nodes().parent_node(declaration_node.id()).kind(),
|
||||
AstKind::ExportNamedDeclaration(_)
|
||||
AstKind::ExportDeclaration(_)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -430,9 +430,8 @@ impl PreferExportFrom {
|
||||
false
|
||||
};
|
||||
|
||||
let needs_source = !ts_kind
|
||||
&& matches!(export_decl.export_kind, ImportOrExportKind::Type)
|
||||
&& export_decl.source.is_none();
|
||||
let needs_source =
|
||||
!ts_kind && matches!(export_decl.export_kind, ImportOrExportKind::Type);
|
||||
|
||||
let violation = Violation {
|
||||
export_name,
|
||||
@@ -462,7 +461,7 @@ impl PreferExportFrom {
|
||||
|
||||
if let AstKind::VariableDeclaration(var_declaration) = next_parent_node.kind()
|
||||
&& var_declaration.kind == VariableDeclarationKind::Const
|
||||
&& let AstKind::ExportNamedDeclaration(export_named_decl) =
|
||||
&& let AstKind::ExportDeclaration(export_named_decl) =
|
||||
ctx.nodes().parent_node(next_parent_node.id()).kind()
|
||||
{
|
||||
if Self::is_variable_used_elsewhere(ctx, var_decl) {
|
||||
@@ -667,7 +666,7 @@ impl PreferExportFrom {
|
||||
locally_used_specifiers: &FxHashSet<SymbolId>,
|
||||
symbol_to_specifier: &FxIndexMap<SymbolId, SpecifierSpec<'a>>,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
re_export_decl: Option<&'a ExportNamedDeclaration<'a>>,
|
||||
re_export_decl: Option<&'a ExportFromDeclaration<'a>>,
|
||||
source: &str,
|
||||
with_clause: Option<&str>,
|
||||
replace_span: Span,
|
||||
@@ -817,7 +816,7 @@ impl PreferExportFrom {
|
||||
locally_used_specifiers: &FxHashSet<SymbolId>,
|
||||
symbol_to_specifier: &FxIndexMap<SymbolId, SpecifierSpec<'a>>,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
re_export_decl: Option<&'a ExportNamedDeclaration<'a>>,
|
||||
re_export_decl: Option<&'a ExportFromDeclaration<'a>>,
|
||||
re_export_source_text: &str,
|
||||
replace_span: Span,
|
||||
replace_export_spans: &[Span],
|
||||
@@ -871,7 +870,7 @@ impl PreferExportFrom {
|
||||
fixer: RuleFixer<'_, '_>,
|
||||
rule_fixes: &mut RuleFix,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
re_export_decl: Option<&'a ExportNamedDeclaration<'a>>,
|
||||
re_export_decl: Option<&'a ExportFromDeclaration<'a>>,
|
||||
re_export_source_text: &str,
|
||||
replace_span: Span,
|
||||
replace_export_spans: &[Span],
|
||||
@@ -902,7 +901,7 @@ impl PreferExportFrom {
|
||||
fn handle_reexport_case<'a>(
|
||||
fixer: RuleFixer<'_, '_>,
|
||||
rule_fixes: &mut RuleFix,
|
||||
re_export: &'a ExportNamedDeclaration<'a>,
|
||||
re_export: &'a ExportFromDeclaration<'a>,
|
||||
re_export_source_text: &str,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
replace_span: Span,
|
||||
@@ -916,7 +915,7 @@ impl PreferExportFrom {
|
||||
let processed_exports_str = Self::get_processed_exports_str(exports_str, re_export);
|
||||
|
||||
if is_namespace {
|
||||
let source = re_export.source.as_ref().unwrap().raw.unwrap();
|
||||
let source = re_export.source.raw.unwrap();
|
||||
let final_replacement = format!("export {processed_exports_str} from {source}");
|
||||
rule_fixes.push(fixer.replace(import_decl.span(), final_replacement));
|
||||
} else {
|
||||
@@ -938,7 +937,7 @@ impl PreferExportFrom {
|
||||
fn get_last_export_span(
|
||||
last_specifier: Option<&ExportSpecifier>,
|
||||
re_export_source_text: &str,
|
||||
re_export: &ExportNamedDeclaration,
|
||||
re_export: &ExportFromDeclaration,
|
||||
) -> Span {
|
||||
if let Some(specifier) = last_specifier {
|
||||
specifier.span()
|
||||
@@ -957,7 +956,7 @@ impl PreferExportFrom {
|
||||
retained_specifiers: &[(&SymbolId, &SpecifierSpec<'a>)],
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
replace_span: Span,
|
||||
re_export_decl: Option<&'a ExportNamedDeclaration<'a>>,
|
||||
re_export_decl: Option<&'a ExportFromDeclaration<'a>>,
|
||||
delete_span: Span,
|
||||
exports_str: &str,
|
||||
replacement_str: &str,
|
||||
@@ -1038,7 +1037,7 @@ impl PreferExportFrom {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_processed_exports_str(exports_str: &str, re_export: &ExportNamedDeclaration) -> String {
|
||||
fn get_processed_exports_str(exports_str: &str, re_export: &ExportFromDeclaration) -> String {
|
||||
if matches!(re_export.export_kind, ImportOrExportKind::Type) {
|
||||
exports_str.cow_replace("type ", "").to_string()
|
||||
} else {
|
||||
@@ -1049,7 +1048,7 @@ impl PreferExportFrom {
|
||||
fn get_insertion_text_for_regular_export(
|
||||
last_specifier: Option<&ExportSpecifier>,
|
||||
processed_exports_str: &str,
|
||||
re_export: &ExportNamedDeclaration,
|
||||
re_export: &ExportFromDeclaration,
|
||||
re_export_source_text: &str,
|
||||
) -> String {
|
||||
match last_specifier {
|
||||
@@ -1146,7 +1145,7 @@ fn has_matching_type_alias<'a>(
|
||||
fn find_corresponding_export<'a>(
|
||||
ctx: &LintContext<'a>,
|
||||
import_decl: &'a ImportDeclaration<'a>,
|
||||
) -> Option<&'a ExportNamedDeclaration<'a>> {
|
||||
) -> Option<&'a ExportFromDeclaration<'a>> {
|
||||
let source = import_decl.source.value.as_str();
|
||||
|
||||
for requested_module in ctx.module_record().requested_modules.get(source)? {
|
||||
@@ -1177,9 +1176,9 @@ fn find_corresponding_export<'a>(
|
||||
fn find_export_named_declaration_by_span<'a>(
|
||||
ctx: &LintContext<'a>,
|
||||
span: Span,
|
||||
) -> Option<&'a ExportNamedDeclaration<'a>> {
|
||||
) -> Option<&'a ExportFromDeclaration<'a>> {
|
||||
ctx.nodes().iter().find_map(|node| {
|
||||
if let AstKind::ExportNamedDeclaration(export_decl) = node.kind()
|
||||
if let AstKind::ExportFromDeclaration(export_decl) = node.kind()
|
||||
&& export_decl.span() == span
|
||||
{
|
||||
Some(export_decl)
|
||||
@@ -1191,7 +1190,7 @@ fn find_export_named_declaration_by_span<'a>(
|
||||
|
||||
fn is_matching_export_kind(
|
||||
import_decl: &ImportDeclaration<'_>,
|
||||
export_decl: &ExportNamedDeclaration<'_>,
|
||||
export_decl: &ExportFromDeclaration<'_>,
|
||||
) -> bool {
|
||||
if import_decl.import_kind == export_decl.export_kind {
|
||||
return true;
|
||||
|
||||
@@ -65,8 +65,8 @@ impl Rule for PreferNodeProtocol {
|
||||
call.common_js_require().map(|s| (s.value, s.span))
|
||||
}
|
||||
AstKind::ImportDeclaration(import) => Some((import.source.value, import.source.span)),
|
||||
AstKind::ExportNamedDeclaration(export) => {
|
||||
export.source.as_ref().map(|item| (item.value, item.span))
|
||||
AstKind::ExportFromDeclaration(export) => {
|
||||
Some((export.source.value, export.source.span))
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
@@ -88,10 +88,8 @@ impl Rule for PreferStringRaw {
|
||||
AstKind::ImportDeclaration(decl) if string_literal.span == decl.source.span => {
|
||||
return;
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(decl) => {
|
||||
if let Some(source) = &decl.source
|
||||
&& string_literal.span == source.span
|
||||
{
|
||||
AstKind::ExportFromDeclaration(decl) => {
|
||||
if string_literal.span == decl.source.span {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,15 +135,13 @@ impl Rule for RequireModuleAttributes {
|
||||
"import statement",
|
||||
);
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(decl) => {
|
||||
if let Some(source) = &decl.source {
|
||||
check_with_clause(
|
||||
ctx,
|
||||
decl.with_clause.as_deref(),
|
||||
source.span,
|
||||
"export statement",
|
||||
);
|
||||
}
|
||||
AstKind::ExportFromDeclaration(decl) => {
|
||||
check_with_clause(
|
||||
ctx,
|
||||
decl.with_clause.as_deref(),
|
||||
decl.source.span,
|
||||
"export statement",
|
||||
);
|
||||
}
|
||||
AstKind::ExportAllDeclaration(decl) => {
|
||||
check_with_clause(
|
||||
|
||||
@@ -67,9 +67,7 @@ impl Rule for RequireModuleSpecifiers {
|
||||
|fixer| fix_import(fixer, import_decl),
|
||||
);
|
||||
}
|
||||
AstKind::ExportNamedDeclaration(export_decl)
|
||||
if export_decl.declaration.is_none() && export_decl.specifiers.is_empty() =>
|
||||
{
|
||||
AstKind::ExportNamedDeclaration(export_decl) if export_decl.specifiers.is_empty() => {
|
||||
let span =
|
||||
find_empty_braces_in_export(ctx, export_decl).unwrap_or(export_decl.span);
|
||||
ctx.diagnostic_with_fix(
|
||||
@@ -77,6 +75,12 @@ impl Rule for RequireModuleSpecifiers {
|
||||
|fixer| fix_export(fixer, export_decl),
|
||||
);
|
||||
}
|
||||
AstKind::ExportFromDeclaration(export_decl) if export_decl.specifiers.is_empty() => {
|
||||
let span =
|
||||
find_empty_braces_in_text(ctx.source_range(export_decl.span), export_decl.span)
|
||||
.unwrap_or(export_decl.span);
|
||||
ctx.diagnostic(require_module_specifiers_diagnostic(span, "export"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -144,10 +148,6 @@ fn fix_import<'a>(fixer: RuleFixer<'_, 'a>, import_decl: &ImportDeclaration<'a>)
|
||||
}
|
||||
|
||||
fn fix_export<'a>(fixer: RuleFixer<'_, 'a>, export_decl: &ExportNamedDeclaration<'a>) -> RuleFix {
|
||||
if export_decl.source.is_some() {
|
||||
return fixer.noop();
|
||||
}
|
||||
|
||||
// Remove the entire `export {}` statement
|
||||
fixer.delete(&export_decl.span)
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ fn has_vue_component_annotation(node: &AstNode, ctx: &LintContext) -> bool {
|
||||
if matches!(
|
||||
ancestor.kind(),
|
||||
AstKind::ExportDefaultDeclaration(_)
|
||||
| AstKind::ExportNamedDeclaration(_)
|
||||
| AstKind::ExportDeclaration(_)
|
||||
| AstKind::ExpressionStatement(_)
|
||||
| AstKind::VariableDeclaration(_)
|
||||
) {
|
||||
|
||||
@@ -38,6 +38,12 @@ source: crates/oxc_linter/src/tester.rs
|
||||
· ───
|
||||
╰────
|
||||
|
||||
⚠ react(only-export-components): Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components.
|
||||
╭─[only_export_components.tsx:1:15]
|
||||
1 │ export { Foo, helper } from './mod';
|
||||
· ──────
|
||||
╰────
|
||||
|
||||
⚠ react(only-export-components): This rule can't verify that `export *` only exports components.
|
||||
╭─[only_export_components.tsx:1:1]
|
||||
1 │ export * from './foo';
|
||||
|
||||
@@ -104,7 +104,7 @@ pub fn get_function_nearest_jsdoc_node<'a, 'b>(
|
||||
// export const foo = () => {}
|
||||
let parent_node = semantic.nodes().parent_node(current_node.id());
|
||||
match parent_node.kind() {
|
||||
AstKind::ExportDefaultDeclaration(_) | AstKind::ExportNamedDeclaration(_) => return Some(parent_node),
|
||||
AstKind::ExportDefaultDeclaration(_) | AstKind::ExportDeclaration(_) => return Some(parent_node),
|
||||
_ => return None
|
||||
}
|
||||
},
|
||||
|
||||
@@ -875,8 +875,8 @@ fn collect_exported_symbols<'a>(
|
||||
let mut exported_symbols = BitSet::new_in(symbols_len, allocator);
|
||||
let mut exported_names = ArenaHashSet::new_in(allocator);
|
||||
for statement in &program.body {
|
||||
let Statement::ExportNamedDeclaration(v) = statement else { continue };
|
||||
let Some(decl) = &v.declaration else { continue };
|
||||
let Statement::ExportDeclaration(v) = statement else { continue };
|
||||
let decl = &v.declaration;
|
||||
if let Declaration::VariableDeclaration(decl) = decl {
|
||||
// Use `bound_names` rather than `get_binding_identifier`: a destructuring
|
||||
// pattern (`export const { find } = x`) exports every bound name, and
|
||||
|
||||
@@ -181,146 +181,147 @@ pub(crate) enum AncestorType {
|
||||
WithClauseWithEntries = 157,
|
||||
ImportAttributeKey = 158,
|
||||
ImportAttributeValue = 159,
|
||||
ExportNamedDeclarationDeclaration = 160,
|
||||
ExportDeclarationDeclaration = 160,
|
||||
ExportNamedDeclarationSpecifiers = 161,
|
||||
ExportNamedDeclarationSource = 162,
|
||||
ExportNamedDeclarationWithClause = 163,
|
||||
ExportDefaultDeclarationDeclaration = 164,
|
||||
ExportAllDeclarationExported = 165,
|
||||
ExportAllDeclarationSource = 166,
|
||||
ExportAllDeclarationWithClause = 167,
|
||||
ExportSpecifierLocal = 168,
|
||||
ExportSpecifierExported = 169,
|
||||
V8IntrinsicExpressionName = 170,
|
||||
V8IntrinsicExpressionArguments = 171,
|
||||
JSXElementOpeningElement = 172,
|
||||
JSXElementChildren = 173,
|
||||
JSXElementClosingElement = 174,
|
||||
JSXOpeningElementName = 175,
|
||||
JSXOpeningElementTypeArguments = 176,
|
||||
JSXOpeningElementAttributes = 177,
|
||||
JSXClosingElementName = 178,
|
||||
JSXFragmentOpeningFragment = 179,
|
||||
JSXFragmentChildren = 180,
|
||||
JSXFragmentClosingFragment = 181,
|
||||
JSXNamespacedNameNamespace = 182,
|
||||
JSXNamespacedNameName = 183,
|
||||
JSXMemberExpressionObject = 184,
|
||||
JSXMemberExpressionProperty = 185,
|
||||
JSXExpressionContainerExpression = 186,
|
||||
JSXAttributeName = 187,
|
||||
JSXAttributeValue = 188,
|
||||
JSXSpreadAttributeArgument = 189,
|
||||
JSXSpreadChildExpression = 190,
|
||||
TSThisParameterTypeAnnotation = 191,
|
||||
TSEnumDeclarationId = 192,
|
||||
TSEnumDeclarationBody = 193,
|
||||
TSEnumBodyMembers = 194,
|
||||
TSEnumMemberId = 195,
|
||||
TSEnumMemberInitializer = 196,
|
||||
TSTypeAnnotationTypeAnnotation = 197,
|
||||
TSLiteralTypeLiteral = 198,
|
||||
TSConditionalTypeCheckType = 199,
|
||||
TSConditionalTypeExtendsType = 200,
|
||||
TSConditionalTypeTrueType = 201,
|
||||
TSConditionalTypeFalseType = 202,
|
||||
TSUnionTypeTypes = 203,
|
||||
TSIntersectionTypeTypes = 204,
|
||||
TSParenthesizedTypeTypeAnnotation = 205,
|
||||
TSTypeOperatorTypeAnnotation = 206,
|
||||
TSArrayTypeElementType = 207,
|
||||
TSIndexedAccessTypeObjectType = 208,
|
||||
TSIndexedAccessTypeIndexType = 209,
|
||||
TSTupleTypeElementTypes = 210,
|
||||
TSNamedTupleMemberLabel = 211,
|
||||
TSNamedTupleMemberElementType = 212,
|
||||
TSOptionalTypeTypeAnnotation = 213,
|
||||
TSRestTypeTypeAnnotation = 214,
|
||||
TSTypeReferenceTypeName = 215,
|
||||
TSTypeReferenceTypeArguments = 216,
|
||||
TSQualifiedNameLeft = 217,
|
||||
TSQualifiedNameRight = 218,
|
||||
TSTypeParameterInstantiationParams = 219,
|
||||
TSTypeParameterName = 220,
|
||||
TSTypeParameterConstraint = 221,
|
||||
TSTypeParameterDefault = 222,
|
||||
TSTypeParameterDeclarationParams = 223,
|
||||
TSTypeAliasDeclarationId = 224,
|
||||
TSTypeAliasDeclarationTypeParameters = 225,
|
||||
TSTypeAliasDeclarationTypeAnnotation = 226,
|
||||
TSClassImplementsExpression = 227,
|
||||
TSClassImplementsTypeArguments = 228,
|
||||
TSInterfaceDeclarationId = 229,
|
||||
TSInterfaceDeclarationTypeParameters = 230,
|
||||
TSInterfaceDeclarationExtends = 231,
|
||||
TSInterfaceDeclarationBody = 232,
|
||||
TSInterfaceBodyBody = 233,
|
||||
TSPropertySignatureKey = 234,
|
||||
TSPropertySignatureTypeAnnotation = 235,
|
||||
TSIndexSignatureParameters = 236,
|
||||
TSIndexSignatureTypeAnnotation = 237,
|
||||
TSCallSignatureDeclarationTypeParameters = 238,
|
||||
TSCallSignatureDeclarationThisParam = 239,
|
||||
TSCallSignatureDeclarationParams = 240,
|
||||
TSCallSignatureDeclarationReturnType = 241,
|
||||
TSMethodSignatureKey = 242,
|
||||
TSMethodSignatureTypeParameters = 243,
|
||||
TSMethodSignatureThisParam = 244,
|
||||
TSMethodSignatureParams = 245,
|
||||
TSMethodSignatureReturnType = 246,
|
||||
TSConstructSignatureDeclarationTypeParameters = 247,
|
||||
TSConstructSignatureDeclarationParams = 248,
|
||||
TSConstructSignatureDeclarationReturnType = 249,
|
||||
TSIndexSignatureNameTypeAnnotation = 250,
|
||||
TSInterfaceHeritageExpression = 251,
|
||||
TSInterfaceHeritageTypeArguments = 252,
|
||||
TSTypePredicateParameterName = 253,
|
||||
TSTypePredicateTypeAnnotation = 254,
|
||||
TSModuleDeclarationId = 255,
|
||||
TSModuleDeclarationBody = 256,
|
||||
TSGlobalDeclarationBody = 257,
|
||||
TSModuleBlockDirectives = 258,
|
||||
TSModuleBlockBody = 259,
|
||||
TSTypeLiteralMembers = 260,
|
||||
TSInferTypeTypeParameter = 261,
|
||||
TSTypeQueryExprName = 262,
|
||||
TSTypeQueryTypeArguments = 263,
|
||||
TSImportTypeSource = 264,
|
||||
TSImportTypeOptions = 265,
|
||||
TSImportTypeQualifier = 266,
|
||||
TSImportTypeTypeArguments = 267,
|
||||
TSImportTypeQualifiedNameLeft = 268,
|
||||
TSImportTypeQualifiedNameRight = 269,
|
||||
TSFunctionTypeTypeParameters = 270,
|
||||
TSFunctionTypeThisParam = 271,
|
||||
TSFunctionTypeParams = 272,
|
||||
TSFunctionTypeReturnType = 273,
|
||||
TSConstructorTypeTypeParameters = 274,
|
||||
TSConstructorTypeParams = 275,
|
||||
TSConstructorTypeReturnType = 276,
|
||||
TSMappedTypeKey = 277,
|
||||
TSMappedTypeConstraint = 278,
|
||||
TSMappedTypeNameType = 279,
|
||||
TSMappedTypeTypeAnnotation = 280,
|
||||
TSTemplateLiteralTypeQuasis = 281,
|
||||
TSTemplateLiteralTypeTypes = 282,
|
||||
TSAsExpressionExpression = 283,
|
||||
TSAsExpressionTypeAnnotation = 284,
|
||||
TSSatisfiesExpressionExpression = 285,
|
||||
TSSatisfiesExpressionTypeAnnotation = 286,
|
||||
TSTypeAssertionTypeAnnotation = 287,
|
||||
TSTypeAssertionExpression = 288,
|
||||
TSImportEqualsDeclarationId = 289,
|
||||
TSImportEqualsDeclarationModuleReference = 290,
|
||||
TSExternalModuleReferenceExpression = 291,
|
||||
TSNonNullExpressionExpression = 292,
|
||||
DecoratorExpression = 293,
|
||||
TSExportAssignmentExpression = 294,
|
||||
TSNamespaceExportDeclarationId = 295,
|
||||
TSInstantiationExpressionExpression = 296,
|
||||
TSInstantiationExpressionTypeArguments = 297,
|
||||
JSDocNullableTypeTypeAnnotation = 298,
|
||||
JSDocNonNullableTypeTypeAnnotation = 299,
|
||||
ExportFromDeclarationSpecifiers = 162,
|
||||
ExportFromDeclarationSource = 163,
|
||||
ExportFromDeclarationWithClause = 164,
|
||||
ExportDefaultDeclarationDeclaration = 165,
|
||||
ExportAllDeclarationExported = 166,
|
||||
ExportAllDeclarationSource = 167,
|
||||
ExportAllDeclarationWithClause = 168,
|
||||
ExportSpecifierLocal = 169,
|
||||
ExportSpecifierExported = 170,
|
||||
V8IntrinsicExpressionName = 171,
|
||||
V8IntrinsicExpressionArguments = 172,
|
||||
JSXElementOpeningElement = 173,
|
||||
JSXElementChildren = 174,
|
||||
JSXElementClosingElement = 175,
|
||||
JSXOpeningElementName = 176,
|
||||
JSXOpeningElementTypeArguments = 177,
|
||||
JSXOpeningElementAttributes = 178,
|
||||
JSXClosingElementName = 179,
|
||||
JSXFragmentOpeningFragment = 180,
|
||||
JSXFragmentChildren = 181,
|
||||
JSXFragmentClosingFragment = 182,
|
||||
JSXNamespacedNameNamespace = 183,
|
||||
JSXNamespacedNameName = 184,
|
||||
JSXMemberExpressionObject = 185,
|
||||
JSXMemberExpressionProperty = 186,
|
||||
JSXExpressionContainerExpression = 187,
|
||||
JSXAttributeName = 188,
|
||||
JSXAttributeValue = 189,
|
||||
JSXSpreadAttributeArgument = 190,
|
||||
JSXSpreadChildExpression = 191,
|
||||
TSThisParameterTypeAnnotation = 192,
|
||||
TSEnumDeclarationId = 193,
|
||||
TSEnumDeclarationBody = 194,
|
||||
TSEnumBodyMembers = 195,
|
||||
TSEnumMemberId = 196,
|
||||
TSEnumMemberInitializer = 197,
|
||||
TSTypeAnnotationTypeAnnotation = 198,
|
||||
TSLiteralTypeLiteral = 199,
|
||||
TSConditionalTypeCheckType = 200,
|
||||
TSConditionalTypeExtendsType = 201,
|
||||
TSConditionalTypeTrueType = 202,
|
||||
TSConditionalTypeFalseType = 203,
|
||||
TSUnionTypeTypes = 204,
|
||||
TSIntersectionTypeTypes = 205,
|
||||
TSParenthesizedTypeTypeAnnotation = 206,
|
||||
TSTypeOperatorTypeAnnotation = 207,
|
||||
TSArrayTypeElementType = 208,
|
||||
TSIndexedAccessTypeObjectType = 209,
|
||||
TSIndexedAccessTypeIndexType = 210,
|
||||
TSTupleTypeElementTypes = 211,
|
||||
TSNamedTupleMemberLabel = 212,
|
||||
TSNamedTupleMemberElementType = 213,
|
||||
TSOptionalTypeTypeAnnotation = 214,
|
||||
TSRestTypeTypeAnnotation = 215,
|
||||
TSTypeReferenceTypeName = 216,
|
||||
TSTypeReferenceTypeArguments = 217,
|
||||
TSQualifiedNameLeft = 218,
|
||||
TSQualifiedNameRight = 219,
|
||||
TSTypeParameterInstantiationParams = 220,
|
||||
TSTypeParameterName = 221,
|
||||
TSTypeParameterConstraint = 222,
|
||||
TSTypeParameterDefault = 223,
|
||||
TSTypeParameterDeclarationParams = 224,
|
||||
TSTypeAliasDeclarationId = 225,
|
||||
TSTypeAliasDeclarationTypeParameters = 226,
|
||||
TSTypeAliasDeclarationTypeAnnotation = 227,
|
||||
TSClassImplementsExpression = 228,
|
||||
TSClassImplementsTypeArguments = 229,
|
||||
TSInterfaceDeclarationId = 230,
|
||||
TSInterfaceDeclarationTypeParameters = 231,
|
||||
TSInterfaceDeclarationExtends = 232,
|
||||
TSInterfaceDeclarationBody = 233,
|
||||
TSInterfaceBodyBody = 234,
|
||||
TSPropertySignatureKey = 235,
|
||||
TSPropertySignatureTypeAnnotation = 236,
|
||||
TSIndexSignatureParameters = 237,
|
||||
TSIndexSignatureTypeAnnotation = 238,
|
||||
TSCallSignatureDeclarationTypeParameters = 239,
|
||||
TSCallSignatureDeclarationThisParam = 240,
|
||||
TSCallSignatureDeclarationParams = 241,
|
||||
TSCallSignatureDeclarationReturnType = 242,
|
||||
TSMethodSignatureKey = 243,
|
||||
TSMethodSignatureTypeParameters = 244,
|
||||
TSMethodSignatureThisParam = 245,
|
||||
TSMethodSignatureParams = 246,
|
||||
TSMethodSignatureReturnType = 247,
|
||||
TSConstructSignatureDeclarationTypeParameters = 248,
|
||||
TSConstructSignatureDeclarationParams = 249,
|
||||
TSConstructSignatureDeclarationReturnType = 250,
|
||||
TSIndexSignatureNameTypeAnnotation = 251,
|
||||
TSInterfaceHeritageExpression = 252,
|
||||
TSInterfaceHeritageTypeArguments = 253,
|
||||
TSTypePredicateParameterName = 254,
|
||||
TSTypePredicateTypeAnnotation = 255,
|
||||
TSModuleDeclarationId = 256,
|
||||
TSModuleDeclarationBody = 257,
|
||||
TSGlobalDeclarationBody = 258,
|
||||
TSModuleBlockDirectives = 259,
|
||||
TSModuleBlockBody = 260,
|
||||
TSTypeLiteralMembers = 261,
|
||||
TSInferTypeTypeParameter = 262,
|
||||
TSTypeQueryExprName = 263,
|
||||
TSTypeQueryTypeArguments = 264,
|
||||
TSImportTypeSource = 265,
|
||||
TSImportTypeOptions = 266,
|
||||
TSImportTypeQualifier = 267,
|
||||
TSImportTypeTypeArguments = 268,
|
||||
TSImportTypeQualifiedNameLeft = 269,
|
||||
TSImportTypeQualifiedNameRight = 270,
|
||||
TSFunctionTypeTypeParameters = 271,
|
||||
TSFunctionTypeThisParam = 272,
|
||||
TSFunctionTypeParams = 273,
|
||||
TSFunctionTypeReturnType = 274,
|
||||
TSConstructorTypeTypeParameters = 275,
|
||||
TSConstructorTypeParams = 276,
|
||||
TSConstructorTypeReturnType = 277,
|
||||
TSMappedTypeKey = 278,
|
||||
TSMappedTypeConstraint = 279,
|
||||
TSMappedTypeNameType = 280,
|
||||
TSMappedTypeTypeAnnotation = 281,
|
||||
TSTemplateLiteralTypeQuasis = 282,
|
||||
TSTemplateLiteralTypeTypes = 283,
|
||||
TSAsExpressionExpression = 284,
|
||||
TSAsExpressionTypeAnnotation = 285,
|
||||
TSSatisfiesExpressionExpression = 286,
|
||||
TSSatisfiesExpressionTypeAnnotation = 287,
|
||||
TSTypeAssertionTypeAnnotation = 288,
|
||||
TSTypeAssertionExpression = 289,
|
||||
TSImportEqualsDeclarationId = 290,
|
||||
TSImportEqualsDeclarationModuleReference = 291,
|
||||
TSExternalModuleReferenceExpression = 292,
|
||||
TSNonNullExpressionExpression = 293,
|
||||
DecoratorExpression = 294,
|
||||
TSExportAssignmentExpression = 295,
|
||||
TSNamespaceExportDeclarationId = 296,
|
||||
TSInstantiationExpressionExpression = 297,
|
||||
TSInstantiationExpressionTypeArguments = 298,
|
||||
JSDocNullableTypeTypeAnnotation = 299,
|
||||
JSDocNonNullableTypeTypeAnnotation = 300,
|
||||
}
|
||||
|
||||
/// Ancestor type used in AST traversal.
|
||||
@@ -627,14 +628,16 @@ pub enum Ancestor<'a, 't> {
|
||||
ImportAttributeKey(ImportAttributeWithoutKey<'a, 't>) = AncestorType::ImportAttributeKey as u16,
|
||||
ImportAttributeValue(ImportAttributeWithoutValue<'a, 't>) =
|
||||
AncestorType::ImportAttributeValue as u16,
|
||||
ExportNamedDeclarationDeclaration(ExportNamedDeclarationWithoutDeclaration<'a, 't>) =
|
||||
AncestorType::ExportNamedDeclarationDeclaration as u16,
|
||||
ExportDeclarationDeclaration(ExportDeclarationWithoutDeclaration<'a, 't>) =
|
||||
AncestorType::ExportDeclarationDeclaration as u16,
|
||||
ExportNamedDeclarationSpecifiers(ExportNamedDeclarationWithoutSpecifiers<'a, 't>) =
|
||||
AncestorType::ExportNamedDeclarationSpecifiers as u16,
|
||||
ExportNamedDeclarationSource(ExportNamedDeclarationWithoutSource<'a, 't>) =
|
||||
AncestorType::ExportNamedDeclarationSource as u16,
|
||||
ExportNamedDeclarationWithClause(ExportNamedDeclarationWithoutWithClause<'a, 't>) =
|
||||
AncestorType::ExportNamedDeclarationWithClause as u16,
|
||||
ExportFromDeclarationSpecifiers(ExportFromDeclarationWithoutSpecifiers<'a, 't>) =
|
||||
AncestorType::ExportFromDeclarationSpecifiers as u16,
|
||||
ExportFromDeclarationSource(ExportFromDeclarationWithoutSource<'a, 't>) =
|
||||
AncestorType::ExportFromDeclarationSource as u16,
|
||||
ExportFromDeclarationWithClause(ExportFromDeclarationWithoutWithClause<'a, 't>) =
|
||||
AncestorType::ExportFromDeclarationWithClause as u16,
|
||||
ExportDefaultDeclarationDeclaration(ExportDefaultDeclarationWithoutDeclaration<'a, 't>) =
|
||||
AncestorType::ExportDefaultDeclarationDeclaration as u16,
|
||||
ExportAllDeclarationExported(ExportAllDeclarationWithoutExported<'a, 't>) =
|
||||
@@ -1412,14 +1415,23 @@ impl<'a, 't> Ancestor<'a, 't> {
|
||||
matches!(self, Self::ImportAttributeKey(_) | Self::ImportAttributeValue(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_export_declaration(self) -> bool {
|
||||
matches!(self, Self::ExportDeclarationDeclaration(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_export_named_declaration(self) -> bool {
|
||||
matches!(self, Self::ExportNamedDeclarationSpecifiers(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_export_from_declaration(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::ExportNamedDeclarationDeclaration(_)
|
||||
| Self::ExportNamedDeclarationSpecifiers(_)
|
||||
| Self::ExportNamedDeclarationSource(_)
|
||||
| Self::ExportNamedDeclarationWithClause(_)
|
||||
Self::ExportFromDeclarationSpecifiers(_)
|
||||
| Self::ExportFromDeclarationSource(_)
|
||||
| Self::ExportFromDeclarationWithClause(_)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2108,7 +2120,7 @@ impl<'a, 't> Ancestor<'a, 't> {
|
||||
|
||||
#[inline]
|
||||
pub fn is_parent_of_declaration(self) -> bool {
|
||||
matches!(self, Self::ExportNamedDeclarationDeclaration(_))
|
||||
matches!(self, Self::ExportDeclarationDeclaration(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -2412,10 +2424,11 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> {
|
||||
Self::WithClauseWithEntries(a) => a.address(),
|
||||
Self::ImportAttributeKey(a) => a.address(),
|
||||
Self::ImportAttributeValue(a) => a.address(),
|
||||
Self::ExportNamedDeclarationDeclaration(a) => a.address(),
|
||||
Self::ExportDeclarationDeclaration(a) => a.address(),
|
||||
Self::ExportNamedDeclarationSpecifiers(a) => a.address(),
|
||||
Self::ExportNamedDeclarationSource(a) => a.address(),
|
||||
Self::ExportNamedDeclarationWithClause(a) => a.address(),
|
||||
Self::ExportFromDeclarationSpecifiers(a) => a.address(),
|
||||
Self::ExportFromDeclarationSource(a) => a.address(),
|
||||
Self::ExportFromDeclarationWithClause(a) => a.address(),
|
||||
Self::ExportDefaultDeclarationDeclaration(a) => a.address(),
|
||||
Self::ExportAllDeclarationExported(a) => a.address(),
|
||||
Self::ExportAllDeclarationSource(a) => a.address(),
|
||||
@@ -11432,84 +11445,48 @@ impl<'a, 't> GetAddress for ImportAttributeWithoutValue<'a, 't> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_NODE_ID: usize =
|
||||
offset_of!(ExportNamedDeclaration, node_id);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_SPAN: usize =
|
||||
offset_of!(ExportNamedDeclaration, span);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_DECLARATION: usize =
|
||||
offset_of!(ExportNamedDeclaration, declaration);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS: usize =
|
||||
offset_of!(ExportNamedDeclaration, specifiers);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_SOURCE: usize =
|
||||
offset_of!(ExportNamedDeclaration, source);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_EXPORT_KIND: usize =
|
||||
offset_of!(ExportNamedDeclaration, export_kind);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_WITH_CLAUSE: usize =
|
||||
offset_of!(ExportNamedDeclaration, with_clause);
|
||||
pub(crate) const OFFSET_EXPORT_DECLARATION_NODE_ID: usize = offset_of!(ExportDeclaration, node_id);
|
||||
pub(crate) const OFFSET_EXPORT_DECLARATION_SPAN: usize = offset_of!(ExportDeclaration, span);
|
||||
pub(crate) const OFFSET_EXPORT_DECLARATION_DECLARATION: usize =
|
||||
offset_of!(ExportDeclaration, declaration);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ExportNamedDeclarationWithoutDeclaration<'a, 't>(
|
||||
pub(crate) *const ExportNamedDeclaration<'a>,
|
||||
pub struct ExportDeclarationWithoutDeclaration<'a, 't>(
|
||||
pub(crate) *const ExportDeclaration<'a>,
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
|
||||
impl<'a, 't> ExportNamedDeclarationWithoutDeclaration<'a, 't> {
|
||||
impl<'a, 't> ExportDeclarationWithoutDeclaration<'a, 't> {
|
||||
#[inline]
|
||||
pub fn node_id(self) -> &'t Cell<NodeId> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_NODE_ID)
|
||||
as *const Cell<NodeId>)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_DECLARATION_NODE_ID) as *const Cell<NodeId>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(self) -> &'t Span {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPAN) as *const Span)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(self) -> &'t ArenaVec<'a, ExportSpecifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS)
|
||||
as *const ArenaVec<'a, ExportSpecifier<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(self) -> &'t Option<StringLiteral<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SOURCE)
|
||||
as *const Option<StringLiteral<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn export_kind(self) -> &'t ImportOrExportKind {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_EXPORT_KIND)
|
||||
as *const ImportOrExportKind)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_clause(self) -> &'t Option<ArenaBox<'a, WithClause<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_WITH_CLAUSE)
|
||||
as *const Option<ArenaBox<'a, WithClause<'a>>>)
|
||||
}
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_EXPORT_DECLARATION_SPAN) as *const Span) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutDeclaration<'a, 't> {
|
||||
impl<'a, 't> GetAddress for ExportDeclarationWithoutDeclaration<'a, 't> {
|
||||
#[inline]
|
||||
fn address(&self) -> Address {
|
||||
unsafe { Address::from_ptr(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_NODE_ID: usize =
|
||||
offset_of!(ExportNamedDeclaration, node_id);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_SPAN: usize =
|
||||
offset_of!(ExportNamedDeclaration, span);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS: usize =
|
||||
offset_of!(ExportNamedDeclaration, specifiers);
|
||||
pub(crate) const OFFSET_EXPORT_NAMED_DECLARATION_EXPORT_KIND: usize =
|
||||
offset_of!(ExportNamedDeclaration, export_kind);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ExportNamedDeclarationWithoutSpecifiers<'a, 't>(
|
||||
@@ -11533,22 +11510,6 @@ impl<'a, 't> ExportNamedDeclarationWithoutSpecifiers<'a, 't> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declaration(self) -> &'t Option<Declaration<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_DECLARATION)
|
||||
as *const Option<Declaration<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(self) -> &'t Option<StringLiteral<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SOURCE)
|
||||
as *const Option<StringLiteral<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn export_kind(self) -> &'t ImportOrExportKind {
|
||||
unsafe {
|
||||
@@ -11556,14 +11517,6 @@ impl<'a, 't> ExportNamedDeclarationWithoutSpecifiers<'a, 't> {
|
||||
as *const ImportOrExportKind)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_clause(self) -> &'t Option<ArenaBox<'a, WithClause<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_WITH_CLAUSE)
|
||||
as *const Option<ArenaBox<'a, WithClause<'a>>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutSpecifiers<'a, 't> {
|
||||
@@ -11573,49 +11526,52 @@ impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutSpecifiers<'a, 't> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_NODE_ID: usize =
|
||||
offset_of!(ExportFromDeclaration, node_id);
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_SPAN: usize =
|
||||
offset_of!(ExportFromDeclaration, span);
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_SPECIFIERS: usize =
|
||||
offset_of!(ExportFromDeclaration, specifiers);
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_SOURCE: usize =
|
||||
offset_of!(ExportFromDeclaration, source);
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_EXPORT_KIND: usize =
|
||||
offset_of!(ExportFromDeclaration, export_kind);
|
||||
pub(crate) const OFFSET_EXPORT_FROM_DECLARATION_WITH_CLAUSE: usize =
|
||||
offset_of!(ExportFromDeclaration, with_clause);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ExportNamedDeclarationWithoutSource<'a, 't>(
|
||||
pub(crate) *const ExportNamedDeclaration<'a>,
|
||||
pub struct ExportFromDeclarationWithoutSpecifiers<'a, 't>(
|
||||
pub(crate) *const ExportFromDeclaration<'a>,
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
|
||||
impl<'a, 't> ExportNamedDeclarationWithoutSource<'a, 't> {
|
||||
impl<'a, 't> ExportFromDeclarationWithoutSpecifiers<'a, 't> {
|
||||
#[inline]
|
||||
pub fn node_id(self) -> &'t Cell<NodeId> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_NODE_ID)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_NODE_ID)
|
||||
as *const Cell<NodeId>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(self) -> &'t Span {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPAN) as *const Span)
|
||||
}
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declaration(self) -> &'t Option<Declaration<'a>> {
|
||||
pub fn source(self) -> &'t StringLiteral<'a> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_DECLARATION)
|
||||
as *const Option<Declaration<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(self) -> &'t ArenaVec<'a, ExportSpecifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS)
|
||||
as *const ArenaVec<'a, ExportSpecifier<'a>>)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SOURCE)
|
||||
as *const StringLiteral<'a>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn export_kind(self) -> &'t ImportOrExportKind {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_EXPORT_KIND)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_EXPORT_KIND)
|
||||
as *const ImportOrExportKind)
|
||||
}
|
||||
}
|
||||
@@ -11623,13 +11579,13 @@ impl<'a, 't> ExportNamedDeclarationWithoutSource<'a, 't> {
|
||||
#[inline]
|
||||
pub fn with_clause(self) -> &'t Option<ArenaBox<'a, WithClause<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_WITH_CLAUSE)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_WITH_CLAUSE)
|
||||
as *const Option<ArenaBox<'a, WithClause<'a>>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutSource<'a, 't> {
|
||||
impl<'a, 't> GetAddress for ExportFromDeclarationWithoutSpecifiers<'a, 't> {
|
||||
#[inline]
|
||||
fn address(&self) -> Address {
|
||||
unsafe { Address::from_ptr(self.0) }
|
||||
@@ -11638,61 +11594,104 @@ impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutSource<'a, 't> {
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ExportNamedDeclarationWithoutWithClause<'a, 't>(
|
||||
pub(crate) *const ExportNamedDeclaration<'a>,
|
||||
pub struct ExportFromDeclarationWithoutSource<'a, 't>(
|
||||
pub(crate) *const ExportFromDeclaration<'a>,
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
|
||||
impl<'a, 't> ExportNamedDeclarationWithoutWithClause<'a, 't> {
|
||||
impl<'a, 't> ExportFromDeclarationWithoutSource<'a, 't> {
|
||||
#[inline]
|
||||
pub fn node_id(self) -> &'t Cell<NodeId> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_NODE_ID)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_NODE_ID)
|
||||
as *const Cell<NodeId>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(self) -> &'t Span {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPAN) as *const Span)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declaration(self) -> &'t Option<Declaration<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_DECLARATION)
|
||||
as *const Option<Declaration<'a>>)
|
||||
}
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(self) -> &'t ArenaVec<'a, ExportSpecifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SPECIFIERS)
|
||||
as *const ArenaVec<'a, ExportSpecifier<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(self) -> &'t Option<StringLiteral<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_SOURCE)
|
||||
as *const Option<StringLiteral<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn export_kind(self) -> &'t ImportOrExportKind {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_NAMED_DECLARATION_EXPORT_KIND)
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_EXPORT_KIND)
|
||||
as *const ImportOrExportKind)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_clause(self) -> &'t Option<ArenaBox<'a, WithClause<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_WITH_CLAUSE)
|
||||
as *const Option<ArenaBox<'a, WithClause<'a>>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 't> GetAddress for ExportFromDeclarationWithoutSource<'a, 't> {
|
||||
#[inline]
|
||||
fn address(&self) -> Address {
|
||||
unsafe { Address::from_ptr(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ExportFromDeclarationWithoutWithClause<'a, 't>(
|
||||
pub(crate) *const ExportFromDeclaration<'a>,
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
|
||||
impl<'a, 't> ExportFromDeclarationWithoutWithClause<'a, 't> {
|
||||
#[inline]
|
||||
pub fn node_id(self) -> &'t Cell<NodeId> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_NODE_ID)
|
||||
as *const Cell<NodeId>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(self) -> &'t Span {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn specifiers(self) -> &'t ArenaVec<'a, ExportSpecifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SPECIFIERS)
|
||||
as *const ArenaVec<'a, ExportSpecifier<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source(self) -> &'t StringLiteral<'a> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_SOURCE)
|
||||
as *const StringLiteral<'a>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn export_kind(self) -> &'t ImportOrExportKind {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_EXPORT_FROM_DECLARATION_EXPORT_KIND)
|
||||
as *const ImportOrExportKind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 't> GetAddress for ExportNamedDeclarationWithoutWithClause<'a, 't> {
|
||||
impl<'a, 't> GetAddress for ExportFromDeclarationWithoutWithClause<'a, 't> {
|
||||
#[inline]
|
||||
fn address(&self) -> Address {
|
||||
unsafe { Address::from_ptr(self.0) }
|
||||
|
||||
@@ -1200,6 +1200,21 @@ pub trait Traverse<'a> {
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter_export_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
}
|
||||
#[inline]
|
||||
fn exit_export_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter_export_named_declaration(
|
||||
&mut self,
|
||||
@@ -1215,6 +1230,21 @@ pub trait Traverse<'a> {
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter_export_from_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportFromDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
}
|
||||
#[inline]
|
||||
fn exit_export_from_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportFromDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter_export_default_declaration(
|
||||
&mut self,
|
||||
|
||||
@@ -1382,7 +1382,9 @@ unsafe fn walk_statement<'a, Tr: Traverse<'a>>(
|
||||
Statement::ImportDeclaration(_)
|
||||
| Statement::ExportAllDeclaration(_)
|
||||
| Statement::ExportDefaultDeclaration(_)
|
||||
| Statement::ExportDeclaration(_)
|
||||
| Statement::ExportNamedDeclaration(_)
|
||||
| Statement::ExportFromDeclaration(_)
|
||||
| Statement::TSExportAssignment(_)
|
||||
| Statement::TSNamespaceExportDeclaration(_) => {
|
||||
walk_module_declaration(traverser, node as *mut _, ctx)
|
||||
@@ -2796,9 +2798,15 @@ unsafe fn walk_module_declaration<'a, Tr: Traverse<'a>>(
|
||||
ModuleDeclaration::ExportDefaultDeclaration(node) => {
|
||||
walk_export_default_declaration(traverser, (&mut **node) as *mut _, ctx)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(node) => {
|
||||
walk_export_declaration(traverser, (&mut **node) as *mut _, ctx)
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(node) => {
|
||||
walk_export_named_declaration(traverser, (&mut **node) as *mut _, ctx)
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(node) => {
|
||||
walk_export_from_declaration(traverser, (&mut **node) as *mut _, ctx)
|
||||
}
|
||||
ModuleDeclaration::TSExportAssignment(node) => {
|
||||
walk_ts_export_assignment(traverser, (&mut **node) as *mut _, ctx)
|
||||
}
|
||||
@@ -3045,43 +3053,72 @@ unsafe fn walk_import_attribute_key<'a, Tr: Traverse<'a>>(
|
||||
traverser.exit_import_attribute_key(&mut *node, ctx);
|
||||
}
|
||||
|
||||
unsafe fn walk_export_declaration<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ExportDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
traverser.enter_export_declaration(&mut *node, ctx);
|
||||
let pop_token = ctx.push_stack(Ancestor::ExportDeclarationDeclaration(
|
||||
ancestor::ExportDeclarationWithoutDeclaration(node, PhantomData),
|
||||
));
|
||||
walk_declaration(
|
||||
traverser,
|
||||
(node as *mut u8).add(ancestor::OFFSET_EXPORT_DECLARATION_DECLARATION) as *mut Declaration,
|
||||
ctx,
|
||||
);
|
||||
ctx.pop_stack(pop_token);
|
||||
traverser.exit_export_declaration(&mut *node, ctx);
|
||||
}
|
||||
|
||||
unsafe fn walk_export_named_declaration<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ExportNamedDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
traverser.enter_export_named_declaration(&mut *node, ctx);
|
||||
let pop_token = ctx.push_stack(Ancestor::ExportNamedDeclarationDeclaration(
|
||||
ancestor::ExportNamedDeclarationWithoutDeclaration(node, PhantomData),
|
||||
let pop_token = ctx.push_stack(Ancestor::ExportNamedDeclarationSpecifiers(
|
||||
ancestor::ExportNamedDeclarationWithoutSpecifiers(node, PhantomData),
|
||||
));
|
||||
if let Some(field) = &mut *((node as *mut u8)
|
||||
.add(ancestor::OFFSET_EXPORT_NAMED_DECLARATION_DECLARATION)
|
||||
as *mut Option<Declaration>)
|
||||
{
|
||||
walk_declaration(traverser, field as *mut _, ctx);
|
||||
}
|
||||
ctx.retag_stack(AncestorType::ExportNamedDeclarationSpecifiers);
|
||||
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_EXPORT_NAMED_DECLARATION_SPECIFIERS)
|
||||
as *mut ArenaVec<ExportSpecifier>)
|
||||
{
|
||||
walk_export_specifier(traverser, item as *mut _, ctx);
|
||||
}
|
||||
if let Some(field) = &mut *((node as *mut u8)
|
||||
.add(ancestor::OFFSET_EXPORT_NAMED_DECLARATION_SOURCE)
|
||||
as *mut Option<StringLiteral>)
|
||||
ctx.pop_stack(pop_token);
|
||||
traverser.exit_export_named_declaration(&mut *node, ctx);
|
||||
}
|
||||
|
||||
unsafe fn walk_export_from_declaration<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ExportFromDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
traverser.enter_export_from_declaration(&mut *node, ctx);
|
||||
let pop_token = ctx.push_stack(Ancestor::ExportFromDeclarationSpecifiers(
|
||||
ancestor::ExportFromDeclarationWithoutSpecifiers(node, PhantomData),
|
||||
));
|
||||
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_EXPORT_FROM_DECLARATION_SPECIFIERS)
|
||||
as *mut ArenaVec<ExportSpecifier>)
|
||||
{
|
||||
ctx.retag_stack(AncestorType::ExportNamedDeclarationSource);
|
||||
walk_string_literal(traverser, field as *mut _, ctx);
|
||||
walk_export_specifier(traverser, item as *mut _, ctx);
|
||||
}
|
||||
ctx.retag_stack(AncestorType::ExportFromDeclarationSource);
|
||||
walk_string_literal(
|
||||
traverser,
|
||||
(node as *mut u8).add(ancestor::OFFSET_EXPORT_FROM_DECLARATION_SOURCE)
|
||||
as *mut StringLiteral,
|
||||
ctx,
|
||||
);
|
||||
if let Some(field) = &mut *((node as *mut u8)
|
||||
.add(ancestor::OFFSET_EXPORT_NAMED_DECLARATION_WITH_CLAUSE)
|
||||
.add(ancestor::OFFSET_EXPORT_FROM_DECLARATION_WITH_CLAUSE)
|
||||
as *mut Option<ArenaBox<WithClause>>)
|
||||
{
|
||||
ctx.retag_stack(AncestorType::ExportNamedDeclarationWithClause);
|
||||
ctx.retag_stack(AncestorType::ExportFromDeclarationWithClause);
|
||||
walk_with_clause(traverser, (&mut **field) as *mut _, ctx);
|
||||
}
|
||||
ctx.pop_stack(pop_token);
|
||||
traverser.exit_export_named_declaration(&mut *node, ctx);
|
||||
traverser.exit_export_from_declaration(&mut *node, ctx);
|
||||
}
|
||||
|
||||
unsafe fn walk_export_default_declaration<'a, Tr: Traverse<'a>>(
|
||||
|
||||
@@ -72,7 +72,7 @@ impl<'a> PeepholeOptimizations {
|
||||
for ancestor in ctx.ancestors() {
|
||||
match ancestor {
|
||||
Ancestor::VariableDeclarationDeclarations(_)
|
||||
| Ancestor::ExportNamedDeclarationDeclaration(_) => {}
|
||||
| Ancestor::ExportDeclarationDeclaration(_) => {}
|
||||
Ancestor::ProgramBody(_) | Ancestor::FunctionBodyStatements(_) => return true,
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
@@ -69,14 +69,14 @@ impl<'a> PeepholeOptimizations {
|
||||
match stmt {
|
||||
Statement::EmptyStatement(_)
|
||||
| Statement::ImportDeclaration(_)
|
||||
| Statement::ExportAllDeclaration(_) => true,
|
||||
| Statement::ExportAllDeclaration(_)
|
||||
| Statement::ExportNamedDeclaration(_)
|
||||
| Statement::ExportFromDeclaration(_) => true,
|
||||
// `export { foo }`, `export { foo } from './x'`, `export type T = …` —
|
||||
// no executable code at the statement itself. The cyclic-eval hazard
|
||||
// from a `from` source is gated separately at program scope (see
|
||||
// `enter_program`).
|
||||
Statement::ExportNamedDeclaration(e) => {
|
||||
e.declaration.as_ref().is_none_or(Self::is_declarative_declaration)
|
||||
}
|
||||
Statement::ExportDeclaration(e) => Self::is_declarative_declaration(&e.declaration),
|
||||
// `export default function() {}` is hoisted; `export default <expr>`
|
||||
// or `export default class C extends … {}` runs user code.
|
||||
Statement::ExportDefaultDeclaration(e) => {
|
||||
|
||||
@@ -82,6 +82,14 @@ impl<'a> Traverse<'a> for Normalize {
|
||||
symbol_liveness::register_named_export(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_export_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
symbol_liveness::register_export_declaration(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_export_default_declaration(
|
||||
&mut self,
|
||||
node: &mut ExportDefaultDeclaration<'a>,
|
||||
|
||||
@@ -490,21 +490,23 @@ pub fn register_using_declaration(
|
||||
liveness.mark_bound_names(declaration);
|
||||
}
|
||||
|
||||
/// Normalize hook: record runtime bindings exposed by a named export.
|
||||
pub fn register_named_export(declaration: &ExportNamedDeclaration<'_>, ctx: &mut TraverseCtx<'_>) {
|
||||
let TraverseCtx { state, scoping, .. } = ctx;
|
||||
/// Normalize hook: record runtime bindings exposed by an exported declaration.
|
||||
pub fn register_export_declaration(declaration: &ExportDeclaration<'_>, ctx: &mut TraverseCtx<'_>) {
|
||||
let TraverseCtx { state, .. } = ctx;
|
||||
let Some(liveness) = state.symbols.liveness_mut() else { return };
|
||||
|
||||
if !declaration.export_kind.is_type()
|
||||
&& let Some(inner) = &declaration.declaration
|
||||
{
|
||||
liveness.mark_bound_names(inner);
|
||||
if !declaration.export_kind().is_type() {
|
||||
liveness.mark_bound_names(&declaration.declaration);
|
||||
}
|
||||
}
|
||||
|
||||
if declaration.source.is_some() || declaration.export_kind.is_type() {
|
||||
/// Normalize hook: record runtime bindings exposed by a local named export.
|
||||
pub fn register_named_export(declaration: &ExportNamedDeclaration<'_>, ctx: &mut TraverseCtx<'_>) {
|
||||
if declaration.export_kind.is_type() {
|
||||
return;
|
||||
}
|
||||
|
||||
let TraverseCtx { state, scoping, .. } = ctx;
|
||||
let Some(liveness) = state.symbols.liveness_mut() else { return };
|
||||
for specifier in &declaration.specifiers {
|
||||
if specifier.export_kind.is_type() {
|
||||
continue;
|
||||
|
||||
@@ -626,7 +626,7 @@ impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
Statement::TSModuleDeclaration(it) => self.visit_ts_module_declaration(it),
|
||||
Statement::TSGlobalDeclaration(it) => self.visit_ts_global_declaration(it),
|
||||
Statement::ExportDefaultDeclaration(it) => self.visit_export_default_declaration(it),
|
||||
Statement::ExportNamedDeclaration(it) => self.visit_export_named_declaration(it),
|
||||
Statement::ExportDeclaration(it) => self.visit_export_declaration(it),
|
||||
Statement::TSExportAssignment(it) => self.visit_ts_export_assignment(it),
|
||||
_ => {
|
||||
// Remaining variants do not contain scopes:
|
||||
@@ -637,6 +637,8 @@ impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
// `TSImportEqualsDeclaration`
|
||||
// `ImportDeclaration`
|
||||
// `ExportAllDeclaration`
|
||||
// `ExportNamedDeclaration`
|
||||
// `ExportFromDeclaration`
|
||||
// `TSNamespaceExportDeclaration`
|
||||
}
|
||||
}
|
||||
@@ -1125,14 +1127,14 @@ impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
ModuleDeclaration::ExportDefaultDeclaration(it) => {
|
||||
self.visit_export_default_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(it) => {
|
||||
self.visit_export_named_declaration(it)
|
||||
}
|
||||
ModuleDeclaration::ExportDeclaration(it) => self.visit_export_declaration(it),
|
||||
ModuleDeclaration::TSExportAssignment(it) => self.visit_ts_export_assignment(it),
|
||||
_ => {
|
||||
// Remaining variants do not contain scopes:
|
||||
// `ImportDeclaration`
|
||||
// `ExportAllDeclaration`
|
||||
// `ExportNamedDeclaration`
|
||||
// `ExportFromDeclaration`
|
||||
// `TSNamespaceExportDeclaration`
|
||||
}
|
||||
}
|
||||
@@ -1199,10 +1201,18 @@ impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_export_declaration(&mut self, it: &ExportDeclaration<'a>) {
|
||||
self.visit_declaration(&it.declaration);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_export_named_declaration(&mut self, it: &ExportNamedDeclaration<'a>) {
|
||||
if let Some(declaration) = &it.declaration {
|
||||
self.visit_declaration(declaration);
|
||||
}
|
||||
// Struct does not contain a scope. Halt traversal.
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_export_from_declaration(&mut self, it: &ExportFromDeclaration<'a>) {
|
||||
// Struct does not contain a scope. Halt traversal.
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -460,20 +460,15 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
// being created. It's an export not an import.
|
||||
let stmt = self.parse_import_declaration(import_span, false);
|
||||
if stmt.is_declaration() {
|
||||
let export_named_decl = ExportNamedDeclaration::boxed(
|
||||
let export_decl = ExportDeclaration::boxed(
|
||||
self.end_span(span),
|
||||
Some(stmt.into_declaration()),
|
||||
[],
|
||||
None,
|
||||
ImportOrExportKind::Value,
|
||||
None,
|
||||
stmt.into_declaration(),
|
||||
self,
|
||||
);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder
|
||||
.visit_export_named_declaration(&export_named_decl);
|
||||
self.module_record_builder.visit_export_declaration(&export_decl);
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(export_named_decl)
|
||||
ModuleDeclaration::ExportDeclaration(export_decl)
|
||||
} else {
|
||||
return self.fatal_error(diagnostics::unexpected_export(stmt.span()));
|
||||
}
|
||||
@@ -490,19 +485,11 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
let modifiers = self.parse_modifiers(false, false);
|
||||
let class_decl = self.parse_class_declaration(class_span, &modifiers, decorators);
|
||||
let decl = Declaration::ClassDeclaration(class_decl);
|
||||
let export_named_decl = ExportNamedDeclaration::boxed(
|
||||
self.end_span(span),
|
||||
Some(decl),
|
||||
[],
|
||||
None,
|
||||
ImportOrExportKind::Value,
|
||||
None,
|
||||
self,
|
||||
);
|
||||
let export_decl = ExportDeclaration::boxed(self.end_span(span), decl, self);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder.visit_export_named_declaration(&export_named_decl);
|
||||
self.module_record_builder.visit_export_declaration(&export_decl);
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(export_named_decl)
|
||||
ModuleDeclaration::ExportDeclaration(export_decl)
|
||||
}
|
||||
Kind::Eq if self.is_ts => ModuleDeclaration::TSExportAssignment(
|
||||
self.parse_ts_export_assignment_declaration(span),
|
||||
@@ -519,23 +506,19 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
Kind::Star => {
|
||||
ModuleDeclaration::ExportAllDeclaration(self.parse_export_all_declaration(span))
|
||||
}
|
||||
Kind::LCurly => {
|
||||
ModuleDeclaration::ExportNamedDeclaration(self.parse_export_named_specifiers(span))
|
||||
}
|
||||
Kind::LCurly => self.parse_export_named_specifiers(span),
|
||||
Kind::Type if self.is_ts => {
|
||||
let next_kind = self.lexer.peek_token().kind();
|
||||
|
||||
match next_kind {
|
||||
// `export type { ...`
|
||||
Kind::LCurly => ModuleDeclaration::ExportNamedDeclaration(
|
||||
self.parse_export_named_specifiers(span),
|
||||
),
|
||||
Kind::LCurly => self.parse_export_named_specifiers(span),
|
||||
// `export type * as ...`
|
||||
Kind::Star => ModuleDeclaration::ExportAllDeclaration(
|
||||
self.parse_export_all_declaration(span),
|
||||
),
|
||||
_ => ModuleDeclaration::ExportNamedDeclaration(
|
||||
self.parse_export_named_declaration(span, decorators),
|
||||
_ => ModuleDeclaration::ExportDeclaration(
|
||||
self.parse_exported_declaration(span, decorators),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -547,8 +530,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
)));
|
||||
self.bump_any();
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(
|
||||
self.parse_export_named_declaration(span, decorators),
|
||||
ModuleDeclaration::ExportDeclaration(
|
||||
self.parse_exported_declaration(span, decorators),
|
||||
)
|
||||
}
|
||||
};
|
||||
@@ -566,10 +549,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
// ExportSpecifier :
|
||||
// ModuleExportName
|
||||
// ModuleExportName as ModuleExportName
|
||||
fn parse_export_named_specifiers(
|
||||
&mut self,
|
||||
span: u32,
|
||||
) -> ArenaBox<'a, ExportNamedDeclaration<'a>> {
|
||||
fn parse_export_named_specifiers(&mut self, span: u32) -> ModuleDeclaration<'a> {
|
||||
let export_kind = self.parse_import_or_export_kind();
|
||||
let opening_span = self.cur_token().span();
|
||||
self.expect(Kind::LCurly);
|
||||
@@ -625,27 +605,35 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
|
||||
self.asi();
|
||||
let span = self.end_span(span);
|
||||
let export_named_decl = ExportNamedDeclaration::boxed(
|
||||
span,
|
||||
None,
|
||||
specifiers,
|
||||
source,
|
||||
export_kind,
|
||||
with_clause,
|
||||
self,
|
||||
);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder.visit_export_named_declaration(&export_named_decl);
|
||||
if let Some(source) = source {
|
||||
let export_from_decl = ExportFromDeclaration::boxed(
|
||||
span,
|
||||
specifiers,
|
||||
source,
|
||||
export_kind,
|
||||
with_clause,
|
||||
self,
|
||||
);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder.visit_export_from_declaration(&export_from_decl);
|
||||
}
|
||||
ModuleDeclaration::ExportFromDeclaration(export_from_decl)
|
||||
} else {
|
||||
let export_named_decl =
|
||||
ExportNamedDeclaration::boxed(span, specifiers, export_kind, self);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder.visit_export_named_declaration(&export_named_decl);
|
||||
}
|
||||
ModuleDeclaration::ExportNamedDeclaration(export_named_decl)
|
||||
}
|
||||
export_named_decl
|
||||
}
|
||||
|
||||
// export Declaration
|
||||
fn parse_export_named_declaration(
|
||||
fn parse_exported_declaration(
|
||||
&mut self,
|
||||
span: u32,
|
||||
decorators: ArenaVec<'a, Decorator<'a>>,
|
||||
) -> ArenaBox<'a, ExportNamedDeclaration<'a>> {
|
||||
) -> ArenaBox<'a, ExportDeclaration<'a>> {
|
||||
let decl_span = self.start_span();
|
||||
let reserved_ctx = self.ctx;
|
||||
let modifiers =
|
||||
@@ -653,25 +641,12 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
self.ctx = self.ctx.union_ambient_if(modifiers.contains_declare());
|
||||
|
||||
let declaration = self.parse_declaration(decl_span, &modifiers, decorators);
|
||||
let export_kind = if declaration.declare() || declaration.is_type() {
|
||||
ImportOrExportKind::Type
|
||||
} else {
|
||||
ImportOrExportKind::Value
|
||||
};
|
||||
self.ctx = reserved_ctx;
|
||||
let export_named_decl = ExportNamedDeclaration::boxed(
|
||||
self.end_span(span),
|
||||
Some(declaration),
|
||||
[],
|
||||
None,
|
||||
export_kind,
|
||||
None,
|
||||
self,
|
||||
);
|
||||
let export_decl = ExportDeclaration::boxed(self.end_span(span), declaration, self);
|
||||
if self.ctx.has_top_level() {
|
||||
self.module_record_builder.visit_export_named_declaration(&export_named_decl);
|
||||
self.module_record_builder.visit_export_declaration(&export_decl);
|
||||
}
|
||||
export_named_decl
|
||||
export_decl
|
||||
}
|
||||
|
||||
// export default HoistableDeclaration[~Yield, +Await, +Default]
|
||||
|
||||
@@ -228,11 +228,11 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Statement::ExportNamedDeclaration(decl) => match &mut decl.declaration {
|
||||
Some(Declaration::FunctionDeclaration(func)) => {
|
||||
Statement::ExportDeclaration(decl) => match &mut decl.declaration {
|
||||
Declaration::FunctionDeclaration(func) => {
|
||||
func.pure = true;
|
||||
}
|
||||
Some(Declaration::VariableDeclaration(var_decl)) if var_decl.kind.is_const() => {
|
||||
Declaration::VariableDeclaration(var_decl) if var_decl.kind.is_const() => {
|
||||
if let Some(Some(expr)) = var_decl.declarations.first_mut().map(|d| &mut d.init)
|
||||
{
|
||||
Self::set_pure_on_function_expr(expr);
|
||||
|
||||
@@ -314,67 +314,79 @@ impl<'a> ModuleRecordBuilder<'a> {
|
||||
self.module_record.has_module_syntax = true;
|
||||
}
|
||||
|
||||
pub fn visit_export_declaration(&mut self, decl: &ExportDeclaration<'a>) {
|
||||
let export_kind = decl.export_kind();
|
||||
let declaration = &decl.declaration;
|
||||
iter_binding_identifiers_of_declaration(declaration, &mut |ident| {
|
||||
let export_name = ExportExportName::Name(NameSpan::new(ident.name.into(), ident.span));
|
||||
let local_name = ExportLocalName::Name(NameSpan::new(ident.name.into(), ident.span));
|
||||
let export_entry = ExportEntry {
|
||||
statement_span: decl.span,
|
||||
span: declaration.span(),
|
||||
module_request: None,
|
||||
import_name: ExportImportName::Null,
|
||||
export_name,
|
||||
local_name,
|
||||
is_type: export_kind.is_type(),
|
||||
};
|
||||
self.add_export_entry(export_entry);
|
||||
self.add_export_binding(ident.name.into(), ident.span);
|
||||
});
|
||||
self.module_record.has_module_syntax = true;
|
||||
}
|
||||
|
||||
pub fn visit_export_named_declaration(&mut self, decl: &ExportNamedDeclaration<'a>) {
|
||||
let module_request =
|
||||
decl.source.as_ref().map(|source| NameSpan::new(source.value, source.span));
|
||||
|
||||
if let Some(module_request) = &module_request {
|
||||
self.add_module_request(
|
||||
module_request.name,
|
||||
RequestedModule {
|
||||
statement_span: decl.span,
|
||||
span: module_request.span,
|
||||
is_type: decl.export_kind.is_type(),
|
||||
is_import: false,
|
||||
},
|
||||
);
|
||||
for specifier in &decl.specifiers {
|
||||
let export_name = ExportExportName::Name(NameSpan::new(
|
||||
specifier.exported.name(),
|
||||
specifier.exported.span(),
|
||||
));
|
||||
let export_entry = ExportEntry {
|
||||
statement_span: decl.span,
|
||||
span: specifier.span,
|
||||
module_request: None,
|
||||
import_name: ExportImportName::Null,
|
||||
export_name,
|
||||
local_name: ExportLocalName::Name(NameSpan::new(
|
||||
specifier.local.name(),
|
||||
specifier.local.span(),
|
||||
)),
|
||||
is_type: specifier.export_kind.is_type() || decl.export_kind.is_type(),
|
||||
};
|
||||
self.add_export_entry(export_entry);
|
||||
self.add_export_binding(specifier.exported.name(), specifier.exported.span());
|
||||
}
|
||||
self.module_record.has_module_syntax = true;
|
||||
}
|
||||
|
||||
if let Some(d) = &decl.declaration {
|
||||
iter_binding_identifiers_of_declaration(d, &mut |ident| {
|
||||
let export_name =
|
||||
ExportExportName::Name(NameSpan::new(ident.name.into(), ident.span));
|
||||
let local_name =
|
||||
ExportLocalName::Name(NameSpan::new(ident.name.into(), ident.span));
|
||||
let export_entry = ExportEntry {
|
||||
statement_span: decl.span,
|
||||
span: d.span(),
|
||||
module_request: module_request.clone(),
|
||||
import_name: ExportImportName::Null,
|
||||
export_name,
|
||||
local_name,
|
||||
is_type: decl.export_kind.is_type(),
|
||||
};
|
||||
self.add_export_entry(export_entry);
|
||||
self.add_export_binding(ident.name.into(), ident.span);
|
||||
});
|
||||
}
|
||||
pub fn visit_export_from_declaration(&mut self, decl: &ExportFromDeclaration<'a>) {
|
||||
let module_request = NameSpan::new(decl.source.value, decl.source.span);
|
||||
self.add_module_request(
|
||||
module_request.name,
|
||||
RequestedModule {
|
||||
statement_span: decl.span,
|
||||
span: module_request.span,
|
||||
is_type: decl.export_kind.is_type(),
|
||||
is_import: false,
|
||||
},
|
||||
);
|
||||
|
||||
for specifier in &decl.specifiers {
|
||||
let export_name = ExportExportName::Name(NameSpan::new(
|
||||
specifier.exported.name(),
|
||||
specifier.exported.span(),
|
||||
));
|
||||
let import_name = if module_request.is_some() {
|
||||
ExportImportName::Name(NameSpan::new(
|
||||
specifier.local.name(),
|
||||
specifier.local.span(),
|
||||
))
|
||||
} else {
|
||||
ExportImportName::Null
|
||||
};
|
||||
let local_name = if module_request.is_some() {
|
||||
ExportLocalName::Null
|
||||
} else {
|
||||
ExportLocalName::Name(NameSpan::new(specifier.local.name(), specifier.local.span()))
|
||||
};
|
||||
let import_name = ExportImportName::Name(NameSpan::new(
|
||||
specifier.local.name(),
|
||||
specifier.local.span(),
|
||||
));
|
||||
let export_entry = ExportEntry {
|
||||
statement_span: decl.span,
|
||||
span: specifier.span,
|
||||
module_request: module_request.clone(),
|
||||
module_request: Some(module_request.clone()),
|
||||
import_name,
|
||||
export_name,
|
||||
local_name,
|
||||
local_name: ExportLocalName::Null,
|
||||
is_type: specifier.export_kind.is_type() || decl.export_kind.is_type(),
|
||||
};
|
||||
self.add_export_entry(export_entry);
|
||||
|
||||
@@ -448,14 +448,14 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
// `export { ... } from "..."` (re-export from a module). A bare `export { ... }`
|
||||
// with no module source re-exports locals and is allowed in a namespace.
|
||||
Statement::ExportNamedDeclaration(decl) if decl.source.is_some() => {
|
||||
Statement::ExportFromDeclaration(decl) => {
|
||||
self.error(diagnostics::export_in_namespace(decl.span));
|
||||
}
|
||||
// `export import x = require("...")` is wrapped in an export declaration.
|
||||
Statement::ExportNamedDeclaration(decl)
|
||||
Statement::ExportDeclaration(decl)
|
||||
if matches!(
|
||||
&decl.declaration,
|
||||
Some(Declaration::TSImportEqualsDeclaration(import_decl))
|
||||
Declaration::TSImportEqualsDeclaration(import_decl)
|
||||
if import_decl.module_reference.is_external()
|
||||
) =>
|
||||
{
|
||||
|
||||
@@ -1459,10 +1459,8 @@ impl<'a, 'b, 'ast> DiscoveryWalker<'a, 'b, 'ast> {
|
||||
self.walk_expression(&node.object);
|
||||
self.walk_statement(&node.body);
|
||||
}
|
||||
Statement::ExportNamedDeclaration(node) => {
|
||||
if let Some(decl) = &node.declaration {
|
||||
self.walk_declaration(decl);
|
||||
}
|
||||
Statement::ExportDeclaration(node) => {
|
||||
self.walk_declaration(&node.declaration);
|
||||
}
|
||||
Statement::ExportDefaultDeclaration(node) => {
|
||||
self.walk_export_default(&node.declaration);
|
||||
@@ -2289,8 +2287,8 @@ impl<'a> OxcVisitor<'a, '_> {
|
||||
Statement::FunctionDeclaration(f) if f.scope_id.get() == Some(scope_id) => {
|
||||
Some(f.id.as_ref().map(|id| id.name))
|
||||
}
|
||||
Statement::ExportNamedDeclaration(e) => match &e.declaration {
|
||||
Some(Declaration::FunctionDeclaration(f)) if f.scope_id.get() == Some(scope_id) => {
|
||||
Statement::ExportDeclaration(e) => match &e.declaration {
|
||||
Declaration::FunctionDeclaration(f) if f.scope_id.get() == Some(scope_id) => {
|
||||
Some(f.id.as_ref().map(|id| id.name))
|
||||
}
|
||||
_ => None,
|
||||
@@ -2299,22 +2297,14 @@ impl<'a> OxcVisitor<'a, '_> {
|
||||
};
|
||||
if let Some(name) = replace_name {
|
||||
let name = name.as_deref().unwrap_or("anonymous");
|
||||
let is_export = matches!(stmt, Statement::ExportNamedDeclaration(_));
|
||||
let is_export = matches!(stmt, Statement::ExportDeclaration(_));
|
||||
let const_decl = ox_build_gated_const_decl(ast, gating_expression, name);
|
||||
if is_export {
|
||||
let decl = match const_decl {
|
||||
Statement::VariableDeclaration(d) => Declaration::VariableDeclaration(d),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
*stmt = Statement::new_export_named_declaration(
|
||||
SPAN,
|
||||
Some(decl),
|
||||
[],
|
||||
None,
|
||||
ImportOrExportKind::Value,
|
||||
None,
|
||||
ast,
|
||||
);
|
||||
*stmt = Statement::new_export_declaration(SPAN, decl, ast);
|
||||
} else {
|
||||
*stmt = const_decl;
|
||||
}
|
||||
@@ -2655,8 +2645,8 @@ fn ox_insert_outlined_after<'a>(
|
||||
let is_target = |f: &Function<'a>| -> bool { f.scope_id.get() == Some(scope_id) };
|
||||
match stmt {
|
||||
Statement::FunctionDeclaration(f) => is_target(f),
|
||||
Statement::ExportNamedDeclaration(e) => {
|
||||
matches!(&e.declaration, Some(Declaration::FunctionDeclaration(f)) if is_target(f))
|
||||
Statement::ExportDeclaration(e) => {
|
||||
matches!(&e.declaration, Declaration::FunctionDeclaration(f) if is_target(f))
|
||||
}
|
||||
Statement::ExportDefaultDeclaration(e) => {
|
||||
matches!(&e.declaration, ExportDefaultDeclarationKind::FunctionDeclaration(f) if is_target(f))
|
||||
|
||||
@@ -6298,7 +6298,9 @@ fn lower_statement<'a>(
|
||||
)?;
|
||||
}
|
||||
oxc::Statement::ImportDeclaration(_)
|
||||
| oxc::Statement::ExportDeclaration(_)
|
||||
| oxc::Statement::ExportNamedDeclaration(_)
|
||||
| oxc::Statement::ExportFromDeclaration(_)
|
||||
| oxc::Statement::ExportDefaultDeclaration(_)
|
||||
| oxc::Statement::ExportAllDeclaration(_) => {
|
||||
builder.record_error(
|
||||
|
||||
Loaded 100 of 146 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user