-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Delay computation of Definition
visibility
#4339
Conversation
03ea2d4
to
0610a43
Compare
(Draft as I need to break this into a few PRs.) |
PR Check ResultsEcosystem✅ ecosystem check detected no changes. BenchmarkLinux
Windows
|
7ff21f5
to
b05eafc
Compare
b05eafc
to
4083ded
Compare
pub string_type_definitions: Vec<(TextRange, &'a str, Snapshot)>, | ||
pub type_definitions: Vec<(&'a Expr, Snapshot)>, | ||
pub functions: Vec<(Snapshot, VisibleScope)>, | ||
pub functions: Vec<Snapshot>, |
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.
VisibleScope
is gone, no longer needs to exist.
pub mod extraction; | ||
pub mod google; | ||
pub mod numpy; | ||
pub mod sections; | ||
pub mod styles; | ||
|
||
#[derive(Debug)] | ||
pub struct Docstring<'a> { |
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.
This was moved out of definition.rs
, unchanged.
self.visibilities.push(visibility); | ||
|
||
Some((definition, visibility)) | ||
} |
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.
Here, we iterate over definitions and compute visibilities as we go. We can do it in a single pass, as it's assumed that parents appear before children (this assumption is documented above, on Definitions
).
One thing that we could do here that I haven't thought about before: Keep the logic as is but don't emit the This will have worse performance for projects that use |
} | ||
overloaded_name = | ||
flake8_annotations::helpers::overloaded_name(self, &definition); | ||
let definitions = std::mem::take(&mut self.ctx.definitions); |
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.
Why is it no longer necessary to to check if self.ctx.definitions
doesn't contain new entries after iterating all definitions? Or was that never necessary to begin with?
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.
It was never necessary, but we did it for consistency.
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.
Added a docstring to clarify this.
This still requires most of the changes I made here, because you need to be able to retroactively check visibility up the parent tree, which our current abstractions don't allow. (We don't store parent-child relationships for definitions right now, so there'd be no way to know whether a child definition is now private.) |
4083ded
to
e708ffb
Compare
Thanks, took all suggestion :) |
Summary
The AST checker has a concept of "definitions", defined as parts of the AST that can be documented with a docstring. In practice, this overlaps with scopes, since everything that can be documented also creates a new scope -- but in my opinion, it's helpful to treat them as separate concepts given that (1) not all constructs that create scopes can be documented (like comprehensions and lambdas), and (2) there are in theory other things that can be documented (like class attributes) that don't create scopes.
Anyway, in order to determine whether a definition is missing a docstring, we need to assess the definition's visibility: is it a public or private function/class/module? Visibility is a concept that relies on parent-child relationships (nested classes within private classes are private; nested classes within public classes can be public). Historically, we tracked these visibility rules as we iterated over the AST.
However, we now need to adjust our visibility rules to respect
__all__
-- if a module defines__all__
, and a definition is excluded from__all__
, it should be considered private. Since__all__
can be modified throughout the program, it's no longer possible to track visibility as we go.This PR refactors the "definitions" concept such that we now track definitions as we go, and then compute visibility after we've traversed the entire program. In the process, I also removed a few abstractions and refactored the
Definition
struct hierarchy to better reflect the layout of the data (i.e., we have separate enums for modules vs. members).Note that we're not yet respecting
__all__
-- that will come in a separate PR. But this PR makes it "trivial" to add that behavior.Test Plan
Can rely entirely on our automated tests here. There should be no behavioral changes.