2
// Gendarme.Rules.BadPractice.DoNotForgetNotImplementedMethodsRule
5
// Cedric Vivier <cedricv@neonux.com>
6
// Sebastien Pouliot <sebastien@ximian.com>
8
// (C) 2008 Cedric Vivier
9
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
11
// Permission is hereby granted, free of charge, to any person obtaining
12
// a copy of this software and associated documentation files (the
13
// "Software"), to deal in the Software without restriction, including
14
// without limitation the rights to use, copy, modify, merge, publish,
15
// distribute, sublicense, and/or sell copies of the Software, and to
16
// permit persons to whom the Software is furnished to do so, subject to
17
// the following conditions:
19
// The above copyright notice and this permission notice shall be
20
// included in all copies or substantial portions of the Software.
22
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
using Gendarme.Framework;
34
using Gendarme.Framework.Engines;
35
using Gendarme.Framework.Helpers;
36
using Gendarme.Framework.Rocks;
41
namespace Gendarme.Rules.BadPractice {
44
/// This rule checks for short methods that throw a <c>System.NotImplementedException</c>
45
/// exception. It's likely a method that has not yet been implemented and should not be
46
/// forgotten by the developer before a release.
51
/// private void Save ()
53
/// throw new NotImplementedException ("pending final format");
57
/// <remarks>This rule is available since Gendarme 2.0</remarks>
59
[Problem ("This method looks like it is not implemented or is incomplete.")]
60
[Solution ("Implement the method and/or make sure it's limitations are well documented.")]
61
[EngineDependency (typeof (OpCodeEngine))]
62
// part of CA1065 is implemented here instead of DoNotThrowInUnexpectedLocationRule so we need to be
63
// able to suppress it too, with the same [SuppressMessage], even if this rule has a larger scope
64
[FxCopCompatibility ("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
65
public class DoNotForgetNotImplementedMethodsRule : Rule, IMethodRule {
67
// contains NEWOBJ and THROW instructions
68
private static OpCodeBitmask bitmask = new OpCodeBitmask (0x0, 0x84000000000000, 0x0, 0x0);
70
public RuleResult CheckMethod (MethodDefinition method)
72
// rule does not apply if there's no IL code
73
// or if it was generated by the compiler or tools
74
if (!method.HasBody || method.IsGeneratedCode ())
75
return RuleResult.DoesNotApply;
77
// is there a Newobj *and* a Throw instruction in this method
78
if (!bitmask.IsSubsetOf (OpCodeEngine.GetBitmask (method)))
79
return RuleResult.DoesNotApply;
82
bool cond_branch = false;
83
foreach (Instruction inst in method.Body.Instructions) {
84
// check if the code is linear or with branches
85
if (FlowControl.Cond_Branch == inst.OpCode.FlowControl)
88
// if there are branch and it's long enough then assume it is implemented
89
if (cond_branch && (++n > 10))
92
// check for "throw new NotImplementedException (...)"
93
if (inst.OpCode.Code != Code.Newobj)
95
MethodReference ctor = (MethodReference) inst.Operand;
96
if (!ctor.DeclaringType.IsNamed ("System", "NotImplementedException"))
98
if (inst.Next.OpCode.Code != Code.Throw)
101
// the defect is more severe if the method is visible outside it's assembly
102
Severity severity = method.IsPublic ? Severity.High : Severity.Medium;
103
Runner.Report (method, severity, Confidence.Normal);
104
return RuleResult.Failure;
107
return RuleResult.Success;
110
public void GenerateBitmask ()
112
OpCodeBitmask bitmask = new OpCodeBitmask ();
113
bitmask.Set (Code.Newobj);
114
bitmask.Set (Code.Throw);
115
Console.WriteLine (bitmask);