TypeScript_Rust_Compiler/
semantic.rs1use crate::ast::*;
4use crate::error::Result;
5use std::collections::HashMap;
6
7pub struct SemanticAnalyzer {
9 symbols: HashMap<String, SymbolInfo>,
11 current_scope: Vec<String>,
13}
14
15#[derive(Debug, Clone)]
17pub struct SymbolInfo {
18 pub name: String,
19 pub symbol_type: SymbolType,
20 pub scope: Vec<String>,
21 pub defined_at: usize,
22}
23
24#[derive(Debug, Clone)]
26pub enum SymbolType {
27 Variable(Type),
28 Function(FunctionSignature),
29 Class(ClassSignature),
30 Interface(InterfaceSignature),
31 Type(Type),
32 Enum(EnumSignature),
33}
34
35#[derive(Debug, Clone)]
37pub struct FunctionSignature {
38 pub name: String,
39 pub parameters: Vec<Parameter>,
40 pub return_type: Type,
41 pub type_parameters: Vec<TypeParameter>,
42}
43
44#[derive(Debug, Clone)]
46pub struct ClassSignature {
47 pub name: String,
48 pub extends: Option<Type>,
49 pub implements: Vec<Type>,
50 pub type_parameters: Vec<TypeParameter>,
51}
52
53#[derive(Debug, Clone)]
55pub struct InterfaceSignature {
56 pub name: String,
57 pub extends: Vec<Type>,
58 pub type_parameters: Vec<TypeParameter>,
59}
60
61#[derive(Debug, Clone)]
63pub struct EnumSignature {
64 pub name: String,
65 pub members: Vec<String>,
66}
67
68impl SemanticAnalyzer {
69 pub fn new() -> Self {
71 Self {
72 symbols: HashMap::new(),
73 current_scope: Vec::new(),
74 }
75 }
76
77 pub fn analyze(&mut self, program: &Program) -> Result<()> {
79 for statement in &program.statements {
80 self.analyze_statement(statement)?;
81 }
82 Ok(())
83 }
84
85 fn analyze_statement(&mut self, statement: &Statement) -> Result<()> {
87 match statement {
88 Statement::VariableDeclaration(var) => {
89 self.analyze_variable_declaration(var)?;
90 }
91 Statement::FunctionDeclaration(func) => {
92 self.analyze_function_declaration(func)?;
93 }
94 Statement::ClassDeclaration(class) => {
95 self.analyze_class_declaration(class)?;
96 }
97 Statement::InterfaceDeclaration(interface) => {
98 self.analyze_interface_declaration(interface)?;
99 }
100 Statement::TypeAlias(type_alias) => {
101 self.analyze_type_alias(type_alias)?;
102 }
103 Statement::EnumDeclaration(enum_decl) => {
104 self.analyze_enum_declaration(enum_decl)?;
105 }
106 Statement::BlockStatement(block) => {
107 self.enter_scope();
108 for stmt in &block.statements {
109 self.analyze_statement(stmt)?;
110 }
111 self.exit_scope();
112 }
113 _ => {
114 }
116 }
117 Ok(())
118 }
119
120 fn analyze_variable_declaration(&mut self, var: &VariableDeclaration) -> Result<()> {
122 let symbol_type = if let Some(ref t) = var.type_annotation {
123 SymbolType::Variable(t.clone())
124 } else {
125 let inferred_type = if let Some(ref init) = var.initializer {
127 self.infer_type_from_expression(init)?
128 } else {
129 Type::Any
130 };
131 SymbolType::Variable(inferred_type)
132 };
133
134 let symbol_info = SymbolInfo {
135 name: var.name.clone(),
136 symbol_type,
137 scope: self.current_scope.clone(),
138 defined_at: 0, };
140
141 self.symbols.insert(var.name.clone(), symbol_info);
142 Ok(())
143 }
144
145 fn analyze_function_declaration(&mut self, func: &FunctionDeclaration) -> Result<()> {
147 let signature = FunctionSignature {
148 name: func.name.clone(),
149 parameters: func.parameters.clone(),
150 return_type: func.return_type.clone().unwrap_or(Type::Void),
151 type_parameters: func.type_parameters.clone(),
152 };
153
154 let symbol_info = SymbolInfo {
155 name: func.name.clone(),
156 symbol_type: SymbolType::Function(signature),
157 scope: self.current_scope.clone(),
158 defined_at: 0, };
160
161 self.symbols.insert(func.name.clone(), symbol_info);
162
163 self.enter_scope();
165 self.analyze_statement(&func.body)?;
166 self.exit_scope();
167
168 Ok(())
169 }
170
171 fn analyze_class_declaration(&mut self, class: &ClassDeclaration) -> Result<()> {
173 let signature = ClassSignature {
174 name: class.name.clone(),
175 extends: class.extends.clone(),
176 implements: class.implements.clone(),
177 type_parameters: class.type_parameters.clone(),
178 };
179
180 let symbol_info = SymbolInfo {
181 name: class.name.clone(),
182 symbol_type: SymbolType::Class(signature),
183 scope: self.current_scope.clone(),
184 defined_at: 0, };
186
187 self.symbols.insert(class.name.clone(), symbol_info);
188
189 self.enter_scope();
191 for member in &class.body.members {
192 self.analyze_class_member(member)?;
193 }
194 self.exit_scope();
195
196 Ok(())
197 }
198
199 fn analyze_interface_declaration(&mut self, interface: &InterfaceDeclaration) -> Result<()> {
201 let signature = InterfaceSignature {
202 name: interface.name.clone(),
203 extends: interface.extends.clone(),
204 type_parameters: interface.type_parameters.clone(),
205 };
206
207 let symbol_info = SymbolInfo {
208 name: interface.name.clone(),
209 symbol_type: SymbolType::Interface(signature),
210 scope: self.current_scope.clone(),
211 defined_at: 0, };
213
214 self.symbols.insert(interface.name.clone(), symbol_info);
215 Ok(())
216 }
217
218 fn analyze_type_alias(&mut self, type_alias: &TypeAlias) -> Result<()> {
220 let symbol_info = SymbolInfo {
221 name: type_alias.name.clone(),
222 symbol_type: SymbolType::Type(type_alias.type_definition.clone()),
223 scope: self.current_scope.clone(),
224 defined_at: 0, };
226
227 self.symbols.insert(type_alias.name.clone(), symbol_info);
228 Ok(())
229 }
230
231 fn analyze_enum_declaration(&mut self, enum_decl: &EnumDeclaration) -> Result<()> {
233 let members: Vec<String> = enum_decl.members.iter().map(|m| m.name.clone()).collect();
234 let signature = EnumSignature {
235 name: enum_decl.name.clone(),
236 members,
237 };
238
239 let symbol_info = SymbolInfo {
240 name: enum_decl.name.clone(),
241 symbol_type: SymbolType::Enum(signature),
242 scope: self.current_scope.clone(),
243 defined_at: 0, };
245
246 self.symbols.insert(enum_decl.name.clone(), symbol_info);
247 Ok(())
248 }
249
250 fn analyze_class_member(&mut self, member: &ClassMember) -> Result<()> {
252 match member {
253 ClassMember::Property(_prop) => {
254 }
256 ClassMember::Method(_method) => {
257 }
259 _ => {
260 }
262 }
263 Ok(())
264 }
265
266 fn infer_type_from_expression(&self, expression: &Expression) -> Result<Type> {
268 match expression {
269 Expression::Literal(literal) => self.infer_type_from_literal(literal),
270 Expression::Identifier(ident) => {
271 if let Some(symbol) = self.symbols.get(ident) {
272 match &symbol.symbol_type {
273 SymbolType::Variable(t) => Ok(t.clone()),
274 _ => Ok(Type::Any),
275 }
276 } else {
277 Ok(Type::Any)
278 }
279 }
280 _ => Ok(Type::Any),
281 }
282 }
283
284 fn infer_type_from_literal(&self, literal: &Literal) -> Result<Type> {
286 match literal {
287 Literal::String(_) => Ok(Type::String),
288 Literal::Number(_) => Ok(Type::Number),
289 Literal::Boolean(_) => Ok(Type::Boolean),
290 Literal::Null => Ok(Type::Null),
291 Literal::Undefined => Ok(Type::Undefined),
292 _ => Ok(Type::Any),
293 }
294 }
295
296 fn enter_scope(&mut self) {
298 self.current_scope.push("block".to_string());
299 }
300
301 fn exit_scope(&mut self) {
303 self.current_scope.pop();
304 }
305
306 pub fn get_symbol(&self, name: &str) -> Option<&SymbolInfo> {
308 self.symbols.get(name)
309 }
310
311 pub fn get_all_symbols(&self) -> &HashMap<String, SymbolInfo> {
313 &self.symbols
314 }
315}
316
317impl Default for SemanticAnalyzer {
318 fn default() -> Self {
319 Self::new()
320 }
321}