Skip to content

Commit e555f30

Browse files
authored
feat(core): properly extract declaration names in module parser (#156)
1 parent c398ac1 commit e555f30

File tree

1 file changed

+123
-9
lines changed

1 file changed

+123
-9
lines changed

core/src/module/mod.rs

Lines changed: 123 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,16 +1506,10 @@ impl ModuleVisitor {
15061506
source_name: None,
15071507
});
15081508
}
1509-
} else if let Some(_declaration) = &decl.declaration {
1509+
} else if let Some(declaration) = &decl.declaration {
15101510
// export const/let/var/function/class declarations
1511-
// For now, we'll mark these as generic exports
1512-
// TODO: extract the actual names
1513-
self.exports.push(ModuleExport {
1514-
name: Some("declaration".to_owned()),
1515-
is_reexport: false,
1516-
source_module: None,
1517-
source_name: None,
1518-
});
1511+
// Extract the actual names from the declaration
1512+
self.extract_declaration_names(declaration);
15191513
}
15201514
}
15211515
}
@@ -1529,4 +1523,124 @@ impl ModuleVisitor {
15291523
ast::ModuleExportName::StringLiteral(lit) => lit.value.as_str().to_owned(),
15301524
}
15311525
}
1526+
1527+
/// Extract export names from declaration AST nodes
1528+
fn extract_declaration_names(&mut self, declaration: &ast::Declaration) {
1529+
match declaration {
1530+
ast::Declaration::VariableDeclaration(var_decl) => {
1531+
// Handle: export const x = 1, y = 2;
1532+
for declarator in &var_decl.declarations {
1533+
self.extract_binding_names(&declarator.id.kind);
1534+
}
1535+
}
1536+
ast::Declaration::FunctionDeclaration(func) => {
1537+
// Handle: export function foo() {}
1538+
if let Some(id) = &func.id {
1539+
self.exports.push(ModuleExport {
1540+
name: Some(id.name.as_str().to_owned()),
1541+
is_reexport: false,
1542+
source_module: None,
1543+
source_name: None,
1544+
});
1545+
}
1546+
}
1547+
ast::Declaration::ClassDeclaration(class) => {
1548+
// Handle: export class Foo {}
1549+
if let Some(id) = &class.id {
1550+
self.exports.push(ModuleExport {
1551+
name: Some(id.name.as_str().to_owned()),
1552+
is_reexport: false,
1553+
source_module: None,
1554+
source_name: None,
1555+
});
1556+
}
1557+
}
1558+
ast::Declaration::TSTypeAliasDeclaration(type_alias) => {
1559+
// Handle: export type Foo = string;
1560+
self.exports.push(ModuleExport {
1561+
name: Some(type_alias.id.name.as_str().to_owned()),
1562+
is_reexport: false,
1563+
source_module: None,
1564+
source_name: None,
1565+
});
1566+
}
1567+
ast::Declaration::TSInterfaceDeclaration(interface) => {
1568+
// Handle: export interface Foo {}
1569+
self.exports.push(ModuleExport {
1570+
name: Some(interface.id.name.as_str().to_owned()),
1571+
is_reexport: false,
1572+
source_module: None,
1573+
source_name: None,
1574+
});
1575+
}
1576+
ast::Declaration::TSEnumDeclaration(enum_decl) => {
1577+
// Handle: export enum Foo {}
1578+
self.exports.push(ModuleExport {
1579+
name: Some(enum_decl.id.name.as_str().to_owned()),
1580+
is_reexport: false,
1581+
source_module: None,
1582+
source_name: None,
1583+
});
1584+
}
1585+
ast::Declaration::TSModuleDeclaration(module_decl) => {
1586+
// Handle: export namespace Foo {} or export module Foo {}
1587+
if let ast::TSModuleDeclarationName::Identifier(id) = &module_decl.id {
1588+
self.exports.push(ModuleExport {
1589+
name: Some(id.name.as_str().to_owned()),
1590+
is_reexport: false,
1591+
source_module: None,
1592+
source_name: None,
1593+
});
1594+
}
1595+
}
1596+
ast::Declaration::TSImportEqualsDeclaration(import_equals) => {
1597+
// Handle: export import Foo = require('foo');
1598+
self.exports.push(ModuleExport {
1599+
name: Some(import_equals.id.name.as_str().to_owned()),
1600+
is_reexport: false,
1601+
source_module: None,
1602+
source_name: None,
1603+
});
1604+
}
1605+
}
1606+
}
1607+
1608+
/// Extract names from binding patterns (handles destructuring)
1609+
fn extract_binding_names(&mut self, binding: &ast::BindingPatternKind) {
1610+
match binding {
1611+
ast::BindingPatternKind::BindingIdentifier(id) => {
1612+
// Simple binding: const x = 1
1613+
self.exports.push(ModuleExport {
1614+
name: Some(id.name.as_str().to_owned()),
1615+
is_reexport: false,
1616+
source_module: None,
1617+
source_name: None,
1618+
});
1619+
}
1620+
ast::BindingPatternKind::ObjectPattern(obj_pattern) => {
1621+
// Object destructuring: const { x, y } = obj
1622+
for property in &obj_pattern.properties {
1623+
self.extract_binding_names(&property.value.kind);
1624+
}
1625+
// Handle rest: const { ...rest } = obj
1626+
if let Some(rest) = &obj_pattern.rest {
1627+
self.extract_binding_names(&rest.argument.kind);
1628+
}
1629+
}
1630+
ast::BindingPatternKind::ArrayPattern(arr_pattern) => {
1631+
// Array destructuring: const [x, y] = arr
1632+
for element in arr_pattern.elements.iter().flatten() {
1633+
self.extract_binding_names(&element.kind);
1634+
}
1635+
// Handle rest: const [...rest] = arr
1636+
if let Some(rest) = &arr_pattern.rest {
1637+
self.extract_binding_names(&rest.argument.kind);
1638+
}
1639+
}
1640+
ast::BindingPatternKind::AssignmentPattern(assignment) => {
1641+
// Default values: const { x = 5 } = obj
1642+
self.extract_binding_names(&assignment.left.kind);
1643+
}
1644+
}
1645+
}
15321646
}

0 commit comments

Comments
 (0)