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: reusable and efficient CtQueries #1090

Merged
merged 28 commits into from
Jan 12, 2017

Conversation

pvojtechovsky
Copy link
Collaborator

This is the clone of #1076 where CtBaseQuery are merged in CtQuery.

These solutions are nearly compatible from client's point of view.

Note: I have not added CtQueryImpl#evaluate(Object, Consumer) into CtQuery, because it is not needed on that high level of coding. The method is public and available in CtQueryImpl.

I would choose #1076, because the code is little bit cleaner (shorted classes = easier maintenance), but it is up to you. Both versions are acceptable for me.

The javadoc has to be read and fixed. There are till some wrong descriptions, which does not fit to latest design. But first choose which PR is adept for merge.

@pvojtechovsky
Copy link
Collaborator Author

Finally we should modify Spoon factory and add there some method which creates CtQueryImpl. I suggest this:

factory.createQuery() - creates unbound query
factory.createQuery(Object input) - creates bound query
actually both methods will return CtQueryImpl instance. Please give me feedback or suggestion for factory method which you like. I do not care how that will exactly look, but I think the factory method should be there.

I will make another PR for that

@pvojtechovsky
Copy link
Collaborator Author

I am finished with code changes. Please check the documentation. Then we can merge it.
Have a look at #1093 If you like it, I can add it as part of this PR too - as you wan ;-)

@monperrus monperrus changed the title Query improvements - CtQuery only feat: reusable and efficient CtQueries Jan 8, 2017
@monperrus
Copy link
Collaborator

Really cool. I've just made a PR on your PR on the tests. If we're along the same line, I will proceed with doc.

I can add it as part of this PR too - as you wan ;-)

No please don't, this PR already contains 3 baby steps, :-) (more on this later)

@monperrus monperrus changed the title feat: reusable and efficient CtQueries WIP feat: reusable and efficient CtQueries Jan 8, 2017
@pvojtechovsky
Copy link
Collaborator Author

I am finished with documentation fixes. It is ready for merge from my point of view

@monperrus
Copy link
Collaborator

monperrus commented Jan 10, 2017 via email

@monperrus
Copy link
Collaborator

monperrus commented Jan 10, 2017 via email


```java
// collecting all methods of deprecated classes
list2 = rootPackage
.filterChildren(new AnnotationFilter(Deprecated.class))
.filterChildren(new TypeFilter(CtMethod.class)).list();
.filterChildren(new AnnotationFilter(Deprecated.class)).list()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why don't you keep an example witch chaining queries here?

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 guess @monperrus removed it.

/**
* Recursively scans all children elements of an input element.
* The matched child element for which (filter.matches(element)==true) are sent to the next query step.
* Essentially the same as {@link CtElement#getElements(Filter)} but more powerful, because it
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just to be sure here: when you say filtered elements are sent to the next query step, it's not mandatory: you can just get the list of filtered elements through list() right? The meaning of your comment here is that the filterChildren can be used in the chain as it returns a CtQuery?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the filterChildren can be used in the chain as it returns a CtQuery?

I do not understand

* actually evaluates the query and returns all the produced elements collected in a List
* Same as {@link CtQuery#list()}, but with static typing on the return type
* and the final filtering, which matches only results, which are assignable from that return type.
*
Copy link
Collaborator

Choose a reason for hiding this comment

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

So classes which are not assignable for that return type are just ignored and you cannot have a ClassCastException?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, exactly

* which is the constant input of this query.
* It is used by {@link CtElement} implementations of {@link CtQueryable}.
*
* @param <O> - the type of element which is produced by the last step of the query
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you forgot to remove reference to param O.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you are right. I removed it now

@@ -90,126 +66,122 @@ public CtQueryImpl() {
* @param input
* @return this to support fluent API
*/
public CtQuery<O> addInput(O input) {
public CtQueryImpl addInput(Object... input) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do you return the impl here and not the interface?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because there are some interesting methods (evaluate, ...) which are available on CtQueryImpl only and if I cast query to CtQueryImpl once then I want to have CtQueryImpl after call of addInput too. It is correct implementation of fluent API

try {
if (stepIdx <= steps.size()) {
//process next intermediate step
AbstractStep step = steps.get(stepIdx - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

you defined a function getStep() for that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok, I change the code so the getStep() is used

* sets next {@link CtConsumer}
*/
void setNext(CtConsumer<Object> next);
private class CurrentStep implements CtConsumer<Object> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Found the name CurrentStep confusing as it's not a step (and does not extends AbstractStep) but more the CurrentConsumer.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok it took me a while to really understand how the whole process work and I think you should improve the doc on this class as it is central to process the different steps.
As far as I can see, this class plays as a kind of an orchestrator to move the step cursor forward, get the step, apply it and finally to call the output consumer. It could be great to add those information in the javadoc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

javadoc added

@@ -28,42 +28,21 @@
import spoon.reflect.visitor.Filter;

/**
* Contains the default implementation of the generic {@link CtQuery} methods
* The facade of {@link CtBaseQuery} which represents a query bound to the {@link CtElement},
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is CtBaseQuery I assume you mean CtQuery?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, CtQuery is correct. DONE

}
}
}

/**
* a step which calls Function. Implements contract of {@link CtQuery#map(CtFunction)}
* a step which calls Function. Implements contract of {@link CtBaseQuery#map(CtFunction)}
Copy link
Collaborator

Choose a reason for hiding this comment

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

CtBaseQuery here again

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, CtQuery is correct. DONE

@surli surli changed the title WIP feat: reusable and efficient CtQueries feature: reusable and efficient CtQueries Jan 12, 2017
@surli
Copy link
Collaborator

surli commented Jan 12, 2017

Ok this is ready to merge for me. @pvojtechovsky could I close #1070 too or is it a pending discussion?

@pvojtechovsky
Copy link
Collaborator Author

I have closed #1070.

@surli
Copy link
Collaborator

surli commented Jan 12, 2017

Ok! Then let's merge and thanks for your work 👍

@surli surli merged commit 319cb70 into INRIA:master Jan 12, 2017
@monperrus
Copy link
Collaborator

monperrus commented Jan 12, 2017 via email

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.

3 participants