如何使用Kotlin检测Java文件的方法主体的结尾?

问题描述

假设我们有一个如下所示的java文件

class Something {

   public static void main(String[] args){
      
      System.out.println("Hello World!");
   
   }

}

我想编写一些Kotlin代码,该代码将遍历此java文件并检测方法主体中有多少行(此处仅是主要方法)。空行计数!

我的方法是简单地使用File forEachline方法逐行读取Java文件。我可以编写代码来检测方法签名。现在,我希望能够确定方法的结束位置。我不知道该怎么做。

如果我只是寻找“}”,那么假设我们位于方法主体的末尾,而实际上我们位于方法内if语句主体的末尾,我的代码可能会出错。

如何避免这种陷阱?

解决方法

一种解决方法是跟踪看到的方括号('{')和方括号('}')的数量。在方法开始时,计数将增加到1。假设方法结构正确,在方法结束时,未括弧的括号数应为0。伪代码应能起作用:

int numLines = 1 (assuming method start line counts)
int numBrackets = 1 (after finding method open bracket for method)
while(numBrackets > 0)
    if char = '{' -> numBrackets++
    if char = '}' -> numBrackets--
    if char = newline -> numLines++
if numBrackets not 0 -> FAIL
return numLines

修改

如以下Gidds所述,此伪代码不足。一个更完整的答案将需要包括并非所有括号都会影响方法结构的事实。一种解决方法是跟踪被解析的当前字符的上下文。在有效上下文中(非字符串文字,注释等)时,仅递增/递减numBrackets。尽管正如Gidds指出的那样,这将增加复杂性。更新的伪代码:

int numLines = 1
int numValidBrackets = 1
Context context = Context(MethodStructure)
while(numValidBrackets > 0)
    context.acceptNextChar(char)
    if char = newline -> numLines++
    if(context.state() != MethodStructure) continue;
    if char = '{' -> numValidBrackets++
    if char = '}' -> numValidBrackets--
if numBrackets not 0 -> FAIL
return numLines