I resume a project for develop some new rules, and one of them is to know if there is an invocation method in a for statement.
So i get the ForStatementTree objet and check the object in the condition(), update() and initializer() functions.
.
Condition() and update() functions return a ListTree, so for my needs, i check if possible the children of each StatementTree (maybe a mistake, but i’m starting this project).
For rules implementation examples, you can directly look into the rules of the Java analyzer itself, it contains hundreds of examples (just make sure to use only what is provided in the public API).
For example, NestedSwitchCheck could give you hints to implement your idea.
Then, to answer your question:
You should not use the implementation (ending with Impl) of the trees, but the interfaces available in the public API. (Ex: use MethodInvocationTree instead of MethodInvocationTreeImpl in your rule).
Thanks for your answer and documentation @Quentin,
I tried to use the interfaces, but the définition of the children() function is from the Abstract class JavaTree.
And i can’t use this class because like the other, it’s not a part of org.sonar.plugins.java.api package and the children() function is protected.
I thought for an another solution : get all invocationMethod instead of ForStatement, and check if the .parent() is a ForStatement (and check his parent if it’s not a ForStatement, etc…), but to me it’s seems significately less effective than get the children of a ForStatement.
and… it doesn’t work properly, because i can’t check if the invocationMethod is in the ForStatement or in the body of the ForStatement.
Ex : the following example is ok ( getMyValue() is in the condition of a ForStatement)
public void test3() {
for (int i = 0; i < getMyValue(); i++) { // Noncompliant
System.out.println(i);
boolean b = getMyValue() > 6;
}
}
But the next case is detected as non compilant (cause a “parent” of println() is a ForStatement)
public void test1() {
for (int i = 0; i < 20; i++) {
System.out.println(i);
boolean b = getMyValue() > 6;
}
}
And the plugin must detect some tricky case like this one :
public void test7() {
for (int i = 0; i < 20 ; if (i < 5) {getMyValue()} else {incrementeMyValue(i)} ) { // Noncompliant
System.out.println(i);
boolean b = getMyValue() > 6;
}
}
So i can’t stop the search if the plugin reach a block/if statement.