Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherited attributes for hidden dependencies?

Tags:

c++

c++14

I have a huge library and couple classes planned to be decommissioned.

E.g.:

class [[deprecated]] OldApi {
// details
};

The idea is that everything what uses this class is deprecated. E.g.: a hidden dependency looks like this in header:

// on API we have no old API dependency
void hiddenDependency();

and in compiling unit:

void hiddenDependency()
{
  OldApi inst;
  // work on it/do something
}

I have really deep dependency graph so manual solution would be a pain. Is there any way/tool to inherit these deprecate attributes?

So after using this tool, the hidden dependencies also would be deprecated:

[[deprecated]]
void hiddenDependency();

Many thanks for help!

like image 397
Naszta Avatar asked Aug 07 '20 13:08

Naszta


3 Answers

I have really deep dependency graph so manual solution would be a pain. Is there any way/tool to inherit these deprecate attributes?

Yes, you can write a tool using a compiler like Clang as a library.

Roughly, you would walk the tree that Clang gives you to find function/method bodies. In each of them, check if there are any references to OldApi or its members. If so, add the attribute to the function/method and output the resulting tree.

If you need to deprecate users of those functions too, you can apply it recursively as needed.

Conceptually easy, but if you have never written a tool like that, it may take a while. Even with experience, you usually need to have a lot of code to modify to this approach worth the time investment.


Having said that, as others have pointed out, the question is odd. When you deprecate something, you typically need to replace that thing in the callers/users, rather than deprecate all the users.

like image 147
Acorn Avatar answered Sep 27 '22 19:09

Acorn


Strictly speaking, hiddenDependency is not deprecated, and [[deprecated]] in OldApi warns hiddenDependency that OldApi is deprecated and it should be updated/replaced, but the body of hiddenDependency is still valid, unless the code has not been designed properly (and same declaration but different definition in OldApi affects hiddenDependency). Nonetheless, if there is some kind of relation between OldApi and hiddenDependency, they may or might be scoped in a namespace (or should have been), so the solution is to deprecate the namespace instead of the class and trying to "inherit" [[deprecated]]:

namespace [[deprecated("Use NewFunctionality instead")]] OldFunctionality {
  class OldApi {
    public:
        OldApi(){ 
        }
  };

  void foo() {
    OldApi bar;
  }
}

Assuming that you are able to deprecate the caller, what's the limit? Should only be the caller of the deprecated method considered as deprecated? Should be the caller of the caller considered as deprecated as well? How many levels of deprecation are expected? Because the compiler warns that hiddenDependency is calling a deprecated method, it points out the reason and the affected line in hiddenDependency. What's the criteria to not move up the warning until the main? Going further, is the criteria to deprecate all the functions which call OldApi? (if so, you already have a group, hence you can encapsulate it i.e. namespace) Or is the criteria all the functions which call OldApi and some extra requirements? (if so, there is not a clear procedure and it has to be done manually).

Even if parsing the whole text looking for the pattern "hiddenDependency calls OldApi" is an option (and probably the most valid one considering your example), it doesn't look like a clean and easy to maintain (or even justify/document) solution.

like image 38
Jose Avatar answered Sep 27 '22 18:09

Jose


Assuming this is a good idea, my approach would be to temporarily delete or rename OldApi and attempt to compile. Your IDE or existing language tooling should be able to emit information about every compiler error, whether it be definitions that reference OldApi, or functions/class declarations that leverage it. Mark every single one as [[deprecated]]. Then, restore OldApi with the [[deprecated]] flag as well.

like image 30
jeremyong Avatar answered Sep 27 '22 17:09

jeremyong