我编写访问者实现并将其传递给操作。 当我调用该操作时,我看到很多“VISITED Psi... with class ...”行, 包括我想要找到的“VISITED PsiMethodCallExpression:commentRepository.delete(comment) 和类 com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl”,但方法 VisitMethodCallExpression 未被调用 - 不是一个“methodCall 访问过” “, 类似的访问ForeachStatement。
为什么visitMethodCallExpression方法没有被调用以及如何解决这个问题?
代码:
package mypackage
import com.intellij.psi.JavaRecursiveElementWalkingVisitor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiForStatement
import com.intellij.psi.PsiForeachStatement
import com.intellij.psi.PsiMethodCallExpression
class AnalyzeVisitor: JavaRecursiveElementWalkingVisitor() {
private var forVisited: Boolean = false
override fun visitElement(element: PsiElement) {
println("VISITED $element with class ${element::class.java}")
super.visitElement(element)
}
override fun visitForStatement(statement: PsiForStatement) {
forVisited = true
println("forStatement visited '$statement'")
super.visitForStatement(statement)
}
override fun visitForeachStatement(statement: PsiForeachStatement?) {
forVisited = true
println("foreachStatement visited'$statement'")
super.visitForeachStatement(statement)
}
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
println("methodCall visited '$expression'")
if (forVisited) {
println("visited")
// some logic
}
super.visitMethodCallExpression(expression)
}
}
我称之为访客的代码
package another.service;
import org.springframework.stereotype.Service;
import ru.itmo.wp.domain.Comment;
import ru.itmo.wp.repository.CommentRepository;
import java.util.List;
@Service
public class CommentService {
private final CommentRepository commentRepository;
public CommentService(CommentRepository commentRepository) {
this.commentRepository = commentRepository;
}
public void saveComment(Comment comment) {
commentRepository.save(comment);
}
public boolean deleteCommentAndDoLogic(Comment comment) {
commentRepository.delete(comment);
System.out.println("Comment deleted " + comment.getText());
return true;
}
public void deleteCommentsSimple(List<Comment> comments) {
for (Comment comment: comments) {
commentRepository.delete(comment);
}
}
public void deleteCommentsInner(List<Comment> comments) {
for (Comment comment: comments) {
boolean t = deleteCommentAndDoLogic(comment);
}
}
}
我尝试将访问元素方法更改为
override fun visitElement(element: PsiElement) {
println("VISITED $element with class ${element::class.java}")
when(element) {
is PsiMethodCallExpression -> {
visitMethodCallExpression(element)
}
is PsiForStatement -> {
visitForStatement(element)
}
is PsiForeachStatement -> {
println("FOUND FOREACH")
visitForeachStatement(element)
}
}
if (element is PsiMethodCallExpression) {
visitMethodCallExpression(element)
}
super.visitElement(element)
}
但这无济于事,因为 PsiMethodCallExpression 是 LeafPsiElement
我不知道为什么,但我使用 Java 而不是 Kotlin,并且它有效。