【问题标题】:Extract methods calls from java code从java代码中提取方法调用
【发布时间】:2015-09-17 05:00:59
【问题描述】:

我想从 java 代码中提取所有方法调用。我写了以下两个正则表达式,但它们无法提取所有方法调用。

Reg1:Pattern.compile("([a-zA-Z][0-9_a-zA-Z]*\\([a-zA-Z0-9_\\s,\\[\\]\\(\\)\\.]+\\))");

Reg2 : Pattern.compile("([a-zA-Z][0-9_a-zA-Z]*\\([\\s]*\\))")

输入:

"{
     if ((war == null) && (config != null)) {
    sb.append( &config= );
    sb.append(URLEncoder.encode(config,getCharset()));
    }
    if ((war == null) && (localWar != null)) {
    sb.append( &war= );
    sb.append(URLEncoder.encode(localWar,getCharset()));
    }
    if (update) {
    sb.append( &update=true );
    }
    if (tag != null) {
      sb.append( &tag= );
      sb.append(URLEncoder.encode(tag,getCharset()));
     }
     }"

输出:

getCharset getCharset getCharset append append append

我无法提取“encode”。

有人知道我应该在正则表达式中添加什么吗?

【问题讨论】:

标签: java parsing javaparser


【解决方案1】:

您需要一个 Java 代码解析器来完成此任务。这是一个使用Java Parser的示例:

public class MethodCallPrinter
{
    public static void main(String[] args) throws Exception
    {
        FileInputStream in = new FileInputStream("MethodCallPrinter.java");

        CompilationUnit cu;
        try
        {
            cu = JavaParser.parse(in);
        }
        finally
        {
            in.close();
        }
        new MethodVisitor().visit(cu, null);
    }

    private static class MethodVisitor extends VoidVisitorAdapter
    {
        @Override
        public void visit(MethodCallExpr methodCall, Object arg)
        {
            System.out.print("Method call: " + methodCall.getName() + "\n");
            List<Expression> args = methodCall.getArgs();
            if (args != null)
                handleExpressions(args);
        }

        private void handleExpressions(List<Expression> expressions)
        {
            for (Expression expr : expressions)
            {
                if (expr instanceof MethodCallExpr)
                    visit((MethodCallExpr) expr, null);
                else if (expr instanceof BinaryExpr)
                {
                    BinaryExpr binExpr = (BinaryExpr)expr;
                    handleExpressions(Arrays.asList(binExpr.getLeft(), binExpr.getRight()));
                }
            }
        }
    }
}

输出:

Method call: parse
Method call: close
Method call: visit
Method call: print
Method call: getName
Method call: getArgs
Method call: handleExpressions
Method call: visit
Method call: handleExpressions
Method call: asList
Method call: getLeft
Method call: getRight

【讨论】:

  • 主要难点是处理句子中的递归。您可以将此添加到您的答案中,例如,另一个访问者的表达式。
  • @laune “句子中的递归”是什么意思?
  • Java 语法定义了如何构造语言的“句子”。在“方法调用”的定义中,通过中间的一些NT,“方法调用”又出现了:递归。 - 所以必须有一个迭代for( Expression e: methodCall.getArgs() ){ ... }等。
  • @laune 明白。我忽略了这一点。认为 Java Parser 会优雅地处理这个问题。 :-)
  • @Sangeeta 您可以使用methodCall.getBeginLine() 检查方法调用是否在您想要的源代码部分内。
猜你喜欢
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多