FxCop Rule for Multi-Targeting
Two months ago, Scott blogged about the multi-targeting support in Visual Studio 2008. I worked on this feature in the planning phase (read “long time ago”), and so I am quite thrilled to see it finally in the hands of developers. Especially, that several years ago I remember our small working group sitting in a room and wondering whether such feature was even possible. The complexities of implementing it in a large project like the Visual Studio seemed quite daunting.
The thing that made implementing multi-targeting in one release possible was the concept of Red and Green bits. You can read about the concept here, here, and here, but quickly: red bits are Framework assemblies that existed in the .NET Framework 2.0 and were serviced in versions 3.0 and 3.5. Green bits are assemblies that were added either in the version 3.0 or 3.5. The servicing changes in Red bit APIs are limited (after all it is servicing) to a very small number of API additions and bug fixes.
We leveraged (and influenced) the decision to limit the number of changes to existing assemblies to drastically simplify the requirements for the multi-targeting system. That is, we made an assumption that the majority of differences between the Framework versions (targets) are on assembly boundaries.
But now I have to confess, there are some limitations in this design that we accepted when we made the original simplifying assumption. There is a very limited number of APIs being added to the Red assemblies and the multi-targeting system is currently not able to detect these. For example, if you set the target to the .NET Framework 2.0 and read the newly-added (albeit obscure) property GCSettings.LatencyMode the program will compile just fine but then fail to run on the .NET Framework 2.0 RTM. The reason is that the property was added to an existing (Red) class GCSettings, not to a new class in a new assembly. Despite that the number of such additional APIs in Red bits is very small (and that we recommend that you still test your programs on all targeted platforms), this can be quite annoying. And so feeling a bit responsible for this (and trying to promote FxCop J), I wrote an FxCop rule that can analyze IL of an assembly targeted at Framework 2.0 and warn you about all calls to members that are not present in 2.0 RTM.
Here is how it works: The test program below uses new LatencyMode enum and calls a new GcSettings.LatencyMode property. As I mentioned above, these APIs don’t exist in .NET Framework 2.0 RTM. Even if I built this project with the multi-targeting target set to Framework 2.0, the system would not complain about calling these APIs. But, as you can see in the error list, the FxCop analysis engine can deal even with this difficult to detect problem. You can think of the rule as a very smart (post) compiler-step.
A sample project with the rule is attached to this post. I provide it without any guarantees, as is, and in fact I am sure it has many bugs and problems. When I find time, I will work on it more to polish it a bit but I don't promise (i.e. treat it as a sample).
BTW, to install the rule, just build it and drop it to the FxCop rules directory. On my machine it is at C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\Rules. In addition you have to go to Project settings of the project you want to analyze and turn on FxCop analysis (the “Code Analysis” tab in the project properties). Lastly, you can either rebuild or right click on a project and choose “Run Code Analysis”. I hope it’s helpful.