Skip to content

Commit 6e3c47f

Browse files
committed
x
1 parent f47dfca commit 6e3c47f

18 files changed

+558
-435
lines changed

ast/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ repository = "https://github.com/RustPython/RustPython"
88
license = "MIT"
99

1010
[features]
11-
default = ["constant-optimization", "fold"]
11+
default = ["constant-optimization", "fold", "location"]
1212
constant-optimization = ["fold"]
13+
location = []
1314
fold = []
1415
unparse = ["rustpython-literal"]
1516

ast/asdl_rs.py

+29-80
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ def asdl_of(name, obj):
6565
class EmitVisitor(asdl.VisitorBase):
6666
"""Visit that emits lines"""
6767

68-
def __init__(self, file):
68+
def __init__(self, file, typeinfo):
6969
self.file = file
70+
self.typeinfo = typeinfo
7071
self.identifiers = set()
7172
super(EmitVisitor, self).__init__()
7273

@@ -165,8 +166,7 @@ def rust_field(field_name):
165166

166167
class TypeInfoEmitVisitor(EmitVisitor):
167168
def __init__(self, file, typeinfo):
168-
self.typeinfo = typeinfo
169-
super().__init__(file)
169+
super().__init__(file, typeinfo)
170170

171171
def has_userdata(self, typ):
172172
return self.typeinfo[typ].has_userdata
@@ -327,7 +327,11 @@ def visitModule(self, mod, depth):
327327
self.emit("type Error;", depth + 1)
328328
self.emit(
329329
"fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;",
330-
depth + 2,
330+
depth + 1,
331+
)
332+
self.emit(
333+
"fn map_located<T>(&mut self, located: Located<T, U>) -> Result<Located<T, Self::TargetU>, Self::Error> { let custom = self.map_user(located.custom)?; Ok(Located { range: located.range, custom, node: located.node }) }",
334+
depth + 1,
331335
)
332336
for dfn in mod.dfns:
333337
self.visit(dfn, depth + 2)
@@ -352,7 +356,7 @@ def visitModule(self, mod, depth):
352356
depth,
353357
)
354358
self.emit(
355-
"Ok(Located { custom: folder.map_user(node.custom)?, range: node.range, node: f(folder, node.node)? })",
359+
"let node = folder.map_located(node)?; Ok(Located { custom: node.custom, range: node.range, node: f(folder, node.node)? })",
356360
depth + 1,
357361
)
358362
self.emit("}", depth)
@@ -575,11 +579,15 @@ def visitSum(self, sum, name, depth):
575579
rustname = enumname = get_rust_type(name)
576580
if sum.attributes:
577581
rustname = enumname + "Kind"
582+
if sum.attributes or self.typeinfo[name].has_userdata:
583+
custom = "<LocationRange>"
584+
else:
585+
custom = ""
578586

579-
self.emit(f"impl NamedNode for ast::{rustname} {{", depth)
587+
self.emit(f"impl NamedNode for ast::{rustname}{custom} {{", depth)
580588
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
581589
self.emit("}", depth)
582-
self.emit(f"impl Node for ast::{rustname} {{", depth)
590+
self.emit(f"impl Node for ast::{rustname}{custom} {{", depth)
583591
self.emit(
584592
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
585593
)
@@ -656,7 +664,10 @@ def gen_sum_fromobj(self, sum, sumname, enumname, rustname, depth):
656664
for cons in sum.types:
657665
self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth)
658666
if cons.fields:
659-
self.emit(f"ast::{rustname}::{cons.name} (ast::{enumname}{cons.name} {{", depth + 1)
667+
self.emit(
668+
f"ast::{rustname}::{cons.name} (ast::{enumname}{cons.name}::<LocationRange> {{",
669+
depth + 1,
670+
)
660671
self.gen_construction_fields(cons, sumname, depth + 1)
661672
self.emit("})", depth + 1)
662673
else:
@@ -691,7 +702,7 @@ def gen_construction(self, cons_path, cons, name, depth):
691702
def extract_location(self, typename, depth):
692703
row = self.decode_field(asdl.Field("int", "lineno"), typename)
693704
column = self.decode_field(asdl.Field("int", "col_offset"), typename)
694-
self.emit(f"let _location = ast::Location::new({row}, {column});", depth)
705+
self.emit(f"let _location = Location::new({row}, {column});", depth)
695706

