1

我有一些方法在我的代码库中不推荐使用,我知道应该如何替换它们,有没有办法自动执行此操作?我使用Visual Studio 2015年更新3,但我愿意用其他文本编辑器...更改对已弃用方法的引用C++

的代码看起来是这样的:

// Deprecated method 
myFunction(char* firstParam, char* secondParam = NULL); 

// New method, same name, different params 
myFunction(char* firstParam, bool flag, char* secondParam = NULL); 

我想要的东西,可以取代的所有引用第一个功能与第二个功能相关。 即:

myFunction("hello", "world"); 
// Replace with 
myFunction("hello", true, "world"); 

myFunction("hello"); 
// Replace with 
myFunction("hello", true); 

myFunction("hello", isTrue); // isTrue is a bool here 
// Do not replace with anything 

myFunction("hello", world); //world is a char* here 
// Replace with 
myFunction("hello", true, world); 

我打开使用Visual Studio或甚至其他文本编辑器解决方案。我没有手动做这件事的原因是因为代码库太大。

+0

使用编辑器的搜索和替换功能?不知道我是否理解这个问题 – user463035818

+0

我不确定我是否理解,因为这些是具有不同签名的截然不同的方法。您不仅需要修改签名,而且在您调用原始方法的每个地方,您都需要更新代码以支持新签名。 –

+0

像使用正则表达式?因为使用正则表达式很难捕获变量类型。 (或者,也许我只是不知道如何) –

回答

1

改变旧函数调用新的这样的说法是真实的(申报新以上故道):

// Deprecated method 
myFunction(char* firstParam, char* secondParam = NULL) 
{ 
    myFunction(firstParam, true, secondParam); 
} 

你或许可以内嵌它也因此编译器将逐字修改代码你在适当情况下:)

+0

我喜欢这个答案,但是不赞成使用的方法会在某个时候被删除,然后这将不再起作用 –

+0

@MichelJiang这将删除旧的方法,因为您已经替换了它。但像上面提出的那样,您可以在其上添加[[deprecated]]或MSDEV __declspec(不赞成使用)的标记,以在编译时警告代码使用旧方式,并随时替换。 – Rob

+0

谢谢,我想我可能会在这个问题上严重地解释自己,但是我想避免手动替换这些函数,我的编译器已经警告我这样一个事实,即函数已被弃用,我应该改变它们,我更加期待以一种方式自动替换它们在代码:)但我会尝试你的建议,看看它是否有帮助 –

-1

怎么样使用“编辑|查找&替代|在文件中替换”? 更换“你好”,世界“你好”,真的,世界

+1

这将无法正确使用新的功能签名的情况下... –

+1

我会添加它不会如果其他可能具有相似功能名称的对象工作。使用具有重构功能的IDE会更好,因为它只会匹配那些编译为具有或不具有可选/ defaulted参数的函数调用的符号。 – Rob

1

为此,您可以与我们的DMS Software Reengineering Toolkit,使用DMS's source-to-source transformations

DMS将AST解析(C++ 17/VisualStudio2015)源代码,应用修改树的源到源变换,并且结果AST被打印以重新生成(修改)源代码。这使得人们可以以可靠的方式自动化大代码库中的代码更改。

DMS重写规则为OP的例子是这样的:

rule add_true_to_hello_world() 
    :functioncall->functioncall 
    = "myFunction(\"hello\", \"world\");" 
    -> "myFunction(\"hello\", true, \"world\");"; 

rule add_true_to_call_with_literal_string(s: STRING) 
    : functioncall->functioncall 
    = "myFunction(\s)" 
    -> "myFunction(\s, true);" 

rule add_true_when_char_star(i:IDENTIFIER,s:STRING, a:argument): 
    :functioncall->functioncall 
    = "\i(\s,\a);" 
    -> "\i(\s, true, \a)" 
    if IsCharStart(a); 

ruleset replace_deprecated_calls = 
    { add_true_to_hello_world, 
     add_true_to_call_with_literal_string, 
     add_true_when_char_star 
    } 

Breif解释:规则具有形式

rule name(metavariable): syntaxclass->syntaxclass 
    lefthandside -> righthandside if condition ; 

规则的名称,以便人们与规则集可以参照他们方便;有时可能有成千上万的规则来执行非常复杂的转换。规则具有指定规则内允许哪种元变量(写入\ v)的参数。 “functioncall-> functioncall”表示法意味着我们正在将函数调用转换为函数调用,而不是别的。围绕C++文本引号是报价从DMS规则文本划定C++文本,导致我们需要逃避实际的C++文本字符串引号与\” [是的,我们可能设计DMS,使这种情况下,非转义。总是不够聪明]。

规则集只是将规则分组以将它们全部应用为一个组。未显示应用规则集的简单DMS调用。

您可以在上面的链接中阅读关于规则语法的更多信息。

我实施他的规则不同于表达OP。他的例子只显示了一个函数调用作为一个语句(注意他的例子中的“;”)发生了变化,但他在文中写道他希望替换所有的函数调用。因此这些规则是关于函数调用的变化,而不是语句。 OP的第一条规则就像他在他的例子中所表达的那样完全一样。它只会在函数调用具有字面意义上的那些参数字符串文字时才起作用。他的第二条规则是,我将其推广为允许一个任意的字符串,而不仅仅是“世界”。我推广的第三条规则是允许任意函数名称,并添加一个类型检查,如他所示。

注意模式匹配实际上发生在语法树上而不是原始文本。 DMS不会被注释中的函数调用或不同的空格/格式所迷惑。

相关问题