From 971737f641f3fb7696b58e6b8761c3c10b9a9c5f Mon Sep 17 00:00:00 2001 From: Glyphack Date: Mon, 30 Oct 2023 19:12:09 +0100 Subject: [PATCH] Add type alias node to semantic analyzer --- typechecker/src/nodes.rs | 2 + typechecker/src/semantic_analyzer.rs | 16 ++- typechecker/src/symbol_table.rs | 10 ++ typechecker/src/type_check/type_evaluator.rs | 3 +- .../inputs/symbol_table/type_alias.py | 19 +-- ...ld__tests__symbol_table@type_alias.py.snap | 125 ++++++++++++++++++ 6 files changed, 153 insertions(+), 22 deletions(-) create mode 100644 typechecker/testdata/output/enderpy_python_type_checker__build__tests__symbol_table@type_alias.py.snap diff --git a/typechecker/src/nodes.rs b/typechecker/src/nodes.rs index 99a6fc6e..ae7842af 100755 --- a/typechecker/src/nodes.rs +++ b/typechecker/src/nodes.rs @@ -337,4 +337,6 @@ impl<'a> TraversalVisitor for EnderpyFile { fn visit_global(&mut self, _g: &parser::ast::Global) {} fn visit_nonlocal(&mut self, _n: &parser::ast::Nonlocal) {} + + fn visit_type_alias(&mut self, _t: &parser::ast::TypeAlias) {} } diff --git a/typechecker/src/semantic_analyzer.rs b/typechecker/src/semantic_analyzer.rs index d5f228d2..81ca722d 100644 --- a/typechecker/src/semantic_analyzer.rs +++ b/typechecker/src/semantic_analyzer.rs @@ -13,7 +13,7 @@ use crate::{ }, symbol_table::{ Alias, Class, Declaration, DeclarationPath, Function, Paramter, SymbolScope, SymbolTable, - SymbolTableNode, SymbolTableScope, SymbolTableType, Variable, + SymbolTableNode, SymbolTableScope, SymbolTableType, Variable, TypeAlias, }, }; @@ -465,8 +465,18 @@ impl TraversalVisitor for SemanticAnalyzer { self.create_symbol(f.name.clone(), function_declaration); } - fn visit_type_alias(&mut self, _t: &parser::ast::TypeAlias) { - todo!() + fn visit_type_alias(&mut self, t: &parser::ast::TypeAlias) { + let declaration_path = DeclarationPath { + module_name: self.file.module_name().clone(), + node: t.node, + }; + self.create_symbol( + t.name.clone(), + Declaration::TypeAlias(TypeAlias { + declaration_path, + type_alias_node: t.clone(), + } + )); } fn visit_async_function_def(&mut self, _f: &parser::ast::AsyncFunctionDef) {} diff --git a/typechecker/src/symbol_table.rs b/typechecker/src/symbol_table.rs index 07c930ba..cd847a46 100644 --- a/typechecker/src/symbol_table.rs +++ b/typechecker/src/symbol_table.rs @@ -65,6 +65,8 @@ pub enum Declaration { // TypeParameterDeclaration represents a type parameter in a generic class or function. // It models type parameters declared on classes and functions like T in List[T]. TypeParameter(Box), + + TypeAlias(TypeAlias), } impl Declaration { @@ -76,6 +78,7 @@ impl Declaration { Declaration::Parameter(p) => &p.declaration_path, Declaration::Alias(a) => &a.declaration_path, Declaration::TypeParameter(t) => &t.declaration_path, + Declaration::TypeAlias(t) => &t.declaration_path, } } } @@ -142,6 +145,12 @@ pub struct Alias { pub import_result: ImportResult, } +#[derive(Debug, Clone)] +pub struct TypeAlias { + pub declaration_path: DeclarationPath, + pub type_alias_node: ast::TypeAlias, +} + #[derive(Debug, Clone, Copy)] pub enum SymbolScope { Global, @@ -299,6 +308,7 @@ impl std::fmt::Display for Declaration { Declaration::Parameter(p) => write!(f, "{:#?}", p), Declaration::Alias(a) => write!(f, "{:#?}", a), Declaration::TypeParameter(t) => write!(f, "{:#?}", t), + Declaration::TypeAlias(t) => write!(f, "{:#?}", t), } } } diff --git a/typechecker/src/type_check/type_evaluator.rs b/typechecker/src/type_check/type_evaluator.rs index 680b5b93..693f667e 100755 --- a/typechecker/src/type_check/type_evaluator.rs +++ b/typechecker/src/type_check/type_evaluator.rs @@ -44,7 +44,7 @@ impl TypeEvaluator { match decl { Some(decl) => self.get_type_from_declaration(decl), None => Ok(PythonType::Unknown), - } + } } pub fn get_type(&self, expr: &ast::Expression) -> Result { match expr { @@ -226,6 +226,7 @@ impl TypeEvaluator { Declaration::Parameter(_) => Ok(PythonType::Unknown), Declaration::Alias(_) => Ok(PythonType::Unknown), Declaration::TypeParameter(_) => Ok(PythonType::Unknown), + Declaration::TypeAlias(_) => Ok(PythonType::Unknown), } } diff --git a/typechecker/test_data/inputs/symbol_table/type_alias.py b/typechecker/test_data/inputs/symbol_table/type_alias.py index b3afe658..c9272b36 100644 --- a/typechecker/test_data/inputs/symbol_table/type_alias.py +++ b/typechecker/test_data/inputs/symbol_table/type_alias.py @@ -1,24 +1,7 @@ # Show me some examples of type aliasing in Python try to give examples for all -# 1. Type aliasing for built-in types -# 2. Type aliasing for user-defined types -# 3. Type aliasing for generic types -# 4. Type aliasing for generic types with type parameters -# 5. Type aliasing for generic types with type parameters and constraints -# 6. Type aliasing for generic types with type parameters and constraints and default values -# 7. Type aliasing for generic types with type parameters and constraints and default values and type parameters -# 8. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints -# 9. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values -# 10. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values and type parameters -# 11. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values and type parameters and constraints -# 12. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values and type parameters and constraints and default values -# 13. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values and type parameters and constraints and default values and type parameters -# 14. Type aliasing for generic types with type parameters and constraints and default values and type parameters and constraints and default values and type parameters and constraints and default values and type parameters and constraints - type Alias1 = int type Alias2 = str type Alias3 = float -type AliasWithParams1[T] = T -type AliasWithParams2[T] = T - +type AliasToAnotherAlias = Alias1 diff --git a/typechecker/testdata/output/enderpy_python_type_checker__build__tests__symbol_table@type_alias.py.snap b/typechecker/testdata/output/enderpy_python_type_checker__build__tests__symbol_table@type_alias.py.snap new file mode 100644 index 00000000..4a0ca4d6 --- /dev/null +++ b/typechecker/testdata/output/enderpy_python_type_checker__build__tests__symbol_table@type_alias.py.snap @@ -0,0 +1,125 @@ +--- +source: typechecker/src/build.rs +description: "# Show me some examples of type aliasing in Python try to give examples for all\n\ntype Alias1 = int\ntype Alias2 = str\ntype Alias3 = float\n\ntype AliasToAnotherAlias = Alias1\n" +expression: result +input_file: typechecker/test_data/inputs/symbol_table/type_alias.py +--- +------------------- +global scope: +Symbols: +Alias1 +- Declarations: +--: TypeAlias { + declaration_path: DeclarationPath { + module_name: [REDACTED]", + node: Node { + start: 81, + end: 98, + }, + }, + type_alias_node: TypeAlias { + node: Node { + start: 81, + end: 98, + }, + name: "Alias1", + type_params: [], + value: Name( + Name { + node: Node { + start: 95, + end: 98, + }, + id: "int", + }, + ), + }, +} +Alias2 +- Declarations: +--: TypeAlias { + declaration_path: DeclarationPath { + module_name: [REDACTED]", + node: Node { + start: 99, + end: 116, + }, + }, + type_alias_node: TypeAlias { + node: Node { + start: 99, + end: 116, + }, + name: "Alias2", + type_params: [], + value: Name( + Name { + node: Node { + start: 113, + end: 116, + }, + id: "str", + }, + ), + }, +} +Alias3 +- Declarations: +--: TypeAlias { + declaration_path: DeclarationPath { + module_name: [REDACTED]", + node: Node { + start: 117, + end: 136, + }, + }, + type_alias_node: TypeAlias { + node: Node { + start: 117, + end: 136, + }, + name: "Alias3", + type_params: [], + value: Name( + Name { + node: Node { + start: 131, + end: 136, + }, + id: "float", + }, + ), + }, +} +AliasToAnotherAlias +- Declarations: +--: TypeAlias { + declaration_path: DeclarationPath { + module_name: [REDACTED]", + node: Node { + start: 138, + end: 171, + }, + }, + type_alias_node: TypeAlias { + node: Node { + start: 138, + end: 171, + }, + name: "AliasToAnotherAlias", + type_params: [], + value: Name( + Name { + node: Node { + start: 165, + end: 171, + }, + id: "Alias1", + }, + ), + }, +} + +all scopes: +------------------- +