Проблема в вашем коде заключается в следующем:
if (statement.isIfStmt()) {
Условие четко указывает на то, что вы имеете дело с оператором if, и, следовательно, вы не можете добавить инструкцию. Вам нужно получить элемент n + 1 (где n - индекс оператора if), а затем использовать:
cu.findAll(Statement.class).get(2).asBlockStmt().addStatement("countA++;")
Есть несколько способов определить выражение, которое нужно добавить, здесьЯ использую простую строку для ясности, но проверяю рабочий пример на предмет реального синтаксиса.
Пока вы можете использовать ту же технику, но она будет более сложной. Для простоты объявления ваших счетчиков будут добавлены в начале метода с использованием следующего подхода:
((BlockStmt)cu.findAll(Statement.class).get(6).getParentNode().get()).addStatement(0, new StringLiteralExpr("int b = 1;"));
Exaplanation
- шестая инструкциясписок всех операторов - это цикл while
- родительский узел этого оператора является основным блоком метода и там, где выхотите добавить свои инструкции
- Этот объект должен быть класс, приведенный к BlockStm t, чтобы иметь возможность использовать метод addStatement
- StringLiteralExpr являетсяподкласс Expression, и здесь он используется для создания экземпляра из строки. Существует множество других реализаций, которые вы можете исследовать.
Я воспроизвел ваш код, создав рабочий JUnit 5, и вот результат, который я получил
открытый класс ParserTest {
String counterName = "count";
Integer counterIndex = 1;
@Test
public void main() {
CompilationUnit cu = StaticJavaParser.parse("class X{void x(){" + " if (x>4) { " + " x=4; "
+ " } " + " else { " + " x=4; " + " } " + " while (i<x) { " + " i++; "
+ " } " + " }}");
cu.findAll(Statement.class).forEach(statement -> {
if (statement.isIfStmt()) {
// Add counter declaration in main block for the if
String counterNameAndIndexIf = counterName + counterIndex++;
// Create expression using StaticJavaParser
Expression ifCounterExpression = StaticJavaParser
.parseVariableDeclarationExpr(" int " + counterNameAndIndexIf + " = 0");
((BlockStmt) statement.getParentNode().get()).addStatement(0, ifCounterExpression);
// Add counter declaration in main block for the else
String counterNameAndIndexElse = counterName + counterIndex++;
// Create expression using StaticJavaParser
Expression elseCounterExpression = StaticJavaParser
.parseVariableDeclarationExpr("int " + counterNameAndIndexElse + " = 0");
((BlockStmt) statement.getParentNode().get()).addStatement(0, elseCounterExpression);
// Add if increment
Expression ifIncrementExpression = StaticJavaParser.parseExpression(counterNameAndIndexIf + "++");
((BlockStmt) statement.getChildNodes().get(1)).addStatement(ifIncrementExpression);
// Add else increment
Expression elseIncrementExpression = StaticJavaParser.parseExpression(counterNameAndIndexElse + "++");
((BlockStmt) statement.getChildNodes().get(2)).addStatement(elseIncrementExpression);
}
if (statement.isWhileStmt()) {
String counterNameAndIndexWhile = counterName + counterIndex++;
Expression whileCounterExpression = StaticJavaParser
.parseVariableDeclarationExpr(" int " + counterNameAndIndexWhile + " = 0");
((BlockStmt) statement.getParentNode().get()).addStatement(0, whileCounterExpression);
// Add while increment
Expression whileIncrementExpression = StaticJavaParser.parseExpression(counterNameAndIndexWhile + "++");
((BlockStmt) statement.getChildNodes().get(1)).addStatement(whileIncrementExpression);
}
});
System.out.println(cu);
}
И результат
class X {
void x() {
int count3 = 0;
int count2 = 0;
int count1 = 0;
if (x > 4) {
x = 4;
count1++;
} else {
x = 4;
count2++;
}
while (i < x) {
i++;
count3++;
}
}
Надеюсь, это поможет. Дайте мне знать, если вам нужны разъяснения о том, как построить любой из этих объектов. Конечно, есть более разумные способы, и код может быть реорганизован, но я хотел, чтобы он был максимально понятным для вас.
Cheers
РЕДАКТИРОВАТЬ: для поддержки вложения операторов и объявления всехПеременные счетчика в главном блоке метода могут быть использованы следующим образом
statement.findRootNode().getChildNodes().get(0).getChildNodes().get(1).getChildNodes().get(2)
Этот подход будет начинаться сверху вниз от корня и всегда будет указывать на основной блок. Используйте его для добавления переменных счетчика.