I've prototyped a solution using the FxCop approach, and I don't think FxCop can actually solve it. I tried the following code in a rule:
public class DoNotUseSpecificEnum : RuleBase
{
private string[] _enumValsToCheck =
{
"APIEnum.Val2"
};
public DoNotUseSpecificEnum ()
: base("DoNotUseSpecificEnum ") { }
public override void VisitBinaryExpression(BinaryExpression binaryExpression)
{
if ( _enumValsToCheck.Contains(
binaryExpression.Operand1.ToString())
|| _enumValsToCheck.Contains( binaryExpression.Operand2.ToString() ) )
{
this.Problems.Add(new Problem(base.GetResolution(),
binaryExpression.SourceContext));
}
base.VisitBinaryExpression(binaryExpression);
}
}
When I trace into the VisitBinaryExpression, I find the Operand1 value to be "1" instead of "APIEnum.Val2". This makes sense in hindsight (FxCop working on MSIL which has replaced the enum names/values with numeric literals); I just wish I'd realized it before I dug into the pain/glory of custom FxCop rules. :)
The other approach I found was using StyleCop to do syntax analysis, but this looks even harder to figure out and less popular than custom FxCop rules.
I'm going to propose the use of Resharper team-specific custom patterns as the way of managing this. I remain concerned about this approach (especially since we'll have the same rules across multiple solutions and teams), but the build machine concern is a lot smaller than I thought. TeamCity allows build-time inspection of Resharper rules out of the box, so we can at least configure our CI server to find and report uses of the enum that haven't been suppressed using Resharper syntax.