696707
def decode_field(self, field, typename):
697708
name = json.dumps(field.name)
@@ -717,86 +728,20 @@ def write_ast_def(mod, typeinfo, f):
717728
"""
718729
#![allow(clippy::derive_partial_eq_without_eq)]
719730
720-
pub use crate::constant::*;
721-
pub use rustpython_compiler_core::text_size::{TextSize, TextRange};
731+
pub use crate::{Located, constant::*};
732+
pub use rustpython_compiler_core::{text_size::{TextSize, TextRange}};
722733
723734
type Ident = String;
724735
\n
725736
"""
726737
)
727738
)
728-
StructVisitor(f, typeinfo).emit_attrs(0)
729-
f.write(
730-
textwrap.dedent(
731-
"""
732-
pub struct Located<T, U = ()> {
733-
pub range: TextRange,
734-
pub custom: U,
735-
pub node: T,
736-
}
737-
738-
impl<T> Located<T> {
739-
pub fn new(start: TextSize, end: TextSize, node: T) -> Self {
740-
Self { range: TextRange::new(start, end), custom: (), node }
741-
}
742-
743-
/// Creates a new node that spans the position specified by `range`.
744-
pub fn with_range(node: T, range: TextRange) -> Self {
745-
Self {
746-
range,
747-
custom: (),
748-
node,
749-
}
750-
}
751-
752-
/// Returns the absolute start position of the node from the beginning of the document.
753-
#[inline]
754-
pub const fn start(&self) -> TextSize {
755-
self.range.start()
756-
}
757-
758-
/// Returns the node
759-
#[inline]
760-
pub fn node(&self) -> &T {
761-
&self.node
762-
}
763-
764-
/// Consumes self and returns the node.
765-
#[inline]
766-
pub fn into_node(self) -> T {
767-
self.node
768-
}
769-
770-
/// Returns the `range` of the node. The range offsets are absolute to the start of the document.
771-
#[inline]
772-
pub const fn range(&self) -> TextRange {
773-
self.range
774-
}
775-
776-
/// Returns the absolute position at which the node ends in the source document.
777-
#[inline]
778-
pub const fn end(&self) -> TextSize {
779-
self.range.end()
780-
}
781-
}
782-
783-
impl<T, U> std::ops::Deref for Located<T, U> {
784-
type Target = T;
785-
786-
fn deref(&self) -> &Self::Target {
787-
&self.node
788-
}
789-
}
790-
\n
791-
""".lstrip()
792-
)
793-
)
794739

795740
c = ChainOfVisitors(StructVisitor(f, typeinfo), FoldModuleVisitor(f, typeinfo))
796741
c.visit(mod)
797742

798743

