mirror of
https://github.com/RustPython/Parser.git
synced 2025-08-26 21:34:55 +00:00
Separate byteoffset ast and located ast
This commit is contained in:
parent
f47dfca4e3
commit
a14e43e03a
21 changed files with 893 additions and 562 deletions
|
@ -8,8 +8,9 @@ repository = "https://github.com/RustPython/RustPython"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["constant-optimization", "fold"]
|
default = ["constant-optimization", "fold", "location"]
|
||||||
constant-optimization = ["fold"]
|
constant-optimization = ["fold"]
|
||||||
|
location = []
|
||||||
fold = []
|
fold = []
|
||||||
unparse = ["rustpython-literal"]
|
unparse = ["rustpython-literal"]
|
||||||
|
|
||||||
|
|
415
ast/asdl_rs.py
415
ast/asdl_rs.py
|
@ -7,6 +7,8 @@ import textwrap
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional, Dict
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
import asdl
|
import asdl
|
||||||
|
|
||||||
|
@ -62,38 +64,62 @@ def asdl_of(name, obj):
|
||||||
return "{} = {}".format(name, types)
|
return "{} = {}".format(name, types)
|
||||||
|
|
||||||
|
|
||||||
class EmitVisitor(asdl.VisitorBase):
|
|
||||||
"""Visit that emits lines"""
|
|
||||||
|
|
||||||
def __init__(self, file):
|
|
||||||
self.file = file
|
|
||||||
self.identifiers = set()
|
|
||||||
super(EmitVisitor, self).__init__()
|
|
||||||
|
|
||||||
def emit_identifier(self, name):
|
|
||||||
name = str(name)
|
|
||||||
if name in self.identifiers:
|
|
||||||
return
|
|
||||||
self.emit("_Py_IDENTIFIER(%s);" % name, 0)
|
|
||||||
self.identifiers.add(name)
|
|
||||||
|
|
||||||
def emit(self, line, depth):
|
|
||||||
if line:
|
|
||||||
line = (" " * TABSIZE * depth) + line
|
|
||||||
self.file.write(line + "\n")
|
|
||||||
|
|
||||||
|
|
||||||
class TypeInfo:
|
class TypeInfo:
|
||||||
|
name: str
|
||||||
|
enum_name: Optional[str]
|
||||||
|
has_userdata: Optional[bool]
|
||||||
|
has_attributes: bool
|
||||||
|
children: set
|
||||||
|
boxed: bool
|
||||||
|
product: bool
|
||||||
|
has_expr: bool = False
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.enum_name = None
|
||||||
self.has_userdata = None
|
self.has_userdata = None
|
||||||
|
self.has_attributes = False
|
||||||
self.children = set()
|
self.children = set()
|
||||||
self.boxed = False
|
self.boxed = False
|
||||||
self.product = False
|
self.product = False
|
||||||
|
self.product_has_expr = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<TypeInfo: {self.name}>"
|
return f"<TypeInfo: {self.name}>"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rust_name(self):
|
||||||
|
return get_rust_type(self.name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sum_name(self):
|
||||||
|
if self.enum_name is None:
|
||||||
|
return self.name
|
||||||
|
else:
|
||||||
|
return f"{self.enum_name}_{self.name}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rust_sum_name(self):
|
||||||
|
rust_name = get_rust_type(self.name)
|
||||||
|
if self.enum_name is None:
|
||||||
|
return rust_name
|
||||||
|
else:
|
||||||
|
name = get_rust_type(self.enum_name) + rust_name
|
||||||
|
return name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rust_suffix(self):
|
||||||
|
if self.product:
|
||||||
|
if self.has_attributes:
|
||||||
|
return "Data"
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
if self.has_attributes:
|
||||||
|
return "Kind"
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
def determine_userdata(self, typeinfo, stack):
|
def determine_userdata(self, typeinfo, stack):
|
||||||
if self.name in stack:
|
if self.name in stack:
|
||||||
return None
|
return None
|
||||||
|
@ -110,6 +136,41 @@ class TypeInfo:
|
||||||
return self.has_userdata
|
return self.has_userdata
|
||||||
|
|
||||||
|
|
||||||
|
class TypeInfoMixin:
|
||||||
|
typeinfo: Dict[str, TypeInfo]
|
||||||
|
|
||||||
|
def has_userdata(self, typ):
|
||||||
|
return self.typeinfo[typ].has_userdata
|
||||||
|
|
||||||
|
def get_generics(self, typ, *generics):
|
||||||
|
if self.has_userdata(typ):
|
||||||
|
return [f"<{g}>" for g in generics]
|
||||||
|
else:
|
||||||
|
return ["" for g in generics]
|
||||||
|
|
||||||
|
|
||||||
|
class EmitVisitor(asdl.VisitorBase, TypeInfoMixin):
|
||||||
|
"""Visit that emits lines"""
|
||||||
|
|
||||||
|
def __init__(self, file, typeinfo):
|
||||||
|
self.file = file
|
||||||
|
self.typeinfo = typeinfo
|
||||||
|
self.identifiers = set()
|
||||||
|
super(EmitVisitor, self).__init__()
|
||||||
|
|
||||||
|
def emit_identifier(self, name):
|
||||||
|
name = str(name)
|
||||||
|
if name in self.identifiers:
|
||||||
|
return
|
||||||
|
self.emit("_Py_IDENTIFIER(%s);" % name, 0)
|
||||||
|
self.identifiers.add(name)
|
||||||
|
|
||||||
|
def emit(self, line, depth):
|
||||||
|
if line:
|
||||||
|
line = (" " * TABSIZE * depth) + line
|
||||||
|
self.file.write(line + "\n")
|
||||||
|
|
||||||
|
|
||||||
class FindUserdataTypesVisitor(asdl.VisitorBase):
|
class FindUserdataTypesVisitor(asdl.VisitorBase):
|
||||||
def __init__(self, typeinfo):
|
def __init__(self, typeinfo):
|
||||||
self.typeinfo = typeinfo
|
self.typeinfo = typeinfo
|
||||||
|
@ -132,21 +193,29 @@ class FindUserdataTypesVisitor(asdl.VisitorBase):
|
||||||
info.has_userdata = False
|
info.has_userdata = False
|
||||||
else:
|
else:
|
||||||
for t in sum.types:
|
for t in sum.types:
|
||||||
self.typeinfo[t.name] = TypeInfo(t.name)
|
if not t.fields:
|
||||||
|
continue
|
||||||
|
t_info = TypeInfo(t.name)
|
||||||
|
t_info.enum_name = name
|
||||||
|
self.typeinfo[t.name] = t_info
|
||||||
self.add_children(t.name, t.fields)
|
self.add_children(t.name, t.fields)
|
||||||
if len(sum.types) > 1:
|
if len(sum.types) > 1:
|
||||||
info.boxed = True
|
info.boxed = True
|
||||||
if sum.attributes:
|
if sum.attributes:
|
||||||
# attributes means Located, which has the `custom: U` field
|
# attributes means located, which has the `custom: U` field
|
||||||
info.has_userdata = True
|
info.has_userdata = True
|
||||||
|
info.has_attributes = True
|
||||||
|
|
||||||
for variant in sum.types:
|
for variant in sum.types:
|
||||||
self.add_children(name, variant.fields)
|
self.add_children(name, variant.fields)
|
||||||
|
|
||||||
def visitProduct(self, product, name):
|
def visitProduct(self, product, name):
|
||||||
info = self.typeinfo[name]
|
info = self.typeinfo[name]
|
||||||
if product.attributes:
|
if product.attributes:
|
||||||
# attributes means Located, which has the `custom: U` field
|
# attributes means located, which has the `custom: U` field
|
||||||
info.has_userdata = True
|
info.has_userdata = True
|
||||||
|
info.has_attributes = True
|
||||||
|
info.has_expr = product_has_expr(product)
|
||||||
if len(product.fields) > 2:
|
if len(product.fields) > 2:
|
||||||
info.boxed = True
|
info.boxed = True
|
||||||
info.product = True
|
info.product = True
|
||||||
|
@ -163,24 +232,17 @@ def rust_field(field_name):
|
||||||
return field_name
|
return field_name
|
||||||
|
|
||||||
|
|
||||||
class TypeInfoEmitVisitor(EmitVisitor):
|
def product_has_expr(product):
|
||||||
def __init__(self, file, typeinfo):
|
return any(f.type != "identifier" for f in product.fields)
|
||||||
self.typeinfo = typeinfo
|
|
||||||
super().__init__(file)
|
|
||||||
|
|
||||||
def has_userdata(self, typ):
|
|
||||||
return self.typeinfo[typ].has_userdata
|
|
||||||
|
|
||||||
def get_generics(self, typ, *generics):
|
|
||||||
if self.has_userdata(typ):
|
|
||||||
return [f"<{g}>" for g in generics]
|
|
||||||
else:
|
|
||||||
return ["" for g in generics]
|
|
||||||
|
|
||||||
|
|
||||||
class StructVisitor(TypeInfoEmitVisitor):
|
class StructVisitor(EmitVisitor):
|
||||||
"""Visitor to generate typedefs for AST."""
|
"""Visitor to generate typedefs for AST."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
super().__init__(*args, **kw)
|
||||||
|
self.rust_type_defs = []
|
||||||
|
|
||||||
def visitModule(self, mod):
|
def visitModule(self, mod):
|
||||||
for dfn in mod.dfns:
|
for dfn in mod.dfns:
|
||||||
self.visit(dfn)
|
self.visit(dfn)
|
||||||
|
@ -208,57 +270,56 @@ class StructVisitor(TypeInfoEmitVisitor):
|
||||||
|
|
||||||
def sum_with_constructors(self, sum, name, depth):
|
def sum_with_constructors(self, sum, name, depth):
|
||||||
typeinfo = self.typeinfo[name]
|
typeinfo = self.typeinfo[name]
|
||||||
enumname = rustname = get_rust_type(name)
|
suffix = typeinfo.rust_suffix
|
||||||
|
rustname = get_rust_type(name)
|
||||||
# all the attributes right now are for location, so if it has attrs we
|
# all the attributes right now are for location, so if it has attrs we
|
||||||
# can just wrap it in Located<>
|
# can just wrap it in Attributed<>
|
||||||
if sum.attributes:
|
|
||||||
enumname = rustname + "Kind"
|
|
||||||
|
|
||||||
for t in sum.types:
|
for t in sum.types:
|
||||||
if not t.fields:
|
if not t.fields:
|
||||||
continue
|
continue
|
||||||
self.emit_attrs(depth)
|
self.sum_subtype_struct(typeinfo, t, rustname, depth)
|
||||||
self.typeinfo[t] = TypeInfo(t)
|
|
||||||
t_generics, t_generics_applied = self.get_generics(t.name, "U = ()", "U")
|
|
||||||
payload_name = f"{rustname}{t.name}"
|
|
||||||
self.emit(f"pub struct {payload_name}{t_generics} {{", depth)
|
|
||||||
for f in t.fields:
|
|
||||||
self.visit(f, typeinfo, "pub ", depth + 1, t.name)
|
|
||||||
self.emit("}", depth)
|
|
||||||
self.emit(
|
|
||||||
textwrap.dedent(
|
|
||||||
f"""
|
|
||||||
impl{t_generics_applied} From<{payload_name}{t_generics_applied}> for {enumname}{t_generics_applied} {{
|
|
||||||
fn from(payload: {payload_name}{t_generics_applied}) -> Self {{
|
|
||||||
{enumname}::{t.name}(payload)
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
depth,
|
|
||||||
)
|
|
||||||
|
|
||||||
generics, generics_applied = self.get_generics(name, "U = ()", "U")
|
generics, generics_applied = self.get_generics(name, "U = ()", "U")
|
||||||
self.emit_attrs(depth)
|
self.emit_attrs(depth)
|
||||||
self.emit(f"pub enum {enumname}{generics} {{", depth)
|
self.emit(f"pub enum {rustname}{suffix}{generics} {{", depth)
|
||||||
for t in sum.types:
|
for t in sum.types:
|
||||||
if t.fields:
|
if t.fields:
|
||||||
t_generics, t_generics_applied = self.get_generics(
|
(t_generics_applied,) = self.get_generics(t.name, "U")
|
||||||
t.name, "U = ()", "U"
|
|
||||||
)
|
|
||||||
self.emit(
|
self.emit(
|
||||||
f"{t.name}({rustname}{t.name}{t_generics_applied}),", depth + 1
|
f"{t.name}({rustname}{t.name}{t_generics_applied}),", depth + 1
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.emit(f"{t.name},", depth + 1)
|
self.emit(f"{t.name},", depth + 1)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
if sum.attributes:
|
if typeinfo.has_attributes:
|
||||||
self.emit(
|
self.emit(
|
||||||
f"pub type {rustname}<U = ()> = Located<{enumname}{generics_applied}, U>;",
|
f"pub type {rustname}<U = ()> = Attributed<{rustname}{suffix}{generics_applied}, U>;",
|
||||||
depth,
|
depth,
|
||||||
)
|
)
|
||||||
self.emit("", depth)
|
self.emit("", depth)
|
||||||
|
|
||||||
|
def sum_subtype_struct(self, sum_typeinfo, t, rustname, depth):
|
||||||
|
self.emit_attrs(depth)
|
||||||
|
generics, generics_applied = self.get_generics(t.name, "U = ()", "U")
|
||||||
|
payload_name = f"{rustname}{t.name}"
|
||||||
|
self.emit(f"pub struct {payload_name}{generics} {{", depth)
|
||||||
|
for f in t.fields:
|
||||||
|
self.visit(f, sum_typeinfo, "pub ", depth + 1, t.name)
|
||||||
|
self.emit("}", depth)
|
||||||
|
self.emit(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
impl{generics_applied} From<{payload_name}{generics_applied}> for {rustname}{sum_typeinfo.rust_suffix}{generics_applied} {{
|
||||||
|
fn from(payload: {payload_name}{generics_applied}) -> Self {{
|
||||||
|
{rustname}{sum_typeinfo.rust_suffix}::{t.name}(payload)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
depth,
|
||||||
|
)
|
||||||
|
|
||||||
def visitConstructor(self, cons, parent, depth):
|
def visitConstructor(self, cons, parent, depth):
|
||||||
if cons.fields:
|
if cons.fields:
|
||||||
self.emit(f"{cons.name} {{", depth)
|
self.emit(f"{cons.name} {{", depth)
|
||||||
|
@ -300,7 +361,7 @@ class StructVisitor(TypeInfoEmitVisitor):
|
||||||
if product.attributes:
|
if product.attributes:
|
||||||
dataname = rustname + "Data"
|
dataname = rustname + "Data"
|
||||||
self.emit_attrs(depth)
|
self.emit_attrs(depth)
|
||||||
has_expr = any(f.type != "identifier" for f in product.fields)
|
has_expr = product_has_expr(product)
|
||||||
if has_expr:
|
if has_expr:
|
||||||
datadef = f"{dataname}{generics}"
|
datadef = f"{dataname}{generics}"
|
||||||
else:
|
else:
|
||||||
|
@ -314,20 +375,24 @@ class StructVisitor(TypeInfoEmitVisitor):
|
||||||
if not has_expr:
|
if not has_expr:
|
||||||
generics_applied = ""
|
generics_applied = ""
|
||||||
self.emit(
|
self.emit(
|
||||||
f"pub type {rustname}<U = ()> = Located<{dataname}{generics_applied}, U>;",
|
f"pub type {rustname}<U = ()> = Attributed<{dataname}{generics_applied}, U>;",
|
||||||
depth,
|
depth,
|
||||||
)
|
)
|
||||||
self.emit("", depth)
|
self.emit("", depth)
|
||||||
|
|
||||||
|
|
||||||
class FoldTraitDefVisitor(TypeInfoEmitVisitor):
|
class FoldTraitDefVisitor(EmitVisitor):
|
||||||
def visitModule(self, mod, depth):
|
def visitModule(self, mod, depth):
|
||||||
self.emit("pub trait Fold<U> {", depth)
|
self.emit("pub trait Fold<U> {", depth)
|
||||||
self.emit("type TargetU;", depth + 1)
|
self.emit("type TargetU;", depth + 1)
|
||||||
self.emit("type Error;", depth + 1)
|
self.emit("type Error;", depth + 1)
|
||||||
self.emit(
|
self.emit(
|
||||||
"fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;",
|
"fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;",
|
||||||
depth + 2,
|
depth + 1,
|
||||||
|
)
|
||||||
|
self.emit(
|
||||||
|
"fn map_located<T>(&mut self, located: Attributed<T, U>) -> Result<Attributed<T, Self::TargetU>, Self::Error> { let custom = self.map_user(located.custom)?; Ok(Attributed { range: located.range, custom, node: located.node }) }",
|
||||||
|
depth + 1,
|
||||||
)
|
)
|
||||||
for dfn in mod.dfns:
|
for dfn in mod.dfns:
|
||||||
self.visit(dfn, depth + 2)
|
self.visit(dfn, depth + 2)
|
||||||
|
@ -345,14 +410,14 @@ class FoldTraitDefVisitor(TypeInfoEmitVisitor):
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
|
||||||
|
|
||||||
class FoldImplVisitor(TypeInfoEmitVisitor):
|
class FoldImplVisitor(EmitVisitor):
|
||||||
def visitModule(self, mod, depth):
|
def visitModule(self, mod, depth):
|
||||||
self.emit(
|
self.emit(
|
||||||
"fn fold_located<U, F: Fold<U> + ?Sized, T, MT>(folder: &mut F, node: Located<T, U>, f: impl FnOnce(&mut F, T) -> Result<MT, F::Error>) -> Result<Located<MT, F::TargetU>, F::Error> {",
|
"fn fold_located<U, F: Fold<U> + ?Sized, T, MT>(folder: &mut F, node: Attributed<T, U>, f: impl FnOnce(&mut F, T) -> Result<MT, F::Error>) -> Result<Attributed<MT, F::TargetU>, F::Error> {",
|
||||||
depth,
|
depth,
|
||||||
)
|
)
|
||||||
self.emit(
|
self.emit(
|
||||||
"Ok(Located { custom: folder.map_user(node.custom)?, range: node.range, node: f(folder, node.node)? })",
|
"let node = folder.map_located(node)?; Ok(Attributed { custom: node.custom, range: node.range, node: f(folder, node.node)? })",
|
||||||
depth + 1,
|
depth + 1,
|
||||||
)
|
)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
@ -363,11 +428,11 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
self.visit(type.value, type.name, depth)
|
self.visit(type.value, type.name, depth)
|
||||||
|
|
||||||
def visitSum(self, sum, name, depth):
|
def visitSum(self, sum, name, depth):
|
||||||
|
typeinfo = self.typeinfo[name]
|
||||||
apply_t, apply_u, apply_target_u = self.get_generics(
|
apply_t, apply_u, apply_target_u = self.get_generics(
|
||||||
name, "T", "U", "F::TargetU"
|
name, "T", "U", "F::TargetU"
|
||||||
)
|
)
|
||||||
enumname = get_rust_type(name)
|
enumname = get_rust_type(name)
|
||||||
is_located = bool(sum.attributes)
|
|
||||||
|
|
||||||
self.emit(f"impl<T, U> Foldable<T, U> for {enumname}{apply_t} {{", depth)
|
self.emit(f"impl<T, U> Foldable<T, U> for {enumname}{apply_t} {{", depth)
|
||||||
self.emit(f"type Mapped = {enumname}{apply_u};", depth + 1)
|
self.emit(f"type Mapped = {enumname}{apply_u};", depth + 1)
|
||||||
|
@ -383,15 +448,13 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {enumname}{apply_u}) -> Result<{enumname}{apply_target_u}, F::Error> {{",
|
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {enumname}{apply_u}) -> Result<{enumname}{apply_target_u}, F::Error> {{",
|
||||||
depth,
|
depth,
|
||||||
)
|
)
|
||||||
if is_located:
|
if typeinfo.has_attributes:
|
||||||
self.emit("fold_located(folder, node, |folder, node| {", depth)
|
self.emit("fold_located(folder, node, |folder, node| {", depth)
|
||||||
rustname = enumname + "Kind"
|
|
||||||
else:
|
|
||||||
rustname = enumname
|
|
||||||
self.emit("match node {", depth + 1)
|
self.emit("match node {", depth + 1)
|
||||||
for cons in sum.types:
|
for cons in sum.types:
|
||||||
fields_pattern = self.make_pattern(
|
fields_pattern = self.make_pattern(
|
||||||
enumname, rustname, cons.name, cons.fields
|
enumname, typeinfo.rust_suffix, cons.name, cons.fields
|
||||||
)
|
)
|
||||||
self.emit(
|
self.emit(
|
||||||
f"{fields_pattern[0]} {{ {fields_pattern[1]} }} {fields_pattern[2]} => {{",
|
f"{fields_pattern[0]} {{ {fields_pattern[1]} }} {fields_pattern[2]} => {{",
|
||||||
|
@ -402,7 +465,7 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
)
|
)
|
||||||
self.emit("}", depth + 2)
|
self.emit("}", depth + 2)
|
||||||
self.emit("}", depth + 1)
|
self.emit("}", depth + 1)
|
||||||
if is_located:
|
if typeinfo.has_attributes:
|
||||||
self.emit("})", depth)
|
self.emit("})", depth)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
|
||||||
|
@ -411,7 +474,7 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
name, "T", "U", "F::TargetU"
|
name, "T", "U", "F::TargetU"
|
||||||
)
|
)
|
||||||
structname = get_rust_type(name)
|
structname = get_rust_type(name)
|
||||||
is_located = bool(product.attributes)
|
has_attributes = bool(product.attributes)
|
||||||
|
|
||||||
self.emit(f"impl<T, U> Foldable<T, U> for {structname}{apply_t} {{", depth)
|
self.emit(f"impl<T, U> Foldable<T, U> for {structname}{apply_t} {{", depth)
|
||||||
self.emit(f"type Mapped = {structname}{apply_u};", depth + 1)
|
self.emit(f"type Mapped = {structname}{apply_u};", depth + 1)
|
||||||
|
@ -427,7 +490,7 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {structname}{apply_u}) -> Result<{structname}{apply_target_u}, F::Error> {{",
|
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {structname}{apply_u}) -> Result<{structname}{apply_target_u}, F::Error> {{",
|
||||||
depth,
|
depth,
|
||||||
)
|
)
|
||||||
if is_located:
|
if has_attributes:
|
||||||
self.emit("fold_located(folder, node, |folder, node| {", depth)
|
self.emit("fold_located(folder, node, |folder, node| {", depth)
|
||||||
rustname = structname + "Data"
|
rustname = structname + "Data"
|
||||||
else:
|
else:
|
||||||
|
@ -435,16 +498,16 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
fields_pattern = self.make_pattern(rustname, structname, None, product.fields)
|
fields_pattern = self.make_pattern(rustname, structname, None, product.fields)
|
||||||
self.emit(f"let {rustname} {{ {fields_pattern[1]} }} = node;", depth + 1)
|
self.emit(f"let {rustname} {{ {fields_pattern[1]} }} = node;", depth + 1)
|
||||||
self.gen_construction(rustname, product.fields, "", depth + 1)
|
self.gen_construction(rustname, product.fields, "", depth + 1)
|
||||||
if is_located:
|
if has_attributes:
|
||||||
self.emit("})", depth)
|
self.emit("})", depth)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
|
||||||
def make_pattern(self, rustname, pyname, fieldname, fields):
|
def make_pattern(self, rustname, suffix, fieldname, fields):
|
||||||
if fields:
|
if fields:
|
||||||
header = f"{pyname}::{fieldname}({rustname}{fieldname}"
|
header = f"{rustname}{suffix}::{fieldname}({rustname}{fieldname}"
|
||||||
footer = ")"
|
footer = ")"
|
||||||
else:
|
else:
|
||||||
header = f"{pyname}::{fieldname}"
|
header = f"{rustname}{suffix}::{fieldname}"
|
||||||
footer = ""
|
footer = ""
|
||||||
|
|
||||||
body = ",".join(rust_field(f.name) for f in fields)
|
body = ",".join(rust_field(f.name) for f in fields)
|
||||||
|
@ -458,7 +521,7 @@ class FoldImplVisitor(TypeInfoEmitVisitor):
|
||||||
self.emit(f"}}{footer})", depth)
|
self.emit(f"}}{footer})", depth)
|
||||||
|
|
||||||
|
|
||||||
class FoldModuleVisitor(TypeInfoEmitVisitor):
|
class FoldModuleVisitor(EmitVisitor):
|
||||||
def visitModule(self, mod):
|
def visitModule(self, mod):
|
||||||
depth = 0
|
depth = 0
|
||||||
self.emit('#[cfg(feature = "fold")]', depth)
|
self.emit('#[cfg(feature = "fold")]', depth)
|
||||||
|
@ -576,10 +639,10 @@ class TraitImplVisitor(EmitVisitor):
|
||||||
if sum.attributes:
|
if sum.attributes:
|
||||||
rustname = enumname + "Kind"
|
rustname = enumname + "Kind"
|
||||||
|
|
||||||
self.emit(f"impl NamedNode for ast::{rustname} {{", depth)
|
self.emit(f"impl NamedNode for ast::located::{rustname} {{", depth)
|
||||||
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
|
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
self.emit(f"impl Node for ast::{rustname} {{", depth)
|
self.emit(f"impl Node for ast::located::{rustname} {{", depth)
|
||||||
self.emit(
|
self.emit(
|
||||||
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
|
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
|
||||||
)
|
)
|
||||||
|
@ -597,10 +660,12 @@ class TraitImplVisitor(EmitVisitor):
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
|
||||||
def constructor_to_object(self, cons, enumname, rustname, depth):
|
def constructor_to_object(self, cons, enumname, rustname, depth):
|
||||||
self.emit(f"ast::{rustname}::{cons.name}", depth)
|
self.emit(f"ast::located::{rustname}::{cons.name}", depth)
|
||||||
if cons.fields:
|
if cons.fields:
|
||||||
fields_pattern = self.make_pattern(cons.fields)
|
fields_pattern = self.make_pattern(cons.fields)
|
||||||
self.emit(f"( ast::{enumname}{cons.name} {{ {fields_pattern} }} )", depth)
|
self.emit(
|
||||||
|
f"( ast::located::{enumname}{cons.name} {{ {fields_pattern} }} )", depth
|
||||||
|
)
|
||||||
self.emit(" => {", depth)
|
self.emit(" => {", depth)
|
||||||
self.make_node(cons.name, cons.fields, depth + 1)
|
self.make_node(cons.name, cons.fields, depth + 1)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
@ -610,15 +675,17 @@ class TraitImplVisitor(EmitVisitor):
|
||||||
if product.attributes:
|
if product.attributes:
|
||||||
structname += "Data"
|
structname += "Data"
|
||||||
|
|
||||||
self.emit(f"impl NamedNode for ast::{structname} {{", depth)
|
self.emit(f"impl NamedNode for ast::located::{structname} {{", depth)
|
||||||
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
|
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
self.emit(f"impl Node for ast::{structname} {{", depth)
|
self.emit(f"impl Node for ast::located::{structname} {{", depth)
|
||||||
self.emit(
|
self.emit(
|
||||||
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
|
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
|
||||||
)
|
)
|
||||||
fields_pattern = self.make_pattern(product.fields)
|
fields_pattern = self.make_pattern(product.fields)
|
||||||
self.emit(f"let ast::{structname} {{ {fields_pattern} }} = self;", depth + 2)
|
self.emit(
|
||||||
|
f"let ast::located::{structname} {{ {fields_pattern} }} = self;", depth + 2
|
||||||
|
)
|
||||||
self.make_node(name, product.fields, depth + 2)
|
self.make_node(name, product.fields, depth + 2)
|
||||||
self.emit("}", depth + 1)
|
self.emit("}", depth + 1)
|
||||||
self.emit(
|
self.emit(
|
||||||
|
@ -656,11 +723,14 @@ class TraitImplVisitor(EmitVisitor):
|
||||||
for cons in sum.types:
|
for cons in sum.types:
|
||||||
self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth)
|
self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth)
|
||||||
if cons.fields:
|
if cons.fields:
|
||||||
self.emit(f"ast::{rustname}::{cons.name} (ast::{enumname}{cons.name} {{", depth + 1)
|
self.emit(
|
||||||
|
f"ast::located::{rustname}::{cons.name} (ast::located::{enumname}{cons.name} {{",
|
||||||
|
depth + 1,
|
||||||
|
)
|
||||||
self.gen_construction_fields(cons, sumname, depth + 1)
|
self.gen_construction_fields(cons, sumname, depth + 1)
|
||||||
self.emit("})", depth + 1)
|
self.emit("})", depth + 1)
|
||||||
else:
|
else:
|
||||||
self.emit(f"ast::{rustname}::{cons.name}", depth + 1)
|
self.emit(f"ast::located::{rustname}::{cons.name}", depth + 1)
|
||||||
self.emit("} else", depth)
|
self.emit("} else", depth)
|
||||||
|
|
||||||
self.emit("{", depth)
|
self.emit("{", depth)
|
||||||
|
@ -684,14 +754,14 @@ class TraitImplVisitor(EmitVisitor):
|
||||||
)
|
)
|
||||||
|
|
||||||
def gen_construction(self, cons_path, cons, name, depth):
|
def gen_construction(self, cons_path, cons, name, depth):
|
||||||
self.emit(f"ast::{cons_path} {{", depth)
|
self.emit(f"ast::located::{cons_path} {{", depth)
|
||||||
self.gen_construction_fields(cons, name, depth + 1)
|
self.gen_construction_fields(cons, name, depth + 1)
|
||||||
self.emit("}", depth)
|
self.emit("}", depth)
|
||||||
|
|
||||||
def extract_location(self, typename, depth):
|
def extract_location(self, typename, depth):
|
||||||
row = self.decode_field(asdl.Field("int", "lineno"), typename)
|
row = self.decode_field(asdl.Field("int", "lineno"), typename)
|
||||||
column = self.decode_field(asdl.Field("int", "col_offset"), typename)
|
column = self.decode_field(asdl.Field("int", "col_offset"), typename)
|
||||||
self.emit(f"let _location = ast::Location::new({row}, {column});", depth)
|
self.emit(f"let _location = Location::new({row}, {column});", depth)
|
||||||
|
|
||||||
def decode_field(self, field, typename):
|
def decode_field(self, field, typename):
|
||||||
name = json.dumps(field.name)
|
name = json.dumps(field.name)
|
||||||
|
@ -711,92 +781,52 @@ class ChainOfVisitors:
|
||||||
v.emit("", 0)
|
v.emit("", 0)
|
||||||
|
|
||||||
|
|
||||||
def write_ast_def(mod, typeinfo, f):
|
def write_generic_def(mod, typeinfo, f):
|
||||||
f.write(
|
f.write(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
#![allow(clippy::derive_partial_eq_without_eq)]
|
#![allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
|
||||||
pub use crate::constant::*;
|
pub use crate::{Attributed, constant::*};
|
||||||
pub use rustpython_compiler_core::text_size::{TextSize, TextRange};
|
use rustpython_compiler_core::{text_size::{TextSize, TextRange}};
|
||||||
|
|
||||||
type Ident = String;
|
type Ident = String;
|
||||||
\n
|
\n
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
StructVisitor(f, typeinfo).emit_attrs(0)
|
|
||||||
f.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
"""
|
|
||||||
pub struct Located<T, U = ()> {
|
|
||||||
pub range: TextRange,
|
|
||||||
pub custom: U,
|
|
||||||
pub node: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Located<T> {
|
|
||||||
pub fn new(start: TextSize, end: TextSize, node: T) -> Self {
|
|
||||||
Self { range: TextRange::new(start, end), custom: (), node }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new node that spans the position specified by `range`.
|
|
||||||
pub fn with_range(node: T, range: TextRange) -> Self {
|
|
||||||
Self {
|
|
||||||
range,
|
|
||||||
custom: (),
|
|
||||||
node,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the absolute start position of the node from the beginning of the document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn start(&self) -> TextSize {
|
|
||||||
self.range.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the node
|
|
||||||
#[inline]
|
|
||||||
pub fn node(&self) -> &T {
|
|
||||||
&self.node
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes self and returns the node.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_node(self) -> T {
|
|
||||||
self.node
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the `range` of the node. The range offsets are absolute to the start of the document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn range(&self) -> TextRange {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the absolute position at which the node ends in the source document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn end(&self) -> TextSize {
|
|
||||||
self.range.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> std::ops::Deref for Located<T, U> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
\n
|
|
||||||
""".lstrip()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
c = ChainOfVisitors(StructVisitor(f, typeinfo), FoldModuleVisitor(f, typeinfo))
|
c = ChainOfVisitors(StructVisitor(f, typeinfo), FoldModuleVisitor(f, typeinfo))
|
||||||
c.visit(mod)
|
c.visit(mod)
|
||||||
|
|
||||||
|
|
||||||
def write_ast_mod(mod, f):
|
def write_located_def(typeinfo, f):
|
||||||
|
f.write(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
use rustpython_compiler_core::LocationRange;
|
||||||
|
|
||||||
|
pub type Located<T> = super::generic::Attributed<T, LocationRange>;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for info in typeinfo.values():
|
||||||
|
if info.has_userdata:
|
||||||
|
generics = "::<LocationRange>"
|
||||||
|
else:
|
||||||
|
generics = ""
|
||||||
|
f.write(
|
||||||
|
f"pub type {info.rust_sum_name} = super::generic::{info.rust_sum_name}{generics};\n"
|
||||||
|
)
|
||||||
|
if info.rust_suffix:
|
||||||
|
if info.rust_suffix == "Data" and not info.has_expr:
|
||||||
|
generics = ""
|
||||||
|
f.write(
|
||||||
|
f"pub type {info.rust_sum_name}{info.rust_suffix} = super::generic::{info.rust_sum_name}{info.rust_suffix}{generics};\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def write_ast_mod(mod, typeinfo, f):
|
||||||
f.write(
|
f.write(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
|
@ -804,16 +834,25 @@ def write_ast_mod(mod, f):
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::common::ascii;
|
use crate::common::ascii;
|
||||||
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
c = ChainOfVisitors(ClassDefVisitor(f), TraitImplVisitor(f), ExtendModuleVisitor(f))
|
c = ChainOfVisitors(
|
||||||
|
ClassDefVisitor(f, typeinfo),
|
||||||
|
TraitImplVisitor(f, typeinfo),
|
||||||
|
ExtendModuleVisitor(f, typeinfo),
|
||||||
|
)
|
||||||
c.visit(mod)
|
c.visit(mod)
|
||||||
|
|
||||||
|
|
||||||
def main(input_filename, ast_mod_filename, ast_def_filename, dump_module=False):
|
def main(
|
||||||
|
input_filename,
|
||||||
|
generic_filename,
|
||||||
|
located_filename,
|
||||||
|
module_filename,
|
||||||
|
dump_module=False,
|
||||||
|
):
|
||||||
auto_gen_msg = AUTOGEN_MESSAGE.format("/".join(Path(__file__).parts[-2:]))
|
auto_gen_msg = AUTOGEN_MESSAGE.format("/".join(Path(__file__).parts[-2:]))
|
||||||
mod = asdl.parse(input_filename)
|
mod = asdl.parse(input_filename)
|
||||||
if dump_module:
|
if dump_module:
|
||||||
|
@ -825,22 +864,34 @@ def main(input_filename, ast_mod_filename, ast_def_filename, dump_module=False):
|
||||||
typeinfo = {}
|
typeinfo = {}
|
||||||
FindUserdataTypesVisitor(typeinfo).visit(mod)
|
FindUserdataTypesVisitor(typeinfo).visit(mod)
|
||||||
|
|
||||||
with ast_def_filename.open("w") as def_file, ast_mod_filename.open("w") as mod_file:
|
with generic_filename.open("w") as generic_file, located_filename.open(
|
||||||
def_file.write(auto_gen_msg)
|
"w"
|
||||||
write_ast_def(mod, typeinfo, def_file)
|
) as located_file:
|
||||||
|
generic_file.write(auto_gen_msg)
|
||||||
|
write_generic_def(mod, typeinfo, generic_file)
|
||||||
|
located_file.write(auto_gen_msg)
|
||||||
|
write_located_def(typeinfo, located_file)
|
||||||
|
|
||||||
mod_file.write(auto_gen_msg)
|
with module_filename.open("w") as module_file:
|
||||||
write_ast_mod(mod, mod_file)
|
module_file.write(auto_gen_msg)
|
||||||
|
write_ast_mod(mod, typeinfo, module_file)
|
||||||
|
|
||||||
print(f"{ast_def_filename}, {ast_mod_filename} regenerated.")
|
print(f"{generic_filename}, {located_filename}, {module_filename} regenerated.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument("input_file", type=Path)
|
parser.add_argument("input_file", type=Path)
|
||||||
parser.add_argument("-M", "--mod-file", type=Path, required=True)
|
parser.add_argument("-G", "--generic-file", type=Path, required=True)
|
||||||
parser.add_argument("-D", "--def-file", type=Path, required=True)
|
parser.add_argument("-L", "--located-file", type=Path, required=True)
|
||||||
|
parser.add_argument("-M", "--module-file", type=Path, required=True)
|
||||||
parser.add_argument("-d", "--dump-module", action="store_true")
|
parser.add_argument("-d", "--dump-module", action="store_true")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
main(args.input_file, args.mod_file, args.def_file, args.dump_module)
|
main(
|
||||||
|
args.input_file,
|
||||||
|
args.generic_file,
|
||||||
|
args.located_file,
|
||||||
|
args.module_file,
|
||||||
|
args.dump_module,
|
||||||
|
)
|
||||||
|
|
76
ast/src/attributed.rs
Normal file
76
ast/src/attributed.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use rustpython_compiler_core::{
|
||||||
|
text_size::{TextRange, TextSize},
|
||||||
|
Location, LocationRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Attributed<T, U = ()> {
|
||||||
|
pub range: TextRange,
|
||||||
|
pub custom: U,
|
||||||
|
pub node: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, U> Attributed<T, U> {
|
||||||
|
/// Returns the node
|
||||||
|
#[inline]
|
||||||
|
pub fn node(&self) -> &T {
|
||||||
|
&self.node
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `range` of the node. The range offsets are absolute to the start of the document.
|
||||||
|
#[inline]
|
||||||
|
pub const fn range(&self) -> TextRange {
|
||||||
|
self.range
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the absolute start position of the node from the beginning of the document.
|
||||||
|
#[inline]
|
||||||
|
pub const fn start(&self) -> TextSize {
|
||||||
|
self.range.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the absolute position at which the node ends in the source document.
|
||||||
|
#[inline]
|
||||||
|
pub const fn end(&self) -> TextSize {
|
||||||
|
self.range.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Attributed<T, ()> {
|
||||||
|
/// Creates a new node that spans the position specified by `range`.
|
||||||
|
pub fn new(range: impl Into<TextRange>, node: T) -> Self {
|
||||||
|
Self {
|
||||||
|
range: range.into(),
|
||||||
|
custom: (),
|
||||||
|
node,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes self and returns the node.
|
||||||
|
#[inline]
|
||||||
|
pub fn into_node(self) -> T {
|
||||||
|
self.node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Attributed<T, LocationRange> {
|
||||||
|
/// Returns the absolute start position of the node from the beginning of the document.
|
||||||
|
#[inline]
|
||||||
|
pub const fn location(&self) -> Location {
|
||||||
|
self.custom.start
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the absolute position at which the node ends in the source document.
|
||||||
|
#[inline]
|
||||||
|
pub const fn end_location(&self) -> Location {
|
||||||
|
self.custom.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, U> std::ops::Deref for Attributed<T, U> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.node
|
||||||
|
}
|
||||||
|
}
|
|
@ -137,6 +137,7 @@ impl<U> crate::fold::Fold<U> for ConstantOptimizer {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use rustpython_compiler_core::text_size::TextRange;
|
||||||
|
|
||||||
#[cfg(feature = "constant-optimization")]
|
#[cfg(feature = "constant-optimization")]
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -146,13 +147,13 @@ mod tests {
|
||||||
let range = TextRange::default();
|
let range = TextRange::default();
|
||||||
#[allow(clippy::let_unit_value)]
|
#[allow(clippy::let_unit_value)]
|
||||||
let custom = ();
|
let custom = ();
|
||||||
let ast = Located {
|
let ast = Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprTuple {
|
node: ExprTuple {
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
elts: vec![
|
elts: vec![
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
@ -161,7 +162,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
},
|
},
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
@ -170,13 +171,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
},
|
},
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprTuple {
|
node: ExprTuple {
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
elts: vec![
|
elts: vec![
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
@ -185,7 +186,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
},
|
},
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
@ -194,7 +195,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
},
|
},
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
@ -216,7 +217,7 @@ mod tests {
|
||||||
.unwrap_or_else(|e| match e {});
|
.unwrap_or_else(|e| match e {});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
new_ast,
|
new_ast,
|
||||||
Located {
|
Attributed {
|
||||||
range,
|
range,
|
||||||
custom,
|
custom,
|
||||||
node: ExprConstant {
|
node: ExprConstant {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{constant, fold::Fold};
|
use crate::{constant, fold::Fold};
|
||||||
|
|
||||||
pub(crate) trait Foldable<T, U> {
|
pub trait Foldable<T, U> {
|
||||||
type Mapped;
|
type Mapped;
|
||||||
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -2,75 +2,11 @@
|
||||||
|
|
||||||
#![allow(clippy::derive_partial_eq_without_eq)]
|
#![allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
|
||||||
pub use crate::constant::*;
|
pub use crate::{constant::*, Attributed};
|
||||||
pub use rustpython_compiler_core::text_size::{TextRange, TextSize};
|
use rustpython_compiler_core::text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
type Ident = String;
|
type Ident = String;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Located<T, U = ()> {
|
|
||||||
pub range: TextRange,
|
|
||||||
pub custom: U,
|
|
||||||
pub node: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Located<T> {
|
|
||||||
pub fn new(start: TextSize, end: TextSize, node: T) -> Self {
|
|
||||||
Self {
|
|
||||||
range: TextRange::new(start, end),
|
|
||||||
custom: (),
|
|
||||||
node,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new node that spans the position specified by `range`.
|
|
||||||
pub fn with_range(node: T, range: TextRange) -> Self {
|
|
||||||
Self {
|
|
||||||
range,
|
|
||||||
custom: (),
|
|
||||||
node,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the absolute start position of the node from the beginning of the document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn start(&self) -> TextSize {
|
|
||||||
self.range.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the node
|
|
||||||
#[inline]
|
|
||||||
pub fn node(&self) -> &T {
|
|
||||||
&self.node
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes self and returns the node.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_node(self) -> T {
|
|
||||||
self.node
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the `range` of the node. The range offsets are absolute to the start of the document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn range(&self) -> TextRange {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the absolute position at which the node ends in the source document.
|
|
||||||
#[inline]
|
|
||||||
pub const fn end(&self) -> TextSize {
|
|
||||||
self.range.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> std::ops::Deref for Located<T, U> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ModModule<U = ()> {
|
pub struct ModModule<U = ()> {
|
||||||
pub body: Vec<Stmt<U>>,
|
pub body: Vec<Stmt<U>>,
|
||||||
|
@ -467,7 +403,7 @@ pub enum StmtKind<U = ()> {
|
||||||
Break,
|
Break,
|
||||||
Continue,
|
Continue,
|
||||||
}
|
}
|
||||||
pub type Stmt<U = ()> = Located<StmtKind<U>, U>;
|
pub type Stmt<U = ()> = Attributed<StmtKind<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ExprBoolOp<U = ()> {
|
pub struct ExprBoolOp<U = ()> {
|
||||||
|
@ -827,7 +763,7 @@ pub enum ExprKind<U = ()> {
|
||||||
Tuple(ExprTuple<U>),
|
Tuple(ExprTuple<U>),
|
||||||
Slice(ExprSlice<U>),
|
Slice(ExprSlice<U>),
|
||||||
}
|
}
|
||||||
pub type Expr<U = ()> = Located<ExprKind<U>, U>;
|
pub type Expr<U = ()> = Attributed<ExprKind<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum ExprContext {
|
pub enum ExprContext {
|
||||||
|
@ -906,7 +842,7 @@ impl<U> From<ExcepthandlerExceptHandler<U>> for ExcepthandlerKind<U> {
|
||||||
pub enum ExcepthandlerKind<U = ()> {
|
pub enum ExcepthandlerKind<U = ()> {
|
||||||
ExceptHandler(ExcepthandlerExceptHandler<U>),
|
ExceptHandler(ExcepthandlerExceptHandler<U>),
|
||||||
}
|
}
|
||||||
pub type Excepthandler<U = ()> = Located<ExcepthandlerKind<U>, U>;
|
pub type Excepthandler<U = ()> = Attributed<ExcepthandlerKind<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Arguments<U = ()> {
|
pub struct Arguments<U = ()> {
|
||||||
|
@ -925,21 +861,21 @@ pub struct ArgData<U = ()> {
|
||||||
pub annotation: Option<Box<Expr<U>>>,
|
pub annotation: Option<Box<Expr<U>>>,
|
||||||
pub type_comment: Option<String>,
|
pub type_comment: Option<String>,
|
||||||
}
|
}
|
||||||
pub type Arg<U = ()> = Located<ArgData<U>, U>;
|
pub type Arg<U = ()> = Attributed<ArgData<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct KeywordData<U = ()> {
|
pub struct KeywordData<U = ()> {
|
||||||
pub arg: Option<Ident>,
|
pub arg: Option<Ident>,
|
||||||
pub value: Expr<U>,
|
pub value: Expr<U>,
|
||||||
}
|
}
|
||||||
pub type Keyword<U = ()> = Located<KeywordData<U>, U>;
|
pub type Keyword<U = ()> = Attributed<KeywordData<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct AliasData {
|
pub struct AliasData {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub asname: Option<Ident>,
|
pub asname: Option<Ident>,
|
||||||
}
|
}
|
||||||
pub type Alias<U = ()> = Located<AliasData, U>;
|
pub type Alias<U = ()> = Attributed<AliasData, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Withitem<U = ()> {
|
pub struct Withitem<U = ()> {
|
||||||
|
@ -1059,7 +995,7 @@ pub enum PatternKind<U = ()> {
|
||||||
MatchAs(PatternMatchAs<U>),
|
MatchAs(PatternMatchAs<U>),
|
||||||
MatchOr(PatternMatchOr<U>),
|
MatchOr(PatternMatchOr<U>),
|
||||||
}
|
}
|
||||||
pub type Pattern<U = ()> = Located<PatternKind<U>, U>;
|
pub type Pattern<U = ()> = Attributed<PatternKind<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct TypeIgnoreTypeIgnore {
|
pub struct TypeIgnoreTypeIgnore {
|
||||||
|
@ -1086,6 +1022,17 @@ pub mod fold {
|
||||||
type TargetU;
|
type TargetU;
|
||||||
type Error;
|
type Error;
|
||||||
fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;
|
fn map_user(&mut self, user: U) -> Result<Self::TargetU, Self::Error>;
|
||||||
|
fn map_located<T>(
|
||||||
|
&mut self,
|
||||||
|
located: Attributed<T, U>,
|
||||||
|
) -> Result<Attributed<T, Self::TargetU>, Self::Error> {
|
||||||
|
let custom = self.map_user(located.custom)?;
|
||||||
|
Ok(Attributed {
|
||||||
|
range: located.range,
|
||||||
|
custom,
|
||||||
|
node: located.node,
|
||||||
|
})
|
||||||
|
}
|
||||||
fn fold_mod(&mut self, node: Mod<U>) -> Result<Mod<Self::TargetU>, Self::Error> {
|
fn fold_mod(&mut self, node: Mod<U>) -> Result<Mod<Self::TargetU>, Self::Error> {
|
||||||
fold_mod(self, node)
|
fold_mod(self, node)
|
||||||
}
|
}
|
||||||
|
@ -1164,11 +1111,12 @@ pub mod fold {
|
||||||
}
|
}
|
||||||
fn fold_located<U, F: Fold<U> + ?Sized, T, MT>(
|
fn fold_located<U, F: Fold<U> + ?Sized, T, MT>(
|
||||||
folder: &mut F,
|
folder: &mut F,
|
||||||
node: Located<T, U>,
|
node: Attributed<T, U>,
|
||||||
f: impl FnOnce(&mut F, T) -> Result<MT, F::Error>,
|
f: impl FnOnce(&mut F, T) -> Result<MT, F::Error>,
|
||||||
) -> Result<Located<MT, F::TargetU>, F::Error> {
|
) -> Result<Attributed<MT, F::TargetU>, F::Error> {
|
||||||
Ok(Located {
|
let node = folder.map_located(node)?;
|
||||||
custom: folder.map_user(node.custom)?,
|
Ok(Attributed {
|
||||||
|
custom: node.custom,
|
||||||
range: node.range,
|
range: node.range,
|
||||||
node: f(folder, node.node)?,
|
node: f(folder, node.node)?,
|
||||||
})
|
})
|
|
@ -1,11 +1,21 @@
|
||||||
mod ast_gen;
|
mod attributed;
|
||||||
mod constant;
|
mod constant;
|
||||||
#[cfg(feature = "fold")]
|
#[cfg(feature = "fold")]
|
||||||
mod fold_helpers;
|
mod fold_helpers;
|
||||||
|
mod generic;
|
||||||
mod impls;
|
mod impls;
|
||||||
|
#[cfg(feature = "location")]
|
||||||
|
pub mod located;
|
||||||
|
#[cfg(feature = "location")]
|
||||||
|
mod locator;
|
||||||
|
|
||||||
#[cfg(feature = "unparse")]
|
#[cfg(feature = "unparse")]
|
||||||
mod unparse;
|
mod unparse;
|
||||||
|
|
||||||
pub use ast_gen::*;
|
pub use attributed::Attributed;
|
||||||
|
pub use constant::{Constant, ConversionFlag};
|
||||||
|
pub use generic::*;
|
||||||
|
#[cfg(feature = "location")]
|
||||||
|
pub use locator::Locator;
|
||||||
|
|
||||||
pub type Suite<U = ()> = Vec<Stmt<U>>;
|
pub type Suite<U = ()> = Vec<Stmt<U>>;
|
||||||
|
|
95
ast/src/located.rs
Normal file
95
ast/src/located.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// File automatically generated by ast/asdl_rs.py.
|
||||||
|
|
||||||
|
use rustpython_compiler_core::LocationRange;
|
||||||
|
|
||||||
|
pub type Located<T> = super::generic::Attributed<T, LocationRange>;
|
||||||
|
pub type Mod = super::generic::Mod<LocationRange>;
|
||||||
|
pub type ModModule = super::generic::ModModule<LocationRange>;
|
||||||
|
pub type ModInteractive = super::generic::ModInteractive<LocationRange>;
|
||||||
|
pub type ModExpression = super::generic::ModExpression<LocationRange>;
|
||||||
|
pub type ModFunctionType = super::generic::ModFunctionType<LocationRange>;
|
||||||
|
pub type Stmt = super::generic::Stmt<LocationRange>;
|
||||||
|
pub type StmtKind = super::generic::StmtKind<LocationRange>;
|
||||||
|
pub type StmtFunctionDef = super::generic::StmtFunctionDef<LocationRange>;
|
||||||
|
pub type StmtAsyncFunctionDef = super::generic::StmtAsyncFunctionDef<LocationRange>;
|
||||||
|
pub type StmtClassDef = super::generic::StmtClassDef<LocationRange>;
|
||||||
|
pub type StmtReturn = super::generic::StmtReturn<LocationRange>;
|
||||||
|
pub type StmtDelete = super::generic::StmtDelete<LocationRange>;
|
||||||
|
pub type StmtAssign = super::generic::StmtAssign<LocationRange>;
|
||||||
|
pub type StmtAugAssign = super::generic::StmtAugAssign<LocationRange>;
|
||||||
|
pub type StmtAnnAssign = super::generic::StmtAnnAssign<LocationRange>;
|
||||||
|
pub type StmtFor = super::generic::StmtFor<LocationRange>;
|
||||||
|
pub type StmtAsyncFor = super::generic::StmtAsyncFor<LocationRange>;
|
||||||
|
pub type StmtWhile = super::generic::StmtWhile<LocationRange>;
|
||||||
|
pub type StmtIf = super::generic::StmtIf<LocationRange>;
|
||||||
|
pub type StmtWith = super::generic::StmtWith<LocationRange>;
|
||||||
|
pub type StmtAsyncWith = super::generic::StmtAsyncWith<LocationRange>;
|
||||||
|
pub type StmtMatch = super::generic::StmtMatch<LocationRange>;
|
||||||
|
pub type StmtRaise = super::generic::StmtRaise<LocationRange>;
|
||||||
|
pub type StmtTry = super::generic::StmtTry<LocationRange>;
|
||||||
|
pub type StmtTryStar = super::generic::StmtTryStar<LocationRange>;
|
||||||
|
pub type StmtAssert = super::generic::StmtAssert<LocationRange>;
|
||||||
|
pub type StmtImport = super::generic::StmtImport<LocationRange>;
|
||||||
|
pub type StmtImportFrom = super::generic::StmtImportFrom<LocationRange>;
|
||||||
|
pub type StmtGlobal = super::generic::StmtGlobal;
|
||||||
|
pub type StmtNonlocal = super::generic::StmtNonlocal;
|
||||||
|
pub type StmtExpr = super::generic::StmtExpr<LocationRange>;
|
||||||
|
pub type Expr = super::generic::Expr<LocationRange>;
|
||||||
|
pub type ExprKind = super::generic::ExprKind<LocationRange>;
|
||||||
|
pub type ExprBoolOp = super::generic::ExprBoolOp<LocationRange>;
|
||||||
|
pub type ExprNamedExpr = super::generic::ExprNamedExpr<LocationRange>;
|
||||||
|
pub type ExprBinOp = super::generic::ExprBinOp<LocationRange>;
|
||||||
|
pub type ExprUnaryOp = super::generic::ExprUnaryOp<LocationRange>;
|
||||||
|
pub type ExprLambda = super::generic::ExprLambda<LocationRange>;
|
||||||
|
pub type ExprIfExp = super::generic::ExprIfExp<LocationRange>;
|
||||||
|
pub type ExprDict = super::generic::ExprDict<LocationRange>;
|
||||||
|
pub type ExprSet = super::generic::ExprSet<LocationRange>;
|
||||||
|
pub type ExprListComp = super::generic::ExprListComp<LocationRange>;
|
||||||
|
pub type ExprSetComp = super::generic::ExprSetComp<LocationRange>;
|
||||||
|
pub type ExprDictComp = super::generic::ExprDictComp<LocationRange>;
|
||||||
|
pub type ExprGeneratorExp = super::generic::ExprGeneratorExp<LocationRange>;
|
||||||
|
pub type ExprAwait = super::generic::ExprAwait<LocationRange>;
|
||||||
|
pub type ExprYield = super::generic::ExprYield<LocationRange>;
|
||||||
|
pub type ExprYieldFrom = super::generic::ExprYieldFrom<LocationRange>;
|
||||||
|
pub type ExprCompare = super::generic::ExprCompare<LocationRange>;
|
||||||
|
pub type ExprCall = super::generic::ExprCall<LocationRange>;
|
||||||
|
pub type ExprFormattedValue = super::generic::ExprFormattedValue<LocationRange>;
|
||||||
|
pub type ExprJoinedStr = super::generic::ExprJoinedStr<LocationRange>;
|
||||||
|
pub type ExprConstant = super::generic::ExprConstant;
|
||||||
|
pub type ExprAttribute = super::generic::ExprAttribute<LocationRange>;
|
||||||
|
pub type ExprSubscript = super::generic::ExprSubscript<LocationRange>;
|
||||||
|
pub type ExprStarred = super::generic::ExprStarred<LocationRange>;
|
||||||
|
pub type ExprName = super::generic::ExprName;
|
||||||
|
pub type ExprList = super::generic::ExprList<LocationRange>;
|
||||||
|
pub type ExprTuple = super::generic::ExprTuple<LocationRange>;
|
||||||
|
pub type ExprSlice = super::generic::ExprSlice<LocationRange>;
|
||||||
|
pub type ExprContext = super::generic::ExprContext;
|
||||||
|
pub type Boolop = super::generic::Boolop;
|
||||||
|
pub type Operator = super::generic::Operator;
|
||||||
|
pub type Unaryop = super::generic::Unaryop;
|
||||||
|
pub type Cmpop = super::generic::Cmpop;
|
||||||
|
pub type Comprehension = super::generic::Comprehension<LocationRange>;
|
||||||
|
pub type Excepthandler = super::generic::Excepthandler<LocationRange>;
|
||||||
|
pub type ExcepthandlerKind = super::generic::ExcepthandlerKind<LocationRange>;
|
||||||
|
pub type ExcepthandlerExceptHandler = super::generic::ExcepthandlerExceptHandler<LocationRange>;
|
||||||
|
pub type Arguments = super::generic::Arguments<LocationRange>;
|
||||||
|
pub type Arg = super::generic::Arg<LocationRange>;
|
||||||
|
pub type ArgData = super::generic::ArgData<LocationRange>;
|
||||||
|
pub type Keyword = super::generic::Keyword<LocationRange>;
|
||||||
|
pub type KeywordData = super::generic::KeywordData<LocationRange>;
|
||||||
|
pub type Alias = super::generic::Alias<LocationRange>;
|
||||||
|
pub type AliasData = super::generic::AliasData;
|
||||||
|
pub type Withitem = super::generic::Withitem<LocationRange>;
|
||||||
|
pub type MatchCase = super::generic::MatchCase<LocationRange>;
|
||||||
|
pub type Pattern = super::generic::Pattern<LocationRange>;
|
||||||
|
pub type PatternKind = super::generic::PatternKind<LocationRange>;
|
||||||
|
pub type PatternMatchValue = super::generic::PatternMatchValue<LocationRange>;
|
||||||
|
pub type PatternMatchSingleton = super::generic::PatternMatchSingleton;
|
||||||
|
pub type PatternMatchSequence = super::generic::PatternMatchSequence<LocationRange>;
|
||||||
|
pub type PatternMatchMapping = super::generic::PatternMatchMapping<LocationRange>;
|
||||||
|
pub type PatternMatchClass = super::generic::PatternMatchClass<LocationRange>;
|
||||||
|
pub type PatternMatchStar = super::generic::PatternMatchStar;
|
||||||
|
pub type PatternMatchAs = super::generic::PatternMatchAs<LocationRange>;
|
||||||
|
pub type PatternMatchOr = super::generic::PatternMatchOr<LocationRange>;
|
||||||
|
pub type TypeIgnore = super::generic::TypeIgnore;
|
||||||
|
pub type TypeIgnoreTypeIgnore = super::generic::TypeIgnoreTypeIgnore;
|
57
ast/src/locator.rs
Normal file
57
ast/src/locator.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use crate::attributed::Attributed;
|
||||||
|
use crate::fold_helpers::Foldable;
|
||||||
|
use rustpython_compiler_core::{
|
||||||
|
text_size::{TextRange, TextSize},
|
||||||
|
Location, LocationRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Converts source code byte-offset to Python convention line and column numbers.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Locator<'a> {
|
||||||
|
source: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Locator<'a> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(source: &'a str) -> Self {
|
||||||
|
Self { source }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source(&'a self) -> &'a str {
|
||||||
|
self.source
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate(&mut self, offset: TextSize) -> Location {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_range(&mut self, range: TextRange) -> LocationRange {
|
||||||
|
self.locate(range.start())..self.locate(range.end())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_ast<X: Foldable<(), LocationRange>>(&mut self, ast: X) -> X::Mapped {
|
||||||
|
ast.fold(self).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::fold::Fold<()> for Locator<'_> {
|
||||||
|
type TargetU = LocationRange;
|
||||||
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
fn map_user(&mut self, _user: ()) -> Result<Self::TargetU, Self::Error> {
|
||||||
|
unreachable!("implemented map_located");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_located<T>(
|
||||||
|
&mut self,
|
||||||
|
node: Attributed<T, ()>,
|
||||||
|
) -> Result<Attributed<T, Self::TargetU>, Self::Error> {
|
||||||
|
let location = self.locate_range(node.range);
|
||||||
|
Ok(Attributed {
|
||||||
|
range: node.range,
|
||||||
|
custom: location,
|
||||||
|
node: node.node,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
use ruff_text_size::TextSize;
|
use crate::{text_size::TextSize, Location};
|
||||||
use std::error::Error as StdError;
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct BaseError<T> {
|
pub struct BaseError<T> {
|
||||||
pub error: T,
|
pub error: T,
|
||||||
pub location: TextSize,
|
pub offset: TextSize,
|
||||||
pub source_path: String,
|
pub source_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,11 +16,11 @@ impl<T> std::ops::Deref for BaseError<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StdError for BaseError<T>
|
impl<T> std::error::Error for BaseError<T>
|
||||||
where
|
where
|
||||||
T: StdError + 'static,
|
T: std::error::Error + 'static,
|
||||||
{
|
{
|
||||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
Some(&self.error)
|
Some(&self.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +34,7 @@ where
|
||||||
f,
|
f,
|
||||||
"{} at byte offset {}",
|
"{} at byte offset {}",
|
||||||
&self.error,
|
&self.error,
|
||||||
u32::from(self.location)
|
u32::from(self.offset)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +50,7 @@ impl<T> BaseError<T> {
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
error: obj.error.into(),
|
error: obj.error.into(),
|
||||||
location: obj.location,
|
offset: obj.offset,
|
||||||
source_path: obj.source_path,
|
source_path: obj.source_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,4 +61,64 @@ impl<T> BaseError<T> {
|
||||||
{
|
{
|
||||||
BaseError::from(self)
|
BaseError::from(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_located<U>(self, locator: &str) -> LocatedError<U>
|
||||||
|
where
|
||||||
|
T: Into<U>,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct LocatedError<T> {
|
||||||
|
pub error: T,
|
||||||
|
pub location: Location,
|
||||||
|
pub source_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> LocatedError<T> {
|
||||||
|
pub fn error(self) -> T {
|
||||||
|
self.error
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from<U>(obj: LocatedError<U>) -> Self
|
||||||
|
where
|
||||||
|
U: Into<T>,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
error: obj.error.into(),
|
||||||
|
location: obj.location,
|
||||||
|
source_path: obj.source_path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into<U>(self) -> LocatedError<U>
|
||||||
|
where
|
||||||
|
T: Into<U>,
|
||||||
|
{
|
||||||
|
LocatedError::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Display for LocatedError<T>
|
||||||
|
where
|
||||||
|
T: std::fmt::Display,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{} at row {} col {}",
|
||||||
|
&self.error, self.location.row, self.location.column,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::error::Error for LocatedError<T>
|
||||||
|
where
|
||||||
|
T: std::error::Error + 'static,
|
||||||
|
{
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
Some(&self.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,13 @@ pub mod marshal;
|
||||||
mod mode;
|
mod mode;
|
||||||
|
|
||||||
pub use bytecode::*;
|
pub use bytecode::*;
|
||||||
pub use error::BaseError;
|
pub use error::{BaseError, LocatedError};
|
||||||
pub use location::Location;
|
pub use location::{Location, LocationRange};
|
||||||
pub use mode::Mode;
|
pub use mode::Mode;
|
||||||
|
|
||||||
pub use ruff_text_size as text_size; // re-export mandatory and frequently accessed dependency
|
pub use ruff_text_size as text_size; // re-export mandatory and frequently accessed dependency
|
||||||
|
|
||||||
|
// FIXME: temp code
|
||||||
|
pub fn to_location(offset: &text_size::TextSize, source: &str) -> Location {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// Source code location.
|
/// Source code location.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
pub(super) row: u32,
|
pub(super) row: u32,
|
||||||
pub(super) column: u32,
|
pub(super) column: u32,
|
||||||
|
@ -96,6 +93,8 @@ impl Location {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type LocationRange = std::ops::Range<Location>;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -114,8 +114,7 @@ pub(crate) fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ArgumentLis
|
||||||
}
|
}
|
||||||
|
|
||||||
keywords.push(ast::Keyword::new(
|
keywords.push(ast::Keyword::new(
|
||||||
start,
|
start..end,
|
||||||
end,
|
|
||||||
ast::KeywordData { arg: name, value },
|
ast::KeywordData { arg: name, value },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,9 @@ pub fn lex(source: &str, mode: Mode) -> impl Iterator<Item = LexResult> + '_ {
|
||||||
pub fn lex_located(
|
pub fn lex_located(
|
||||||
source: &str,
|
source: &str,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
start_location: TextSize,
|
start_offset: TextSize,
|
||||||
) -> impl Iterator<Item = LexResult> + '_ {
|
) -> impl Iterator<Item = LexResult> + '_ {
|
||||||
SoftKeywordTransformer::new(Lexer::new(source.chars(), start_location), mode)
|
SoftKeywordTransformer::new(Lexer::new(source.chars(), start_offset), mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Lexer<T>
|
impl<T> Lexer<T>
|
||||||
|
|
|
@ -92,9 +92,9 @@ pub fn parse_expression(source: &str, path: &str) -> Result<ast::Expr, ParseErro
|
||||||
pub fn parse_expression_located(
|
pub fn parse_expression_located(
|
||||||
source: &str,
|
source: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
location: TextSize,
|
offset: TextSize,
|
||||||
) -> Result<ast::Expr, ParseError> {
|
) -> Result<ast::Expr, ParseError> {
|
||||||
parse_located(source, Mode::Expression, path, location).map(|top| match top {
|
parse_located(source, Mode::Expression, path, offset).map(|top| match top {
|
||||||
ast::Mod::Expression(ast::ModExpression { body }) => *body,
|
ast::Mod::Expression(ast::ModExpression { body }) => *body,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
|
@ -161,9 +161,9 @@ pub fn parse_located(
|
||||||
source: &str,
|
source: &str,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
source_path: &str,
|
source_path: &str,
|
||||||
location: TextSize,
|
offset: TextSize,
|
||||||
) -> Result<ast::Mod, ParseError> {
|
) -> Result<ast::Mod, ParseError> {
|
||||||
let lxr = lexer::lex_located(source, mode, location);
|
let lxr = lexer::lex_located(source, mode, offset);
|
||||||
parse_tokens(lxr, mode, source_path)
|
parse_tokens(lxr, mode, source_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,17 +233,17 @@ fn parse_error_from_lalrpop(
|
||||||
// TODO: Are there cases where this isn't an EOF?
|
// TODO: Are there cases where this isn't an EOF?
|
||||||
LalrpopError::InvalidToken { location } => ParseError {
|
LalrpopError::InvalidToken { location } => ParseError {
|
||||||
error: ParseErrorType::Eof,
|
error: ParseErrorType::Eof,
|
||||||
location,
|
offset: location,
|
||||||
source_path,
|
source_path,
|
||||||
},
|
},
|
||||||
LalrpopError::ExtraToken { token } => ParseError {
|
LalrpopError::ExtraToken { token } => ParseError {
|
||||||
error: ParseErrorType::ExtraToken(token.1),
|
error: ParseErrorType::ExtraToken(token.1),
|
||||||
location: token.0,
|
offset: token.0,
|
||||||
source_path,
|
source_path,
|
||||||
},
|
},
|
||||||
LalrpopError::User { error } => ParseError {
|
LalrpopError::User { error } => ParseError {
|
||||||
error: ParseErrorType::Lexical(error.error),
|
error: ParseErrorType::Lexical(error.error),
|
||||||
location: error.location,
|
offset: error.location,
|
||||||
source_path,
|
source_path,
|
||||||
},
|
},
|
||||||
LalrpopError::UnrecognizedToken { token, expected } => {
|
LalrpopError::UnrecognizedToken { token, expected } => {
|
||||||
|
@ -252,7 +252,7 @@ fn parse_error_from_lalrpop(
|
||||||
let expected = (expected.len() == 1).then(|| expected[0].clone());
|
let expected = (expected.len() == 1).then(|| expected[0].clone());
|
||||||
ParseError {
|
ParseError {
|
||||||
error: ParseErrorType::UnrecognizedToken(token.1, expected),
|
error: ParseErrorType::UnrecognizedToken(token.1, expected),
|
||||||
location: token.0,
|
offset: token.0,
|
||||||
source_path,
|
source_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,13 +262,13 @@ fn parse_error_from_lalrpop(
|
||||||
if indent_error {
|
if indent_error {
|
||||||
ParseError {
|
ParseError {
|
||||||
error: ParseErrorType::Lexical(LexicalErrorType::IndentationError),
|
error: ParseErrorType::Lexical(LexicalErrorType::IndentationError),
|
||||||
location,
|
offset: location,
|
||||||
source_path,
|
source_path,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ParseError {
|
ParseError {
|
||||||
error: ParseErrorType::Eof,
|
error: ParseErrorType::Eof,
|
||||||
location,
|
offset: location,
|
||||||
source_path,
|
source_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ SmallStatement: ast::Stmt = {
|
||||||
PassStatement: ast::Stmt = {
|
PassStatement: ast::Stmt = {
|
||||||
<location:@L> "pass" <end_location:@R> => {
|
<location:@L> "pass" <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtKind::Pass,
|
ast::StmtKind::Pass,
|
||||||
)
|
)
|
||||||
|
@ -78,7 +78,7 @@ PassStatement: ast::Stmt = {
|
||||||
DelStatement: ast::Stmt = {
|
DelStatement: ast::Stmt = {
|
||||||
<location:@L> "del" <targets:ExpressionList2> <end_location:@R> => {
|
<location:@L> "del" <targets:ExpressionList2> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtDelete { targets: targets.into_iter().map(|expr| set_context(expr, ast::ExprContext::Del)).collect() }.into()
|
ast::StmtDelete { targets: targets.into_iter().map(|expr| set_context(expr, ast::ExprContext::Del)).collect() }.into()
|
||||||
)
|
)
|
||||||
|
@ -90,7 +90,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
// Just an expression, no assignment:
|
// Just an expression, no assignment:
|
||||||
if suffix.is_empty() {
|
if suffix.is_empty() {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtExpr { value: Box::new(expression) }.into()
|
ast::StmtExpr { value: Box::new(expression) }.into()
|
||||||
)
|
)
|
||||||
|
@ -105,7 +105,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
let value = Box::new(values.into_iter().next().unwrap());
|
let value = Box::new(values.into_iter().next().unwrap());
|
||||||
|
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtAssign { targets, value, type_comment: None }.into()
|
ast::StmtAssign { targets, value, type_comment: None }.into()
|
||||||
)
|
)
|
||||||
|
@ -113,7 +113,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
},
|
},
|
||||||
<location:@L> <target:TestOrStarExprList> <op:AugAssign> <rhs:TestListOrYieldExpr> <end_location:@R> => {
|
<location:@L> <target:TestOrStarExprList> <op:AugAssign> <rhs:TestListOrYieldExpr> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtAugAssign {
|
ast::StmtAugAssign {
|
||||||
target: Box::new(set_context(target, ast::ExprContext::Store)),
|
target: Box::new(set_context(target, ast::ExprContext::Store)),
|
||||||
|
@ -125,7 +125,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
<location:@L> <target:Test<"all">> ":" <annotation:Test<"all">> <rhs:AssignSuffix?> <end_location:@R> => {
|
<location:@L> <target:Test<"all">> ":" <annotation:Test<"all">> <rhs:AssignSuffix?> <end_location:@R> => {
|
||||||
let simple = matches!(target.node, ast::ExprKind::Name { .. });
|
let simple = matches!(target.node, ast::ExprKind::Name { .. });
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtAnnAssign {
|
ast::StmtAnnAssign {
|
||||||
target: Box::new(set_context(target, ast::ExprContext::Store)),
|
target: Box::new(set_context(target, ast::ExprContext::Store)),
|
||||||
|
@ -186,28 +186,28 @@ AugAssign: ast::Operator = {
|
||||||
FlowStatement: ast::Stmt = {
|
FlowStatement: ast::Stmt = {
|
||||||
<location:@L> "break" <end_location:@R> => {
|
<location:@L> "break" <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtKind::Break,
|
ast::StmtKind::Break,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "continue" <end_location:@R> => {
|
<location:@L> "continue" <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtKind::Continue,
|
ast::StmtKind::Continue,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "return" <value:TestList?> <end_location:@R> => {
|
<location:@L> "return" <value:TestList?> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtReturn { value: value.map(Box::new) }.into()
|
ast::StmtReturn { value: value.map(Box::new) }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> <expression:YieldExpr> <end_location:@R> => {
|
<location:@L> <expression:YieldExpr> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtExpr { value: Box::new(expression) }.into()
|
ast::StmtExpr { value: Box::new(expression) }.into()
|
||||||
)
|
)
|
||||||
|
@ -218,14 +218,14 @@ FlowStatement: ast::Stmt = {
|
||||||
RaiseStatement: ast::Stmt = {
|
RaiseStatement: ast::Stmt = {
|
||||||
<location:@L> "raise" <end_location:@R> => {
|
<location:@L> "raise" <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtRaise { exc: None, cause: None }.into()
|
ast::StmtRaise { exc: None, cause: None }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "raise" <t:Test<"all">> <c:("from" Test<"all">)?> <end_location:@R> => {
|
<location:@L> "raise" <t:Test<"all">> <c:("from" Test<"all">)?> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtRaise { exc: Some(Box::new(t)), cause: c.map(|x| Box::new(x.1)) }.into()
|
ast::StmtRaise { exc: Some(Box::new(t)), cause: c.map(|x| Box::new(x.1)) }.into()
|
||||||
)
|
)
|
||||||
|
@ -235,7 +235,7 @@ RaiseStatement: ast::Stmt = {
|
||||||
ImportStatement: ast::Stmt = {
|
ImportStatement: ast::Stmt = {
|
||||||
<location:@L> "import" <names: OneOrMore<ImportAsAlias<DottedName>>> <end_location:@R> => {
|
<location:@L> "import" <names: OneOrMore<ImportAsAlias<DottedName>>> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtImport { names }.into()
|
ast::StmtImport { names }.into()
|
||||||
)
|
)
|
||||||
|
@ -243,7 +243,7 @@ ImportStatement: ast::Stmt = {
|
||||||
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> <end_location:@R> => {
|
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> <end_location:@R> => {
|
||||||
let (level, module) = source;
|
let (level, module) = source;
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtImportFrom {
|
ast::StmtImportFrom {
|
||||||
level,
|
level,
|
||||||
|
@ -273,14 +273,14 @@ ImportAsNames: Vec<ast::Alias> = {
|
||||||
<location:@L> "(" <i:OneOrMore<ImportAsAlias<Identifier>>> ","? ")" <end_location:@R> => i,
|
<location:@L> "(" <i:OneOrMore<ImportAsAlias<Identifier>>> ","? ")" <end_location:@R> => i,
|
||||||
<location:@L> "*" <end_location:@R> => {
|
<location:@L> "*" <end_location:@R> => {
|
||||||
// Star import all
|
// Star import all
|
||||||
vec![ast::Alias::new(location, end_location, ast::AliasData { name: "*".to_string(), asname: None })]
|
vec![ast::Alias::new(location..end_location, ast::AliasData { name: "*".to_string(), asname: None })]
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
ImportAsAlias<I>: ast::Alias = {
|
ImportAsAlias<I>: ast::Alias = {
|
||||||
<location:@L> <name:I> <a: ("as" Identifier)?> <end_location:@R> => ast::Alias::new(location, end_location, ast::AliasData { name, asname: a.map(|a| a.1) }),
|
<location:@L> <name:I> <a: ("as" Identifier)?> <end_location:@R> => ast::Alias::new(location..end_location, ast::AliasData { name, asname: a.map(|a| a.1) }),
|
||||||
}
|
}
|
||||||
|
|
||||||
// A name like abc or abc.def.ghi
|
// A name like abc or abc.def.ghi
|
||||||
|
@ -299,7 +299,7 @@ DottedName: String = {
|
||||||
GlobalStatement: ast::Stmt = {
|
GlobalStatement: ast::Stmt = {
|
||||||
<location:@L> "global" <names:OneOrMore<Identifier>> <end_location:@R> => {
|
<location:@L> "global" <names:OneOrMore<Identifier>> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtGlobal { names }.into()
|
ast::StmtGlobal { names }.into()
|
||||||
)
|
)
|
||||||
|
@ -309,7 +309,7 @@ GlobalStatement: ast::Stmt = {
|
||||||
NonlocalStatement: ast::Stmt = {
|
NonlocalStatement: ast::Stmt = {
|
||||||
<location:@L> "nonlocal" <names:OneOrMore<Identifier>> <end_location:@R> => {
|
<location:@L> "nonlocal" <names:OneOrMore<Identifier>> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtNonlocal { names }.into()
|
ast::StmtNonlocal { names }.into()
|
||||||
)
|
)
|
||||||
|
@ -319,7 +319,7 @@ NonlocalStatement: ast::Stmt = {
|
||||||
AssertStatement: ast::Stmt = {
|
AssertStatement: ast::Stmt = {
|
||||||
<location:@L> "assert" <test:Test<"all">> <msg: ("," Test<"all">)?> <end_location:@R> => {
|
<location:@L> "assert" <test:Test<"all">> <msg: ("," Test<"all">)?> <end_location:@R> => {
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtAssert {
|
ast::StmtAssert {
|
||||||
test: Box::new(test),
|
test: Box::new(test),
|
||||||
|
@ -350,7 +350,7 @@ MatchStatement: ast::Stmt = {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.end();
|
.end();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtMatch {
|
ast::StmtMatch {
|
||||||
subject: Box::new(subject),
|
subject: Box::new(subject),
|
||||||
|
@ -367,7 +367,7 @@ MatchStatement: ast::Stmt = {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.end();
|
.end();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtMatch {
|
ast::StmtMatch {
|
||||||
subject: Box::new(subject),
|
subject: Box::new(subject),
|
||||||
|
@ -386,11 +386,11 @@ MatchStatement: ast::Stmt = {
|
||||||
let mut subjects = subjects;
|
let mut subjects = subjects;
|
||||||
subjects.insert(0, subject);
|
subjects.insert(0, subject);
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtMatch {
|
ast::StmtMatch {
|
||||||
subject: Box::new(ast::Expr::new(
|
subject: Box::new(ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple {
|
ast::ExprTuple {
|
||||||
elts: subjects,
|
elts: subjects,
|
||||||
|
@ -421,7 +421,7 @@ Guard: ast::Expr = {
|
||||||
|
|
||||||
Patterns: ast::Pattern = {
|
Patterns: ast::Pattern = {
|
||||||
<location:@L> <pattern:Pattern> "," <end_location:@R> => ast::Pattern::new(
|
<location:@L> <pattern:Pattern> "," <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::PatternMatchSequence {
|
ast::PatternMatchSequence {
|
||||||
patterns: vec![pattern]
|
patterns: vec![pattern]
|
||||||
|
@ -431,7 +431,7 @@ Patterns: ast::Pattern = {
|
||||||
let mut patterns = patterns;
|
let mut patterns = patterns;
|
||||||
patterns.insert(0, pattern);
|
patterns.insert(0, pattern);
|
||||||
ast::Pattern::new(
|
ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::PatternMatchSequence {
|
ast::PatternMatchSequence {
|
||||||
patterns
|
patterns
|
||||||
|
@ -455,7 +455,7 @@ AsPattern: ast::Pattern = {
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
Ok(ast::Pattern::new(
|
Ok(ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::PatternMatchAs {
|
ast::PatternMatchAs {
|
||||||
pattern: Some(Box::new(pattern)),
|
pattern: Some(Box::new(pattern)),
|
||||||
|
@ -472,7 +472,7 @@ OrPattern: ast::Pattern = {
|
||||||
let mut patterns = patterns;
|
let mut patterns = patterns;
|
||||||
patterns.insert(0, pattern);
|
patterns.insert(0, pattern);
|
||||||
ast::Pattern::new(
|
ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::PatternMatchOr { patterns }.into()
|
ast::PatternMatchOr { patterns }.into()
|
||||||
)
|
)
|
||||||
|
@ -481,37 +481,37 @@ OrPattern: ast::Pattern = {
|
||||||
|
|
||||||
ClosedPattern: ast::Pattern = {
|
ClosedPattern: ast::Pattern = {
|
||||||
<location:@L> <node:LiteralPattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:LiteralPattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:CapturePattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:CapturePattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:StarPattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:StarPattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:ValuePattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:ValuePattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:SequencePattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:SequencePattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:MappingPattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:MappingPattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
<location:@L> <node:ClassPattern> <end_location:@R> => ast::Pattern::new(
|
<location:@L> <node:ClassPattern> <end_location:@R> => ast::Pattern::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
node,
|
node,
|
||||||
),
|
),
|
||||||
|
@ -543,7 +543,7 @@ StarPattern: ast::PatternKind = {
|
||||||
|
|
||||||
ConstantAtom: ast::Expr = {
|
ConstantAtom: ast::Expr = {
|
||||||
<location:@L> <value:Constant> <end_location:@R> => ast::Expr::new(
|
<location:@L> <value:Constant> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprConstant { value, kind: None }.into()
|
ast::ExprConstant { value, kind: None }.into()
|
||||||
),
|
),
|
||||||
|
@ -552,7 +552,7 @@ ConstantAtom: ast::Expr = {
|
||||||
ConstantExpr: ast::Expr = {
|
ConstantExpr: ast::Expr = {
|
||||||
ConstantAtom,
|
ConstantAtom,
|
||||||
<location:@L> "-" <operand:ConstantAtom> <end_location:@R> => ast::Expr::new(
|
<location:@L> "-" <operand:ConstantAtom> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprUnaryOp {
|
ast::ExprUnaryOp {
|
||||||
op: ast::Unaryop::USub,
|
op: ast::Unaryop::USub,
|
||||||
|
@ -563,7 +563,7 @@ ConstantExpr: ast::Expr = {
|
||||||
|
|
||||||
AddOpExpr: ast::Expr = {
|
AddOpExpr: ast::Expr = {
|
||||||
<location:@L> <left:ConstantExpr> <op:AddOp> <right:ConstantAtom> <end_location:@R> => ast::Expr::new(
|
<location:@L> <left:ConstantExpr> <op:AddOp> <right:ConstantAtom> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp {
|
ast::ExprBinOp {
|
||||||
left: Box::new(left),
|
left: Box::new(left),
|
||||||
|
@ -603,7 +603,7 @@ CapturePattern: ast::PatternKind = {
|
||||||
|
|
||||||
MatchName: ast::Expr = {
|
MatchName: ast::Expr = {
|
||||||
<location:@L> <name:Identifier> <end_location:@R> => ast::Expr::new(
|
<location:@L> <name:Identifier> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprName { id: name, ctx: ast::ExprContext::Load }.into(),
|
ast::ExprName { id: name, ctx: ast::ExprContext::Load }.into(),
|
||||||
),
|
),
|
||||||
|
@ -611,7 +611,7 @@ MatchName: ast::Expr = {
|
||||||
|
|
||||||
MatchNameOrAttr: ast::Expr = {
|
MatchNameOrAttr: ast::Expr = {
|
||||||
<location:@L> <name:MatchName> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
<location:@L> <name:MatchName> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprAttribute {
|
ast::ExprAttribute {
|
||||||
value: Box::new(name),
|
value: Box::new(name),
|
||||||
|
@ -620,7 +620,7 @@ MatchNameOrAttr: ast::Expr = {
|
||||||
}.into(),
|
}.into(),
|
||||||
),
|
),
|
||||||
<location:@L> <e:MatchNameOrAttr> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e:MatchNameOrAttr> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprAttribute {
|
ast::ExprAttribute {
|
||||||
value: Box::new(e),
|
value: Box::new(e),
|
||||||
|
@ -641,7 +641,7 @@ MappingKey: ast::Expr = {
|
||||||
AddOpExpr,
|
AddOpExpr,
|
||||||
MatchNameOrAttr,
|
MatchNameOrAttr,
|
||||||
<location:@L> "None" <end_location:@R> => ast::Expr::new(
|
<location:@L> "None" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: ast::Constant::None,
|
value: ast::Constant::None,
|
||||||
|
@ -649,7 +649,7 @@ MappingKey: ast::Expr = {
|
||||||
}.into(),
|
}.into(),
|
||||||
),
|
),
|
||||||
<location:@L> "True" <end_location:@R> => ast::Expr::new(
|
<location:@L> "True" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: true.into(),
|
value: true.into(),
|
||||||
|
@ -657,7 +657,7 @@ MappingKey: ast::Expr = {
|
||||||
}.into(),
|
}.into(),
|
||||||
),
|
),
|
||||||
<location:@L> "False" <end_location:@R> => ast::Expr::new(
|
<location:@L> "False" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: false.into(),
|
value: false.into(),
|
||||||
|
@ -804,7 +804,7 @@ IfStatement: ast::Stmt = {
|
||||||
// handle elif:
|
// handle elif:
|
||||||
for i in s2.into_iter().rev() {
|
for i in s2.into_iter().rev() {
|
||||||
let x = ast::Stmt::new(
|
let x = ast::Stmt::new(
|
||||||
i.0,
|
i.0..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtIf { test: Box::new(i.2), body: i.4, orelse: last }.into()
|
ast::StmtIf { test: Box::new(i.2), body: i.4, orelse: last }.into()
|
||||||
);
|
);
|
||||||
|
@ -812,7 +812,7 @@ IfStatement: ast::Stmt = {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtIf { test: Box::new(test), body, orelse: last }.into()
|
ast::StmtIf { test: Box::new(test), body, orelse: last }.into()
|
||||||
)
|
)
|
||||||
|
@ -828,7 +828,7 @@ WhileStatement: ast::Stmt = {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.end();
|
.end();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtWhile {
|
ast::StmtWhile {
|
||||||
test: Box::new(test),
|
test: Box::new(test),
|
||||||
|
@ -855,7 +855,7 @@ ForStatement: ast::Stmt = {
|
||||||
} else {
|
} else {
|
||||||
ast::StmtFor { target, iter, body, orelse, type_comment }.into()
|
ast::StmtFor { target, iter, body, orelse, type_comment }.into()
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, end_location, node)
|
ast::Stmt::new(location..end_location, node)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -870,7 +870,7 @@ TryStatement: ast::Stmt = {
|
||||||
.or_else(|| handlers.last().map(|last| last.end()))
|
.or_else(|| handlers.last().map(|last| last.end()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtTry {
|
ast::StmtTry {
|
||||||
body,
|
body,
|
||||||
|
@ -890,7 +890,7 @@ TryStatement: ast::Stmt = {
|
||||||
.or_else(|| handlers.last().map(|last| last.end()))
|
.or_else(|| handlers.last().map(|last| last.end()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtTryStar {
|
ast::StmtTryStar {
|
||||||
body,
|
body,
|
||||||
|
@ -906,7 +906,7 @@ TryStatement: ast::Stmt = {
|
||||||
let finalbody = finally.2;
|
let finalbody = finally.2;
|
||||||
let end_location = finalbody.last().unwrap().end();
|
let end_location = finalbody.last().unwrap().end();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtTry {
|
ast::StmtTry {
|
||||||
body,
|
body,
|
||||||
|
@ -922,7 +922,7 @@ ExceptStarClause: ast::Excepthandler = {
|
||||||
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
|
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
|
||||||
let end_location = body.last().unwrap().end();
|
let end_location = body.last().unwrap().end();
|
||||||
ast::Excepthandler::new(
|
ast::Excepthandler::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExcepthandlerExceptHandler {
|
ast::ExcepthandlerExceptHandler {
|
||||||
type_: Some(Box::new(typ)),
|
type_: Some(Box::new(typ)),
|
||||||
|
@ -934,7 +934,7 @@ ExceptStarClause: ast::Excepthandler = {
|
||||||
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
|
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
|
||||||
let end_location = body.last().unwrap().end();
|
let end_location = body.last().unwrap().end();
|
||||||
ast::Excepthandler::new(
|
ast::Excepthandler::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExcepthandlerExceptHandler {
|
ast::ExcepthandlerExceptHandler {
|
||||||
type_: Some(Box::new(x.0)),
|
type_: Some(Box::new(x.0)),
|
||||||
|
@ -950,7 +950,7 @@ ExceptClause: ast::Excepthandler = {
|
||||||
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
|
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
|
||||||
let end_location = body.last().unwrap().end();
|
let end_location = body.last().unwrap().end();
|
||||||
ast::Excepthandler::new(
|
ast::Excepthandler::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExcepthandlerExceptHandler {
|
ast::ExcepthandlerExceptHandler {
|
||||||
type_: typ.map(Box::new),
|
type_: typ.map(Box::new),
|
||||||
|
@ -962,7 +962,7 @@ ExceptClause: ast::Excepthandler = {
|
||||||
<location:@L> "except" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
|
<location:@L> "except" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
|
||||||
let end_location = body.last().unwrap().end();
|
let end_location = body.last().unwrap().end();
|
||||||
ast::Excepthandler::new(
|
ast::Excepthandler::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExcepthandlerExceptHandler {
|
ast::ExcepthandlerExceptHandler {
|
||||||
type_: Some(Box::new(x.0)),
|
type_: Some(Box::new(x.0)),
|
||||||
|
@ -982,7 +982,7 @@ WithStatement: ast::Stmt = {
|
||||||
} else {
|
} else {
|
||||||
ast::StmtWith { items, body, type_comment }.into()
|
ast::StmtWith { items, body, type_comment }.into()
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, end_location, node)
|
ast::Stmt::new(location..end_location, node)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1023,7 +1023,7 @@ FuncDef: ast::Stmt = {
|
||||||
} else {
|
} else {
|
||||||
ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment }.into()
|
ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment }.into()
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, end_location, node)
|
ast::Stmt::new(location..end_location, node)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1126,7 +1126,7 @@ ParameterDef<ArgType>: (ast::Arg, Option<ast::Expr>) = {
|
||||||
|
|
||||||
UntypedParameter: ast::Arg = {
|
UntypedParameter: ast::Arg = {
|
||||||
<location:@L> <arg:Identifier> <end_location:@R> => ast::Arg::new(
|
<location:@L> <arg:Identifier> <end_location:@R> => ast::Arg::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ArgData { arg, annotation: None, type_comment: None },
|
ast::ArgData { arg, annotation: None, type_comment: None },
|
||||||
),
|
),
|
||||||
|
@ -1135,14 +1135,14 @@ UntypedParameter: ast::Arg = {
|
||||||
TypedParameter: ast::Arg = {
|
TypedParameter: ast::Arg = {
|
||||||
<location:@L> <arg:Identifier> <a:(":" Test<"all">)?> <end_location:@R> => {
|
<location:@L> <arg:Identifier> <a:(":" Test<"all">)?> <end_location:@R> => {
|
||||||
let annotation = a.map(|x| Box::new(x.1));
|
let annotation = a.map(|x| Box::new(x.1));
|
||||||
ast::Arg::new(location, end_location, ast::ArgData { arg, annotation, type_comment: None })
|
ast::Arg::new(location..end_location, ast::ArgData { arg, annotation, type_comment: None })
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
StarTypedParameter: ast::Arg = {
|
StarTypedParameter: ast::Arg = {
|
||||||
<location:@L> <arg:Identifier> <a:(":" TestOrStarExpr)?> <end_location:@R> => {
|
<location:@L> <arg:Identifier> <a:(":" TestOrStarExpr)?> <end_location:@R> => {
|
||||||
let annotation = a.map(|x| Box::new(x.1));
|
let annotation = a.map(|x| Box::new(x.1));
|
||||||
ast::Arg::new(location, end_location, ast::ArgData { arg, annotation, type_comment: None })
|
ast::Arg::new(location..end_location, ast::ArgData { arg, annotation, type_comment: None })
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1193,7 +1193,7 @@ ClassDef: ast::Stmt = {
|
||||||
};
|
};
|
||||||
let end_location = body.last().unwrap().end();
|
let end_location = body.last().unwrap().end();
|
||||||
ast::Stmt::new(
|
ast::Stmt::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::StmtClassDef {
|
ast::StmtClassDef {
|
||||||
name,
|
name,
|
||||||
|
@ -1215,12 +1215,12 @@ Decorator: ast::Expr = {
|
||||||
|
|
||||||
YieldExpr: ast::Expr = {
|
YieldExpr: ast::Expr = {
|
||||||
<location:@L> "yield" <value:TestList?> <end_location:@R> => ast::Expr::new(
|
<location:@L> "yield" <value:TestList?> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprYield { value: value.map(Box::new) }.into()
|
ast::ExprYield { value: value.map(Box::new) }.into()
|
||||||
),
|
),
|
||||||
<location:@L> "yield" "from" <e:Test<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> "yield" "from" <e:Test<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprYieldFrom { value: Box::new(e) }.into()
|
ast::ExprYieldFrom { value: Box::new(e) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1228,7 +1228,7 @@ YieldExpr: ast::Expr = {
|
||||||
|
|
||||||
Test<Goal>: ast::Expr = {
|
Test<Goal>: ast::Expr = {
|
||||||
<location:@L> <body:OrTest<"all">> "if" <test:OrTest<"all">> "else" <orelse:Test<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <body:OrTest<"all">> "if" <test:OrTest<"all">> "else" <orelse:Test<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprIfExp {
|
ast::ExprIfExp {
|
||||||
test: Box::new(test),
|
test: Box::new(test),
|
||||||
|
@ -1248,11 +1248,11 @@ NamedExpressionTest: ast::Expr = {
|
||||||
NamedExpression: ast::Expr = {
|
NamedExpression: ast::Expr = {
|
||||||
<location:@L> <id:Identifier> <end_location:@R> ":=" <value:Test<"all">> => {
|
<location:@L> <id:Identifier> <end_location:@R> ":=" <value:Test<"all">> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
value.end(),
|
value.end(),
|
||||||
ast::ExprNamedExpr {
|
ast::ExprNamedExpr {
|
||||||
target: Box::new(ast::Expr::new(
|
target: Box::new(ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprName { id, ctx: ast::ExprContext::Store }.into(),
|
ast::ExprName { id, ctx: ast::ExprContext::Store }.into(),
|
||||||
)),
|
)),
|
||||||
|
@ -1279,7 +1279,7 @@ LambdaDef: ast::Expr = {
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
Ok(ast::Expr::new(
|
Ok(ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprLambda {
|
ast::ExprLambda {
|
||||||
args: Box::new(p),
|
args: Box::new(p),
|
||||||
|
@ -1294,7 +1294,7 @@ OrTest<Goal>: ast::Expr = {
|
||||||
let mut values = vec![e1];
|
let mut values = vec![e1];
|
||||||
values.extend(e2.into_iter().map(|e| e.1));
|
values.extend(e2.into_iter().map(|e| e.1));
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBoolOp { op: ast::Boolop::Or, values }.into()
|
ast::ExprBoolOp { op: ast::Boolop::Or, values }.into()
|
||||||
)
|
)
|
||||||
|
@ -1307,7 +1307,7 @@ AndTest<Goal>: ast::Expr = {
|
||||||
let mut values = vec![e1];
|
let mut values = vec![e1];
|
||||||
values.extend(e2.into_iter().map(|e| e.1));
|
values.extend(e2.into_iter().map(|e| e.1));
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBoolOp { op: ast::Boolop::And, values }.into()
|
ast::ExprBoolOp { op: ast::Boolop::And, values }.into()
|
||||||
)
|
)
|
||||||
|
@ -1317,7 +1317,7 @@ AndTest<Goal>: ast::Expr = {
|
||||||
|
|
||||||
NotTest<Goal>: ast::Expr = {
|
NotTest<Goal>: ast::Expr = {
|
||||||
<location:@L> "not" <e:NotTest<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> "not" <e:NotTest<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprUnaryOp { operand: Box::new(e), op: ast::Unaryop::Not }.into()
|
ast::ExprUnaryOp { operand: Box::new(e), op: ast::Unaryop::Not }.into()
|
||||||
),
|
),
|
||||||
|
@ -1328,7 +1328,7 @@ Comparison<Goal>: ast::Expr = {
|
||||||
<location:@L> <left:Expression<"all">> <comparisons:(CompOp Expression<"all">)+> <end_location:@R> => {
|
<location:@L> <left:Expression<"all">> <comparisons:(CompOp Expression<"all">)+> <end_location:@R> => {
|
||||||
let (ops, comparators) = comparisons.into_iter().unzip();
|
let (ops, comparators) = comparisons.into_iter().unzip();
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprCompare { left: Box::new(left), ops, comparators }.into()
|
ast::ExprCompare { left: Box::new(left), ops, comparators }.into()
|
||||||
)
|
)
|
||||||
|
@ -1351,7 +1351,7 @@ CompOp: ast::Cmpop = {
|
||||||
|
|
||||||
Expression<Goal>: ast::Expr = {
|
Expression<Goal>: ast::Expr = {
|
||||||
<location:@L> <e1:Expression<"all">> "|" <e2:XorExpression<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e1:Expression<"all">> "|" <e2:XorExpression<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitOr, right: Box::new(e2) }.into()
|
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitOr, right: Box::new(e2) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1360,7 +1360,7 @@ Expression<Goal>: ast::Expr = {
|
||||||
|
|
||||||
XorExpression<Goal>: ast::Expr = {
|
XorExpression<Goal>: ast::Expr = {
|
||||||
<location:@L> <e1:XorExpression<"all">> "^" <e2:AndExpression<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e1:XorExpression<"all">> "^" <e2:AndExpression<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitXor, right: Box::new(e2) }.into()
|
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitXor, right: Box::new(e2) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1369,7 +1369,7 @@ XorExpression<Goal>: ast::Expr = {
|
||||||
|
|
||||||
AndExpression<Goal>: ast::Expr = {
|
AndExpression<Goal>: ast::Expr = {
|
||||||
<location:@L> <e1:AndExpression<"all">> "&" <e2:ShiftExpression<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e1:AndExpression<"all">> "&" <e2:ShiftExpression<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitAnd, right: Box::new(e2) }.into()
|
ast::ExprBinOp { left: Box::new(e1), op: ast::Operator::BitAnd, right: Box::new(e2) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1378,7 +1378,7 @@ AndExpression<Goal>: ast::Expr = {
|
||||||
|
|
||||||
ShiftExpression<Goal>: ast::Expr = {
|
ShiftExpression<Goal>: ast::Expr = {
|
||||||
<location:@L> <e1:ShiftExpression<"all">> <op:ShiftOp> <e2:ArithmeticExpression<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e1:ShiftExpression<"all">> <op:ShiftOp> <e2:ArithmeticExpression<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(e1), op, right: Box::new(e2) }.into()
|
ast::ExprBinOp { left: Box::new(e1), op, right: Box::new(e2) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1392,7 +1392,7 @@ ShiftOp: ast::Operator = {
|
||||||
|
|
||||||
ArithmeticExpression<Goal>: ast::Expr = {
|
ArithmeticExpression<Goal>: ast::Expr = {
|
||||||
<location:@L> <a:ArithmeticExpression<"all">> <op:AddOp> <b:Term<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <a:ArithmeticExpression<"all">> <op:AddOp> <b:Term<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(a), op, right: Box::new(b) }.into()
|
ast::ExprBinOp { left: Box::new(a), op, right: Box::new(b) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1406,7 +1406,7 @@ AddOp: ast::Operator = {
|
||||||
|
|
||||||
Term<Goal>: ast::Expr = {
|
Term<Goal>: ast::Expr = {
|
||||||
<location:@L> <a:Term<"all">> <op:MulOp> <b:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <a:Term<"all">> <op:MulOp> <b:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(a), op, right: Box::new(b) }.into()
|
ast::ExprBinOp { left: Box::new(a), op, right: Box::new(b) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1423,7 +1423,7 @@ MulOp: ast::Operator = {
|
||||||
|
|
||||||
Factor<Goal>: ast::Expr = {
|
Factor<Goal>: ast::Expr = {
|
||||||
<location:@L> <op:UnaryOp> <e:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <op:UnaryOp> <e:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprUnaryOp { operand: Box::new(e), op }.into()
|
ast::ExprUnaryOp { operand: Box::new(e), op }.into()
|
||||||
),
|
),
|
||||||
|
@ -1438,7 +1438,7 @@ UnaryOp: ast::Unaryop = {
|
||||||
|
|
||||||
Power<Goal>: ast::Expr = {
|
Power<Goal>: ast::Expr = {
|
||||||
<location:@L> <e:AtomExpr<"all">> "**" <b:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e:AtomExpr<"all">> "**" <b:Factor<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprBinOp { left: Box::new(e), op: ast::Operator::Pow, right: Box::new(b) }.into()
|
ast::ExprBinOp { left: Box::new(e), op: ast::Operator::Pow, right: Box::new(b) }.into()
|
||||||
),
|
),
|
||||||
|
@ -1448,7 +1448,7 @@ Power<Goal>: ast::Expr = {
|
||||||
AtomExpr<Goal>: ast::Expr = {
|
AtomExpr<Goal>: ast::Expr = {
|
||||||
<location:@L> "await" <atom:AtomExpr2<"all">> <end_location:@R> => {
|
<location:@L> "await" <atom:AtomExpr2<"all">> <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprAwait { value: Box::new(atom) }.into()
|
ast::ExprAwait { value: Box::new(atom) }.into()
|
||||||
)
|
)
|
||||||
|
@ -1460,18 +1460,18 @@ AtomExpr2<Goal>: ast::Expr = {
|
||||||
Atom<Goal>,
|
Atom<Goal>,
|
||||||
<location:@L> <f:AtomExpr2<"all">> "(" <a:ArgumentList> ")" <end_location:@R> => {
|
<location:@L> <f:AtomExpr2<"all">> "(" <a:ArgumentList> ")" <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprCall { func: Box::new(f), args: a.args, keywords: a.keywords }.into()
|
ast::ExprCall { func: Box::new(f), args: a.args, keywords: a.keywords }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> <e:AtomExpr2<"all">> "[" <s:SubscriptList> "]" <end_location:@R> => ast::Expr::new(
|
<location:@L> <e:AtomExpr2<"all">> "[" <s:SubscriptList> "]" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprSubscript { value: Box::new(e), slice: Box::new(s), ctx: ast::ExprContext::Load }.into()
|
ast::ExprSubscript { value: Box::new(e), slice: Box::new(s), ctx: ast::ExprContext::Load }.into()
|
||||||
),
|
),
|
||||||
<location:@L> <e:AtomExpr2<"all">> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
<location:@L> <e:AtomExpr2<"all">> "." <attr:Identifier> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprAttribute { value: Box::new(e), attr, ctx: ast::ExprContext::Load }.into()
|
ast::ExprAttribute { value: Box::new(e), attr, ctx: ast::ExprContext::Load }.into()
|
||||||
),
|
),
|
||||||
|
@ -1488,7 +1488,7 @@ SubscriptList: ast::Expr = {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple { elts: dims, ctx: ast::ExprContext::Load }.into(),
|
ast::ExprTuple { elts: dims, ctx: ast::ExprContext::Load }.into(),
|
||||||
)
|
)
|
||||||
|
@ -1503,7 +1503,7 @@ Subscript: ast::Expr = {
|
||||||
let upper = e2.map(Box::new);
|
let upper = e2.map(Box::new);
|
||||||
let step = e3.flatten().map(Box::new);
|
let step = e3.flatten().map(Box::new);
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprSlice { lower, upper, step }.into()
|
ast::ExprSlice { lower, upper, step }.into()
|
||||||
)
|
)
|
||||||
|
@ -1517,26 +1517,26 @@ SliceOp: Option<ast::Expr> = {
|
||||||
Atom<Goal>: ast::Expr = {
|
Atom<Goal>: ast::Expr = {
|
||||||
<location:@L> <s:(@L string @R)+> =>? Ok(parse_strings(s)?),
|
<location:@L> <s:(@L string @R)+> =>? Ok(parse_strings(s)?),
|
||||||
<location:@L> <value:Constant> <end_location:@R> => ast::Expr::new(
|
<location:@L> <value:Constant> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprConstant { value, kind: None }.into()
|
ast::ExprConstant { value, kind: None }.into()
|
||||||
),
|
),
|
||||||
<location:@L> <name:Identifier> <end_location:@R> => ast::Expr::new(
|
<location:@L> <name:Identifier> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprName { id: name, ctx: ast::ExprContext::Load }.into()
|
ast::ExprName { id: name, ctx: ast::ExprContext::Load }.into()
|
||||||
),
|
),
|
||||||
<location:@L> "[" <e:ListLiteralValues?> "]"<end_location:@R> => {
|
<location:@L> "[" <e:ListLiteralValues?> "]"<end_location:@R> => {
|
||||||
let elts = e.unwrap_or_default();
|
let elts = e.unwrap_or_default();
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprList { elts, ctx: ast::ExprContext::Load }.into()
|
ast::ExprList { elts, ctx: ast::ExprContext::Load }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "[" <elt:TestOrStarNamedExpr> <generators:CompFor> "]" <end_location:@R> => {
|
<location:@L> "[" <elt:TestOrStarNamedExpr> <generators:CompFor> "]" <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprListComp { elt: Box::new(elt), generators }.into()
|
ast::ExprListComp { elt: Box::new(elt), generators }.into()
|
||||||
)
|
)
|
||||||
|
@ -1546,7 +1546,7 @@ Atom<Goal>: ast::Expr = {
|
||||||
elts.into_iter().next().unwrap()
|
elts.into_iter().next().unwrap()
|
||||||
} else {
|
} else {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into()
|
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into()
|
||||||
)
|
)
|
||||||
|
@ -1564,21 +1564,21 @@ Atom<Goal>: ast::Expr = {
|
||||||
} else {
|
} else {
|
||||||
let elts = left.into_iter().flatten().chain([mid]).chain(right).collect();
|
let elts = left.into_iter().flatten().chain([mid]).chain(right).collect();
|
||||||
Ok(ast::Expr::new(
|
Ok(ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into(),
|
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "(" ")" <end_location:@R> => ast::Expr::new(
|
<location:@L> "(" ")" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple { elts: Vec::new(), ctx: ast::ExprContext::Load }.into()
|
ast::ExprTuple { elts: Vec::new(), ctx: ast::ExprContext::Load }.into()
|
||||||
),
|
),
|
||||||
"(" <e:YieldExpr> ")" => e,
|
"(" <e:YieldExpr> ")" => e,
|
||||||
<location:@L> "(" <elt:NamedExpressionTest> <generators:CompFor> ")" <end_location:@R> => {
|
<location:@L> "(" <elt:NamedExpressionTest> <generators:CompFor> ")" <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprGeneratorExp { elt: Box::new(elt), generators }.into()
|
ast::ExprGeneratorExp { elt: Box::new(elt), generators }.into()
|
||||||
)
|
)
|
||||||
|
@ -1596,14 +1596,14 @@ Atom<Goal>: ast::Expr = {
|
||||||
.map(|(k, v)| (k.map(|x| *x), v))
|
.map(|(k, v)| (k.map(|x| *x), v))
|
||||||
.unzip();
|
.unzip();
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprDict { keys, values }.into()
|
ast::ExprDict { keys, values }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "{" <e1:DictEntry> <generators:CompFor> "}" <end_location:@R> => {
|
<location:@L> "{" <e1:DictEntry> <generators:CompFor> "}" <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprDictComp {
|
ast::ExprDictComp {
|
||||||
key: Box::new(e1.0),
|
key: Box::new(e1.0),
|
||||||
|
@ -1613,21 +1613,21 @@ Atom<Goal>: ast::Expr = {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "{" <elts:SetLiteralValues> "}" <end_location:@R> => ast::Expr::new(
|
<location:@L> "{" <elts:SetLiteralValues> "}" <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprSet { elts }.into()
|
ast::ExprSet { elts }.into()
|
||||||
),
|
),
|
||||||
<location:@L> "{" <elt:NamedExpressionTest> <generators:CompFor> "}" <end_location:@R> => {
|
<location:@L> "{" <elt:NamedExpressionTest> <generators:CompFor> "}" <end_location:@R> => {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprSetComp { elt: Box::new(elt), generators }.into()
|
ast::ExprSetComp { elt: Box::new(elt), generators }.into()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
<location:@L> "True" <end_location:@R> => ast::Expr::new(location, end_location, ast::ExprConstant { value: true.into(), kind: None }.into()),
|
<location:@L> "True" <end_location:@R> => ast::Expr::new(location..end_location, ast::ExprConstant { value: true.into(), kind: None }.into()),
|
||||||
<location:@L> "False" <end_location:@R> => ast::Expr::new(location, end_location, ast::ExprConstant { value: false.into(), kind: None }.into()),
|
<location:@L> "False" <end_location:@R> => ast::Expr::new(location..end_location, ast::ExprConstant { value: false.into(), kind: None }.into()),
|
||||||
<location:@L> "None" <end_location:@R> => ast::Expr::new(location, end_location, ast::ExprConstant { value: ast::Constant::None, kind: None }.into()),
|
<location:@L> "None" <end_location:@R> => ast::Expr::new(location..end_location, ast::ExprConstant { value: ast::Constant::None, kind: None }.into()),
|
||||||
<location:@L> "..." <end_location:@R> => ast::Expr::new(location, end_location, ast::ExprConstant { value: ast::Constant::Ellipsis, kind: None }.into()),
|
<location:@L> "..." <end_location:@R> => ast::Expr::new(location..end_location, ast::ExprConstant { value: ast::Constant::Ellipsis, kind: None }.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
ListLiteralValues: Vec<ast::Expr> = {
|
ListLiteralValues: Vec<ast::Expr> = {
|
||||||
|
@ -1679,7 +1679,7 @@ GenericList<Element>: ast::Expr = {
|
||||||
elts.into_iter().next().unwrap()
|
elts.into_iter().next().unwrap()
|
||||||
} else {
|
} else {
|
||||||
ast::Expr::new(
|
ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into()
|
ast::ExprTuple { elts, ctx: ast::ExprContext::Load }.into()
|
||||||
)
|
)
|
||||||
|
@ -1690,7 +1690,7 @@ GenericList<Element>: ast::Expr = {
|
||||||
// Test
|
// Test
|
||||||
StarExpr: ast::Expr = {
|
StarExpr: ast::Expr = {
|
||||||
<location:@L> "*" <e:Expression<"all">> <end_location:@R> => ast::Expr::new(
|
<location:@L> "*" <e:Expression<"all">> <end_location:@R> => ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprStarred { value: Box::new(e), ctx: ast::ExprContext::Load }.into(),
|
ast::ExprStarred { value: Box::new(e), ctx: ast::ExprContext::Load }.into(),
|
||||||
)
|
)
|
||||||
|
@ -1725,8 +1725,7 @@ FunctionArgument: (Option<(crate::text_size::TextSize, crate::text_size::TextSiz
|
||||||
<location:@L> <e:NamedExpressionTest> <c:CompFor?> <end_location:@R> => {
|
<location:@L> <e:NamedExpressionTest> <c:CompFor?> <end_location:@R> => {
|
||||||
let expr = match c {
|
let expr = match c {
|
||||||
Some(c) => ast::Expr::new(
|
Some(c) => ast::Expr::new(
|
||||||
location,
|
location..end_location,
|
||||||
end_location,
|
|
||||||
ast::ExprGeneratorExp {
|
ast::ExprGeneratorExp {
|
||||||
elt: Box::new(e),
|
elt: Box::new(e),
|
||||||
generators: c,
|
generators: c,
|
||||||
|
@ -1739,7 +1738,7 @@ FunctionArgument: (Option<(crate::text_size::TextSize, crate::text_size::TextSiz
|
||||||
<location:@L> <i:Identifier> "=" <e:Test<"all">> <end_location:@R> => (Some((location, end_location, Some(i))), e),
|
<location:@L> <i:Identifier> "=" <e:Test<"all">> <end_location:@R> => (Some((location, end_location, Some(i))), e),
|
||||||
<location:@L> "*" <e:Test<"all">> <end_location:@R> => {
|
<location:@L> "*" <e:Test<"all">> <end_location:@R> => {
|
||||||
let expr = ast::Expr::new(
|
let expr = ast::Expr::new(
|
||||||
location,
|
location..
|
||||||
end_location,
|
end_location,
|
||||||
ast::ExprStarred { value: Box::new(e), ctx: ast::ExprContext::Load }.into(),
|
ast::ExprStarred { value: Box::new(e), ctx: ast::ExprContext::Load }.into(),
|
||||||
);
|
);
|
||||||
|
|
279
parser/src/python.rs
generated
279
parser/src/python.rs
generated
File diff suppressed because it is too large
Load diff
|
@ -10,9 +10,7 @@ use crate::{
|
||||||
token::{StringKind, Tok},
|
token::{StringKind, Tok},
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_compiler_core::{
|
use rustpython_compiler_core::text_size::{TextLen, TextSize};
|
||||||
text_size::{TextLen, TextSize},
|
|
||||||
};
|
|
||||||
|
|
||||||
// unicode_name2 does not expose `MAX_NAME_LENGTH`, so we replicate that constant here, fix #3798
|
// unicode_name2 does not expose `MAX_NAME_LENGTH`, so we replicate that constant here, fix #3798
|
||||||
const MAX_UNICODE_NAME: usize = 88;
|
const MAX_UNICODE_NAME: usize = 88;
|
||||||
|
@ -67,7 +65,7 @@ impl<'a> StringParser<'a> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn expr(&self, node: ExprKind) -> Expr {
|
fn expr(&self, node: ExprKind) -> Expr {
|
||||||
Expr::new(self.start, self.end, node)
|
Expr::new(self.start..self.end, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_unicode_literal(&mut self, literal_number: usize) -> Result<char, LexicalError> {
|
fn parse_unicode_literal(&mut self, literal_number: usize) -> Result<char, LexicalError> {
|
||||||
|
@ -624,8 +622,7 @@ pub(crate) fn parse_strings(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(Expr::new(
|
return Ok(Expr::new(
|
||||||
initial_start,
|
initial_start..last_end,
|
||||||
last_end,
|
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: Constant::Bytes(content),
|
value: Constant::Bytes(content),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
@ -648,8 +645,7 @@ pub(crate) fn parse_strings(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(Expr::new(
|
return Ok(Expr::new(
|
||||||
initial_start,
|
initial_start..last_end,
|
||||||
last_end,
|
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: Constant::Str(content.join("")),
|
value: Constant::Str(content.join("")),
|
||||||
kind: initial_kind,
|
kind: initial_kind,
|
||||||
|
@ -664,8 +660,7 @@ pub(crate) fn parse_strings(
|
||||||
|
|
||||||
let take_current = |current: &mut Vec<String>| -> Expr {
|
let take_current = |current: &mut Vec<String>| -> Expr {
|
||||||
Expr::new(
|
Expr::new(
|
||||||
initial_start,
|
initial_start..last_end,
|
||||||
last_end,
|
|
||||||
ast::ExprConstant {
|
ast::ExprConstant {
|
||||||
value: Constant::Str(current.drain(..).join("")),
|
value: Constant::Str(current.drain(..).join("")),
|
||||||
kind: initial_kind.clone(),
|
kind: initial_kind.clone(),
|
||||||
|
@ -696,8 +691,7 @@ pub(crate) fn parse_strings(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Expr::new(
|
Ok(Expr::new(
|
||||||
initial_start,
|
initial_start..last_end,
|
||||||
last_end,
|
|
||||||
ast::ExprJoinedStr { values: deduped }.into(),
|
ast::ExprJoinedStr { values: deduped }.into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,6 +463,13 @@ impl RangeBounds<TextSize> for TextRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Range<TextSize>> for TextRange {
|
||||||
|
#[inline]
|
||||||
|
fn from(r: Range<TextSize>) -> Self {
|
||||||
|
TextRange::new(r.start, r.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> From<TextRange> for Range<T>
|
impl<T> From<TextRange> for Range<T>
|
||||||
where
|
where
|
||||||
T: From<TextSize>,
|
T: From<TextSize>,
|
||||||
|
|
|
@ -63,6 +63,30 @@ impl TextSize {
|
||||||
pub fn of<T: TextLen>(text: T) -> TextSize {
|
pub fn of<T: TextLen>(text: T) -> TextSize {
|
||||||
text.text_len()
|
text.text_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns current raw `offset` as u32.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use ruff_text_size::*;
|
||||||
|
/// assert_eq!(TextSize::from(4).to_u32(), 4);
|
||||||
|
/// ```
|
||||||
|
pub fn to_u32(&self) -> u32 {
|
||||||
|
self.raw
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns current raw `offset` as usize.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use ruff_text_size::*;
|
||||||
|
/// assert_eq!(TextSize::from(4).to_usize(), 4);
|
||||||
|
/// ```
|
||||||
|
pub fn to_usize(&self) -> usize {
|
||||||
|
self.raw as usize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods to act like a primitive integer type, where reasonably applicable.
|
/// Methods to act like a primitive integer type, where reasonably applicable.
|
||||||
|
@ -91,7 +115,7 @@ impl From<u32> for TextSize {
|
||||||
impl From<TextSize> for u32 {
|
impl From<TextSize> for u32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(value: TextSize) -> Self {
|
fn from(value: TextSize) -> Self {
|
||||||
value.raw
|
value.to_u32()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +130,7 @@ impl TryFrom<usize> for TextSize {
|
||||||
impl From<TextSize> for usize {
|
impl From<TextSize> for usize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(value: TextSize) -> Self {
|
fn from(value: TextSize) -> Self {
|
||||||
value.raw as usize
|
value.to_usize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
scripts/update_asdl.sh
Executable file
7
scripts/update_asdl.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd "$(dirname "$(dirname "$0")")"
|
||||||
|
|
||||||
|
python ast/asdl_rs.py --generic-file ast/src/generic.rs --located-file ast/src/located.rs --module-file ../RustPython/vm/src/stdlib/ast/gen.rs ast/Python.asdl
|
||||||
|
rustfmt ast/src/generic.rs ast/src/located.rs ../RustPython/vm/src/stdlib/ast/gen.rs
|
Loading…
Add table
Add a link
Reference in a new issue