mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:09:22 +00:00
Auto-generate AST boilerplate (#15544)
This PR replaces most of the hard-coded AST definitions with a generation script, similar to what happens in `rust_python_formatter`. I've replaced every "rote" definition that I could find, where the content is entirely boilerplate and only depends on what syntax nodes there are and which groups they belong to. This is a pretty massive diff, but it's entirely a refactoring. It should make absolutely no changes to the API or implementation. In particular, this required adding some configuration knobs that let us override default auto-generated names where they don't line up with types that we created previously by hand. ## Test plan There should be no changes outside of the `rust_python_ast` crate, which verifies that there were no API changes as a result of the auto-generation. Aggressive `cargo clippy` and `uvx pre-commit` runs after each commit in the branch. --------- Co-authored-by: Micha Reiser <micha@reiser.io> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
4351d85d24
commit
8e3633f55a
15 changed files with 10074 additions and 8513 deletions
4
.gitattributes
vendored
4
.gitattributes
vendored
|
@ -14,5 +14,7 @@ crates/ruff_python_parser/resources/invalid/re_lex_logical_token_mac_eol.py text
|
||||||
|
|
||||||
crates/ruff_python_parser/resources/inline linguist-generated=true
|
crates/ruff_python_parser/resources/inline linguist-generated=true
|
||||||
|
|
||||||
ruff.schema.json linguist-generated=true text=auto eol=lf
|
ruff.schema.json -diff linguist-generated=true text=auto eol=lf
|
||||||
|
crates/ruff_python_ast/src/generated.rs -diff linguist-generated=true text=auto eol=lf
|
||||||
|
crates/ruff_python_formatter/src/generated.rs -diff linguist-generated=true text=auto eol=lf
|
||||||
*.md.snap linguist-language=Markdown
|
*.md.snap linguist-language=Markdown
|
||||||
|
|
6
.github/workflows/ci.yaml
vendored
6
.github/workflows/ci.yaml
vendored
|
@ -386,6 +386,12 @@ jobs:
|
||||||
- name: "Install Rust toolchain"
|
- name: "Install Rust toolchain"
|
||||||
run: rustup component add rustfmt
|
run: rustup component add rustfmt
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
# Run all code generation scripts, and verify that the current output is
|
||||||
|
# already checked into git.
|
||||||
|
- run: python crates/ruff_python_ast/generate.py
|
||||||
|
- run: python crates/ruff_python_formatter/generate.py
|
||||||
|
- run: test -z "$(git status --porcelain)"
|
||||||
|
# Verify that adding a plugin or rule produces clean code.
|
||||||
- run: ./scripts/add_rule.py --name DoTheThing --prefix F --code 999 --linter pyflakes
|
- run: ./scripts/add_rule.py --name DoTheThing --prefix F --code 999 --linter pyflakes
|
||||||
- run: cargo check
|
- run: cargo check
|
||||||
- run: cargo fmt --all --check
|
- run: cargo fmt --all --check
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import _SpecialForm, Any, LiteralString
|
from typing import Any, LiteralString, _SpecialForm
|
||||||
|
|
||||||
# Special operations
|
# Special operations
|
||||||
def static_assert(condition: object, msg: LiteralString | None = None) -> None: ...
|
def static_assert(condition: object, msg: LiteralString | None = None) -> None: ...
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff/tests/show_settings.rs
|
source: crates/ruff/tests/show_settings.rs
|
||||||
|
assertion_line: 30
|
||||||
info:
|
info:
|
||||||
program: ruff
|
program: ruff
|
||||||
args:
|
args:
|
||||||
- check
|
- check
|
||||||
- "--show-settings"
|
- "--show-settings"
|
||||||
- unformatted.py
|
- unformatted.py
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
success: true
|
success: true
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
|
@ -72,6 +72,8 @@ file_resolver.project_root = "[BASEPATH]"
|
||||||
linter.exclude = []
|
linter.exclude = []
|
||||||
linter.project_root = "[BASEPATH]"
|
linter.project_root = "[BASEPATH]"
|
||||||
linter.rules.enabled = [
|
linter.rules.enabled = [
|
||||||
|
unsorted-imports (I001),
|
||||||
|
missing-required-import (I002),
|
||||||
multiple-imports-on-one-line (E401),
|
multiple-imports-on-one-line (E401),
|
||||||
module-import-not-at-top-of-file (E402),
|
module-import-not-at-top-of-file (E402),
|
||||||
multiple-statements-on-one-line-colon (E701),
|
multiple-statements-on-one-line-colon (E701),
|
||||||
|
@ -133,6 +135,8 @@ linter.rules.enabled = [
|
||||||
raise-not-implemented (F901),
|
raise-not-implemented (F901),
|
||||||
]
|
]
|
||||||
linter.rules.should_fix = [
|
linter.rules.should_fix = [
|
||||||
|
unsorted-imports (I001),
|
||||||
|
missing-required-import (I002),
|
||||||
multiple-imports-on-one-line (E401),
|
multiple-imports-on-one-line (E401),
|
||||||
module-import-not-at-top-of-file (E402),
|
module-import-not-at-top-of-file (E402),
|
||||||
multiple-statements-on-one-line-colon (E701),
|
multiple-statements-on-one-line-colon (E701),
|
||||||
|
|
174
crates/ruff_python_ast/ast.toml
Normal file
174
crates/ruff_python_ast/ast.toml
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
# This file is used by generate.py to autogenerate our Python AST data model.
|
||||||
|
#
|
||||||
|
# We have defined a Rust struct for each syntax node in `src/nodes.rs`. Many of
|
||||||
|
# these nodes belong to groups. For instance, there is a `Stmt` group
|
||||||
|
# consisting of all of the syntax nodes that represent valid Python statements.
|
||||||
|
#
|
||||||
|
# There is a special group named `ungrouped` that contains syntax nodes that do
|
||||||
|
# not belong to any group.
|
||||||
|
#
|
||||||
|
# Each group is defined by two sections below. The `[GROUP]` section defines
|
||||||
|
# options that control the auto-generation for that group. The `[GROUP.nodes]`
|
||||||
|
# section defines which syntax nodes belong to that group. The name of each
|
||||||
|
# entry in the nodes section must match the name of the corresponding Rust
|
||||||
|
# struct. The value of each entry defines options that control the
|
||||||
|
# auto-generation for that syntax node.
|
||||||
|
#
|
||||||
|
# The following group options are available:
|
||||||
|
#
|
||||||
|
# add_suffix_to_is_methods: [true/false]
|
||||||
|
# Controls the name of the is_foo methods of the group's enums. If false (the
|
||||||
|
# default), these methods will use the variant name in snake_case. If true,
|
||||||
|
# then the group prefix will be moved to the end before snake_casing. (That
|
||||||
|
# is, `StmtIf` will become `if_stmt`.)
|
||||||
|
#
|
||||||
|
# anynode_is_label: foo_bar
|
||||||
|
# Controls the name of the AnyNode::foo_bar, AnyNode::is_foo_bar, and
|
||||||
|
# AnyNodeRef::is_foo_bar methods. The default is the group name in
|
||||||
|
# snake_case.
|
||||||
|
#
|
||||||
|
# ref_enum_ty:
|
||||||
|
# The name of the reference enum that we create for this group. The default
|
||||||
|
# is the group name with `Ref` added to the end.
|
||||||
|
#
|
||||||
|
# rustdoc:
|
||||||
|
# A rustdoc comment that is added to the group's enums.
|
||||||
|
#
|
||||||
|
# The following syntax node options are available:
|
||||||
|
#
|
||||||
|
# variant:
|
||||||
|
# The name of the enum variant for this syntax node. Defaults to the node
|
||||||
|
# name with the group prefix removed. (That is, `StmtIf` becomes `If`.)
|
||||||
|
|
||||||
|
[Mod]
|
||||||
|
anynode_is_label = "module"
|
||||||
|
rustdoc = "/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)"
|
||||||
|
|
||||||
|
[Mod.nodes]
|
||||||
|
ModModule = {}
|
||||||
|
ModExpression = {}
|
||||||
|
|
||||||
|
[Stmt]
|
||||||
|
add_suffix_to_is_methods = true
|
||||||
|
anynode_is_label = "statement"
|
||||||
|
rustdoc = "/// See also [stmt](https://docs.python.org/3/library/ast.html#ast.stmt)"
|
||||||
|
ref_enum_ty = "StatementRef"
|
||||||
|
|
||||||
|
[Stmt.nodes]
|
||||||
|
StmtFunctionDef = {}
|
||||||
|
StmtClassDef = {}
|
||||||
|
StmtReturn = {}
|
||||||
|
StmtDelete = {}
|
||||||
|
StmtTypeAlias = {}
|
||||||
|
StmtAssign = {}
|
||||||
|
StmtAugAssign = {}
|
||||||
|
StmtAnnAssign = {}
|
||||||
|
StmtFor = {}
|
||||||
|
StmtWhile = {}
|
||||||
|
StmtIf = {}
|
||||||
|
StmtWith = {}
|
||||||
|
StmtMatch = {}
|
||||||
|
StmtRaise = {}
|
||||||
|
StmtTry = {}
|
||||||
|
StmtAssert = {}
|
||||||
|
StmtImport = {}
|
||||||
|
StmtImportFrom = {}
|
||||||
|
StmtGlobal = {}
|
||||||
|
StmtNonlocal = {}
|
||||||
|
StmtExpr = {}
|
||||||
|
StmtPass = {}
|
||||||
|
StmtBreak = {}
|
||||||
|
StmtContinue = {}
|
||||||
|
StmtIpyEscapeCommand = {}
|
||||||
|
|
||||||
|
[Expr]
|
||||||
|
add_suffix_to_is_methods = true
|
||||||
|
anynode_is_label = "expression"
|
||||||
|
rustdoc = "/// See also [expr](https://docs.python.org/3/library/ast.html#ast.expr)"
|
||||||
|
ref_enum_ty = "ExpressionRef"
|
||||||
|
|
||||||
|
[Expr.nodes]
|
||||||
|
ExprBoolOp = {}
|
||||||
|
ExprNamed = {}
|
||||||
|
ExprBinOp = {}
|
||||||
|
ExprUnaryOp = {}
|
||||||
|
ExprLambda = {}
|
||||||
|
ExprIf = {}
|
||||||
|
ExprDict = {}
|
||||||
|
ExprSet = {}
|
||||||
|
ExprListComp = {}
|
||||||
|
ExprSetComp = {}
|
||||||
|
ExprDictComp = {}
|
||||||
|
ExprGenerator = {}
|
||||||
|
ExprAwait = {}
|
||||||
|
ExprYield = {}
|
||||||
|
ExprYieldFrom = {}
|
||||||
|
ExprCompare = {}
|
||||||
|
ExprCall = {}
|
||||||
|
ExprFString = {}
|
||||||
|
ExprStringLiteral = {}
|
||||||
|
ExprBytesLiteral = {}
|
||||||
|
ExprNumberLiteral = {}
|
||||||
|
ExprBooleanLiteral = {}
|
||||||
|
ExprNoneLiteral = {}
|
||||||
|
ExprEllipsisLiteral = {}
|
||||||
|
ExprAttribute = {}
|
||||||
|
ExprSubscript = {}
|
||||||
|
ExprStarred = {}
|
||||||
|
ExprName = {}
|
||||||
|
ExprList = {}
|
||||||
|
ExprTuple = {}
|
||||||
|
ExprSlice = {}
|
||||||
|
ExprIpyEscapeCommand = {}
|
||||||
|
|
||||||
|
[ExceptHandler]
|
||||||
|
rustdoc = "/// See also [excepthandler](https://docs.python.org/3/library/ast.html#ast.excepthandler)"
|
||||||
|
|
||||||
|
[ExceptHandler.nodes]
|
||||||
|
ExceptHandlerExceptHandler = {}
|
||||||
|
|
||||||
|
[FStringElement.nodes]
|
||||||
|
FStringExpressionElement = {variant = "Expression"}
|
||||||
|
FStringLiteralElement = {variant = "Literal"}
|
||||||
|
|
||||||
|
[Pattern]
|
||||||
|
rustdoc = "/// See also [pattern](https://docs.python.org/3/library/ast.html#ast.pattern)"
|
||||||
|
|
||||||
|
[Pattern.nodes]
|
||||||
|
PatternMatchValue = {}
|
||||||
|
PatternMatchSingleton = {}
|
||||||
|
PatternMatchSequence = {}
|
||||||
|
PatternMatchMapping = {}
|
||||||
|
PatternMatchClass = {}
|
||||||
|
PatternMatchStar = {}
|
||||||
|
PatternMatchAs = {}
|
||||||
|
PatternMatchOr = {}
|
||||||
|
|
||||||
|
[TypeParam]
|
||||||
|
rustdoc = "/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param)"
|
||||||
|
|
||||||
|
[TypeParam.nodes]
|
||||||
|
TypeParamTypeVar = {}
|
||||||
|
TypeParamTypeVarTuple = {}
|
||||||
|
TypeParamParamSpec = {}
|
||||||
|
|
||||||
|
[ungrouped.nodes]
|
||||||
|
FStringFormatSpec = {}
|
||||||
|
PatternArguments = {}
|
||||||
|
PatternKeyword = {}
|
||||||
|
Comprehension = {}
|
||||||
|
Arguments = {}
|
||||||
|
Parameters = {}
|
||||||
|
Parameter = {}
|
||||||
|
ParameterWithDefault = {}
|
||||||
|
Keyword = {}
|
||||||
|
Alias = {}
|
||||||
|
WithItem = {}
|
||||||
|
MatchCase = {}
|
||||||
|
Decorator = {}
|
||||||
|
ElifElseClause = {}
|
||||||
|
TypeParams = {}
|
||||||
|
FString = {}
|
||||||
|
StringLiteral = {}
|
||||||
|
BytesLiteral = {}
|
||||||
|
Identifier = {}
|
752
crates/ruff_python_ast/generate.py
Normal file
752
crates/ruff_python_ast/generate.py
Normal file
|
@ -0,0 +1,752 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# /// script
|
||||||
|
# requires-python = ">=3.11"
|
||||||
|
# dependencies = []
|
||||||
|
# ///
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from subprocess import check_output
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
|
||||||
|
def rustfmt(code: str) -> str:
|
||||||
|
return check_output(["rustfmt", "--emit=stdout"], input=code, text=True)
|
||||||
|
|
||||||
|
|
||||||
|
def to_snake_case(node: str) -> str:
|
||||||
|
"""Converts CamelCase to snake_case"""
|
||||||
|
return re.sub("([A-Z])", r"_\1", node).lower().lstrip("_")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Read AST description
|
||||||
|
|
||||||
|
|
||||||
|
def load_ast(root: Path) -> list[Group]:
|
||||||
|
ast_path = root.joinpath("crates", "ruff_python_ast", "ast.toml")
|
||||||
|
with ast_path.open("rb") as ast_file:
|
||||||
|
ast = tomllib.load(ast_file)
|
||||||
|
return [Group(group_name, group) for group_name, group in ast.items()]
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Preprocess
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Group:
|
||||||
|
name: str
|
||||||
|
nodes: list[Node]
|
||||||
|
owned_enum_ty: str
|
||||||
|
ref_enum_ty: str
|
||||||
|
|
||||||
|
add_suffix_to_is_methods: bool
|
||||||
|
anynode_is_label: str
|
||||||
|
rustdoc: str | None
|
||||||
|
|
||||||
|
def __init__(self, group_name: str, group: dict[str, Any]) -> None:
|
||||||
|
self.name = group_name
|
||||||
|
self.owned_enum_ty = group_name
|
||||||
|
self.ref_enum_ty = group.get("ref_enum_ty", group_name + "Ref")
|
||||||
|
self.add_suffix_to_is_methods = group.get("add_suffix_to_is_methods", False)
|
||||||
|
self.anynode_is_label = group.get("anynode_is_label", to_snake_case(group_name))
|
||||||
|
self.rustdoc = group.get("rustdoc")
|
||||||
|
self.nodes = [
|
||||||
|
Node(self, node_name, node) for node_name, node in group["nodes"].items()
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Node:
|
||||||
|
name: str
|
||||||
|
variant: str
|
||||||
|
ty: str
|
||||||
|
|
||||||
|
def __init__(self, group: Group, node_name: str, node: dict[str, Any]) -> None:
|
||||||
|
self.name = node_name
|
||||||
|
self.variant = node.get("variant", node_name.removeprefix(group.name))
|
||||||
|
self.ty = f"crate::{node_name}"
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Preamble
|
||||||
|
|
||||||
|
|
||||||
|
def write_preamble(out: list[str]) -> None:
|
||||||
|
out.append("""
|
||||||
|
// This is a generated file. Don't modify it by hand!
|
||||||
|
// Run `crates/ruff_python_ast/generate.py` to re-generate the file.
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Owned enum
|
||||||
|
|
||||||
|
|
||||||
|
def write_owned_enum(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Create an enum for each group that contains an owned copy of a syntax node.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum TypeParam {
|
||||||
|
TypeVar(TypeParamTypeVar),
|
||||||
|
TypeVarTuple(TypeParamTypeVarTuple),
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also creates:
|
||||||
|
- `impl Ranged for TypeParam`
|
||||||
|
- `TypeParam::visit_source_order`
|
||||||
|
- `impl From<TypeParamTypeVar> for TypeParam`
|
||||||
|
- `impl Ranged for TypeParamTypeVar`
|
||||||
|
- `fn TypeParam::is_type_var() -> bool`
|
||||||
|
|
||||||
|
If the `add_suffix_to_is_methods` group option is true, then the
|
||||||
|
`is_type_var` method will be named `is_type_var_type_param`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
|
||||||
|
out.append("")
|
||||||
|
if group.rustdoc is not None:
|
||||||
|
out.append(group.rustdoc)
|
||||||
|
out.append("#[derive(Clone, Debug, PartialEq, is_macro::Is)]")
|
||||||
|
out.append(f"pub enum {group.owned_enum_ty} {{")
|
||||||
|
for node in group.nodes:
|
||||||
|
if group.add_suffix_to_is_methods:
|
||||||
|
is_name = to_snake_case(node.variant + group.name)
|
||||||
|
out.append(f'#[is(name = "{is_name}")]')
|
||||||
|
out.append(f"{node.variant}({node.ty}),")
|
||||||
|
out.append("}")
|
||||||
|
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl From<{node.ty}> for {group.owned_enum_ty} {{
|
||||||
|
fn from(node: {node.ty}) -> Self {{
|
||||||
|
Self::{node.variant}(node)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append(f"""
|
||||||
|
impl ruff_text_size::Ranged for {group.owned_enum_ty} {{
|
||||||
|
fn range(&self) -> ruff_text_size::TextRange {{
|
||||||
|
match self {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"Self::{node.variant}(node) => node.range(),")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl ruff_text_size::Ranged for {node.ty} {{
|
||||||
|
fn range(&self) -> ruff_text_size::TextRange {{
|
||||||
|
self.range
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
out.append(f"""
|
||||||
|
impl {group.owned_enum_ty} {{
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) fn visit_source_order<'a, V>(&'a self, visitor: &mut V)
|
||||||
|
where
|
||||||
|
V: crate::visitor::source_order::SourceOrderVisitor<'a> + ?Sized,
|
||||||
|
{{
|
||||||
|
match self {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""{group.owned_enum_ty}::{node.variant}(node) => node.visit_source_order(visitor),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Ref enum
|
||||||
|
|
||||||
|
|
||||||
|
def write_ref_enum(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Create an enum for each group that contains a reference to a syntax node.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum TypeParamRef<'a> {
|
||||||
|
TypeVar(&'a TypeParamTypeVar),
|
||||||
|
TypeVarTuple(&'a TypeParamTypeVarTuple),
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also creates:
|
||||||
|
- `impl<'a> From<&'a TypeParam> for TypeParamRef<'a>`
|
||||||
|
- `impl<'a> From<&'a TypeParamTypeVar> for TypeParamRef<'a>`
|
||||||
|
- `impl Ranged for TypeParamRef<'_>`
|
||||||
|
- `fn TypeParamRef::is_type_var() -> bool`
|
||||||
|
|
||||||
|
The name of the enum can be customized via the `ref_enum_ty` group option.
|
||||||
|
The name of each variant can be customized via the `variant` node option. If
|
||||||
|
the `add_suffix_to_is_methods` group option is true, then the `is_type_var`
|
||||||
|
method will be named `is_type_var_type_param`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
|
||||||
|
out.append("")
|
||||||
|
if group.rustdoc is not None:
|
||||||
|
out.append(group.rustdoc)
|
||||||
|
out.append("""#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]""")
|
||||||
|
out.append(f"""pub enum {group.ref_enum_ty}<'a> {{""")
|
||||||
|
for node in group.nodes:
|
||||||
|
if group.add_suffix_to_is_methods:
|
||||||
|
is_name = to_snake_case(node.variant + group.name)
|
||||||
|
out.append(f'#[is(name = "{is_name}")]')
|
||||||
|
out.append(f"""{node.variant}(&'a {node.ty}),""")
|
||||||
|
out.append("}")
|
||||||
|
|
||||||
|
out.append(f"""
|
||||||
|
impl<'a> From<&'a {group.owned_enum_ty}> for {group.ref_enum_ty}<'a> {{
|
||||||
|
fn from(node: &'a {group.owned_enum_ty}) -> Self {{
|
||||||
|
match node {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""{group.owned_enum_ty}::{node.variant}(node) => {group.ref_enum_ty}::{node.variant}(node),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl<'a> From<&'a {node.ty}> for {group.ref_enum_ty}<'a> {{
|
||||||
|
fn from(node: &'a {node.ty}) -> Self {{
|
||||||
|
Self::{node.variant}(node)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append(f"""
|
||||||
|
impl ruff_text_size::Ranged for {group.ref_enum_ty}<'_> {{
|
||||||
|
fn range(&self) -> ruff_text_size::TextRange {{
|
||||||
|
match self {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"Self::{node.variant}(node) => node.range(),")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# AnyNode
|
||||||
|
|
||||||
|
|
||||||
|
def write_anynode(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Create the AnyNode type.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum AnyNode {
|
||||||
|
...
|
||||||
|
TypeParamTypeVar(TypeParamTypeVar),
|
||||||
|
TypeParamTypeVarTuple(TypeParamTypeVarTuple),
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also creates:
|
||||||
|
- `impl From<TypeParam> for AnyNode`
|
||||||
|
- `impl From<TypeParamTypeVarTuple> for AnyNode`
|
||||||
|
- `impl Ranged for AnyNode`
|
||||||
|
- `fn AnyNode::type_param(self) -> Option<TypeParam>`
|
||||||
|
- `fn AnyNode::is_type_param(&self) -> bool`
|
||||||
|
- `fn AnyNode::is_type_param_type_var(&self) -> bool`
|
||||||
|
- `fn AnyNode::as_ref(&self) -> AnyNodeRef`
|
||||||
|
|
||||||
|
The name of the `type_param` and `is_type_param` methods can be customized
|
||||||
|
via the `anynode_is_label` group option.
|
||||||
|
"""
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
#[derive(Clone, Debug, is_macro::Is, PartialEq)]
|
||||||
|
pub enum AnyNode {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"{node.name}({node.ty}),")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name != "ungrouped":
|
||||||
|
out.append(f"""
|
||||||
|
impl From<{group.owned_enum_ty}> for AnyNode {{
|
||||||
|
fn from(node: {group.owned_enum_ty}) -> AnyNode {{
|
||||||
|
match node {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""{group.owned_enum_ty}::{node.variant}(node) => AnyNode::{node.name}(node),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl From<{node.ty}> for AnyNode {{
|
||||||
|
fn from(node: {node.ty}) -> AnyNode {{
|
||||||
|
AnyNode::{node.name}(node)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl ruff_text_size::Ranged for AnyNode {
|
||||||
|
fn range(&self) -> ruff_text_size::TextRange {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""AnyNode::{node.name}(node) => node.range(),""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
out.append(f"""
|
||||||
|
impl AnyNode {{
|
||||||
|
pub fn {group.anynode_is_label}(self) -> Option<{group.owned_enum_ty}> {{
|
||||||
|
match self {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNode::{node.name}(node) => Some({group.owned_enum_ty}::{node.variant}(node)),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
out.append(f"""
|
||||||
|
impl AnyNode {{
|
||||||
|
pub const fn is_{group.anynode_is_label}(&self) -> bool {{
|
||||||
|
matches!(self,
|
||||||
|
""")
|
||||||
|
for i, node in enumerate(group.nodes):
|
||||||
|
if i > 0:
|
||||||
|
out.append("|")
|
||||||
|
out.append(f"""AnyNode::{node.name}(_)""")
|
||||||
|
out.append("""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl AnyNode {
|
||||||
|
pub const fn as_ref(&self) -> AnyNodeRef {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNode::{node.name}(node) => AnyNodeRef::{node.name}(node),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# AnyNodeRef
|
||||||
|
|
||||||
|
|
||||||
|
def write_anynoderef(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Create the AnyNodeRef type.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum AnyNodeRef<'a> {
|
||||||
|
...
|
||||||
|
TypeParamTypeVar(&'a TypeParamTypeVar),
|
||||||
|
TypeParamTypeVarTuple(&'a TypeParamTypeVarTuple),
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also creates:
|
||||||
|
- `impl<'a> From<&'a TypeParam> for AnyNodeRef<'a>`
|
||||||
|
- `impl<'a> From<TypeParamRef<'a>> for AnyNodeRef<'a>`
|
||||||
|
- `impl<'a> From<&'a TypeParamTypeVarTuple> for AnyNodeRef<'a>`
|
||||||
|
- `impl Ranged for AnyNodeRef<'_>`
|
||||||
|
- `fn AnyNodeRef::as_ptr(&self) -> std::ptr::NonNull<()>`
|
||||||
|
- `fn AnyNodeRef::visit_preorder(self, visitor &mut impl SourceOrderVisitor)`
|
||||||
|
- `fn AnyNode::is_type_param(&self) -> bool`
|
||||||
|
"""
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
#[derive(Copy, Clone, Debug, is_macro::Is, PartialEq)]
|
||||||
|
pub enum AnyNodeRef<'a> {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""{node.name}(&'a {node.ty}),""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name != "ungrouped":
|
||||||
|
out.append(f"""
|
||||||
|
impl<'a> From<&'a {group.owned_enum_ty}> for AnyNodeRef<'a> {{
|
||||||
|
fn from(node: &'a {group.owned_enum_ty}) -> AnyNodeRef<'a> {{
|
||||||
|
match node {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""{group.owned_enum_ty}::{node.variant}(node) => AnyNodeRef::{node.name}(node),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append(f"""
|
||||||
|
impl<'a> From<{group.ref_enum_ty}<'a>> for AnyNodeRef<'a> {{
|
||||||
|
fn from(node: {group.ref_enum_ty}<'a>) -> AnyNodeRef<'a> {{
|
||||||
|
match node {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""{group.ref_enum_ty}::{node.variant}(node) => AnyNodeRef::{node.name}(node),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl<'a> From<&'a {node.ty}> for AnyNodeRef<'a> {{
|
||||||
|
fn from(node: &'a {node.ty}) -> AnyNodeRef<'a> {{
|
||||||
|
AnyNodeRef::{node.name}(node)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl ruff_text_size::Ranged for AnyNodeRef<'_> {
|
||||||
|
fn range(&self) -> ruff_text_size::TextRange {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""AnyNodeRef::{node.name}(node) => node.range(),""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl AnyNodeRef<'_> {
|
||||||
|
pub fn as_ptr(&self) -> std::ptr::NonNull<()> {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNodeRef::{node.name}(node) => std::ptr::NonNull::from(*node).cast(),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl<'a> AnyNodeRef<'a> {
|
||||||
|
pub fn visit_preorder<'b, V>(self, visitor: &mut V)
|
||||||
|
where
|
||||||
|
V: crate::visitor::source_order::SourceOrderVisitor<'b> + ?Sized,
|
||||||
|
'a: 'b,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNodeRef::{node.name}(node) => node.visit_source_order(visitor),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name == "ungrouped":
|
||||||
|
continue
|
||||||
|
out.append(f"""
|
||||||
|
impl AnyNodeRef<'_> {{
|
||||||
|
pub const fn is_{group.anynode_is_label}(self) -> bool {{
|
||||||
|
matches!(self,
|
||||||
|
""")
|
||||||
|
for i, node in enumerate(group.nodes):
|
||||||
|
if i > 0:
|
||||||
|
out.append("|")
|
||||||
|
out.append(f"""AnyNodeRef::{node.name}(_)""")
|
||||||
|
out.append("""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# NodeKind
|
||||||
|
|
||||||
|
|
||||||
|
def write_nodekind(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Create the NodeKind type.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum NodeKind {
|
||||||
|
...
|
||||||
|
TypeParamTypeVar,
|
||||||
|
TypeParamTypeVarTuple,
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Also creates:
|
||||||
|
- `fn AnyNode::kind(&self) -> NodeKind`
|
||||||
|
- `fn AnyNodeRef::kind(self) -> NodeKind`
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
|
pub enum NodeKind {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""{node.name},""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl AnyNode {
|
||||||
|
pub const fn kind(&self) -> NodeKind {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""AnyNode::{node.name}(_) => NodeKind::{node.name},""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
out.append("""
|
||||||
|
impl AnyNodeRef<'_> {
|
||||||
|
pub const fn kind(self) -> NodeKind {
|
||||||
|
match self {
|
||||||
|
""")
|
||||||
|
for group in groups:
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""AnyNodeRef::{node.name}(_) => NodeKind::{node.name},""")
|
||||||
|
out.append("""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# AstNode
|
||||||
|
|
||||||
|
|
||||||
|
def write_astnode(out: list[str], groups: list[Group]) -> None:
|
||||||
|
"""
|
||||||
|
Creates AstNode trait impls:
|
||||||
|
- `impl AstNode for TypeParam`
|
||||||
|
- `impl AstNode for TypeParamTypeVar`
|
||||||
|
"""
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
if group.name != "ungrouped":
|
||||||
|
out.append(f"""
|
||||||
|
impl crate::AstNode for {group.owned_enum_ty} {{
|
||||||
|
type Ref<'a> = {group.ref_enum_ty}<'a>;
|
||||||
|
|
||||||
|
fn cast(node: AnyNode) -> Option<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{{
|
||||||
|
match node {{
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNode::{node.name}(node) => Some({group.owned_enum_ty}::{node.variant}(node)),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cast_ref(node: AnyNodeRef) -> Option<Self::Ref<'_>> {
|
||||||
|
match node {
|
||||||
|
""")
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(
|
||||||
|
f"""AnyNodeRef::{node.name}(node) => Some({group.ref_enum_ty}::{node.variant}(node)),"""
|
||||||
|
)
|
||||||
|
out.append("""
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_cast(kind: NodeKind) -> bool {
|
||||||
|
matches!(kind,
|
||||||
|
""")
|
||||||
|
for i, node in enumerate(group.nodes):
|
||||||
|
if i > 0:
|
||||||
|
out.append("|")
|
||||||
|
out.append(f"""NodeKind::{node.name}""")
|
||||||
|
out.append("""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_node_ref(&self) -> AnyNodeRef {
|
||||||
|
AnyNodeRef::from(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_any_node(self) -> AnyNode {
|
||||||
|
AnyNode::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for node in group.nodes:
|
||||||
|
out.append(f"""
|
||||||
|
impl crate::AstNode for {node.ty} {{
|
||||||
|
type Ref<'a> = &'a Self;
|
||||||
|
|
||||||
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{{
|
||||||
|
if let AnyNode::{node.name}(node) = kind {{
|
||||||
|
Some(node)
|
||||||
|
}} else {{
|
||||||
|
None
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {{
|
||||||
|
if let AnyNodeRef::{node.name}(node) = kind {{
|
||||||
|
Some(node)
|
||||||
|
}} else {{
|
||||||
|
None
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
fn can_cast(kind: NodeKind) -> bool {{
|
||||||
|
matches!(kind, NodeKind::{node.name})
|
||||||
|
}}
|
||||||
|
|
||||||
|
fn as_any_node_ref(&self) -> AnyNodeRef {{
|
||||||
|
AnyNodeRef::from(self)
|
||||||
|
}}
|
||||||
|
|
||||||
|
fn into_any_node(self) -> AnyNode {{
|
||||||
|
AnyNode::from(self)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Format and write output
|
||||||
|
|
||||||
|
|
||||||
|
def generate(groups: list[Group]) -> list[str]:
|
||||||
|
out = []
|
||||||
|
write_preamble(out)
|
||||||
|
write_owned_enum(out, groups)
|
||||||
|
write_ref_enum(out, groups)
|
||||||
|
write_anynode(out, groups)
|
||||||
|
write_anynoderef(out, groups)
|
||||||
|
write_nodekind(out, groups)
|
||||||
|
write_astnode(out, groups)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def write_output(root: Path, out: list[str]) -> None:
|
||||||
|
out_path = root.joinpath("crates", "ruff_python_ast", "src", "generated.rs")
|
||||||
|
out_path.write_text(rustfmt("\n".join(out)))
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Main
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
root = Path(
|
||||||
|
check_output(["git", "rev-parse", "--show-toplevel"], text=True).strip()
|
||||||
|
)
|
||||||
|
groups = load_ast(root)
|
||||||
|
out = generate(groups)
|
||||||
|
write_output(root, out)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -4,334 +4,15 @@ use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
self as ast, AnyNodeRef, AnyStringFlags, Expr, ExprBytesLiteral, ExprFString,
|
self as ast, AnyNodeRef, AnyStringFlags, Expr, ExprBytesLiteral, ExprFString,
|
||||||
ExprStringLiteral, StringFlags,
|
ExprStringLiteral, ExpressionRef, StringFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unowned pendant to [`ast::Expr`] that stores a reference instead of a owned value.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub enum ExpressionRef<'a> {
|
|
||||||
BoolOp(&'a ast::ExprBoolOp),
|
|
||||||
Named(&'a ast::ExprNamed),
|
|
||||||
BinOp(&'a ast::ExprBinOp),
|
|
||||||
UnaryOp(&'a ast::ExprUnaryOp),
|
|
||||||
Lambda(&'a ast::ExprLambda),
|
|
||||||
If(&'a ast::ExprIf),
|
|
||||||
Dict(&'a ast::ExprDict),
|
|
||||||
Set(&'a ast::ExprSet),
|
|
||||||
ListComp(&'a ast::ExprListComp),
|
|
||||||
SetComp(&'a ast::ExprSetComp),
|
|
||||||
DictComp(&'a ast::ExprDictComp),
|
|
||||||
Generator(&'a ast::ExprGenerator),
|
|
||||||
Await(&'a ast::ExprAwait),
|
|
||||||
Yield(&'a ast::ExprYield),
|
|
||||||
YieldFrom(&'a ast::ExprYieldFrom),
|
|
||||||
Compare(&'a ast::ExprCompare),
|
|
||||||
Call(&'a ast::ExprCall),
|
|
||||||
FString(&'a ast::ExprFString),
|
|
||||||
StringLiteral(&'a ast::ExprStringLiteral),
|
|
||||||
BytesLiteral(&'a ast::ExprBytesLiteral),
|
|
||||||
NumberLiteral(&'a ast::ExprNumberLiteral),
|
|
||||||
BooleanLiteral(&'a ast::ExprBooleanLiteral),
|
|
||||||
NoneLiteral(&'a ast::ExprNoneLiteral),
|
|
||||||
EllipsisLiteral(&'a ast::ExprEllipsisLiteral),
|
|
||||||
Attribute(&'a ast::ExprAttribute),
|
|
||||||
Subscript(&'a ast::ExprSubscript),
|
|
||||||
Starred(&'a ast::ExprStarred),
|
|
||||||
Name(&'a ast::ExprName),
|
|
||||||
List(&'a ast::ExprList),
|
|
||||||
Tuple(&'a ast::ExprTuple),
|
|
||||||
Slice(&'a ast::ExprSlice),
|
|
||||||
IpyEscapeCommand(&'a ast::ExprIpyEscapeCommand),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a Box<Expr>> for ExpressionRef<'a> {
|
impl<'a> From<&'a Box<Expr>> for ExpressionRef<'a> {
|
||||||
fn from(value: &'a Box<Expr>) -> Self {
|
fn from(value: &'a Box<Expr>) -> Self {
|
||||||
ExpressionRef::from(value.as_ref())
|
ExpressionRef::from(value.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Expr> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a Expr) -> Self {
|
|
||||||
match value {
|
|
||||||
Expr::BoolOp(value) => ExpressionRef::BoolOp(value),
|
|
||||||
Expr::Named(value) => ExpressionRef::Named(value),
|
|
||||||
Expr::BinOp(value) => ExpressionRef::BinOp(value),
|
|
||||||
Expr::UnaryOp(value) => ExpressionRef::UnaryOp(value),
|
|
||||||
Expr::Lambda(value) => ExpressionRef::Lambda(value),
|
|
||||||
Expr::If(value) => ExpressionRef::If(value),
|
|
||||||
Expr::Dict(value) => ExpressionRef::Dict(value),
|
|
||||||
Expr::Set(value) => ExpressionRef::Set(value),
|
|
||||||
Expr::ListComp(value) => ExpressionRef::ListComp(value),
|
|
||||||
Expr::SetComp(value) => ExpressionRef::SetComp(value),
|
|
||||||
Expr::DictComp(value) => ExpressionRef::DictComp(value),
|
|
||||||
Expr::Generator(value) => ExpressionRef::Generator(value),
|
|
||||||
Expr::Await(value) => ExpressionRef::Await(value),
|
|
||||||
Expr::Yield(value) => ExpressionRef::Yield(value),
|
|
||||||
Expr::YieldFrom(value) => ExpressionRef::YieldFrom(value),
|
|
||||||
Expr::Compare(value) => ExpressionRef::Compare(value),
|
|
||||||
Expr::Call(value) => ExpressionRef::Call(value),
|
|
||||||
Expr::FString(value) => ExpressionRef::FString(value),
|
|
||||||
Expr::StringLiteral(value) => ExpressionRef::StringLiteral(value),
|
|
||||||
Expr::BytesLiteral(value) => ExpressionRef::BytesLiteral(value),
|
|
||||||
Expr::NumberLiteral(value) => ExpressionRef::NumberLiteral(value),
|
|
||||||
Expr::BooleanLiteral(value) => ExpressionRef::BooleanLiteral(value),
|
|
||||||
Expr::NoneLiteral(value) => ExpressionRef::NoneLiteral(value),
|
|
||||||
Expr::EllipsisLiteral(value) => ExpressionRef::EllipsisLiteral(value),
|
|
||||||
Expr::Attribute(value) => ExpressionRef::Attribute(value),
|
|
||||||
Expr::Subscript(value) => ExpressionRef::Subscript(value),
|
|
||||||
Expr::Starred(value) => ExpressionRef::Starred(value),
|
|
||||||
Expr::Name(value) => ExpressionRef::Name(value),
|
|
||||||
Expr::List(value) => ExpressionRef::List(value),
|
|
||||||
Expr::Tuple(value) => ExpressionRef::Tuple(value),
|
|
||||||
Expr::Slice(value) => ExpressionRef::Slice(value),
|
|
||||||
Expr::IpyEscapeCommand(value) => ExpressionRef::IpyEscapeCommand(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a ast::ExprBoolOp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprBoolOp) -> Self {
|
|
||||||
Self::BoolOp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprNamed> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprNamed) -> Self {
|
|
||||||
Self::Named(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprBinOp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprBinOp) -> Self {
|
|
||||||
Self::BinOp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprUnaryOp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprUnaryOp) -> Self {
|
|
||||||
Self::UnaryOp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprLambda> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprLambda) -> Self {
|
|
||||||
Self::Lambda(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprIf> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprIf) -> Self {
|
|
||||||
Self::If(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprDict> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprDict) -> Self {
|
|
||||||
Self::Dict(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprSet> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprSet) -> Self {
|
|
||||||
Self::Set(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprListComp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprListComp) -> Self {
|
|
||||||
Self::ListComp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprSetComp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprSetComp) -> Self {
|
|
||||||
Self::SetComp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprDictComp> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprDictComp) -> Self {
|
|
||||||
Self::DictComp(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprGenerator> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprGenerator) -> Self {
|
|
||||||
Self::Generator(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprAwait> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprAwait) -> Self {
|
|
||||||
Self::Await(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprYield> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprYield) -> Self {
|
|
||||||
Self::Yield(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprYieldFrom> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprYieldFrom) -> Self {
|
|
||||||
Self::YieldFrom(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprCompare> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprCompare) -> Self {
|
|
||||||
Self::Compare(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprCall> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprCall) -> Self {
|
|
||||||
Self::Call(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprFString> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprFString) -> Self {
|
|
||||||
Self::FString(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprStringLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprStringLiteral) -> Self {
|
|
||||||
Self::StringLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprBytesLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprBytesLiteral) -> Self {
|
|
||||||
Self::BytesLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprNumberLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprNumberLiteral) -> Self {
|
|
||||||
Self::NumberLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprBooleanLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprBooleanLiteral) -> Self {
|
|
||||||
Self::BooleanLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprNoneLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprNoneLiteral) -> Self {
|
|
||||||
Self::NoneLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprEllipsisLiteral> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprEllipsisLiteral) -> Self {
|
|
||||||
Self::EllipsisLiteral(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprAttribute> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprAttribute) -> Self {
|
|
||||||
Self::Attribute(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprSubscript> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprSubscript) -> Self {
|
|
||||||
Self::Subscript(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprStarred> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprStarred) -> Self {
|
|
||||||
Self::Starred(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprName> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprName) -> Self {
|
|
||||||
Self::Name(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprList> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprList) -> Self {
|
|
||||||
Self::List(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprTuple> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprTuple) -> Self {
|
|
||||||
Self::Tuple(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprSlice> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprSlice) -> Self {
|
|
||||||
Self::Slice(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a ast::ExprIpyEscapeCommand> for ExpressionRef<'a> {
|
|
||||||
fn from(value: &'a ast::ExprIpyEscapeCommand) -> Self {
|
|
||||||
Self::IpyEscapeCommand(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<ExpressionRef<'a>> for AnyNodeRef<'a> {
|
|
||||||
fn from(value: ExpressionRef<'a>) -> Self {
|
|
||||||
match value {
|
|
||||||
ExpressionRef::BoolOp(expression) => AnyNodeRef::ExprBoolOp(expression),
|
|
||||||
ExpressionRef::Named(expression) => AnyNodeRef::ExprNamed(expression),
|
|
||||||
ExpressionRef::BinOp(expression) => AnyNodeRef::ExprBinOp(expression),
|
|
||||||
ExpressionRef::UnaryOp(expression) => AnyNodeRef::ExprUnaryOp(expression),
|
|
||||||
ExpressionRef::Lambda(expression) => AnyNodeRef::ExprLambda(expression),
|
|
||||||
ExpressionRef::If(expression) => AnyNodeRef::ExprIf(expression),
|
|
||||||
ExpressionRef::Dict(expression) => AnyNodeRef::ExprDict(expression),
|
|
||||||
ExpressionRef::Set(expression) => AnyNodeRef::ExprSet(expression),
|
|
||||||
ExpressionRef::ListComp(expression) => AnyNodeRef::ExprListComp(expression),
|
|
||||||
ExpressionRef::SetComp(expression) => AnyNodeRef::ExprSetComp(expression),
|
|
||||||
ExpressionRef::DictComp(expression) => AnyNodeRef::ExprDictComp(expression),
|
|
||||||
ExpressionRef::Generator(expression) => AnyNodeRef::ExprGenerator(expression),
|
|
||||||
ExpressionRef::Await(expression) => AnyNodeRef::ExprAwait(expression),
|
|
||||||
ExpressionRef::Yield(expression) => AnyNodeRef::ExprYield(expression),
|
|
||||||
ExpressionRef::YieldFrom(expression) => AnyNodeRef::ExprYieldFrom(expression),
|
|
||||||
ExpressionRef::Compare(expression) => AnyNodeRef::ExprCompare(expression),
|
|
||||||
ExpressionRef::Call(expression) => AnyNodeRef::ExprCall(expression),
|
|
||||||
ExpressionRef::FString(expression) => AnyNodeRef::ExprFString(expression),
|
|
||||||
ExpressionRef::StringLiteral(expression) => AnyNodeRef::ExprStringLiteral(expression),
|
|
||||||
ExpressionRef::BytesLiteral(expression) => AnyNodeRef::ExprBytesLiteral(expression),
|
|
||||||
ExpressionRef::NumberLiteral(expression) => AnyNodeRef::ExprNumberLiteral(expression),
|
|
||||||
ExpressionRef::BooleanLiteral(expression) => AnyNodeRef::ExprBooleanLiteral(expression),
|
|
||||||
ExpressionRef::NoneLiteral(expression) => AnyNodeRef::ExprNoneLiteral(expression),
|
|
||||||
ExpressionRef::EllipsisLiteral(expression) => {
|
|
||||||
AnyNodeRef::ExprEllipsisLiteral(expression)
|
|
||||||
}
|
|
||||||
ExpressionRef::Attribute(expression) => AnyNodeRef::ExprAttribute(expression),
|
|
||||||
ExpressionRef::Subscript(expression) => AnyNodeRef::ExprSubscript(expression),
|
|
||||||
ExpressionRef::Starred(expression) => AnyNodeRef::ExprStarred(expression),
|
|
||||||
ExpressionRef::Name(expression) => AnyNodeRef::ExprName(expression),
|
|
||||||
ExpressionRef::List(expression) => AnyNodeRef::ExprList(expression),
|
|
||||||
ExpressionRef::Tuple(expression) => AnyNodeRef::ExprTuple(expression),
|
|
||||||
ExpressionRef::Slice(expression) => AnyNodeRef::ExprSlice(expression),
|
|
||||||
ExpressionRef::IpyEscapeCommand(expression) => {
|
|
||||||
AnyNodeRef::ExprIpyEscapeCommand(expression)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ranged for ExpressionRef<'_> {
|
|
||||||
fn range(&self) -> TextRange {
|
|
||||||
match self {
|
|
||||||
ExpressionRef::BoolOp(expression) => expression.range(),
|
|
||||||
ExpressionRef::Named(expression) => expression.range(),
|
|
||||||
ExpressionRef::BinOp(expression) => expression.range(),
|
|
||||||
ExpressionRef::UnaryOp(expression) => expression.range(),
|
|
||||||
ExpressionRef::Lambda(expression) => expression.range(),
|
|
||||||
ExpressionRef::If(expression) => expression.range(),
|
|
||||||
ExpressionRef::Dict(expression) => expression.range(),
|
|
||||||
ExpressionRef::Set(expression) => expression.range(),
|
|
||||||
ExpressionRef::ListComp(expression) => expression.range(),
|
|
||||||
ExpressionRef::SetComp(expression) => expression.range(),
|
|
||||||
ExpressionRef::DictComp(expression) => expression.range(),
|
|
||||||
ExpressionRef::Generator(expression) => expression.range(),
|
|
||||||
ExpressionRef::Await(expression) => expression.range(),
|
|
||||||
ExpressionRef::Yield(expression) => expression.range(),
|
|
||||||
ExpressionRef::YieldFrom(expression) => expression.range(),
|
|
||||||
ExpressionRef::Compare(expression) => expression.range(),
|
|
||||||
ExpressionRef::Call(expression) => expression.range(),
|
|
||||||
ExpressionRef::FString(expression) => expression.range(),
|
|
||||||
ExpressionRef::StringLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::BytesLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::NumberLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::BooleanLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::NoneLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::EllipsisLiteral(expression) => expression.range(),
|
|
||||||
ExpressionRef::Attribute(expression) => expression.range(),
|
|
||||||
ExpressionRef::Subscript(expression) => expression.range(),
|
|
||||||
ExpressionRef::Starred(expression) => expression.range(),
|
|
||||||
ExpressionRef::Name(expression) => expression.range(),
|
|
||||||
ExpressionRef::List(expression) => expression.range(),
|
|
||||||
ExpressionRef::Tuple(expression) => expression.range(),
|
|
||||||
ExpressionRef::Slice(expression) => expression.range(),
|
|
||||||
ExpressionRef::IpyEscapeCommand(expression) => expression.range(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unowned pendant to all the literal variants of [`ast::Expr`] that stores a
|
/// Unowned pendant to all the literal variants of [`ast::Expr`] that stores a
|
||||||
/// reference instead of an owned value.
|
/// reference instead of an owned value.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, is_macro::Is)]
|
#[derive(Copy, Clone, Debug, PartialEq, is_macro::Is)]
|
||||||
|
|
8790
crates/ruff_python_ast/src/generated.rs
generated
Normal file
8790
crates/ruff_python_ast/src/generated.rs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,13 +2,15 @@ use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub use expression::*;
|
pub use expression::*;
|
||||||
|
pub use generated::*;
|
||||||
pub use int::*;
|
pub use int::*;
|
||||||
pub use node::{AnyNode, AnyNodeRef, AstNode, NodeKind};
|
pub use node::AstNode;
|
||||||
pub use nodes::*;
|
pub use nodes::*;
|
||||||
|
|
||||||
pub mod comparable;
|
pub mod comparable;
|
||||||
pub mod docstrings;
|
pub mod docstrings;
|
||||||
mod expression;
|
mod expression;
|
||||||
|
mod generated;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
pub mod identifier;
|
pub mod identifier;
|
||||||
mod int;
|
mod int;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,10 @@
|
||||||
|
use crate::AnyNodeRef;
|
||||||
use crate::{
|
use crate::{
|
||||||
Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator, ElifElseClause,
|
Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator, ElifElseClause,
|
||||||
ExceptHandler, Expr, FString, FStringElement, Keyword, MatchCase, Mod, Operator, Parameter,
|
ExceptHandler, Expr, FString, FStringElement, Keyword, MatchCase, Mod, Operator, Parameter,
|
||||||
ParameterWithDefault, Parameters, Pattern, PatternArguments, PatternKeyword, Singleton, Stmt,
|
ParameterWithDefault, Parameters, Pattern, PatternArguments, PatternKeyword, Singleton, Stmt,
|
||||||
StringLiteral, TypeParam, TypeParams, UnaryOp, WithItem,
|
StringLiteral, TypeParam, TypeParams, UnaryOp, WithItem,
|
||||||
};
|
};
|
||||||
use crate::{AnyNodeRef, AstNode};
|
|
||||||
|
|
||||||
/// Visitor that traverses all nodes recursively in the order they appear in the source.
|
/// Visitor that traverses all nodes recursively in the order they appear in the source.
|
||||||
///
|
///
|
||||||
|
@ -203,33 +203,7 @@ where
|
||||||
let node = AnyNodeRef::from(stmt);
|
let node = AnyNodeRef::from(stmt);
|
||||||
|
|
||||||
if visitor.enter_node(node).is_traverse() {
|
if visitor.enter_node(node).is_traverse() {
|
||||||
match stmt {
|
stmt.visit_source_order(visitor);
|
||||||
Stmt::Expr(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::FunctionDef(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::ClassDef(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Return(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Delete(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::TypeAlias(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Assign(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::AugAssign(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::AnnAssign(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::For(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::While(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::If(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::With(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Match(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Raise(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Try(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Assert(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Import(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::ImportFrom(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Pass(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Break(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Continue(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Global(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::Nonlocal(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
Stmt::IpyEscapeCommand(stmt) => stmt.visit_source_order(visitor),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor.leave_node(node);
|
visitor.leave_node(node);
|
||||||
|
@ -455,11 +429,7 @@ where
|
||||||
{
|
{
|
||||||
let node = AnyNodeRef::from(type_param);
|
let node = AnyNodeRef::from(type_param);
|
||||||
if visitor.enter_node(node).is_traverse() {
|
if visitor.enter_node(node).is_traverse() {
|
||||||
match type_param {
|
type_param.visit_source_order(visitor);
|
||||||
TypeParam::TypeVar(type_param) => type_param.visit_source_order(visitor),
|
|
||||||
TypeParam::TypeVarTuple(type_param) => type_param.visit_source_order(visitor),
|
|
||||||
TypeParam::ParamSpec(type_param) => type_param.visit_source_order(visitor),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
visitor.leave_node(node);
|
visitor.leave_node(node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ nodes_file = (
|
||||||
root.joinpath("crates")
|
root.joinpath("crates")
|
||||||
.joinpath("ruff_python_ast")
|
.joinpath("ruff_python_ast")
|
||||||
.joinpath("src")
|
.joinpath("src")
|
||||||
.joinpath("node.rs")
|
.joinpath("generated.rs")
|
||||||
.read_text()
|
.read_text()
|
||||||
)
|
)
|
||||||
node_lines = (
|
node_lines = (
|
||||||
|
|
216
crates/ruff_python_formatter/src/generated.rs
generated
216
crates/ruff_python_formatter/src/generated.rs
generated
|
@ -2392,6 +2392,114 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::PatternMatchOr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamTypeVar, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_type_var::FormatTypeParamTypeVar
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, node: &ast::TypeParamTypeVar, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamTypeVar>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamTypeVar,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamTypeVar,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamTypeVarTuple, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, node: &ast::TypeParamTypeVarTuple, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamTypeVarTuple>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamTypeVarTuple,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamTypeVarTuple,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamParamSpec, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_param_spec::FormatTypeParamParamSpec
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, node: &ast::TypeParamParamSpec, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamParamSpec>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamParamSpec,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamParamSpec,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FormatRule<ast::PatternArguments, PyFormatContext<'_>>
|
impl FormatRule<ast::PatternArguments, PyFormatContext<'_>>
|
||||||
for crate::pattern::pattern_arguments::FormatPatternArguments
|
for crate::pattern::pattern_arguments::FormatPatternArguments
|
||||||
{
|
{
|
||||||
|
@ -2827,114 +2935,6 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatRule<ast::TypeParamTypeVar, PyFormatContext<'_>>
|
|
||||||
for crate::type_param::type_param_type_var::FormatTypeParamTypeVar
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, node: &ast::TypeParamTypeVar, f: &mut PyFormatter) -> FormatResult<()> {
|
|
||||||
FormatNodeRule::<ast::TypeParamTypeVar>::fmt(self, node, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
|
||||||
type Format<'a> = FormatRefWithRule<
|
|
||||||
'a,
|
|
||||||
ast::TypeParamTypeVar,
|
|
||||||
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
|
||||||
FormatRefWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
|
||||||
type Format = FormatOwnedWithRule<
|
|
||||||
ast::TypeParamTypeVar,
|
|
||||||
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn into_format(self) -> Self::Format {
|
|
||||||
FormatOwnedWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormatRule<ast::TypeParamTypeVarTuple, PyFormatContext<'_>>
|
|
||||||
for crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, node: &ast::TypeParamTypeVarTuple, f: &mut PyFormatter) -> FormatResult<()> {
|
|
||||||
FormatNodeRule::<ast::TypeParamTypeVarTuple>::fmt(self, node, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
|
||||||
type Format<'a> = FormatRefWithRule<
|
|
||||||
'a,
|
|
||||||
ast::TypeParamTypeVarTuple,
|
|
||||||
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
|
||||||
FormatRefWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
|
||||||
type Format = FormatOwnedWithRule<
|
|
||||||
ast::TypeParamTypeVarTuple,
|
|
||||||
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn into_format(self) -> Self::Format {
|
|
||||||
FormatOwnedWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormatRule<ast::TypeParamParamSpec, PyFormatContext<'_>>
|
|
||||||
for crate::type_param::type_param_param_spec::FormatTypeParamParamSpec
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, node: &ast::TypeParamParamSpec, f: &mut PyFormatter) -> FormatResult<()> {
|
|
||||||
FormatNodeRule::<ast::TypeParamParamSpec>::fmt(self, node, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
|
||||||
type Format<'a> = FormatRefWithRule<
|
|
||||||
'a,
|
|
||||||
ast::TypeParamParamSpec,
|
|
||||||
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
|
||||||
FormatRefWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
|
||||||
type Format = FormatOwnedWithRule<
|
|
||||||
ast::TypeParamParamSpec,
|
|
||||||
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
|
||||||
PyFormatContext<'ast>,
|
|
||||||
>;
|
|
||||||
fn into_format(self) -> Self::Format {
|
|
||||||
FormatOwnedWithRule::new(
|
|
||||||
self,
|
|
||||||
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormatRule<ast::FString, PyFormatContext<'_>> for crate::other::f_string::FormatFString {
|
impl FormatRule<ast::FString, PyFormatContext<'_>> for crate::other::f_string::FormatFString {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, node: &ast::FString, f: &mut PyFormatter) -> FormatResult<()> {
|
fn fmt(&self, node: &ast::FString, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
|
|
@ -71,6 +71,9 @@ ignore = [
|
||||||
# Conflicts with the formatter
|
# Conflicts with the formatter
|
||||||
"COM812", "ISC001"
|
"COM812", "ISC001"
|
||||||
]
|
]
|
||||||
|
extend-select = [
|
||||||
|
"I",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
force-exclude = '''
|
force-exclude = '''
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue