Skip to content
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

Add end locations to all nodes #4192

Merged
merged 6 commits into from
Oct 17, 2022

Conversation

charliermarsh
Copy link
Collaborator

@charliermarsh charliermarsh commented Oct 2, 2022

Summary

I'm finding myself needing end locations for AST nodes (similar to in the Python AST). Is there interest in enabling this? If so, happy to clean up and test further.

@charliermarsh charliermarsh force-pushed the charlie/end-location branch 2 times, most recently from 430985f to 3a18132 Compare October 2, 2022 02:03
@youknowone
Copy link
Member

Please feel free to let me know if you need any help

@charliermarsh
Copy link
Collaborator Author

@youknowone - Just rebased. I've been using this code successfully in Ruff for a while now, would love to get it merged if you're open to it! Let me know what needs fixing / addressing :)

@youknowone
Copy link
Member

@charliermarsh I didn't check the details yet, but could you check the failing tests?

@charliermarsh
Copy link
Collaborator Author

@youknowone - Absolutely, will do, thanks.

@charliermarsh
Copy link
Collaborator Author

@youknowone - Tests passing!

@youknowone
Copy link
Member

Because we are trying to leave our own footprints to CPython codes as less as possible, I reverted the last commit but tried to change end_location to be optional.

@charliermarsh
Copy link
Collaborator Author

I can change it to Optional (but populated everywhere, as it is now) if you'd prefer?

@charliermarsh
Copy link
Collaborator Author

Or are you suggesting something else? Using Optional is less convenient for me as a "client" of the parser but I know the spec marks it as optional :)

@youknowone youknowone self-requested a review October 16, 2022 15:01
@charliermarsh
Copy link
Collaborator Author

Specifically, I could change the struct to:

#[derive(Debug, PartialEq)]
pub struct Located<T, U = ()> {
    pub location: Location,
    pub end_location: Option<Location>,
    pub custom: U,
    pub node: T,
}

...then propagate that throughout the codebase.

@youknowone
Copy link
Member

I am ok with either way unless it works well with CPython test codes.
If you mean end_location: Option<Location>, that's also a good way because leaving fake value as I did is a sort of anti-pattern.

@charliermarsh
Copy link
Collaborator Author

I can try to make that change today.

@charliermarsh
Copy link
Collaborator Author

In practice, does CPython ever omit end_lineno and end_col_offset when you go through ast.parse? Or are they just optional when creating AST nodes "manually"?

@youknowone
Copy link
Member

@charliermarsh because I made incomplete commit last push, you can work on the new one as a base.

I am sorry, I don't know well about CPython ast that much.
cc @fanninpm @coolreader18

@charliermarsh
Copy link
Collaborator Author

charliermarsh commented Oct 16, 2022

@youknowone - Hoping I didn't override your work. This is ready for review.

@@ -2307,8 +2307,6 @@ class C:
cdef = ast.parse(s).body[0]
self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)

# TODO: RUSTPYTHON
@unittest.expectedFailure
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowone - All other test changes were now able to be reverted.

pub custom: U,
pub node: T,
}

impl<T> Located<T> {
pub fn new(location: Location, node: T) -> Self {
pub fn new(location: Location, end_location: Location, node: T) -> Self {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept Location as a required field in ::new for now. (We can omit it in special cases by going through the Struct directly, as in ast.rs.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could see arguments either way here. On the one hand, it's odd that the field you pass in differs from what's stored on the struct. On the other hand, this encourages good behavior and reduces the number of code changes required.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this approach and the idea encouraging good behavior.

@@ -0,0 +1,173 @@
use rustpython_ast::{Expr, ExprContext, ExprKind};

pub fn set_context(expr: Expr, ctx: ExprContext) -> Expr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary part of end_location?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no, sorry, I need to revert this. Not sure how it got included.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Removed.)

@youknowone youknowone merged commit 610d408 into RustPython:main Oct 17, 2022
@youknowone
Copy link
Member

Awesome! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants