我目前不幸地在处理别人的C#代码,这个代码真是让我吃惊。我不知道之前的那个人是如何维护这份代码的,因为它的各种病态已经导致了IDE、编译器和运行时环境的崩溃...
我今天面临的问题涉及一个15兆字节的源文件,其中有一些令人难以置信的病态嵌套代码,例如:
if(var == 0) {
// do stuff
}
else {
if(var == 1) {
// do stuff
}
else {
if(var == 2) {
// do stuff, identical word for word to the `var == 1` case
}
else {
// etc.
}
}
}
这种写法本来就是一个值得质疑的样式选择。然而,这与代码的另一个问题相结合:其中一些块的深度接近1000层(我测量过最深的块超过了700层)。我真诚地希望在我之前,这位程序员被迫强制离开这个代码之前,已经运行了一个样式工具,以避免我目前看到的可怕情况。我无法想象他们现在可能会编写这段代码,特别是由于每第三或第四次对代码进行编辑都会导致IDE崩溃(有时还会删除源文件的副本)。
我编写了一个基于正则表达式的简单工具来尝试压缩较简单的情况,但它似乎只能处理一半,然后破坏了这个特定的代码 (我不确定它失败是因为这个代码有时也使用预处理器条件语句,还是因为最长的匹配项将近10MB并且Lua的正则表达式匹配器无法应对)。我希望有一个广泛使用的工具或技术可以解决这个问题。我已经不得不使用astyle清理代码中的其他一些样式“问题”。 astyle的--remove-brackets
选项几乎可以做到我想要的效果,但需要花括号里的语句是单行上的单个语句,而这在这里绝对不是这种情况...(只是为了打好我的“i”的点,我检查过了; astyle没有创建这个特定的问题。)
编辑:深入研究这个问题代码,发现像这样的东西:
#if OneThing
int num2296 = otherThing();
#endif
#if AnotherThing
int num44 = otherThing()
int num45 = 0;
#endif
int num72 = 0;
#if OneThing
int num45 = 0; // note: multiple equivalent declarations of num45
#endif
#if OneThing
for(int num2297 = 0; num2297 < num2296; ++num2297) {
num45 = doSomething(num2297);
#endif
#if AnotherThing
for(int num43 = 0; num43 < num44; ++num43) {
num45 = doSomething(num43);
#endif
if(somethingElse(num45)) {
++num72;
}
} // note: only one closing brace for the two protected by #ifs
这段代码有两个版本,用于不同的目的。其中一个版本定义了OneThing,另一个版本定义了AnotherThing。然而,这两个版本的大部分区别只在于变量名不同,逻辑相同(并非全部相同)。
以上片段末尾的大括号错误说明了我的简单工具为什么会出错。这看起来越来越像是故意设计的保障措施,而不是无辜的无能。如果代码曾经处于使用反编译器生成类似于num2276
这样的变量名的点上,那么它现在已经不再是那个点了。
不幸的是,这意味着自动化工具可能不能独立完成所有任务。我必须慢慢地修复上一个程序员造成的损害。我把这个问题留在这里,以便万一有一个神奇的工具,可以将两个版本都转换为SSA并识别和合并它们的逻辑等价性,然后再转换回去......
switch
语句会更好。顺便说一句,好问题。 - Maciej Los