Move range to each Node (#4969)

This commit is contained in:
Jeong, YunWon authored and GitHub committed 2023-05-15 17:00:23 +09:00
1 parent 7a6000d181
commit f5fc30ae63
7 files changed
+3731 -2805

No files matched your search

Generated
+8 -7
View File
@@ -1795,7 +1795,7 @@ dependencies = [
[[package]]
name = "ruff_source_location"
version = "0.0.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"memchr",
"once_cell",
@@ -1805,7 +1805,7 @@ dependencies = [
[[package]]
name = "ruff_text_size"
version = "0.0.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
[[package]]
name = "rustc-hash"
@@ -1863,12 +1863,13 @@ dependencies = [
[[package]]
name = "rustpython-ast"
version = "0.2.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"is-macro",
"num-bigint",
"rustpython-literal",
"rustpython-parser-core",
"static_assertions",
]
[[package]]
@@ -1971,7 +1972,7 @@ dependencies = [
[[package]]
name = "rustpython-format"
version = "0.2.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"bitflags 2.2.1",
"itertools",
@@ -1998,7 +1999,7 @@ dependencies = [
[[package]]
name = "rustpython-literal"
version = "0.2.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"hexf-parse",
"lexical-parse-float",
@@ -2009,7 +2010,7 @@ dependencies = [
[[package]]
name = "rustpython-parser"
version = "0.2.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"anyhow",
"itertools",
@@ -2031,7 +2032,7 @@ dependencies = [
[[package]]
name = "rustpython-parser-core"
version = "0.2.0"
source = "git+https://github.com/RustPython/Parser.git?rev=a983f4383fb1ad8c1c66acb1d5b0016e59f95a49#a983f4383fb1ad8c1c66acb1d5b0016e59f95a49"
source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=718354673eb2cc9645d63fc0c50b4ad08e5595c2#718354673eb2cc9645d63fc0c50b4ad08e5595c2"
dependencies = [
"ruff_source_location",
"ruff_text_size",
+10 -10
View File
@@ -29,16 +29,16 @@ rustpython-pylib = { path = "pylib" }
rustpython-stdlib = { path = "stdlib" }
rustpython-doc = { git = "https://github.com/RustPython/__doc__", branch = "main" }
rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "a983f4383fb1ad8c1c66acb1d5b0016e59f95a49" }
rustpython-parser-core = { git = "https://github.com/RustPython/Parser.git", rev = "a983f4383fb1ad8c1c66acb1d5b0016e59f95a49" }
rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "a983f4383fb1ad8c1c66acb1d5b0016e59f95a49" }
rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "a983f4383fb1ad8c1c66acb1d5b0016e59f95a49" }
rustpython-format = { git = "https://github.com/RustPython/Parser.git", rev = "a983f4383fb1ad8c1c66acb1d5b0016e59f95a49" }
#rustpython-literal = { path = "../RustPython-parser/literal" }
#rustpython-parser-core = { path = "../RustPython-parser/core" }
#rustpython-parser = { path = "../RustPython-parser/parser" }
#rustpython-ast = { path = "../RustPython-parser/ast" }
#rustpython-format = { path = "../RustPython-parser/format" }
rustpython-literal = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "718354673eb2cc9645d63fc0c50b4ad08e5595c2" }
rustpython-parser-core = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "718354673eb2cc9645d63fc0c50b4ad08e5595c2" }
rustpython-parser = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "718354673eb2cc9645d63fc0c50b4ad08e5595c2" }
rustpython-ast = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "718354673eb2cc9645d63fc0c50b4ad08e5595c2" }
rustpython-format = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "718354673eb2cc9645d63fc0c50b4ad08e5595c2" }
# rustpython-literal = { path = "../RustPython-parser/literal" }
# rustpython-parser-core = { path = "../RustPython-parser/core" }
# rustpython-parser = { path = "../RustPython-parser/parser" }
# rustpython-ast = { path = "../RustPython-parser/ast" }
# rustpython-format = { path = "../RustPython-parser/format" }
ahash = "0.7.6"
anyhow = "1.0.45"
File diff suppressed because it is too large. Load diff
+176 -99
View File
@@ -12,7 +12,7 @@ use crate::{
IndexMap,
};
use bitflags::bitflags;
use rustpython_ast as ast;
use rustpython_ast::{self as ast, located::Located};
use rustpython_parser_core::source_code::{LineNumber, SourceLocation};
use std::{borrow::Cow, fmt};
@@ -607,12 +607,12 @@ impl SymbolTableBuilder {
}
fn scan_parameter(&mut self, parameter: &ast::located::Arg) -> SymbolTableResult {
let usage = if parameter.node.annotation.is_some() {
let usage = if parameter.annotation.is_some() {
SymbolUsage::AnnotationParameter
} else {
SymbolUsage::Parameter
};
self.register_name(parameter.node.arg.as_str(), usage, parameter.location())
self.register_name(parameter.arg.as_str(), usage, parameter.location())
}
fn scan_parameters_annotations(
@@ -626,7 +626,7 @@ impl SymbolTableBuilder {
}
fn scan_parameter_annotation(&mut self, parameter: &ast::located::Arg) -> SymbolTableResult {
if let Some(annotation) = &parameter.node.annotation {
if let Some(annotation) = &parameter.annotation {
self.scan_annotation(annotation)?;
}
Ok(())
@@ -641,90 +641,96 @@ impl SymbolTableBuilder {
}
fn scan_statement(&mut self, statement: &ast::located::Stmt) -> SymbolTableResult {
use ast::{StmtKind::*, *};
let location = statement.location();
if let ImportFrom(StmtImportFrom { module, names, .. }) = &statement.node {
use ast::located::*;
if let Stmt::ImportFrom(StmtImportFrom { module, names, .. }) = &statement {
if module.as_ref().map(|id| id.as_str()) == Some("__future__") {
for feature in names {
if &feature.node.name == "annotations" {
if &feature.name == "annotations" {
self.future_annotations = true;
}
}
}
}
match &statement.node {
Global(StmtGlobal { names }) => {
match &statement {
Stmt::Global(StmtGlobal { names, range }) => {
for name in names {
self.register_name(name.as_str(), SymbolUsage::Global, location)?;
self.register_name(name.as_str(), SymbolUsage::Global, range.start)?;
}
}
Nonlocal(StmtNonlocal { names }) => {
Stmt::Nonlocal(StmtNonlocal { names, range }) => {
for name in names {
self.register_name(name.as_str(), SymbolUsage::Nonlocal, location)?;
self.register_name(name.as_str(), SymbolUsage::Nonlocal, range.start)?;
}
}
FunctionDef(StmtFunctionDef {
Stmt::FunctionDef(StmtFunctionDef {
name,
body,
args,
decorator_list,
returns,
range,
..
})
| AsyncFunctionDef(StmtAsyncFunctionDef {
| Stmt::AsyncFunctionDef(StmtAsyncFunctionDef {
name,
body,
args,
decorator_list,
returns,
range,
..
}) => {
self.scan_expressions(decorator_list, ExpressionContext::Load)?;
self.register_name(name.as_str(), SymbolUsage::Assigned, location)?;
self.register_name(name.as_str(), SymbolUsage::Assigned, range.start)?;
if let Some(expression) = returns {
self.scan_annotation(expression)?;
}
self.enter_function(name.as_str(), args, location.row)?;
self.enter_function(name.as_str(), args, range.start.row)?;
self.scan_statements(body)?;
self.leave_scope();
}
ClassDef(StmtClassDef {
Stmt::ClassDef(StmtClassDef {
name,
body,
bases,
keywords,
decorator_list,
range,
}) => {
self.enter_scope(name.as_str(), SymbolTableType::Class, location.row.get());
self.enter_scope(name.as_str(), SymbolTableType::Class, range.start.row.get());
let prev_class = std::mem::replace(&mut self.class_name, Some(name.to_string()));
self.register_name("__module__", SymbolUsage::Assigned, location)?;
self.register_name("__qualname__", SymbolUsage::Assigned, location)?;
self.register_name("__doc__", SymbolUsage::Assigned, location)?;
self.register_name("__class__", SymbolUsage::Assigned, location)?;
self.register_name("__module__", SymbolUsage::Assigned, range.start)?;
self.register_name("__qualname__", SymbolUsage::Assigned, range.start)?;
self.register_name("__doc__", SymbolUsage::Assigned, range.start)?;
self.register_name("__class__", SymbolUsage::Assigned, range.start)?;
self.scan_statements(body)?;
self.leave_scope();
self.class_name = prev_class;
self.scan_expressions(bases, ExpressionContext::Load)?;
for keyword in keywords {
self.scan_expression(&keyword.node.value, ExpressionContext::Load)?;
self.scan_expression(&keyword.value, ExpressionContext::Load)?;
}
self.scan_expressions(decorator_list, ExpressionContext::Load)?;
self.register_name(name.as_str(), SymbolUsage::Assigned, location)?;
self.register_name(name.as_str(), SymbolUsage::Assigned, range.start)?;
}
Expr(StmtExpr { value }) => self.scan_expression(value, ExpressionContext::Load)?,
If(StmtIf { test, body, orelse }) => {
Stmt::Expr(StmtExpr { value, .. }) => {
self.scan_expression(value, ExpressionContext::Load)?
}
Stmt::If(StmtIf {
test, body, orelse, ..
}) => {
self.scan_expression(test, ExpressionContext::Load)?;
self.scan_statements(body)?;
self.scan_statements(orelse)?;
}
For(StmtFor {
Stmt::For(StmtFor {
target,
iter,
body,
orelse,
..
})
| AsyncFor(StmtAsyncFor {
| Stmt::AsyncFor(StmtAsyncFor {
target,
iter,
body,
@@ -736,61 +742,69 @@ impl SymbolTableBuilder {
self.scan_statements(body)?;
self.scan_statements(orelse)?;
}
While(StmtWhile { test, body, orelse }) => {
Stmt::While(StmtWhile {
test, body, orelse, ..
}) => {
self.scan_expression(test, ExpressionContext::Load)?;
self.scan_statements(body)?;
self.scan_statements(orelse)?;
}
Break | Continue | Pass => {
Stmt::Break(_) | Stmt::Continue(_) | Stmt::Pass(_) => {
// No symbols here.
}
Import(StmtImport { names }) | ImportFrom(StmtImportFrom { names, .. }) => {
Stmt::Import(StmtImport { names, range })
| Stmt::ImportFrom(StmtImportFrom { names, range, .. }) => {
for name in names {
if let Some(alias) = &name.node.asname {
if let Some(alias) = &name.asname {
// `import my_module as my_alias`
self.register_name(alias.as_str(), SymbolUsage::Imported, location)?;
self.register_name(alias.as_str(), SymbolUsage::Imported, range.start)?;
} else {
// `import module`
self.register_name(
name.node.name.split('.').next().unwrap(),
name.name.split('.').next().unwrap(),
SymbolUsage::Imported,
location,
range.start,
)?;
}
}
}
Return(StmtReturn { value }) => {
Stmt::Return(StmtReturn { value, .. }) => {
if let Some(expression) = value {
self.scan_expression(expression, ExpressionContext::Load)?;
}
}
Assert(StmtAssert { test, msg }) => {
Stmt::Assert(StmtAssert { test, msg, .. }) => {
self.scan_expression(test, ExpressionContext::Load)?;
if let Some(expression) = msg {
self.scan_expression(expression, ExpressionContext::Load)?;
}
}
Delete(StmtDelete { targets }) => {
Stmt::Delete(StmtDelete { targets, .. }) => {
self.scan_expressions(targets, ExpressionContext::Delete)?;
}
Assign(StmtAssign { targets, value, .. }) => {
Stmt::Assign(StmtAssign { targets, value, .. }) => {
self.scan_expressions(targets, ExpressionContext::Store)?;
self.scan_expression(value, ExpressionContext::Load)?;
}
AugAssign(StmtAugAssign { target, value, .. }) => {
Stmt::AugAssign(StmtAugAssign { target, value, .. }) => {
self.scan_expression(target, ExpressionContext::Store)?;
self.scan_expression(value, ExpressionContext::Load)?;
}
AnnAssign(StmtAnnAssign {
Stmt::AnnAssign(StmtAnnAssign {
target,
annotation,
value,
simple,
range,
}) => {
// https://github.com/python/cpython/blob/main/Python/symtable.c#L1233
match &target.node {
ast::ExprKind::Name(ast::ExprName { id, .. }) if *simple => {
self.register_name(id.as_str(), SymbolUsage::AnnotationAssigned, location)?;
match &**target {
Expr::Name(ast::ExprName { id, .. }) if *simple => {
self.register_name(
id.as_str(),
SymbolUsage::AnnotationAssigned,
range.start,
)?;
}
_ => {
self.scan_expression(target, ExpressionContext::Store)?;
@@ -801,7 +815,8 @@ impl SymbolTableBuilder {
self.scan_expression(value, ExpressionContext::Load)?;
}
}
With(StmtWith { items, body, .. }) | AsyncWith(StmtAsyncWith { items, body, .. }) => {
Stmt::With(StmtWith { items, body, .. })
| Stmt::AsyncWith(StmtAsyncWith { items, body, .. }) => {
for item in items {
self.scan_expression(&item.context_expr, ExpressionContext::Load)?;
if let Some(expression) = &item.optional_vars {
@@ -810,43 +825,46 @@ impl SymbolTableBuilder {
}
self.scan_statements(body)?;
}
Try(StmtTry {
Stmt::Try(StmtTry {
body,
handlers,
orelse,
finalbody,
range,
})
| TryStar(StmtTryStar {
| Stmt::TryStar(StmtTryStar {
body,
handlers,
orelse,
finalbody,
range,
}) => {
self.scan_statements(body)?;
for handler in handlers {
let ast::ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler {
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
type_,
name,
body,
}) = &handler.node;
..
}) = &handler;
if let Some(expression) = type_ {
self.scan_expression(expression, ExpressionContext::Load)?;
}
if let Some(name) = name {
self.register_name(name.as_str(), SymbolUsage::Assigned, location)?;
self.register_name(name.as_str(), SymbolUsage::Assigned, range.start)?;
}
self.scan_statements(body)?;
}
self.scan_statements(orelse)?;
self.scan_statements(finalbody)?;
}
Match(StmtMatch { subject, cases: _ }) => {
Stmt::Match(StmtMatch { subject, .. }) => {
return Err(SymbolTableError {
error: "match expression is not implemented yet".to_owned(),
location: Some(subject.location()),
});
}
Raise(StmtRaise { exc, cause }) => {
Stmt::Raise(StmtRaise { exc, cause, .. }) => {
if let Some(expression) = exc {
self.scan_expression(expression, ExpressionContext::Load)?;
}
@@ -874,30 +892,50 @@ impl SymbolTableBuilder {
expression: &ast::located::Expr,
context: ExpressionContext,
) -> SymbolTableResult {
use ast::{ExprKind::*, *};
let location = expression.location();
match &expression.node {
BinOp(ExprBinOp { left, right, .. }) => {
use ast::located::*;
match expression {
Expr::BinOp(ExprBinOp {
left,
right,
range: _,
..
}) => {
self.scan_expression(left, context)?;
self.scan_expression(right, context)?;
}
BoolOp(ExprBoolOp { values, .. }) => {
Expr::BoolOp(ExprBoolOp {
values, range: _, ..
}) => {
self.scan_expressions(values, context)?;
}
Compare(ExprCompare {
left, comparators, ..
Expr::Compare(ExprCompare {
left,
comparators,
range: _,
..
}) => {
self.scan_expression(left, context)?;
self.scan_expressions(comparators, context)?;
}
Subscript(ExprSubscript { value, slice, .. }) => {
Expr::Subscript(ExprSubscript {
value,
slice,
range: _,
..
}) => {
self.scan_expression(value, ExpressionContext::Load)?;
self.scan_expression(slice, ExpressionContext::Load)?;
}
Attribute(ExprAttribute { value, .. }) => {
Expr::Attribute(ExprAttribute {
value, range: _, ..
}) => {
self.scan_expression(value, ExpressionContext::Load)?;
}
Dict(ExprDict { keys, values }) => {
Expr::Dict(ExprDict {
keys,
values,
range: _,
}) => {
for (key, value) in keys.iter().zip(values.iter()) {
if let Some(key) = key {
self.scan_expression(key, context)?;
@@ -905,30 +943,39 @@ impl SymbolTableBuilder {
self.scan_expression(value, context)?;
}
}
Await(ExprAwait { value }) => {
Expr::Await(ExprAwait { value, range: _ }) => {
self.scan_expression(value, context)?;
}
Yield(ExprYield { value }) => {
Expr::Yield(ExprYield { value, range: _ }) => {
if let Some(expression) = value {
self.scan_expression(expression, context)?;
}
}
YieldFrom(ExprYieldFrom { value }) => {
Expr::YieldFrom(ExprYieldFrom { value, range: _ }) => {
self.scan_expression(value, context)?;
}
UnaryOp(ExprUnaryOp { operand, .. }) => {
Expr::UnaryOp(ExprUnaryOp {
operand, range: _, ..
}) => {
self.scan_expression(operand, context)?;
}
Constant(ExprConstant { .. }) => {}
Starred(ExprStarred { value, .. }) => {
Expr::Constant(ExprConstant { range: _, .. }) => {}
Expr::Starred(ExprStarred {
value, range: _, ..
}) => {
self.scan_expression(value, context)?;
}
Tuple(ExprTuple { elts, .. })
| Set(ExprSet { elts, .. })
| List(ExprList { elts, .. }) => {
Expr::Tuple(ExprTuple { elts, range: _, .. })
| Expr::Set(ExprSet { elts, range: _, .. })
| Expr::List(ExprList { elts, range: _, .. }) => {
self.scan_expressions(elts, context)?;
}
Slice(ExprSlice { lower, upper, step }) => {
Expr::Slice(ExprSlice {
lower,
upper,
step,
range: _,
}) => {
if let Some(lower) = lower {
self.scan_expression(lower, context)?;
}
@@ -939,26 +986,40 @@ impl SymbolTableBuilder {
self.scan_expression(step, context)?;
}
}
GeneratorExp(ExprGeneratorExp { elt, generators }) => {
self.scan_comprehension("genexpr", elt, None, generators, location)?;
Expr::GeneratorExp(ExprGeneratorExp {
elt,
generators,
range,
}) => {
self.scan_comprehension("genexpr", elt, None, generators, range.start)?;
}
ListComp(ExprListComp { elt, generators }) => {
self.scan_comprehension("genexpr", elt, None, generators, location)?;
Expr::ListComp(ExprListComp {
elt,
generators,
range,
}) => {
self.scan_comprehension("genexpr", elt, None, generators, range.start)?;
}
SetComp(ExprSetComp { elt, generators }) => {
self.scan_comprehension("genexpr", elt, None, generators, location)?;
Expr::SetComp(ExprSetComp {
elt,
generators,
range,
}) => {
self.scan_comprehension("genexpr", elt, None, generators, range.start)?;
}
DictComp(ExprDictComp {
Expr::DictComp(ExprDictComp {
key,
value,
generators,
range,
}) => {
self.scan_comprehension("genexpr", key, Some(value), generators, location)?;
self.scan_comprehension("genexpr", key, Some(value), generators, range.start)?;
}
Call(ExprCall {
Expr::Call(ExprCall {
func,
args,
keywords,
range: _,
}) => {
match context {
ExpressionContext::IterDefinitionExp => {
@@ -971,38 +1032,41 @@ impl SymbolTableBuilder {
self.scan_expressions(args, ExpressionContext::Load)?;
for keyword in keywords {
self.scan_expression(&keyword.node.value, ExpressionContext::Load)?;
self.scan_expression(&keyword.value, ExpressionContext::Load)?;
}
}
FormattedValue(ExprFormattedValue {
value, format_spec, ..
Expr::FormattedValue(ExprFormattedValue {
value,
format_spec,
range: _,
..
}) => {
self.scan_expression(value, ExpressionContext::Load)?;
if let Some(spec) = format_spec {
self.scan_expression(spec, ExpressionContext::Load)?;
}
}
JoinedStr(ExprJoinedStr { values }) => {
Expr::JoinedStr(ExprJoinedStr { values, range: _ }) => {
for value in values {
self.scan_expression(value, ExpressionContext::Load)?;
}
}
Name(ExprName { id, .. }) => {
Expr::Name(ExprName { id, range, .. }) => {
let id = id.as_str();
// Determine the contextual usage of this symbol:
match context {
ExpressionContext::Delete => {
self.register_name(id, SymbolUsage::Assigned, location)?;
self.register_name(id, SymbolUsage::Used, location)?;
self.register_name(id, SymbolUsage::Assigned, range.start)?;
self.register_name(id, SymbolUsage::Used, range.start)?;
}
ExpressionContext::Load | ExpressionContext::IterDefinitionExp => {
self.register_name(id, SymbolUsage::Used, location)?;
self.register_name(id, SymbolUsage::Used, range.start)?;
}
ExpressionContext::Store => {
self.register_name(id, SymbolUsage::Assigned, location)?;
self.register_name(id, SymbolUsage::Assigned, range.start)?;
}
ExpressionContext::Iter => {
self.register_name(id, SymbolUsage::Iter, location)?;
self.register_name(id, SymbolUsage::Iter, range.start)?;
}
}
// Interesting stuff about the __class__ variable:
@@ -1011,10 +1075,14 @@ impl SymbolTableBuilder {
&& self.tables.last().unwrap().typ == SymbolTableType::Function
&& id == "super"
{
self.register_name("__class__", SymbolUsage::Used, location)?;
self.register_name("__class__", SymbolUsage::Used, range.start)?;
}
}
Lambda(ExprLambda { args, body }) => {
Expr::Lambda(ExprLambda {
args,
body,
range: _,
}) => {
self.enter_function("lambda", args, expression.location().row)?;
match context {
ExpressionContext::IterDefinitionExp => {
@@ -1026,13 +1094,22 @@ impl SymbolTableBuilder {
}
self.leave_scope();
}
IfExp(ExprIfExp { test, body, orelse }) => {
Expr::IfExp(ExprIfExp {
test,
body,
orelse,
range: _,
}) => {
self.scan_expression(test, ExpressionContext::Load)?;
self.scan_expression(body, ExpressionContext::Load)?;
self.scan_expression(orelse, ExpressionContext::Load)?;
}
NamedExpr(ExprNamedExpr { target, value }) => {
Expr::NamedExpr(ExprNamedExpr {
target,
value,
range,
}) => {
// named expressions are not allowed in the definition of
// comprehension iterator definitions
if let ExpressionContext::IterDefinitionExp = context {
@@ -1048,20 +1125,20 @@ impl SymbolTableBuilder {
// that are used in comprehensions. This required to correctly
// propagate the scope of the named assigned named and not to
// propagate inner names.
if let Name(ExprName { id, .. }) = &target.node {
if let Expr::Name(ExprName { id, .. }) = &**target {
let id = id.as_str();
let table = self.tables.last().unwrap();
if table.typ == SymbolTableType::Comprehension {
self.register_name(
id,
SymbolUsage::AssignedNamedExprInComprehension,
location,
range.start,
)?;
} else {
// omit one recursion. When the handling of an store changes for
// Identifiers this needs adapted - more forward safe would be
// calling scan_expression directly.
self.register_name(id, SymbolUsage::Assigned, location)?;
self.register_name(id, SymbolUsage::Assigned, range.start)?;
}
} else {
self.scan_expression(target, ExpressionContext::Store)?;
+37 -57
View File
@@ -6,13 +6,10 @@
mod gen;
use crate::{
builtins::{self, PyModule, PyStrRef, PyType},
builtins::{self, PyDict, PyModule, PyStrRef, PyType},
class::{PyClassImpl, StaticType},
compiler::core::bytecode::OpArgType,
compiler::CompileError,
compiler::{
core::bytecode::OpArgType,
parser::text_size::{TextRange, TextSize},
},
convert::ToPyException,
source_code::{OneIndexed, SourceLocation, SourceLocator, SourceRange},
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
@@ -36,10 +33,10 @@ mod _ast {
#[pyattr]
#[pyclass(module = "_ast", name = "AST")]
#[derive(Debug, PyPayload)]
pub(crate) struct AstNode;
pub(crate) struct NodeAst;
#[pyclass(flags(BASETYPE, HAS_DICT))]
impl AstNode {
impl NodeAst {
#[pyslot]
#[pymethod(magic)]
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
@@ -149,65 +146,48 @@ impl<T: Node> Node for Option<T> {
}
}
impl<T: NamedNode> Node for ast::located::Located<T> {
fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef {
let location = self.location();
let end_location = self.end_location();
let obj = self.node.ast_to_object(vm);
node_add_location(&obj, location, end_location, vm);
obj
}
fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult<Self> {
fn make_location(row: u32, column: u32) -> Option<SourceLocation> {
Some(SourceLocation {
row: OneIndexed::new(row)?,
column: OneIndexed::from_zero_indexed(column),
})
}
let row = ast::Int::ast_from_object(vm, get_node_field(vm, &object, "lineno", T::NAME)?)?;
let column =
ast::Int::ast_from_object(vm, get_node_field(vm, &object, "col_offset", T::NAME)?)?;
let location = make_location(row.to_u32(), column.to_u32());
let end_row = get_node_field_opt(vm, &object, "end_lineno")?
.map(|obj| ast::Int::ast_from_object(vm, obj))
.transpose()?;
let end_column = get_node_field_opt(vm, &object, "end_col_offset")?
.map(|obj| ast::Int::ast_from_object(vm, obj))
.transpose()?;
let end_location = if let (Some(row), Some(column)) = (end_row, end_column) {
make_location(row.to_u32(), column.to_u32())
} else {
None
};
let node = T::ast_from_object(vm, object)?;
Ok(ast::located::Located {
range: TextRange::empty(TextSize::new(0)),
custom: SourceRange {
start: location.unwrap_or(SourceLocation::default()),
end: end_location,
},
node,
fn range_from_object(
vm: &VirtualMachine,
object: PyObjectRef,
name: &str,
) -> PyResult<SourceRange> {
fn make_location(row: u32, column: u32) -> Option<SourceLocation> {
Some(SourceLocation {
row: OneIndexed::new(row)?,
column: OneIndexed::from_zero_indexed(column),
})
}
let row = ast::Int::ast_from_object(vm, get_node_field(vm, &object, "lineno", name)?)?;
let column = ast::Int::ast_from_object(vm, get_node_field(vm, &object, "col_offset", name)?)?;
let location = make_location(row.to_u32(), column.to_u32());
let end_row = get_node_field_opt(vm, &object, "end_lineno")?
.map(|obj| ast::Int::ast_from_object(vm, obj))
.transpose()?;
let end_column = get_node_field_opt(vm, &object, "end_col_offset")?
.map(|obj| ast::Int::ast_from_object(vm, obj))
.transpose()?;
let end_location = if let (Some(row), Some(column)) = (end_row, end_column) {
make_location(row.to_u32(), column.to_u32())
} else {
None
};
let range = SourceRange {
start: location.unwrap_or(SourceLocation::default()),
end: end_location,
};
Ok(range)
}
fn node_add_location(
node: &PyObject,
location: SourceLocation,
end_location: Option<SourceLocation>,
vm: &VirtualMachine,
) {
let dict = node.dict().unwrap();
dict.set_item("lineno", vm.ctx.new_int(location.row.get()).into(), vm)
fn node_add_location(dict: &Py<PyDict>, range: SourceRange, vm: &VirtualMachine) {
dict.set_item("lineno", vm.ctx.new_int(range.start.row.get()).into(), vm)
.unwrap();
dict.set_item(
"col_offset",
vm.ctx.new_int(location.column.to_zero_indexed()).into(),
vm.ctx.new_int(range.start.column.to_zero_indexed()).into(),
vm,
)
.unwrap();
if let Some(end_location) = end_location {
if let Some(end_location) = range.end {
dict.set_item(
"end_lineno",
vm.ctx.new_int(end_location.row.get()).into(),
@@ -364,7 +344,7 @@ pub(crate) fn compile(
}
// Required crate visibility for inclusion by gen.rs
pub(crate) use _ast::AstNode;
pub(crate) use _ast::NodeAst;
// Used by builtins::compile()
pub const PY_COMPILE_FLAG_AST_ONLY: i32 = 0x0400;
+3189 -2363
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -124,7 +124,7 @@ mod builtins {
if args
.source
.fast_isinstance(&ast::AstNode::make_class(&vm.ctx))
.fast_isinstance(&ast::NodeAst::make_class(&vm.ctx))
{
#[cfg(not(feature = "rustpython-codegen"))]
{