ts_gen/parse/first_pass/
mod.rs1use oxc_ast::ast;
8
9use crate::ir;
10use crate::parse::scope::ScopeId;
11
12mod collect;
13pub mod converters;
14mod populate;
15
16pub use collect::collect_type_names;
18pub use populate::populate_declarations;
19
20pub fn is_module(program: &ast::Program<'_>) -> bool {
29 program.body.iter().any(|stmt| {
30 matches!(
31 stmt,
32 ast::Statement::ImportDeclaration(_)
33 | ast::Statement::ExportAllDeclaration(_)
34 | ast::Statement::ExportDefaultDeclaration(_)
35 | ast::Statement::ExportNamedDeclaration(_)
36 | ast::Statement::TSExportAssignment(_)
37 )
38 })
39}
40
41fn is_string_literal_union(ts_type: &ast::TSType<'_>) -> bool {
44 match ts_type {
45 ast::TSType::TSUnionType(union) => union.types.iter().all(|t| {
46 matches!(
47 t,
48 ast::TSType::TSLiteralType(lit) if matches!(&lit.literal, ast::TSLiteral::StringLiteral(_))
49 )
50 }),
51 ast::TSType::TSLiteralType(lit) => matches!(&lit.literal, ast::TSLiteral::StringLiteral(_)),
52 _ => false,
53 }
54}
55
56fn register_type(
57 name: &str,
58 kind: ir::RegisteredKind,
59 ctx: &ir::ModuleContext,
60 registry: &mut ir::TypeRegistry,
61 gctx: &mut crate::context::GlobalContext,
62 scope: ScopeId,
63 exported: bool,
64) {
65 registry.types.insert(
66 name.to_string(),
67 ir::TypeInfo {
68 kind: kind.clone(),
69 primary_context: ctx.clone(),
70 },
71 );
72
73 let name_str = name.to_string();
75 let placeholder_kind = match kind {
76 ir::RegisteredKind::Class | ir::RegisteredKind::MergedClassLike => {
77 ir::TypeKind::Class(ir::ClassDecl {
78 name: name_str.clone(),
79 js_name: name_str.clone(),
80 type_params: vec![],
81 extends: None,
82 implements: vec![],
83 is_abstract: false,
84 members: vec![],
85 type_module_context: ctx.clone(),
86 })
87 }
88 ir::RegisteredKind::Interface => ir::TypeKind::Interface(ir::InterfaceDecl {
89 name: name_str.clone(),
90 js_name: name_str.clone(),
91 type_params: vec![],
92 extends: vec![],
93 members: vec![],
94 classification: ir::InterfaceClassification::Unclassified,
95 }),
96 ir::RegisteredKind::StringEnum => ir::TypeKind::StringEnum(ir::StringEnumDecl {
97 name: name_str.clone(),
98 variants: vec![],
99 }),
100 ir::RegisteredKind::NumericEnum => ir::TypeKind::NumericEnum(ir::NumericEnumDecl {
101 name: name_str.clone(),
102 variants: vec![],
103 }),
104 ir::RegisteredKind::TypeAlias => ir::TypeKind::TypeAlias(ir::TypeAliasDecl {
105 name: name_str.clone(),
106 type_params: vec![],
107 target: ir::TypeRef::Any,
108 from_module: None,
109 }),
110 ir::RegisteredKind::Function => ir::TypeKind::Function(ir::FunctionDecl {
111 name: name_str.clone(),
112 js_name: name_str.clone(),
113 type_params: vec![],
114 params: vec![],
115 return_type: ir::TypeRef::Any,
116 overloads: vec![],
117 }),
118 ir::RegisteredKind::Variable => ir::TypeKind::Variable(ir::VariableDecl {
119 name: name_str.clone(),
120 js_name: name_str.clone(),
121 type_ref: ir::TypeRef::Any,
122 is_const: false,
123 }),
124 ir::RegisteredKind::Namespace => {
125 let ns_scope = gctx.scopes.create_child(scope);
126 ir::TypeKind::Namespace(ir::NamespaceDecl {
127 name: name_str.clone(),
128 declarations: vec![],
129 child_scope: ns_scope,
130 })
131 }
132 };
133
134 let type_id = gctx.insert_type(ir::TypeDeclaration {
135 kind: placeholder_kind,
136 module_context: ctx.clone(),
137 doc: None,
138 scope_id: scope,
139 exported,
140 });
141 gctx.scopes.insert(scope, name_str, type_id);
142}
143
144fn register_import(
146 local_name: &str,
147 original_name: &str,
148 from_module: &str,
149 gctx: &mut crate::context::GlobalContext,
150 scope: ScopeId,
151) {
152 gctx.pending_imports
153 .push(crate::parse::scope::PendingImport {
154 scope,
155 local_name: local_name.to_string(),
156 from_module: from_module.to_string(),
157 original_name: original_name.to_string(),
158 });
159}