如何使用 kotlin 检测 java 文件的方法体结束?

How to detect the end of a method body of a java file using kotlin?

假设我们有一个 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 所指出的,这个 pseudo-code 是不够的。更完整的答案需要包括并非所有括号都会影响方法结构的事实。解决这个问题的一种方法是跟踪正在解析的当前字符的上下文。只有 increment/decrement numBrackets 在有效上下文中(non-string 文字、注释等)。尽管正如 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