微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

查找 If/Else 块中的当前语句是否是 THEN 分支的最后一个语句

如何解决查找 If/Else 块中的当前语句是否是 THEN 分支的最后一个语句

我正在使用 JavaParser 解析以下代码内容并识别语句的顺序:

class X {
   void x() {
     int x = 1;
     if (x>4) {
        x=21;
     } else {
        if (x>1) {
           x=3;
        } else {
           x=212;
        } 
     } 
     if (x==4) { 
        x=3;
     }
}}

我用来解析上面例子的代码

private static void statements(BlockStmt block,State beforeState,State afterState) {
    List<State> states = new ArrayList<>();

    for (Statement statement : block.getStatements()) {
        states.add(new State(statement));
    }

    beforeState.nextStates.add(states.get(0));

    for (int i = 0; i < states.size(); i++) {
        State currentState = states.get(i);
        
        State nextState;
        if (i == states.size() - 1) {
            nextState = afterState;
        } else {
            nextState = states.get(i + 1);
        }

        currentState.statement.accept(new VoidVisitorWithDefaults<Void>() {
            @Override
            public void visit(ExpressionStmt n,Void arg) {
                currentState.nextStates.add(nextState);
            }

            @Override
            public void visit(IfStmt n,Void arg) {
                statements(n.getThenStmt().asBlockStmt(),currentState,nextState);
                n.getElseStmt().ifPresent(elseStmt ->
                        statements(elseStmt.asBlockStmt(),nextState));
            }
        },null);
 } }

我还想做的是确定当前语句是否是表达式语句(即赋值),如果是,则查找它是否是 If/Else 语句的 THEN 块中包含的最后一个语句。在上面的示例中,这将是语句 x=3;。但是,我不确定如何实现这一点。

到目前为止,我的想法是这样的:

ExpressionStmt exprStmt = (ExpressionStmt) currentState.statement;
Node exprStmtParent = exprStmt.getParent();
List<Node> exprStmtSibilings = exprStmtParent.getChildNodes();
Node lastNode = exprStmtSiblings.get(exprStmtSiblings.size() - 1);
boolean exprStmtIsLast = lastNode == ifStmt;

适用于 if 语句但不适用于赋值。关于如何解决这个问题有什么建议吗?

解决方法

这个答案可能为时已晚,但这是您解决问题的方法。

如果 n.getThenStmt() 的结果是 BlockStmt,您可以对其调用 getStatements,返回一个 NodeList,然后在列表上调用 getLast。

使用equals方法比较节点更安全。

访问者需要调用 super.visit 方法来完全访问节点(表达式或语句)。

下面是一个简化的例子。

public void test() {
    String str = "class X {\r\n" + 
            "   void x() {\r\n" + 
            "     int x = 1;\r\n" + 
            "     if (x>4) {\r\n" + 
            "        x=21;\r\n" + 
            "     } else {\r\n" + 
            "        if (x>1) {\r\n" + 
            "           x=3;\r\n" + 
            "        } else {\r\n" + 
            "           x=212;\r\n" + 
            "        } \r\n" + 
            "     } \r\n" + 
            "     if (x==4) { \r\n" + 
            "        x=3;\r\n" + 
            "     }\r\n" + 
            "}}";
    CompilationUnit cu = StaticJavaParser.parse(str);
    
    VoidVisitor<Void> visitor = new VoidVisitorAdapter<Void>() {
        
        ExpressionStmt currentStmt; 
        
        @Override
        public void visit(ExpressionStmt n,Void arg) {
            currentStmt = n;
            super.visit(n,arg);
        }
        
        @Override
        public void visit(IfStmt n,Void arg) {
            Statement then = n.getThenStmt();
            if (then instanceof BlockStmt) {
                BlockStmt blockThenStmt = then.asBlockStmt();
                super.visit(blockThenStmt,arg); // <-- visit statements in thenStmt
                Optional<Statement> oStmt = blockThenStmt.getStatements().getLast();
                if (oStmt.isPresent() && oStmt.get().equals(currentStmt)) {
                    System.out.println(String.format("--> %s expression is the last of %s",currentStmt.toString(),n.toString()));
                }
            }
            super.visit(n,arg); // <-- visit nested ifStmt
        }
    };
    cu.accept(visitor,null);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。