799-
def write_ast_mod(mod, f):
744+
def write_ast_mod(mod, typeinfo, f):
800745
f.write(
801746
textwrap.dedent(
802747
"""
@@ -809,7 +754,11 @@ def write_ast_mod(mod, f):
809754
)
810755
)
811756

812-
c = ChainOfVisitors(ClassDefVisitor(f), TraitImplVisitor(f), ExtendModuleVisitor(f))
757+
c = ChainOfVisitors(
758+
ClassDefVisitor(f, typeinfo),
759+
TraitImplVisitor(f, typeinfo),
760+
ExtendModuleVisitor(f, typeinfo),
761+
)
813762
c.visit(mod)
814763

815764

@@ -830,7 +779,7 @@ def main(input_filename, ast_mod_filename, ast_def_filename, dump_module=False):
830779
write_ast_def(mod, typeinfo, def_file)
831780

832781
mod_file.write(auto_gen_msg)
833-
write_ast_mod(mod, mod_file)
782+
write_ast_mod(mod, typeinfo, mod_file)
834783

835784
print(f"{ast_def_filename}, {ast_mod_filename} regenerated.")
836785

ast/src/ast_gen.rs

+14-66
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,11 @@
22

33
#![allow(clippy::derive_partial_eq_without_eq)]
44

5-
pub use crate::constant::*;
5+
pub use crate::{constant::*, Located};
66
pub use rustpython_compiler_core::text_size::{TextRange, TextSize};
77

88
type Ident = String;
99

10-
#[derive(Clone, Debug, PartialEq)]
11-
pub struct Located<T, U = ()> {
12-
pub range: TextRange,
13-
pub custom: U,
14-
pub node: T,
15-
}
16-
17-
impl<T> Located<T> {
18-
pub fn new(start: TextSize, end: TextSize, node: T) -> Self {
19-
Self {
20-
range: TextRange::new(start, end),
21-
custom: (),
22-
node,
23-
}
24-
}
25-
26-
/// Creates a new node that spans the position specified by `range`.
27-
pub fn with_range(node: T, range: TextRange) -> Self {
28-
Self {
29-
range,
30-
custom: (),
31-
node,
32-
}
33-
}
34-
35-
/// Returns the absolute start position of the node from the beginning of the document.
36-
#[inline]
37-
pub const fn start(&self) -> TextSize {
38-
self.range.start()
39-
}
40-
41-
/// Returns the node
42-
#[inline]
43-
pub fn node(&self) -> &T {
44-
&self.node
45-
}
46-
47-
/// Consumes self and returns the node.
48-
#[inline]
49-
pub fn into_node(self) -> T {
50-
self.node
51-
}
52-
53-
/// Returns the `range` of the node. The range offsets are absolute to the start of the document.
54-
#[inline]
55-
pub const fn range(&self) -> TextRange {
56-
self.range
57-
}
58-
59-
/// Returns the absolute position at which the node ends in the source document.
60-
#[inline]
61-
pub const fn end(&self) -> TextSize {
62-
self.range.end()
63-
}
64-
}
65-
66-
impl<T, U> std::ops::Deref for Located<T, U> {
67-
type Target = T;
68-
69-
fn deref(&self) -> &Self::Target {
70-
&self.node
71-
}
72-
}
73-
7410
#[derive(Clone, Debug, PartialEq)]
7511
pub struct ModModule<U = ()> {
7612
pub body: Vec<Stmt<U>>,
@@ -1086,6 +1022,17 @@ pub mod fold {
10861022
type TargetU;
10871023
type Error;
10881024
fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;
1025+
fn map_located<T>(
1026+
&mut self,
1027+
located: Located<T, U>,
1028+
) -> Result<Located<T, Self::TargetU>, Self::Error> {
1029+
let custom = self.map_user(located.custom)?;
1030+
Ok(Located {
1031+
range: located.range,
1032+
custom,
1033+
node: located.node,
1034+
})
1035+
}
10891036
fn fold_mod(&mut self, node: Mod<U>) -> Result<Mod<Self::TargetU>, Self::Error> {
10901037
fold_mod(self, node)
10911038
}
@@ -1167,8 +1114,9 @@ pub mod fold {
11671114
node: Located<T, U>,
11681115
f: impl FnOnce(&mut F, T) -> Result<MT, F::Error>,
11691116
) -> Result<Located<MT, F::TargetU>, F::Error> {
1117+
let node = folder.map_located(node)?;
11701118
Ok(Located {
1171-
custom: folder.map_user(node.custom)?,
1119+
custom: node.custom,
11721120
range: node.range,
11731121
node: f(folder, node.node)?,
11741122
})

ast/src/fold_helpers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{constant, fold::Fold};
22

3-
pub(crate) trait Foldable<T, U> {
3+
pub trait Foldable<T, U> {
44
type Mapped;
55
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
66
self,

ast/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@ mod constant;
33
#[cfg(feature = "fold")]
44
mod fold_helpers;
55
mod impls;
6+
mod located;
7+
#[cfg(feature = "location")]
8+
mod locator;
9+
610
#[cfg(feature = "unparse")]
711
mod unparse;
812

913
pub use ast_gen::*;
14+
pub use located::Located;
15+
#[cfg(feature = "location")]
16+
pub use locator::Locator;
1017

1118
pub type Suite<U = ()> = Vec<Stmt<U>>;

0 commit comments

Comments
 (0)