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: template parameters collecting TemplateMatcher #1080

Closed
pvojtechovsky opened this issue Dec 29, 2016 · 8 comments
Closed

feature: template parameters collecting TemplateMatcher #1080

pvojtechovsky opened this issue Dec 29, 2016 · 8 comments
Labels

Comments

@pvojtechovsky
Copy link
Collaborator

TemplateMatcher actually returns the list of model elements, which matches the Template T1.
It would be nice if TemplateMatcher would not return only list of matching elements, but for each matched element it might return Template parameters, which can be used to build that element using Template T1.
I am speaking about inverse process to the Template T1.apply(templateParameters TP1) creates an element E1_1.

What it would be good for? Replacing of one design pattern implementation by another implementation.

Example:
code like

for(Iterator iter=collection.iterator();iter.hasNext();) {
ItemType item = iter.next();
...bodyOfLooop...
}

might be automatically replaced by modern for(ItemType item : cllection){...bodyOfLoop...)

Algoritm:

  1. search for all accurences of oldLoop using TemplateMatcher and templateOldLoop
  2. for each occurence check if moodern loop is compatible
  3. for each compatible oldLoop create model element newLoop of modern loop using templateModernLoop+actual template parameters
  4. replace oldLoop by newLoop.

And not only that ;-)

@monperrus
Copy link
Collaborator

It's a very interesting improvement of template matchers.

@monperrus
Copy link
Collaborator

monperrus commented Jan 9, 2017

actually, there a natural way of getting the matched expression: taking the template parameter name:

public TemplateParameter<Collection<?>> _col_;
...
if (_col_.S().size() > 10)

then, one gets the value of match as follows:

interface TemplateMatcher{
CtElement getMatchedElement(String name)
}

aMatcher.getMatchedElement("_col_") ->the matched expression

@pvojtechovsky
Copy link
Collaborator Author

I searched through existing code and have found no getMatchedElement, so you probably speak about future API design. Right?

In Future I would like to use TemplateMatcher as query Filter. It would be change like this:

class TemplateMatcher implements Filter {
  public boolean match(CtElement element) {
    return this.match(element, this.templateRoot);
  }
... current code of TemplateMatcher ...
}

So it can be used in query to search for elements, which matches the template. In my case I expect that TemplateMatcher will usually match more then one element, so I need TemplateMatcher API, which will give me access to actual template parameters for each element.

S1) May be the code based on your TemplateMatcher.getMatchedElement might look like this:

TemplateMatcher matcher = new TemplateMatcher(template);
rootPackage.filterChildren(matcher).map(match->{
  //this code is called immediately after `matcher` matches the `match` element
  //so may be we can access matcher's current state like this
  CtElement templateParam1 = matcher.getMatchedElement("_col_");
  ... do something with templateParam1 ...
}).list();

This approach is good for some use cases. For my use case I need method

interface TemplateMatcher{
Map<String,CtElement> getMatchedTemplateParameterElements()
}

The later call of

aMatcher.getMatchedTemplateParameterElements().get("_col_") ->the matched expression

would return same matched expression like in your case.

S2) So I will probably write code with following behavior

TemplateMatcher matcher = new TemplateMatcher(template);
Map<CtElement,Map<String, CtElement>> matchToParams = new IdentityHashMap<>();
rootPackage.filterChildren(matcher).map(match->{
  //this code is called immediately after `matcher` matches the `match` element
  //so may be we can access matcher's current state like this
  matchToParams.put(match, matcher.getMatchedTemplateParameterElements());
  return false;
}).list();

I will then process matchToParams

@monperrus
Copy link
Collaborator

In Future I would like to use TemplateMatcher as query Filter. It would be change like this: class TemplateMatcher implements Filter

This sounds like a very meaningful and interesting first baby step.

@pvojtechovsky
Copy link
Collaborator Author

Good idea. I will make a PR for that

@pvojtechovsky
Copy link
Collaborator Author

Will be solved by #1686

@monperrus monperrus changed the title feature: template parameters collecting TemplateMatcher feature: use TemplateMatcher as query Filter Apr 20, 2018
@monperrus monperrus changed the title feature: use TemplateMatcher as query Filter feature: template parameters collecting TemplateMatcher Apr 20, 2018
@monperrus
Copy link
Collaborator

About advanced matching, see this paper https://homes.cs.washington.edu/~remywang/yoko.pdf and in particular the operators at the end of Section 2.2

@monperrus
Copy link
Collaborator

closed by #1686

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

No branches or pull requests

3 participants