Avoid changing enumerations Flags status

Rule ND1505 API Breaking Changes

Runs only in diff mode (baseline defined). Matches enumerations whose FlagsAttribute tagging changed since the baseline (added or removed).

FlagsAttribute is a strong property, less for behavior (only enum.ToString() changes) than for meaning: range of values or range of flags? Changing it can significantly impact clients.

How to fix

Keep the FlagsAttribute status of each enumeration stable, now and in the future.

CQLinq source

This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.

// <Name>Avoid changing enumerations Flags status</Name>
// <Id>ND1505:AvoidChangingEnumerationsFlagsStatus</Id>

warnif count > 0 

let oldFlags = codeBase.OlderVersion().ThirdParty.Types.WithFullName("System.FlagsAttribute").FirstOrDefault()
let newFlags = ThirdParty.Types.WithFullName("System.FlagsAttribute").FirstOrDefault()
where oldFlags != null || newFlags != null

from t in Application.Types where
   t.IsEnumeration &&
   t.IsPresentInBothBuilds() 
let hasFlagsAttributeNow = newFlags != null && t.HasAttribute(newFlags)
let usedToHaveFlagsAttribute = oldFlags != null && t.OlderVersion().HasAttribute(oldFlags) 
where hasFlagsAttributeNow != usedToHaveFlagsAttribute
select new { 
   t, 
   expl = hasFlagsAttributeNow ?
      "is now tagged with the *FlagsAttribute* but wasn't in baseline" :
      "used to be tagged with the *FlagsAttribute* in baseline but not anymore", 

   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Expl>
// The public *{0}* {1}. This breaks client code using it.
//</Expl>

//<Desc>
// Runs only in *diff mode* (baseline defined). Matches enumerations whose
// *FlagsAttribute* tagging changed since the *baseline* (added or removed).
//
// *FlagsAttribute* is a strong property, less for *behavior* (only
// *enum.ToString()* changes) than for *meaning*: **range of values** or
// **range of flags**? Changing it can significantly impact clients.
//</Desc>

//<HowToFix>
// Keep the *FlagsAttribute* status of each enumeration stable, now and in
// the future.
//</HowToFix>

API Breaking Changes: all 9 items