Home » Archived » EMF-IncQuery » Find and count elements of certain type inside a element
|
Re: Find and count elements of certain type inside a element [message #1395658 is a reply to message #1395286] |
Mon, 07 July 2014 07:58 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi Mario,
sadly, you have found an important limitation of our query language: there is no way to express constraints over the containment hierarchy; and we do not allow calling methods/EOperations on EClasses in check/eval expressions.
The main reason for these limitations are two-folds:
1. Incrementally indexing the containment hierarchy (especially transitively) is really expensive in terms of both memory usage and initialization time.
2. Our indexing only behaves correctly when all called operations/methods are pure functions (in the functional sense). The most important thing that must not be called from check expressions are value getters, and until now we have approximated this by removing the support for calling any method/operation on EClasses. This is not the best/final solution, but we couldn't come up with something better until now.
I can suggest only a single (ugly) workaround for short-term solution: create a pattern, that enumerates all possible children of a node, and then use the transitive closure of this pattern. For performance and resource usage, try to use as few relations as possible for your case. We have (an unfinished) example of this kind available in the following (JaMoPP-based) example: https://github.com/ujhelyiz/viatra2-programunderstanding/blob/master/transformation/hu.bme.mit.viatra2.examples.reveng/src/hu/bme/mit/viatra2/examples/reveng/queries.eiq - look at the belowStatement and statementInPattern patterns.
For longer term, we are already working on an alternative query strategy, that instead of indexing matches uses a search-based strategy that we already tested to support these use cases, but is not yet ready for external usage. If this algorithm is finished, we are planning to fine-tune the query language to support a wider range of use cases. See the https://bugs.eclipse.org/bugs/show_bug.cgi?id=406073 tracking bug for the state of this approach.
Cheers,
Zoltán
|
|
|
Re: Find and count elements of certain type inside a element [message #1395807 is a reply to message #1395658] |
Mon, 07 July 2014 12:20 |
Jan Reimann Messages: 140 Registered: July 2009 |
Senior Member |
|
|
What about this:
package test
import "http://www.emftext.org/java/statements"
import "http://www.emftext.org/java/members"
import "http://www.emftext.org/java/containers"
import "http://www.emftext.org/java"
import "http://www.emftext.org/java/instantiations"
pattern findMethod(method : ClassMethod) {
countForLoop == count find findForLoop(method, _forLoop);
countWhileLoop == count find findWhileLoop(method, _whileLoop);
countConditions == count find findCondition(method, _conditions);
sum == eval(countForLoop + countWhileLoop + countConditions);
check(sum >= 4);
}
private pattern findForLoop(method: ClassMethod, loop : ForLoop){
find findSomethingTransitively(method, loop);
}
private pattern findWhileLoop(method: ClassMethod, loop : WhileLoop){
find findSomethingTransitively(method, loop);
}
private pattern findCondition(method: ClassMethod, condition : Condition){
find findSomethingTransitively(method, condition);
}
private pattern findSomethingTransitively(container, child){
find findSomething+(container, child);
}
private pattern findSomething(container, child){
StatementListContainer.statements(container, child);
} or {
StatementContainer.statement(container, child);
} or {
Switch.cases(container, caseBlock);
SwitchCase.statements(caseBlock, child);
} or {
TryBlock.catcheBlocks(container, catchBlock);
CatchBlock.statements(catchBlock, child);
} or {
Condition.elseStatement(container, child);
}
|
|
| | |
Goto Forum:
Current Time: Thu Apr 25 22:08:58 GMT 2024
Powered by FUDForum. Page generated in 0.03067 seconds
|