mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Move range to each Node (#4969)
This commit is contained in:
1 parent
7a6000d181
commit
f5fc30ae63
7 files changed
+3731
-2805
No files matched your search
Generated
+8
-7
@@ -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
@@ -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"
|
||||
|
||||
+310
-268
File diff suppressed because it is too large.
Load diff
@@ -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) = ¶meter.node.annotation {
|
||||
if let Some(annotation) = ¶meter.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
@@ -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;
|
||||
|
||||
|
||||
Generated
+3189
-2363
File diff suppressed because it is too large.
Load diff
@@ -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"))]
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user