From dc4acdf19e740aa9fd9ba4857a8e618a1643db32 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Tue, 21 Jul 2020 00:47:22 -0500 Subject: [PATCH 1/5] Update itertools --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d968cb1..6846c43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] indexmap = "1.0" -itertools = "0.8.0" +itertools = "0.9" rustpython-bytecode = { path = "../bytecode", version = "0.1.1" } rustpython-parser = { path = "../parser", version = "0.1.1" } num-complex = { version = "0.2", features = ["serde"] } From 66731121ab3af0f44e290e2ffc25613267dcc076 Mon Sep 17 00:00:00 2001 From: lynskylate Date: Fri, 31 Jul 2020 02:11:00 +0800 Subject: [PATCH 2/5] Introduce symtable test and add is_annotation for symbol --- src/symboltable.rs | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/symboltable.rs b/src/symboltable.rs index 5714367..f2f0aab 100644 --- a/src/symboltable.rs +++ b/src/symboltable.rs @@ -97,10 +97,13 @@ pub struct Symbol { pub name: String, // pub table: SymbolTableRef, pub scope: SymbolScope, + // TODO(lynskylate@gmail.com): Use bitflags replace pub is_referenced: bool, pub is_assigned: bool, pub is_parameter: bool, pub is_free: bool, + pub is_annotated: bool, + pub is_imported: bool, // indicates if the symbol gets a value assigned by a named expression in a comprehension // this is required to correct the scope in the analysis. @@ -121,6 +124,8 @@ impl Symbol { is_assigned: false, is_parameter: false, is_free: false, + is_annotated: false, + is_imported: false, is_assign_namedexpr_in_comprehension: false, is_iter: false, } @@ -276,6 +281,11 @@ impl<'a> SymbolTableAnalyzer<'a> { fn analyze_unknown_symbol(&self, symbol: &mut Symbol) { if symbol.is_assigned || symbol.is_parameter { symbol.scope = SymbolScope::Local; + } else if !symbol.is_assigned && symbol.is_referenced { + // if symbol is referenced in its block, but not assigned to. + // https://docs.python.org/3/library/symtable.html?highlight=symtable#symtable.Symbol.is_free + symbol.scope = SymbolScope::Unknown; + symbol.is_free = true; } else { // Interesting stuff about the __class__ variable: // https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object @@ -394,7 +404,10 @@ enum SymbolUsage { Nonlocal, Used, Assigned, + Imported, + AnnotationAssigned, Parameter, + AnnotationParameter, AssignedNamedExprInCompr, Iter, } @@ -460,7 +473,11 @@ impl SymbolTableBuilder { } fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult { - self.register_name(¶meter.arg, SymbolUsage::Parameter) + if let Some(_annotation) = ¶meter.annotation { + self.register_name(¶meter.arg, SymbolUsage::AnnotationParameter) + } else { + self.register_name(¶meter.arg, SymbolUsage::Parameter) + } } fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult { @@ -564,12 +581,12 @@ impl SymbolTableBuilder { for name in names { if let Some(alias) = &name.alias { // `import mymodule as myalias` - self.register_name(alias, SymbolUsage::Assigned)?; + self.register_name(alias, SymbolUsage::Imported)?; } else { // `import module` self.register_name( name.symbol.split('.').next().unwrap(), - SymbolUsage::Assigned, + SymbolUsage::Imported, )?; } } @@ -601,7 +618,12 @@ impl SymbolTableBuilder { annotation, value, } => { - self.scan_expression(target, &ExpressionContext::Store)?; + // https://github.com/python/cpython/blob/master/Python/symtable.c#L1233 + if let ast::ExpressionType::Identifier { ref name } = target.node { + self.register_name(name, SymbolUsage::AnnotationAssigned)?; + } else { + self.scan_expression(target, &ExpressionContext::Store)?; + } self.scan_expression(annotation, &ExpressionContext::Load)?; if let Some(value) = value { self.scan_expression(value, &ExpressionContext::Load)?; @@ -984,9 +1006,21 @@ impl SymbolTableBuilder { }); } } + SymbolUsage::Imported => { + symbol.is_assigned = true; + symbol.is_imported = true; + } SymbolUsage::Parameter => { symbol.is_parameter = true; } + SymbolUsage::AnnotationParameter => { + symbol.is_parameter = true; + symbol.is_annotated = true; + } + SymbolUsage::AnnotationAssigned => { + symbol.is_assigned = true; + symbol.is_annotated = true; + } SymbolUsage::Assigned => { symbol.is_assigned = true; } From 70eeb2874891d0d8efdae454dc497e5c7027cccf Mon Sep 17 00:00:00 2001 From: Yiqun Ling Date: Sat, 1 Aug 2020 01:29:11 +0800 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Jeong YunWon --- src/symboltable.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/symboltable.rs b/src/symboltable.rs index f2f0aab..811fd48 100644 --- a/src/symboltable.rs +++ b/src/symboltable.rs @@ -473,11 +473,12 @@ impl SymbolTableBuilder { } fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult { - if let Some(_annotation) = ¶meter.annotation { - self.register_name(¶meter.arg, SymbolUsage::AnnotationParameter) + let usage = if parameter.annotation.is_some() { + SymbolUsage::AnnotationParamater } else { - self.register_name(¶meter.arg, SymbolUsage::Parameter) - } + SymbolUsage::Parameter + }; + self.regsiter_name(¶meter.arg, usage) } fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult { From dcca6624329b991889d8f82497dcb224c578c131 Mon Sep 17 00:00:00 2001 From: lynskylate Date: Sat, 1 Aug 2020 02:05:44 +0800 Subject: [PATCH 4/5] Optimize code --- src/symboltable.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/symboltable.rs b/src/symboltable.rs index 811fd48..79e0b2b 100644 --- a/src/symboltable.rs +++ b/src/symboltable.rs @@ -97,7 +97,7 @@ pub struct Symbol { pub name: String, // pub table: SymbolTableRef, pub scope: SymbolScope, - // TODO(lynskylate@gmail.com): Use bitflags replace + // TODO: Use bitflags replace pub is_referenced: bool, pub is_assigned: bool, pub is_parameter: bool, @@ -474,11 +474,11 @@ impl SymbolTableBuilder { fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult { let usage = if parameter.annotation.is_some() { - SymbolUsage::AnnotationParamater + SymbolUsage::AnnotationParameter } else { SymbolUsage::Parameter }; - self.regsiter_name(¶meter.arg, usage) + self.register_name(¶meter.arg, usage) } fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult { From 32232811fb57febcbada51b7effaea0441a4d9d5 Mon Sep 17 00:00:00 2001 From: lynskylate Date: Sun, 2 Aug 2020 03:43:19 +0800 Subject: [PATCH 5/5] Fix scope change --- src/symboltable.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/symboltable.rs b/src/symboltable.rs index 79e0b2b..e8b80f0 100644 --- a/src/symboltable.rs +++ b/src/symboltable.rs @@ -281,11 +281,6 @@ impl<'a> SymbolTableAnalyzer<'a> { fn analyze_unknown_symbol(&self, symbol: &mut Symbol) { if symbol.is_assigned || symbol.is_parameter { symbol.scope = SymbolScope::Local; - } else if !symbol.is_assigned && symbol.is_referenced { - // if symbol is referenced in its block, but not assigned to. - // https://docs.python.org/3/library/symtable.html?highlight=symtable#symtable.Symbol.is_free - symbol.scope = SymbolScope::Unknown; - symbol.is_free = true; } else { // Interesting stuff about the __class__ variable: // https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object