Avoid API breaking changes

 

If you are developing a framework, the last thing you want to happen when releasing a new version of your product is to break the code of your clients because of an API change. For example, you want to make sure that all public methods you had in previous versions are here in the next version, unless you tagged some of them with System.ObsoleteAttribute.

There is one major company in the .NET sphere that publishes a big framework and that has this need: Microsoft. To make sure that the .NET framework public API doesn’t contain breaking changes, Microsoft developed the tool LibCheck that detects automatically API breaking change.

The tool NDepend can also be used to detect API breaking changes thanks to some astute CQL rules. The following CQL rule warns if a public method of the previous version is not public anymore or has been removed in the new version.


WARN IF Count > 0 IN SELECT METHODS WHERE
IsInOlderBuild AND IsPublic AND (VisibilityWasChanged OR WasRemoved)


 


The condition IsInOlderBuild needs a little explanation. When comparing 2 versions of a code base, NDepend stores in memory the 2 code base structures, the older one and the newer one. This is why the comparison is immediate, everything is in-memory. Also, in this context, NDepend has to choose on which structure the query will be run. The condition IsInOlderBuild forces NDepend to run the query on the older build. Actually we don’t need the condition IsInOlderBuild here because when a query contains the condition WasRemoved, NDepend automatically runs the query against the older build. However, I estimate that adding IsInOlderBuild makes the query easier to read and understand.

The query can be read: Warn if there are methods that used to be public and for which visibility was changed or have been removed. Interestingly enough, we notice that if the visibility used to be public and has changed, it means that the visibility is not public anymore, hence the API breaking issue. This is also a good example of mixing ortogonal CQL features (here comparison and visibility) in the same query to obtain smarter queries. I will blog more on this in the future, this will be an important direction for the product in 2008.


Eventually, we could also add the CQL condition IsObsolete to make sure that the query doesn’t match obsolete methods that have been removed.

WARN IF Count > 0 IN SELECT METHODS WHERE
IsInOlderBuild AND IsPublic AND !IsObsolete AND (VisibilityWasChanged OR WasRemoved)



In the same spirit, it is easy to write the following CQL rule that detects public types of the previous version that are not public anymore or that has been removed in the new version:

WARN IF Count > 0 IN SELECT TYPES WHERE
IsInOlderBuild AND IsPublic AND (VisibilityWasChanged OR WasRemoved)
 

Notice that in this previous post I explained how to configure an NDepend project to define the previous version of your code base to compare with during an analysis. Basically you can choose between:



  • Compare with the last analysis available.

  • Compare with the analysis made N days ago.

  • Compare with the particular analysis made on MM/DD/YYYY hh:mm 

Of course, you can also still use the VisualNDepend GUI to compare any 2 previous analysis.


This entry was posted in Featured. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Chris Johnson

    Yes, that sounds good, but does it work for native code? if not I’m not really interested in it right now.
    I’ve been writing my own tools at work using an API that ships with some software we purchased call ‘Understand 4 c++. It a great source code analysis tool, which I find indispensable.

  • http://www.stormwindproject.org Bernardo Heynemann

    Hi Patrick,

    We have a plug-in in StormwindProject that does just that.
    You can check more details in http://www.stormwindproject.org/index.php/CCNet-Plugins/Home.html.

    Hope it helps!

    Bernardo Heynemann
    Stormwind Project Committer
    http://www.stormwindproject.org