Changing references to deprecated methods C++

风格不统一 提交于 2019-12-12 21:09:43

问题


I have some methods that are deprecated in my codebase and I know how I'm supposed to replace them, is there any way to do this automatically? I'm using Visual studio 2015 update 3 but I'm open to using other text editors...

The code looks like this :

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

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

I just want something that could replace all references to the first function with a reference to the second one. i.e:

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

and

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

and

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

and

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

I'm open to solutions using visual studio or even other text editors. The reason I'm not doing it manually is because codebase is too large.


回答1:


Change the old function to call the new with that argument being true (declare the new one above the old of course):

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

You can probably inline it too so the compiler will literally change the code for you where appropriate :)




回答2:


You can do this with our DMS Software Reengineering Toolkit, using DMS's source-to-source transformations.

DMS parses (C++17/VisualStudio2015) source code to an AST, applies the source-to-source transforms which modify the tree, and the the result AST is prettyprinted to regenerate (modified) source code. This allows one to automate code changes across large code bases in a reliable way.

DMS rewrite rules for OP's examples would look like this:

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 explanation: rules have the form

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

Rules have names so people and rulesets can refer to them conveniently; sometimes one might have thousands of rules to carry out very complex transforms. A rule has parameters specifying what kind of metavariables (written \v) are allowed inside the rule. The "functioncall->functioncall" notation means we are transforming function calls into function calls and not something else. Quote marks around C++ text are metaquotes delimiting C++ text from DMS rule text, causing us to need to escape the actual C++ literal string quote marks with \". [Yeah we might have designed DMS to make that case non-escaped; can't always be clever enough].

A ruleset just groups rules to they can all be applied as a group. Not shown is the trivial DMS call to apply the ruleset.

You can read more about rule syntax at the link above.

I implemented his rules differently than OP expressed. His examples show only a function call as a statement (note the ";" in his examples) getting changed, but he writes in the text that he wants to replace all function calls. Thus these rules are about changes to function calls, not statements. OP's first rule I coded exactly as he showed in his example; it will only work if the function call has literally those argument string literas. His second rule I generalized to allow an arbitrary literal string rather than just "world". The third rule I generalized to allow an arbitrary function name and added a type check as he indicated.

Note the pattern matches actually occur over syntax trees and not raw text. DMS won't be fooled by function calls inside comments or with different whitespacing/formatting.




回答3:


What about using "Edit | Find & replace | Replace in Files" ? Replace "Hello", world with "Hello", true, world



来源:https://stackoverflow.com/questions/46566616/changing-references-to-deprecated-methods-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!