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

feature: introduce the concept of lexical scope (interface LexicalScope) #2813

Merged
merged 7 commits into from
Jan 23, 2019

Conversation

pvojtechovsky
Copy link
Collaborator

@pvojtechovsky pvojtechovsky commented Dec 1, 2018

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

@pvojtechovsky pvojtechovsky changed the title WiP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Dec 1, 2018
@pvojtechovsky pvojtechovsky changed the title feature: NameScope detects conflicts on names WiP feature: NameScope detects conflicts on names Dec 1, 2018
@pvojtechovsky pvojtechovsky force-pushed the feaNameScope branch 2 times, most recently from bf4cb63 to ae93fe0 Compare December 1, 2018 21:35
@pvojtechovsky pvojtechovsky changed the title WiP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Dec 1, 2018
@pvojtechovsky pvojtechovsky changed the title feature: NameScope detects conflicts on names WiP feature: NameScope detects conflicts on names Dec 2, 2018
@pvojtechovsky pvojtechovsky changed the title WiP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Dec 2, 2018
@pvojtechovsky pvojtechovsky changed the title feature: NameScope detects conflicts on names WiP feature: NameScope detects conflicts on names Dec 3, 2018
@surli surli changed the title WiP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Dec 3, 2018
@surli surli changed the title feature: NameScope detects conflicts on names WIP feature: NameScope detects conflicts on names Dec 3, 2018
@surli
Copy link
Collaborator

surli commented Dec 3, 2018

@pvojtechovsky you leave in the main comment that it's ready for review, but apparently it's not anymore? What's missing?

@pvojtechovsky pvojtechovsky changed the title WIP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Dec 3, 2018
@pvojtechovsky
Copy link
Collaborator Author

I WiP it because it needed rebase (there was 2 PRs here). Now it is ready for review.

@monperrus
Copy link
Collaborator

thanks for the big feature, we need a little bit of time to review it correctly :-) (doc, tests)

@monperrus
Copy link
Collaborator

Hi Pavel,

Just checked-out locally.

I have hard time to understand the intent and the design:

  • what's the goal of NameScope?
  • why do we have both NameScope and NameScope.Scanner as public? Could we have only one public class?
  • NameScope depends on its subclass SimpleNameScope, which is kind of bad design.

Merry Christmas, --Martin

@pvojtechovsky
Copy link
Collaborator Author

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 Renata and which checks the NameScopes at time when literal "1" and "2" are scanned.

Merry Christmas to You too ;-)
Pavel

/**
* @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
Copy link
Contributor

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.

@pvojtechovsky pvojtechovsky changed the title feature: NameScope detects conflicts on names WiP feature: NameScope detects conflicts on names Dec 27, 2018
@pvojtechovsky
Copy link
Collaborator Author

I have hard time to understand the intent and the design

I just refactored it. There are two public classes now:

  • NameScopeScanner - scanner which knows current NameScope
  • NameScope - a mapping of simple name to named CtElement, which is imported/defined in actually scanned scope.
    Other classes are internal and represents different kinds of of NameScopes.

It is ready for review.

@pvojtechovsky pvojtechovsky changed the title WiP feature: NameScope detects conflicts on names feature: NameScope detects conflicts on names Jan 2, 2019
@pvojtechovsky pvojtechovsky changed the title feature: NameScope detects conflicts on names feature: NameScope and NameScopeScanner provides mapping from simple name to CtElement Jan 2, 2019
@monperrus
Copy link
Collaborator

I'm working on it

@monperrus
Copy link
Collaborator

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?

@monperrus monperrus changed the title feature: NameScope and NameScopeScanner provides mapping from simple name to CtElement feature: introduce the concept of lexical scope (interface LexicalScope) Jan 8, 2019
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<>();
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 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... :-)

Copy link
Collaborator

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.

@pvojtechovsky
Copy link
Collaborator Author

Is that correct?

yes.

Can we KISS this PR and merge AbstractNameScope and its subclasses?

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.

@monperrus
Copy link
Collaborator

KISSed it

@monperrus
Copy link
Collaborator

@pvojtechovsky WDYT?

@pvojtechovsky
Copy link
Collaborator Author

I am ok with this KISS. I like new LexicalScope term. It fits well.
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.

Why do you think that it is better design to let TypeNameScope extends NameScopeImpl, while NameScopeImpl contains a specific implementation which is not used in TypeNameScope? I like more the design with abstract class, which exactly express what is shared code used by all children.
But if you think it is easier to maintain I can live with that. They are internal classes and I do not expect that anybody will ever need to extend them. And yes, 2 classes to maintain is better then 3 classes :-)

@monperrus
Copy link
Collaborator

monperrus commented Jan 14, 2019 via email

@nharrand
Copy link
Collaborator

Awesome feature. It would have saved me a lot of trouble a couple months ago!

@nharrand nharrand merged commit a16f436 into INRIA:master Jan 23, 2019
@pvojtechovsky pvojtechovsky deleted the feaNameScope branch January 25, 2019 06:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants