mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-09 22:25:23 +00:00
Field accessor and utilities (#20)
* Apply is-macro to Constant and ast nodes
This commit is contained in:
parent
2baad9ead6
commit
947fb53d0b
6 changed files with 117 additions and 18 deletions
|
@ -25,6 +25,7 @@ anyhow = "1.0.45"
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
insta = "1.14.0"
|
insta = "1.14.0"
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
|
is-macro = "0.2.2"
|
||||||
log = "0.4.16"
|
log = "0.4.16"
|
||||||
num-complex = "0.4.0"
|
num-complex = "0.4.0"
|
||||||
num-bigint = "0.4.3"
|
num-bigint = "0.4.3"
|
||||||
|
|
|
@ -19,4 +19,5 @@ visitor = []
|
||||||
rustpython-parser-core = { workspace = true }
|
rustpython-parser-core = { workspace = true }
|
||||||
rustpython-literal = { workspace = true, optional = true }
|
rustpython-literal = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
is-macro = { workspace = true }
|
||||||
num-bigint = { workspace = true }
|
num-bigint = { workspace = true }
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import re
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -16,26 +17,34 @@ import asdl
|
||||||
TABSIZE = 4
|
TABSIZE = 4
|
||||||
AUTO_GEN_MESSAGE = "// File automatically generated by {}.\n\n"
|
AUTO_GEN_MESSAGE = "// File automatically generated by {}.\n\n"
|
||||||
|
|
||||||
builtin_type_mapping = {
|
BUILTIN_TYPE_NAMES = {
|
||||||
"identifier": "Identifier",
|
"identifier": "Identifier",
|
||||||
"string": "String",
|
"string": "String",
|
||||||
"int": "Int",
|
"int": "Int",
|
||||||
"constant": "Constant",
|
"constant": "Constant",
|
||||||
}
|
}
|
||||||
assert builtin_type_mapping.keys() == asdl.builtin_types
|
assert BUILTIN_TYPE_NAMES.keys() == asdl.builtin_types
|
||||||
|
|
||||||
builtin_int_mapping = {
|
BUILTIN_INT_NAMES = {
|
||||||
"simple": "bool",
|
"simple": "bool",
|
||||||
"is_async": "bool",
|
"is_async": "bool",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RUST_KEYWORDS = {"if", "while", "for", "return", "match", "try", "await", "yield"}
|
||||||
|
|
||||||
|
|
||||||
|
def rust_field_name(name):
|
||||||
|
name = rust_type_name(name)
|
||||||
|
return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
|
||||||
|
|
||||||
|
|
||||||
def rust_type_name(name):
|
def rust_type_name(name):
|
||||||
"""Return a string for the C name of the type.
|
"""Return a string for the C name of the type.
|
||||||
|
|
||||||
This function special cases the default types provided by asdl.
|
This function special cases the default types provided by asdl.
|
||||||
"""
|
"""
|
||||||
if name in asdl.builtin_types:
|
if name in asdl.builtin_types:
|
||||||
builtin = builtin_type_mapping[name]
|
builtin = BUILTIN_TYPE_NAMES[name]
|
||||||
return builtin
|
return builtin
|
||||||
elif name.islower():
|
elif name.islower():
|
||||||
return "".join(part.capitalize() for part in name.split("_"))
|
return "".join(part.capitalize() for part in name.split("_"))
|
||||||
|
@ -271,6 +280,7 @@ class StructVisitor(EmitVisitor):
|
||||||
def simple_sum(self, sum, name, depth):
|
def simple_sum(self, sum, name, depth):
|
||||||
rust_name = rust_type_name(name)
|
rust_name = rust_type_name(name)
|
||||||
self.emit_attrs(depth)
|
self.emit_attrs(depth)
|
||||||
|
self.emit("#[derive(is_macro::Is)]", depth)
|
||||||
self.emit(f"pub enum {rust_name} {{", depth)
|
self.emit(f"pub enum {rust_name} {{", depth)
|
||||||
for variant in sum.types:
|
for variant in sum.types:
|
||||||
self.emit(f"{variant.name},", depth + 1)
|
self.emit(f"{variant.name},", depth + 1)
|
||||||
|
@ -291,8 +301,15 @@ class StructVisitor(EmitVisitor):
|
||||||
|
|
||||||
generics, generics_applied = self.apply_generics(name, "U = ()", "U")
|
generics, generics_applied = self.apply_generics(name, "U = ()", "U")
|
||||||
self.emit_attrs(depth)
|
self.emit_attrs(depth)
|
||||||
|
self.emit("#[derive(is_macro::Is)]", depth)
|
||||||
self.emit(f"pub enum {rust_name}{suffix}{generics} {{", depth)
|
self.emit(f"pub enum {rust_name}{suffix}{generics} {{", depth)
|
||||||
|
needs_escape = any(rust_field_name(t.name) in RUST_KEYWORDS for t in sum.types)
|
||||||
for t in sum.types:
|
for t in sum.types:
|
||||||
|
if needs_escape:
|
||||||
|
self.emit(
|
||||||
|
f'#[is(name = "{rust_field_name(t.name)}_{rust_name.lower()}")]',
|
||||||
|
depth + 1,
|
||||||
|
)
|
||||||
if t.fields:
|
if t.fields:
|
||||||
(t_generics_applied,) = self.apply_generics(t.name, "U")
|
(t_generics_applied,) = self.apply_generics(t.name, "U")
|
||||||
self.emit(
|
self.emit(
|
||||||
|
@ -361,7 +378,7 @@ class StructVisitor(EmitVisitor):
|
||||||
if field.seq:
|
if field.seq:
|
||||||
typ = f"Vec<{typ}>"
|
typ = f"Vec<{typ}>"
|
||||||
if typ == "Int":
|
if typ == "Int":
|
||||||
typ = builtin_int_mapping.get(field.name, typ)
|
typ = BUILTIN_INT_NAMES.get(field.name, typ)
|
||||||
name = rust_field(field.name)
|
name = rust_field(field.name)
|
||||||
self.emit(f"{vis}{name}: {typ},", depth)
|
self.emit(f"{vis}{name}: {typ},", depth)
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl std::cmp::PartialEq<usize> for Int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Constant {
|
pub enum Constant {
|
||||||
None,
|
None,
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
@ -127,6 +127,21 @@ pub enum Constant {
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Constant {
|
||||||
|
pub fn is_true(self) -> bool {
|
||||||
|
self.bool().map_or(false, |b| b)
|
||||||
|
}
|
||||||
|
pub fn is_false(self) -> bool {
|
||||||
|
self.bool().map_or(false, |b| !b)
|
||||||
|
}
|
||||||
|
pub fn complex(self) -> Option<(f64, f64)> {
|
||||||
|
match self {
|
||||||
|
Constant::Complex { real, imag } => Some((real, imag)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<String> for Constant {
|
impl From<String> for Constant {
|
||||||
fn from(s: String) -> Constant {
|
fn from(s: String) -> Constant {
|
||||||
Self::Str(s)
|
Self::Str(s)
|
||||||
|
@ -247,3 +262,14 @@ impl<T, U> std::ops::Deref for Attributed<T, U> {
|
||||||
&self.node
|
&self.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_is_macro() {
|
||||||
|
let none = Constant::None;
|
||||||
|
assert!(none.is_none());
|
||||||
|
assert!(!none.is_bool());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl<U> From<ModFunctionType<U>> for Mod<U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Mod<U = ()> {
|
pub enum Mod<U = ()> {
|
||||||
Module(ModModule<U>),
|
Module(ModModule<U>),
|
||||||
Interactive(ModInteractive<U>),
|
Interactive(ModInteractive<U>),
|
||||||
|
@ -366,34 +366,61 @@ impl<U> From<StmtExpr<U>> for StmtKind<U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum StmtKind<U = ()> {
|
pub enum StmtKind<U = ()> {
|
||||||
|
#[is(name = "function_def_stmt")]
|
||||||
FunctionDef(StmtFunctionDef<U>),
|
FunctionDef(StmtFunctionDef<U>),
|
||||||
|
#[is(name = "async_function_def_stmt")]
|
||||||
AsyncFunctionDef(StmtAsyncFunctionDef<U>),
|
AsyncFunctionDef(StmtAsyncFunctionDef<U>),
|
||||||
|
#[is(name = "class_def_stmt")]
|
||||||
ClassDef(StmtClassDef<U>),
|
ClassDef(StmtClassDef<U>),
|
||||||
|
#[is(name = "return_stmt")]
|
||||||
Return(StmtReturn<U>),
|
Return(StmtReturn<U>),
|
||||||
|
#[is(name = "delete_stmt")]
|
||||||
Delete(StmtDelete<U>),
|
Delete(StmtDelete<U>),
|
||||||
|
#[is(name = "assign_stmt")]
|
||||||
Assign(StmtAssign<U>),
|
Assign(StmtAssign<U>),
|
||||||
|
#[is(name = "aug_assign_stmt")]
|
||||||
AugAssign(StmtAugAssign<U>),
|
AugAssign(StmtAugAssign<U>),
|
||||||
|
#[is(name = "ann_assign_stmt")]
|
||||||
AnnAssign(StmtAnnAssign<U>),
|
AnnAssign(StmtAnnAssign<U>),
|
||||||
|
#[is(name = "for_stmt")]
|
||||||
For(StmtFor<U>),
|
For(StmtFor<U>),
|
||||||
|
#[is(name = "async_for_stmt")]
|
||||||
AsyncFor(StmtAsyncFor<U>),
|
AsyncFor(StmtAsyncFor<U>),
|
||||||
|
#[is(name = "while_stmt")]
|
||||||
While(StmtWhile<U>),
|
While(StmtWhile<U>),
|
||||||
|
#[is(name = "if_stmt")]
|
||||||
If(StmtIf<U>),
|
If(StmtIf<U>),
|
||||||
|
#[is(name = "with_stmt")]
|
||||||
With(StmtWith<U>),
|
With(StmtWith<U>),
|
||||||
|
#[is(name = "async_with_stmt")]
|
||||||
AsyncWith(StmtAsyncWith<U>),
|
AsyncWith(StmtAsyncWith<U>),
|
||||||
|
#[is(name = "match_stmt")]
|
||||||
Match(StmtMatch<U>),
|
Match(StmtMatch<U>),
|
||||||
|
#[is(name = "raise_stmt")]
|
||||||
Raise(StmtRaise<U>),
|
Raise(StmtRaise<U>),
|
||||||
|
#[is(name = "try_stmt")]
|
||||||
Try(StmtTry<U>),
|
Try(StmtTry<U>),
|
||||||
|
#[is(name = "try_star_stmt")]
|
||||||
TryStar(StmtTryStar<U>),
|
TryStar(StmtTryStar<U>),
|
||||||
|
#[is(name = "assert_stmt")]
|
||||||
Assert(StmtAssert<U>),
|
Assert(StmtAssert<U>),
|
||||||
|
#[is(name = "import_stmt")]
|
||||||
Import(StmtImport<U>),
|
Import(StmtImport<U>),
|
||||||
|
#[is(name = "import_from_stmt")]
|
||||||
ImportFrom(StmtImportFrom<U>),
|
ImportFrom(StmtImportFrom<U>),
|
||||||
|
#[is(name = "global_stmt")]
|
||||||
Global(StmtGlobal),
|
Global(StmtGlobal),
|
||||||
|
#[is(name = "nonlocal_stmt")]
|
||||||
Nonlocal(StmtNonlocal),
|
Nonlocal(StmtNonlocal),
|
||||||
|
#[is(name = "expr_stmt")]
|
||||||
Expr(StmtExpr<U>),
|
Expr(StmtExpr<U>),
|
||||||
|
#[is(name = "pass_stmt")]
|
||||||
Pass,
|
Pass,
|
||||||
|
#[is(name = "break_stmt")]
|
||||||
Break,
|
Break,
|
||||||
|
#[is(name = "continue_stmt")]
|
||||||
Continue,
|
Continue,
|
||||||
}
|
}
|
||||||
pub type Stmt<U = ()> = Attributed<StmtKind<U>, U>;
|
pub type Stmt<U = ()> = Attributed<StmtKind<U>, U>;
|
||||||
|
@ -726,52 +753,79 @@ impl<U> From<ExprSlice<U>> for ExprKind<U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum ExprKind<U = ()> {
|
pub enum ExprKind<U = ()> {
|
||||||
|
#[is(name = "bool_op_expr")]
|
||||||
BoolOp(ExprBoolOp<U>),
|
BoolOp(ExprBoolOp<U>),
|
||||||
|
#[is(name = "named_expr_expr")]
|
||||||
NamedExpr(ExprNamedExpr<U>),
|
NamedExpr(ExprNamedExpr<U>),
|
||||||
|
#[is(name = "bin_op_expr")]
|
||||||
BinOp(ExprBinOp<U>),
|
BinOp(ExprBinOp<U>),
|
||||||
|
#[is(name = "unary_op_expr")]
|
||||||
UnaryOp(ExprUnaryOp<U>),
|
UnaryOp(ExprUnaryOp<U>),
|
||||||
|
#[is(name = "lambda_expr")]
|
||||||
Lambda(ExprLambda<U>),
|
Lambda(ExprLambda<U>),
|
||||||
|
#[is(name = "if_exp_expr")]
|
||||||
IfExp(ExprIfExp<U>),
|
IfExp(ExprIfExp<U>),
|
||||||
|
#[is(name = "dict_expr")]
|
||||||
Dict(ExprDict<U>),
|
Dict(ExprDict<U>),
|
||||||
|
#[is(name = "set_expr")]
|
||||||
Set(ExprSet<U>),
|
Set(ExprSet<U>),
|
||||||
|
#[is(name = "list_comp_expr")]
|
||||||
ListComp(ExprListComp<U>),
|
ListComp(ExprListComp<U>),
|
||||||
|
#[is(name = "set_comp_expr")]
|
||||||
SetComp(ExprSetComp<U>),
|
SetComp(ExprSetComp<U>),
|
||||||
|
#[is(name = "dict_comp_expr")]
|
||||||
DictComp(ExprDictComp<U>),
|
DictComp(ExprDictComp<U>),
|
||||||
|
#[is(name = "generator_exp_expr")]
|
||||||
GeneratorExp(ExprGeneratorExp<U>),
|
GeneratorExp(ExprGeneratorExp<U>),
|
||||||
|
#[is(name = "await_expr")]
|
||||||
Await(ExprAwait<U>),
|
Await(ExprAwait<U>),
|
||||||
|
#[is(name = "yield_expr")]
|
||||||
Yield(ExprYield<U>),
|
Yield(ExprYield<U>),
|
||||||
|
#[is(name = "yield_from_expr")]
|
||||||
YieldFrom(ExprYieldFrom<U>),
|
YieldFrom(ExprYieldFrom<U>),
|
||||||
|
#[is(name = "compare_expr")]
|
||||||
Compare(ExprCompare<U>),
|
Compare(ExprCompare<U>),
|
||||||
|
#[is(name = "call_expr")]
|
||||||
Call(ExprCall<U>),
|
Call(ExprCall<U>),
|
||||||
|
#[is(name = "formatted_value_expr")]
|
||||||
FormattedValue(ExprFormattedValue<U>),
|
FormattedValue(ExprFormattedValue<U>),
|
||||||
|
#[is(name = "joined_str_expr")]
|
||||||
JoinedStr(ExprJoinedStr<U>),
|
JoinedStr(ExprJoinedStr<U>),
|
||||||
|
#[is(name = "constant_expr")]
|
||||||
Constant(ExprConstant),
|
Constant(ExprConstant),
|
||||||
|
#[is(name = "attribute_expr")]
|
||||||
Attribute(ExprAttribute<U>),
|
Attribute(ExprAttribute<U>),
|
||||||
|
#[is(name = "subscript_expr")]
|
||||||
Subscript(ExprSubscript<U>),
|
Subscript(ExprSubscript<U>),
|
||||||
|
#[is(name = "starred_expr")]
|
||||||
Starred(ExprStarred<U>),
|
Starred(ExprStarred<U>),
|
||||||
|
#[is(name = "name_expr")]
|
||||||
Name(ExprName),
|
Name(ExprName),
|
||||||
|
#[is(name = "list_expr")]
|
||||||
List(ExprList<U>),
|
List(ExprList<U>),
|
||||||
|
#[is(name = "tuple_expr")]
|
||||||
Tuple(ExprTuple<U>),
|
Tuple(ExprTuple<U>),
|
||||||
|
#[is(name = "slice_expr")]
|
||||||
Slice(ExprSlice<U>),
|
Slice(ExprSlice<U>),
|
||||||
}
|
}
|
||||||
pub type Expr<U = ()> = Attributed<ExprKind<U>, U>;
|
pub type Expr<U = ()> = Attributed<ExprKind<U>, U>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum ExprContext {
|
pub enum ExprContext {
|
||||||
Load,
|
Load,
|
||||||
Store,
|
Store,
|
||||||
Del,
|
Del,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Boolop {
|
pub enum Boolop {
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Operator {
|
pub enum Operator {
|
||||||
Add,
|
Add,
|
||||||
Sub,
|
Sub,
|
||||||
|
@ -788,7 +842,7 @@ pub enum Operator {
|
||||||
FloorDiv,
|
FloorDiv,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Unaryop {
|
pub enum Unaryop {
|
||||||
Invert,
|
Invert,
|
||||||
Not,
|
Not,
|
||||||
|
@ -796,7 +850,7 @@ pub enum Unaryop {
|
||||||
USub,
|
USub,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum Cmpop {
|
pub enum Cmpop {
|
||||||
Eq,
|
Eq,
|
||||||
NotEq,
|
NotEq,
|
||||||
|
@ -831,7 +885,7 @@ impl<U> From<ExcepthandlerExceptHandler<U>> for ExcepthandlerKind<U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum ExcepthandlerKind<U = ()> {
|
pub enum ExcepthandlerKind<U = ()> {
|
||||||
ExceptHandler(ExcepthandlerExceptHandler<U>),
|
ExceptHandler(ExcepthandlerExceptHandler<U>),
|
||||||
}
|
}
|
||||||
|
@ -977,7 +1031,7 @@ impl<U> From<PatternMatchOr<U>> for PatternKind<U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum PatternKind<U = ()> {
|
pub enum PatternKind<U = ()> {
|
||||||
MatchValue(PatternMatchValue<U>),
|
MatchValue(PatternMatchValue<U>),
|
||||||
MatchSingleton(PatternMatchSingleton),
|
MatchSingleton(PatternMatchSingleton),
|
||||||
|
@ -1002,7 +1056,7 @@ impl From<TypeIgnoreTypeIgnore> for TypeIgnore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
pub enum TypeIgnore {
|
pub enum TypeIgnore {
|
||||||
TypeIgnore(TypeIgnoreTypeIgnore),
|
TypeIgnore(TypeIgnoreTypeIgnore),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{Constant, ExprKind};
|
||||||
|
|
||||||
impl<U> ExprKind<U> {
|
impl<U> ExprKind<U> {
|
||||||
/// Returns a short name for the node suitable for use in error messages.
|
/// Returns a short name for the node suitable for use in error messages.
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn python_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
ExprKind::BoolOp { .. } | ExprKind::BinOp { .. } | ExprKind::UnaryOp { .. } => {
|
ExprKind::BoolOp { .. } | ExprKind::BinOp { .. } | ExprKind::UnaryOp { .. } => {
|
||||||
"operator"
|
"operator"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue