Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF-IncQuery » Find and count elements of certain type inside a element
Find and count elements of certain type inside a element [message #1395286] Sun, 06 July 2014 17:57 Go to next message
Mario Bauer is currently offline Mario BauerFriend
Messages: 21
Registered: May 2014
Junior Member

I have to write a query in Incquery, that finds elements of certain types inside an element.
In a Java Query I use either allContents or the getChildenByEType() method of the JaMoPP metamodel.

The concrete example for the JaMoPP metamodel:

Inside a method all elements of type

must be found.

The query should only return the methods, that contain more than four elements of this.
I know this works using the count statement.

The method class has a method "getChildenByEType(EClass)" or getChildrenByType(Class).
But I cannot call this method in an Incquery query.

Is there any way to solve this problem with Incquery?

Thanks, Mario
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 Go to previous messageGo to next message
Zoltan Ujhelyi is currently offline Zoltan UjhelyiFriend
Messages: 237
Registered: July 2009
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: - 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 tracking bug for the state of this approach.

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 Go to previous message
Jan Reimann is currently offline Jan ReimannFriend
Messages: 134
Registered: July 2009
Senior Member
What about this:

package test

import ""
import ""
import ""
import ""
import ""

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);
Previous Topic:Compare values
Next Topic:Simplification of Query
Goto Forum:

Current Time: Wed Apr 01 03:11:52 GMT 2015

Powered by FUDForum. Page generated in 0.01718 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software