TypeScript_Rust_Compiler/
semantic.rs

1//! Semantic analysis for TypeScript code
2
3use crate::ast::*;
4use crate::error::Result;
5use std::collections::HashMap;
6
7/// Semantic analyzer for TypeScript code
8pub struct SemanticAnalyzer {
9    /// Symbol table for variables and functions
10    symbols: HashMap<String, SymbolInfo>,
11    /// Current scope
12    current_scope: Vec<String>,
13}
14
15/// Information about a symbol
16#[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/// Type of symbol
25#[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/// Function signature
36#[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/// Class signature
45#[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/// Interface signature
54#[derive(Debug, Clone)]
55pub struct InterfaceSignature {
56    pub name: String,
57    pub extends: Vec<Type>,
58    pub type_parameters: Vec<TypeParameter>,
59}
60
61/// Enum signature
62#[derive(Debug, Clone)]
63pub struct EnumSignature {
64    pub name: String,
65    pub members: Vec<String>,
66}
67
68impl SemanticAnalyzer {
69    /// Create a new semantic analyzer
70    pub fn new() -> Self {
71        Self {
72            symbols: HashMap::new(),
73            current_scope: Vec::new(),
74        }
75    }
76
77    /// Analyze a program
78    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    /// Analyze a statement
86    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                // Handle other statement types
115            }
116        }
117        Ok(())
118    }
119
120    /// Analyze variable declaration
121    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            // Infer type from initializer
126            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, // TODO: Get actual position
139        };
140
141        self.symbols.insert(var.name.clone(), symbol_info);
142        Ok(())
143    }
144
145    /// Analyze function declaration
146    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, // TODO: Get actual position
159        };
160
161        self.symbols.insert(func.name.clone(), symbol_info);
162
163        // Analyze function body
164        self.enter_scope();
165        self.analyze_statement(&func.body)?;
166        self.exit_scope();
167
168        Ok(())
169    }
170
171    /// Analyze class declaration
172    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, // TODO: Get actual position
185        };
186
187        self.symbols.insert(class.name.clone(), symbol_info);
188
189        // Analyze class body
190        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    /// Analyze interface declaration
200    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, // TODO: Get actual position
212        };
213
214        self.symbols.insert(interface.name.clone(), symbol_info);
215        Ok(())
216    }
217
218    /// Analyze type alias
219    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, // TODO: Get actual position
225        };
226
227        self.symbols.insert(type_alias.name.clone(), symbol_info);
228        Ok(())
229    }
230
231    /// Analyze enum declaration
232    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, // TODO: Get actual position
244        };
245
246        self.symbols.insert(enum_decl.name.clone(), symbol_info);
247        Ok(())
248    }
249
250    /// Analyze class member
251    fn analyze_class_member(&mut self, member: &ClassMember) -> Result<()> {
252        match member {
253            ClassMember::Property(_prop) => {
254                // Analyze property
255            }
256            ClassMember::Method(_method) => {
257                // Analyze method
258            }
259            _ => {
260                // Handle other member types
261            }
262        }
263        Ok(())
264    }
265
266    /// Infer type from expression
267    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    /// Infer type from literal
285    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    /// Enter a new scope
297    fn enter_scope(&mut self) {
298        self.current_scope.push("block".to_string());
299    }
300
301    /// Exit current scope
302    fn exit_scope(&mut self) {
303        self.current_scope.pop();
304    }
305
306    /// Get symbol information
307    pub fn get_symbol(&self, name: &str) -> Option<&SymbolInfo> {
308        self.symbols.get(name)
309    }
310
311    /// Get all symbols
312    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}