C++/CLI support comes to ReSharper C++
ReSharper C++ joined the ReSharper fold back in 2015 to bring the power of ReSharper to the world of C++ – and has been getting better ever since! For most people this has rounded out the ReSharper story within Visual Studio. However an odd gap remains. Odd because the worlds of C++ and C# are bridged by the interop language, C++/CLI, yet this has remained unsupported by the ReSharper family.
Until now, that is!
From 2018.2 (available now in the EAP) ReSharper C++ has initial support for C++/CLI. There are some limitations, so read on to find out more. Support is enabled by default, but can be disabled by going to ReSharper | Options | Code Editing | C++ | Inspections, and unchecking “Enable C++/CLI support”. But we hope you won’t do that – especially as we’re also looking for user feedback and greater field experience.
A peculiar beast
As a rule nobody uses C++/CLI as a primary language. That’s not what it’s been designed for. While C# is a highly productive language, and is no slouch when it comes to performance, there are many reasons that we may also have a parts of our project written in pure C++. C++/CLI is an answer to the question, “how do I get to, or from, my pure C++ from C# (or any .NET language)?”. If you just need to call into C++, and it exposes a C API, P/Invoke may be the simplest way to go. But for more complex cases – where you want to model richer types and class hierarchies – C++/CLI let’s you do that. But it comes at the cost of a more complex language, with curious syntactic additions and sometimes tricky lifetime issues. So any help we can get from our tools while writing and maintaining this code is very welcome.
What is supported?
ReSharper C++ 2018.2 gives us initial support for C++/CLI projects. What does that mean? Well first it means that the parser and resolver now finally understand the extension system, with ^’s for CLR references, `gcnew` for allocating on the managed heap, etc. It also means that many static analysis features now work and can give us valuable insight. Note that, at time of this writing, there may still be a few limitations here. Please report these in our issue tracker so we can address them as quickly as possible.
Within C++/CLI code we have access to all the same great refactorings and intention actions as in pure C++ code. For example postfix templates are a great way to rewrite statements around a value. Where applicable these should work across C++/CLI and pure C++ codebases – for example you can rename a pure C++ symbol, or even a C# symbol, from within a C++/CLI usage. Again, some limitations may apply.
We can also navigate between C# and C++/CLI worlds. For example if we place the caret over a C++/CLI method name in some C# code you can now navigate to the definition in the C++/CLI code (note that this is referred to as “Go to declaration” in the menu, due to how these terms are used in C#). You can do the same going the other way, too.
For now there are some known limitations here. For instance from a C# project in the same solution, renaming a C++/CLI symbol is not an option. From the C++/CLI project, renaming a symbol referred to by the C# project wll rename it within the C++/CLI code, but not in the C# project. As mentioned already, renaming a native C++ symbol from a C++/CLI project works as expected, however.
Code generation is also limited for now, as generators for C++/CLI specific constructs, such as ref classes, have not yet been written. And the `#using` directive (for importing metadata in directly from a dll) is not supported at all – meaning both the use of the `#using` directive, as well as any symbols referenced from the dll, will currently be flagged as errors by the analyser.
We need your help
C++/CLI is unique in many ways. Software projects that make use of it tend to be larger enterprise style projects of in-house code bases that cannot be shared outside the organisation. There is very little in the way of non-trivial open source projects using C++/CLI. Here at JetBrains we only use it in some small ways internally to the ReShaper C++ implementation. So it is particularly difficult to build realistic test cases. As we move to expand our coverage we’ll rely a lot more on the community to tell us what’s not working (of course we’d also love to hear what’s working, too!) so we can do our best to address it and make our C++/CLI support first class.