mirror of
https://github.com/RustPython/Parser.git
synced 2025-08-02 09:52:34 +00:00
Introduce symtable test and add is_annotation for symbol
This commit is contained in:
parent
f6e25fc0cb
commit
66731121ab
1 changed files with 38 additions and 4 deletions
|
@ -97,10 +97,13 @@ pub struct Symbol {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
// pub table: SymbolTableRef,
|
// pub table: SymbolTableRef,
|
||||||
pub scope: SymbolScope,
|
pub scope: SymbolScope,
|
||||||
|
// TODO(lynskylate@gmail.com): Use bitflags replace
|
||||||
pub is_referenced: bool,
|
pub is_referenced: bool,
|
||||||
pub is_assigned: bool,
|
pub is_assigned: bool,
|
||||||
pub is_parameter: bool,
|
pub is_parameter: bool,
|
||||||
pub is_free: 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
|
// 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.
|
// this is required to correct the scope in the analysis.
|
||||||
|
@ -121,6 +124,8 @@ impl Symbol {
|
||||||
is_assigned: false,
|
is_assigned: false,
|
||||||
is_parameter: false,
|
is_parameter: false,
|
||||||
is_free: false,
|
is_free: false,
|
||||||
|
is_annotated: false,
|
||||||
|
is_imported: false,
|
||||||
is_assign_namedexpr_in_comprehension: false,
|
is_assign_namedexpr_in_comprehension: false,
|
||||||
is_iter: false,
|
is_iter: false,
|
||||||
}
|
}
|
||||||
|
@ -276,6 +281,11 @@ impl<'a> SymbolTableAnalyzer<'a> {
|
||||||
fn analyze_unknown_symbol(&self, symbol: &mut Symbol) {
|
fn analyze_unknown_symbol(&self, symbol: &mut Symbol) {
|
||||||
if symbol.is_assigned || symbol.is_parameter {
|
if symbol.is_assigned || symbol.is_parameter {
|
||||||
symbol.scope = SymbolScope::Local;
|
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 {
|
} else {
|
||||||
// Interesting stuff about the __class__ variable:
|
// Interesting stuff about the __class__ variable:
|
||||||
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
|
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
|
||||||
|
@ -394,7 +404,10 @@ enum SymbolUsage {
|
||||||
Nonlocal,
|
Nonlocal,
|
||||||
Used,
|
Used,
|
||||||
Assigned,
|
Assigned,
|
||||||
|
Imported,
|
||||||
|
AnnotationAssigned,
|
||||||
Parameter,
|
Parameter,
|
||||||
|
AnnotationParameter,
|
||||||
AssignedNamedExprInCompr,
|
AssignedNamedExprInCompr,
|
||||||
Iter,
|
Iter,
|
||||||
}
|
}
|
||||||
|
@ -460,8 +473,12 @@ impl SymbolTableBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult {
|
fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult {
|
||||||
|
if let Some(_annotation) = ¶meter.annotation {
|
||||||
|
self.register_name(¶meter.arg, SymbolUsage::AnnotationParameter)
|
||||||
|
} else {
|
||||||
self.register_name(¶meter.arg, SymbolUsage::Parameter)
|
self.register_name(¶meter.arg, SymbolUsage::Parameter)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult {
|
fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult {
|
||||||
for parameter in parameters {
|
for parameter in parameters {
|
||||||
|
@ -564,12 +581,12 @@ impl SymbolTableBuilder {
|
||||||
for name in names {
|
for name in names {
|
||||||
if let Some(alias) = &name.alias {
|
if let Some(alias) = &name.alias {
|
||||||
// `import mymodule as myalias`
|
// `import mymodule as myalias`
|
||||||
self.register_name(alias, SymbolUsage::Assigned)?;
|
self.register_name(alias, SymbolUsage::Imported)?;
|
||||||
} else {
|
} else {
|
||||||
// `import module`
|
// `import module`
|
||||||
self.register_name(
|
self.register_name(
|
||||||
name.symbol.split('.').next().unwrap(),
|
name.symbol.split('.').next().unwrap(),
|
||||||
SymbolUsage::Assigned,
|
SymbolUsage::Imported,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -601,7 +618,12 @@ impl SymbolTableBuilder {
|
||||||
annotation,
|
annotation,
|
||||||
value,
|
value,
|
||||||
} => {
|
} => {
|
||||||
|
// 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(target, &ExpressionContext::Store)?;
|
||||||
|
}
|
||||||
self.scan_expression(annotation, &ExpressionContext::Load)?;
|
self.scan_expression(annotation, &ExpressionContext::Load)?;
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
self.scan_expression(value, &ExpressionContext::Load)?;
|
self.scan_expression(value, &ExpressionContext::Load)?;
|
||||||
|
@ -984,9 +1006,21 @@ impl SymbolTableBuilder {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SymbolUsage::Imported => {
|
||||||
|
symbol.is_assigned = true;
|
||||||
|
symbol.is_imported = true;
|
||||||
|
}
|
||||||
SymbolUsage::Parameter => {
|
SymbolUsage::Parameter => {
|
||||||
symbol.is_parameter = true;
|
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 => {
|
SymbolUsage::Assigned => {
|
||||||
symbol.is_assigned = true;
|
symbol.is_assigned = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue