-
-
Notifications
You must be signed in to change notification settings - Fork 351
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
feature: introduce the concept of lexical scope (interface LexicalScope) #2813
Conversation
648fe9e
to
64112a6
Compare
bf4cb63
to
ae93fe0
Compare
16d2922
to
4f26993
Compare
4f26993
to
aed68f3
Compare
@pvojtechovsky you leave in the main comment that it's ready for review, but apparently it's not anymore? What's missing? |
aed68f3
to
0775ff4
Compare
I WiP it because it needed rebase (there was 2 PRs here). Now it is ready for review. |
thanks for the big feature, we need a little bit of time to review it correctly :-) (doc, tests) |
Hi Pavel, Just checked-out locally. I have hard time to understand the intent and the design:
Merry Christmas, --Martin |
Hi Martin, I believe it is hard to understand. I do not like that too, but I do not have better idea and I do not have time to do it better. What is the purpose? While scanning AST there is always available a queue of NameScopes, which can map any simple name to an element of AST, which maps to that name in current scanning scope. So whole feature consists of Scanner, which constructs and keeps NameScopes depending on the scanned element and provides current NameScope in each scanning step. See test which scans the Type Merry Christmas to You too ;-) |
/** | ||
* @param name to be searched simple name | ||
* @param consumer is called for each named element with same name which are accessible from this {@link NameScope} | ||
* as long as there are some elements and consumer returns null. If `consumer` return not null value then it is returned |
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.
I suggest fixing the sentence to clarify what is going on. I do not understand what you mean here.
0775ff4
to
10b5db5
Compare
I just refactored it. There are two public classes now:
It is ready for review. |
I'm working on it |
I think I understand :-) You're introducing "lexical scope" as first class concept in Spoon (see https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping). Pushed some changes accordingly (names + tests) Is that correct? Can we KISS this PR and merge AbstractNameScope and its subclasses? |
public class NameScopeScanner<T> extends EarlyTerminatingScanner<T> { | ||
private final Deque<NameScope> scopes = new ArrayDeque<>(); | ||
public class LexicalScopeBuilder extends EarlyTerminatingScanner<Object> { | ||
private final List<LexicalScope> allScopes = new ArrayList<>(); |
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.
I do not think that collecting of all scopes makes sense.
Note that scopes are even changing during scanning. For example:
void draw() {
//scope1
int a;
//scope2
int b;
//scope3
}
while scanning the statements of method draw
, there is only one LexicalScope object whose content is different while scanning each comment.
In all my current use cases (handling of imports #2683) I am scanning AST and I need current lexical scope only.
If you see an use case behind I can live with that. I hope that amount of collected elements is not too big to consume much memory... :-)
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.
Thanks for the explanation. Fixed.
yes.
Note that subclasses are already internal. I need only the interfaces, so I am open to any changes concerning subclasses if you think the design is better then. Feel free to refactor it. |
KISSed it |
@pvojtechovsky WDYT? |
I am ok with this KISS. I like new LexicalScope term. It fits well. Why do you think that it is better design to let |
I just suggest to rename |LexicalScopeBuilder| to |LexicalScopeScanner|, because main purpose of
this class is still "to scan" and to provide the LexicalScope during that scanning process.
Agree, done.
Why do you think that it is better design to let |TypeNameScope| extends |NameScopeImpl|
|TypeNameScope reuses the parent and scoped element (constructor)|
I like more the design with abstract class, which exactly express what is shared code used by all
children.
Yes, but it's harder to understand. I tend to prefer maintainability over pure, yet potentially
over-engineered, design esp. for open-source.
But if you think it is easier to maintain I can live with that.
Perfect. @nharrand do you merge?
|
Awesome feature. It would have saved me a lot of trouble a couple months ago! |
Implements scanner, which knows the named elements of actually scanned context. It is used by model validators of #2683 to detect conflicts.
It is ready for review