-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Auto generate visit_source_order
#17180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -15,7 +15,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
| import tomllib | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Types that require `crate::`. We can slowly remove these types as we move them to generate scripts. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| types_requiring_create_prefix = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| types_requiring_create_prefix = { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "IpyEscapeKind", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "ExprContext", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Identifier", | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -33,12 +33,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
| "Decorator", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "TypeParams", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Parameters", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Arguments", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "ElifElseClause", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "WithItem", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "MatchCase", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Alias", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def rustfmt(code: str) -> str: | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -124,6 +123,8 @@ class Node: | |||||||||||||||||||||||||||||||||||||||||||||||||
| doc: str | None | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields: list[Field] | None | ||||||||||||||||||||||||||||||||||||||||||||||||||
| derives: list[str] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| custom_source_order: bool | ||||||||||||||||||||||||||||||||||||||||||||||||||
| source_order: list[str] | None | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, group: Group, node_name: str, node: dict[str, Any]) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.name = node_name | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -133,33 +134,90 @@ def __init__(self, group: Group, node_name: str, node: dict[str, Any]) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||
| fields = node.get("fields") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if fields is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.fields = [Field(f) for f in fields] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.custom_source_order = node.get("custom_source_order", False) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.derives = node.get("derives", []) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.doc = node.get("doc") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.source_order = node.get("source_order") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def fields_in_source_order(self) -> list[Field]: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.fields is None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.source_order is None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return list(filter(lambda x: not x.skip_source_order(), self.fields)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fields = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for field_name in self.source_order: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| field = None | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for field in self.fields: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if field.skip_source_order(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if field.name == field_name: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| field = field | ||||||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields.append(field) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return fields | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @dataclass | ||||||||||||||||||||||||||||||||||||||||||||||||||
| class Field: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ty: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| _skip_visit: bool | ||||||||||||||||||||||||||||||||||||||||||||||||||
| is_annotation: bool | ||||||||||||||||||||||||||||||||||||||||||||||||||
| parsed_ty: FieldType | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, field: dict[str, Any]) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.name = field["name"] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.ty = field["type"] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.parsed_ty = FieldType(self.ty) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self._skip_visit = field.get("skip_visit", False) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.is_annotation = field.get("is_annotation", False) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def skip_source_order(self) -> bool: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return self._skip_visit or self.parsed_ty.inner in [ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "str", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "ExprContext", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Name", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "u32", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "bool", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Number", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "IpyEscapeKind", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extracts the type argument from the given rust type with AST field type syntax. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Box<str> -> str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Box<Expr?> -> Expr | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # If the type does not have a type argument, it will return the string. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Does not support nested types | ||||||||||||||||||||||||||||||||||||||||||||||||||
| def extract_type_argument(rust_type_str: str) -> str: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| rust_type_str = rust_type_str.replace("*", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| rust_type_str = rust_type_str.replace("?", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| rust_type_str = rust_type_str.replace("&", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| open_bracket_index = rust_type_str.find("<") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if open_bracket_index == -1: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return rust_type_str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| close_bracket_index = rust_type_str.rfind(">") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if close_bracket_index == -1 or close_bracket_index <= open_bracket_index: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError(f"Brackets are not balanced for type {rust_type_str}") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| inner_type = rust_type_str[open_bracket_index + 1 : close_bracket_index].strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return inner_type | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @dataclass | ||||||||||||||||||||||||||||||||||||||||||||||||||
| class FieldType: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| rule: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| inner: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| seq: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||||
| optional: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||||
| slice_: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, rule: str) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.rule = rule | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.name = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.inner = extract_type_argument(rule) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # The following cases are the limitations of this parser(and not used in the ast.toml): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # * Rules that involve declaring a sequence with optional items e.g. Vec<Option<...>> | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -201,6 +259,7 @@ def write_preamble(out: list[str]) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||
| // Run `crates/ruff_python_ast/generate.py` to re-generate the file. | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::name::Name; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::visitor::source_order::SourceOrderVisitor; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| """) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -703,6 +762,98 @@ def write_node(out: list[str], ast: Ast) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||
| out.append("") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # ------------------------------------------------------------------------------ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Source order visitor | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @dataclass | ||||||||||||||||||||||||||||||||||||||||||||||||||
| class VisitorInfo: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: str | ||||||||||||||||||||||||||||||||||||||||||||||||||
| accepts_sequence: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Map of AST node types to their corresponding visitor information | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type_to_visitor_function: dict[str, VisitorInfo] = { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Decorator": VisitorInfo("visit_decorator"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Identifier": VisitorInfo("visit_identifier"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "crate::TypeParams": VisitorInfo("visit_type_params", True), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "crate::Parameters": VisitorInfo("visit_parameters", True), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Expr": VisitorInfo("visit_expr"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Stmt": VisitorInfo("visit_body", True), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Arguments": VisitorInfo("visit_arguments", True), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "crate::Arguments": VisitorInfo("visit_arguments", True), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Operator": VisitorInfo("visit_operator"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "ElifElseClause": VisitorInfo("visit_elif_else_clause"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "WithItem": VisitorInfo("visit_with_item"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "MatchCase": VisitorInfo("visit_match_case"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "ExceptHandler": VisitorInfo("visit_except_handler"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Alias": VisitorInfo("visit_alias"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "UnaryOp": VisitorInfo("visit_unary_op"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "DictItem": VisitorInfo("visit_dict_item"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Comprehension": VisitorInfo("visit_comprehension"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "CmpOp": VisitorInfo("visit_cmp_op"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "FStringValue": VisitorInfo("visit_f_string_value"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "StringLiteralValue": VisitorInfo("visit_string_literal"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "BytesLiteralValue": VisitorInfo("visit_bytes_literal"), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+776
to
+798
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we change this to only include the exceptions. Most names can be derived directly from the type's name by converting to snake case. It would also be nice if there's a way to specify those names without having to touch the generator script. This also makes me wonder. Is this, sort of, the inverse of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First off, this mapping is proportional to the number of types that fields can have, not proportional to the number of fields themselves or syntax nodes, so it's less worrisome to spell out all of the options. We already do that, for instance, in the definition of That said, I agree with Micha's suggestion to make this mapping only include the exceptions if possible. There's also another option, which I don't know yet if I like. But I want to write it up to see what I feel about it. You could also do this with a trait over in trait FieldVisitor {
fn visit<'a, V: SourceOrderVisitor<'a>>(&'a self, visitor: &mut V);
}
impl FieldVisitor for Decorator {
fn visit<'a, V: SourceOrderVisitor<'a>>(&'a self, visitor: &mut V) {
visitor.visit_decorator(self);
}
}
/* and so on */Things I don't like about this suggestion:
Things I do like:
What do others think?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's an interesting trick. Would the trait implementations be code-gened or hand written? This is interesting. What I dislike about it is that it adds "accidental" complexity. It's something that's only necessary because we codegen the visitor. I think I have a slight preference to keep the complexity in I do like the things that you call out as positives :)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this idea too. One other thing that made the visitors hard without touching the code here was that some visit a slice of that type(like I'm probably wrong but I feel this change is overall useful even if there was no code generation. My reply to first comment starts here:
@MichaReiser are you suggesting to generate the visitor name from the field name? I initially created the table for visitors that visit a sequence. I wanted to mark what visitors require a for loop. I'm thinking about this idea, to determine the visitor name:
Hopefully the point 3 can be gone after I send a refactor either just making it consistent or applying Douglas's suggestion.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be great if we can explore this idea as a separate PR, unless it creates a lot of additional work.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of inferring behavior from the presence of an 👍 to landing this as-is and iterating on possible changes in later PRs |
||||||||||||||||||||||||||||||||||||||||||||||||||
| annotation_visitor_function = VisitorInfo("visit_annotation") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def write_source_order(out: list[str], ast: Ast) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for group in ast.groups: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for node in group.nodes: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if node.fields is None or node.custom_source_order: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name = node.name | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields_list = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| body = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| for field in node.fields: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if field.skip_source_order(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields_list += f"{field.name}: _,\n" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields_list += f"{field.name},\n" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fields_list += "range: _,\n" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| for field in node.fields_in_source_order(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor = type_to_visitor_function[field.parsed_ty.inner] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if field.is_annotation: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor = annotation_visitor_function | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if field.parsed_ty.optional: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| body += f""" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some({field.name}) = {field.name} {{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor.{visitor.name}({field.name}); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }}\n | ||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| elif not visitor.accepts_sequence and field.parsed_ty.seq: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| body += f""" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for elm in {field.name} {{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor.{visitor.name}(elm); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| body += f"visitor.{visitor.name}({field.name});\n" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+819
to
+836
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The trait would let you get rid of all of this logic (except for
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor_arg_name = "visitor" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(node.fields_in_source_order()) == 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| visitor_arg_name = "_" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| out.append(f""" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| impl {name} {{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub(crate) fn visit_source_order<'a, V>(&'a self, {visitor_arg_name}: &mut V) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| where | ||||||||||||||||||||||||||||||||||||||||||||||||||
| V: SourceOrderVisitor<'a> + ?Sized, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| {{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let {name} {{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| {fields_list} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }} = self; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| {body} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| """) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # ------------------------------------------------------------------------------ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Format and write output | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -715,6 +866,7 @@ def generate(ast: Ast) -> list[str]: | |||||||||||||||||||||||||||||||||||||||||||||||||
| write_anynoderef(out, ast) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| write_nodekind(out, ast) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| write_node(out, ast) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| write_source_order(out, ast) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return out | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the meaning of
in_annotation. Could we add some documentation for it.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I forgot about this one. This is only needed to determine the visitor function. For other expressions we use
visit_exprbut for annotations we havevisit_annotation.This could go to the generate script as well since we don't have a lot of annotations and it's not gonna change probably. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also be true for
StmtAnnAssign,TypeAliasand other statements or is it just this one?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed it for
StmtAnnAssign. ForTypeAliaswe did not have it before?https://github.com/astral-sh/ruff/pull/17180/files#diff-97bb55be932e9d4bbd9219dfd4d62507ae171c8b642a3feceeceeb7fd4d1c6a6L121
But you are right for value it should be annotation. I changed it to annotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference is to preserve the behavior from the hand written visitor and to change the visiting (if that's indeed the case) in a separate PR