【问题标题】:Adding a line in a method block of java code using python使用python在java代码的方法块中添加一行
【发布时间】:2018-11-14 06:22:43
【问题描述】:

我有很多 java 文件,我必须在其中搜索一个方法,如果存在,我必须在此方法中添加一行“如果此行不存在”。必须在方法的右大括号之前添加此行。

到目前为止,我有以下代码:

import os
import ntpath
extensions = set(['.java','.kt'])
for subdir, dirs, files in os.walk("/src/main"):
        for file in files:
            filepath = subdir + os.sep + file
            extension = os.path.splitext(filepath)[1]
            if extension in extensions:
                if 'onCreate(' in open(filepath).read():
                        print (ntpath.basename(filepath))
                        if 'onPause' in open (filepath).read():
                            print ("is Activity and contains onPause\n")
                            #Check if Config.pauseCollectingLifecycleData(); is in this code bloack, if exists do nothing, if does not exist add to the end of code block before }
                        if 'onResume' in open (filepath).read():
                            print ("is Activity and contains onResume\n")
                            #Check if Config.resumeCollectingLifecycleData(); is in this code bloack, if exists do nothing, if does not exist add to the end of code block before }

但我不知道从哪里开始,Python 不是我的第一语言。我可以要求引导正确的方向。

示例: 我正在寻找具有以下签名的方法:

public void onPause(){
   super.onPause();
   // Add my line here
}

public void onPause(){
   super.onPause();
   Config.pauseCollectingLifecycleData(); // Line exists do nothing 
}

【问题讨论】:

  • 不要多次读取文件。在if extension in extensions 之后,将文件内容读入一个变量并在该变量上使用insourcecode = open(filepath).read(),然后是if "onPause" in sourcecode。更快,更清洁。

标签: java python python-3.x python-2.7 code-editor


【解决方案1】:

这实际上是相当困难的。首先,您的if "onPause" in sourcecode 方法目前不区分定义 onPause()调用 它。其次,找到正确的结束 } 并非易事。天真地,您可能只是计算打开和关闭花括号({ 增加块级别,} 减少它),并假设使块级别为零的} 是该方法的关闭花键。但是,这可能是错误的!因为该方法可能包含一些 string literal 包含(可能不平衡的)卷曲。或者 cmets 带有卷曲。这会弄乱块级计数。

要正确执行此操作,您必须构建一个实际的 Java 解析器。即使使用诸如tatsu 之类的库,这也需要大量工作。

如果你对一个相当不稳定的kludge 没问题,你可以尝试使用上面提到的块级计数和缩进作为线索(假设你的源代码缩进得体)。这是我作为起点的一些东西:

def augment_function(sourcecode, function, line_to_insert):
    in_function = False
    blocklevel = 0
    insert_before = None
    source = sourcecode.split("\n")
    for line_no, line in enumerate(source):
        if in_function:
            if "{" in line:
                blocklevel += 1
            if "}" in line:
                blocklevel -= 1
                if blocklevel == 0:
                    insert_before = line_no
                    indent = len(line) - len(line.lstrip(" ")) + 4  #4=your indent level
                    break
        elif function in line and "public " in line:
            in_function = True
            if "{" in line:
                blocklevel += 1
    if insert_before:
        source.insert(insert_before, " "*indent + line_to_insert)
    return "\n".join(source)

# test code:
java_code = """class Foo {
    private int foo;
    public void main(String[] args) {
        foo = 1;
    }
    public void setFoo(int f)
    {
        foo = f;
    }
    public int getFoo(int f) {
        return foo;
    }
}
"""
print(augment_function(java_code, "setFoo", "log.debug(\"setFoo\")"))

请注意,这很容易受到各种边缘情况的影响(例如字符串或注释中的{,或者制表符缩进而不是空格,或者可能还有其他一千种情况)。这只是您的一个起点。

【讨论】:

  • 谢谢你,久违了——我最终使用了 IDE 的搜索和正则表达式工具 :) 不过你写的很漂亮!
猜你喜欢
  • 2014-08-23
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 2010-09-07
  • 2019-06-22
相关资源
最近更新 更多