获取MethodDeclaration的行号

时间:2015-02-08 22:30:01

标签: java eclipse eclipse-jdt

我正在尝试创建Java文件解析器,但我无法获得每种方法的正确行号。这是我现在的代码:

ASTParser parser = ASTParser.newParser(AST.JLS4);
parser.setSource(FileUtils.readFileToString(new File("Main.java"), "UTF-8").toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setResolveBindings(true);

Map options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_5, options);
parser.setCompilerOptions(options);

final CompilationUnit cu = (CompilationUnit) parser.createAST(null /* IProgressMonitor */);

cu.accept(new ASTVisitor() {
    public boolean visit(MethodDeclaration node) {
        System.out.println("MethodName: " + node.getName().toString());
        System.out.println("MethodLineNumber: " + cu.getLineNumber(node.getStartPosition()));

        return false;
    }
});

想象一下,我们正在解析以下类

public class Main
{
  /**
   *
   */
  public Main() {

  }
}

代码

cu.getLineNumber(node.getStartPosition())

而不是返回6,返回3.显然eclipse.jdt API认为javacode也属于该方法。所以,我的问题是,如何获得方法Main()的正确行号?

EDIT_1

我们可以访问JavaDoc:

String javadoc = node.getJavadoc().toString();

并计算行数

Pattern NLINE = Pattern.compile("(\n)|(\r)|(\r\n)");
Matcher m = NLINE.matcher(javadoc);
int lines = 1;
while (m.find())
  lines++;

并且实际上适用于该情况但不适用于所有情况,例如

public class Main
{
  /**
   * 
   *
   *
   *
   *
   *
   *
   */
  public Main() {

  }
}

-

node.getJavadoc().toString():
/** 
 */

public class Main
{
  /**
   * Constructor
   *
   * @param <K> the key type
   * @param <V> the value type
   */
  public Main() {

  }
}

-

node.getJavadoc().toString():
/** 
 * Constructor
 * @param<K>
 *  the key type
 * @param<V>
 *  the value type
 */

显然,Javadoc类的toString方法忽略空行并将label @param视为两行等等。

干杯;)

2 个答案:

答案 0 :(得分:2)

致电getName()的{​​{1}}获取方法名称的MethodDeclaration并获取该名称的行号。

答案 1 :(得分:0)

示例代码,希望对您有所帮助。

    public MethodNode getMethodforGivenLineNum(String srcFilePath, int linenum) {
        ASTParser parser = ASTParser.newParser(AST.JLS8);

        char[] fileContent = null;
        try {
            fileContent = getFileContent(srcFilePath).toCharArray();
        } catch (IOException e) {
            System.out.printf("getMethodforGivenLineNum-getFileContent failed!\n%s", srcFilePath);
            e.printStackTrace();
            return null;
        }

        parser.setSource(fileContent);

        CompilationUnit cu = (CompilationUnit) parser.createAST(null);

        List<MethodNode> methodNodeList = new ArrayList<>();

        cu.accept(new ASTVisitor() {
            @Override
            public boolean visit(MethodDeclaration node) {
                SimpleName methodName = node.getName();

                int startLineNum = cu.getLineNumber(node.getStartPosition());

                int endLineNum = cu.getLineNumber(node.getStartPosition() + node.getLength());

                methodNodeList.add(new MethodNode(methodName.toString(), node, startLineNum, endLineNum));
                return false;
            }
        });