Это на самом деле довольно сложно.Прежде всего, ваш подход if "onPause" in sourcecode
в настоящее время не различает , определяющий onPause()
и , вызывающий it.И во-вторых, найти правильное закрытие }
нетривиально.Наивно, вы можете просто считать открывающие и закрывающие curlies ({
увеличивает уровень блока, }
уменьшает его), и предполагать, что }
, который делает нулевой уровень блока, является закрывающим вьющимся значением метода.Однако это может быть неправильно!Поскольку метод может содержать некоторую строку литерал , содержащую (возможно, несбалансированные) кривые.Или комментарии с завитками.Это может привести к неправильному подсчету уровней блоков.
Чтобы сделать это правильно, вам нужно будет создать настоящий анализатор 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\")"))
Обратите внимание, что это уязвимо для всех видов крайних случаев (таких как {
в строке или в комментарии, или отступ в табуляции вместо этогопространства, или, возможно, тысячи других вещей).Это только отправная точка для вас.