diff options
author | Sebastien Pouliot <sebastien.pouliot@gmail.com> | 2013-04-28 19:50:45 +0400 |
---|---|---|
committer | Sebastien Pouliot <sebastien.pouliot@gmail.com> | 2013-04-28 19:50:45 +0400 |
commit | 16a47e11c3701a35be9898031205584b7ff74459 (patch) | |
tree | 2719f9c13b1de1a3d80112d92683d5c05d94cd4d | |
parent | 6e7e1cde353ff4927b39f82fe1066eb951506fab (diff) | |
parent | 43d871f1f2fd485bdcf9dd30dea94501e3b9f942 (diff) |
Merge pull request #26 from steve-s/master
AvoidUnusedPrivateFieldsRule scans nested types for private fields usage.
-rw-r--r-- | gendarme/rules/Gendarme.Rules.Performance/AvoidUnusedPrivateFieldsRule.cs | 42 | ||||
-rw-r--r-- | gendarme/rules/Gendarme.Rules.Performance/Test/AvoidUnusedPrivateFieldsTest.cs | 41 |
2 files changed, 71 insertions, 12 deletions
diff --git a/gendarme/rules/Gendarme.Rules.Performance/AvoidUnusedPrivateFieldsRule.cs b/gendarme/rules/Gendarme.Rules.Performance/AvoidUnusedPrivateFieldsRule.cs index bc8c0e52..c7d74a5c 100644 --- a/gendarme/rules/Gendarme.Rules.Performance/AvoidUnusedPrivateFieldsRule.cs +++ b/gendarme/rules/Gendarme.Rules.Performance/AvoidUnusedPrivateFieldsRule.cs @@ -105,36 +105,54 @@ namespace Gendarme.Rules.Performance { // copy all fields into an hashset fields.Clear (); foreach (FieldDefinition field in type.Fields) { - if (!field.IsPrivate || field.IsLiteral) + if (!field.IsPrivate || field.IsLiteral || field.IsGeneratedCode ()) continue; fields.Add (field); } // scan all methods, including constructors, to find if the field is used + if (fields.Count > 0) { + CheckFieldsUsageInType (type); + } + + // scan nested types becuase they also have access to private fields of their parent + if (type.HasNestedTypes && fields.Count > 0) { + foreach (TypeDefinition nested in type.NestedTypes) { + CheckFieldsUsageInType (nested); + } + } + + // check remaining (private) fields in the set + foreach (FieldDefinition field in fields) { + Runner.Report (field, Severity.Medium, Confidence.Normal); + } + return Runner.CurrentRuleResult; + } + + private void CheckFieldsUsageInType (TypeDefinition type) + { foreach (MethodDefinition method in type.Methods) { if (!method.HasBody) continue; // don't check the method if it does not access any field if (!OpCodeEngine.GetBitmask (method).Intersect (LoadStoreFields)) - continue; + continue; foreach (Instruction ins in method.Body.Instructions) { - FieldDefinition fd = ins.GetField (); - if (fd == null) - continue; + FieldDefinition fd = ins.GetField (); + if (fd == null) + continue; - fields.Remove (fd); + fields.Remove (fd); } + + if (fields.Count == 0) + break; } - - // check remaining (private) fields in the set - foreach (FieldDefinition field in fields) { - Runner.Report (field, Severity.Medium, Confidence.Normal); - } - return Runner.CurrentRuleResult; } + #if false public void Bitmask () { diff --git a/gendarme/rules/Gendarme.Rules.Performance/Test/AvoidUnusedPrivateFieldsTest.cs b/gendarme/rules/Gendarme.Rules.Performance/Test/AvoidUnusedPrivateFieldsTest.cs index 212bebfb..dbb9f153 100644 --- a/gendarme/rules/Gendarme.Rules.Performance/Test/AvoidUnusedPrivateFieldsTest.cs +++ b/gendarme/rules/Gendarme.Rules.Performance/Test/AvoidUnusedPrivateFieldsTest.cs @@ -162,5 +162,46 @@ namespace Test.Rules.Performance { AssertRuleFailure<GenericUnused<int>> (1); AssertRuleSuccess<GenericUsed<int>> (); } + + class FieldsUsedInNested { + private bool field; + + private static string staticField; + + class Nested { + public void Foo (FieldsUsedInNested parent) + { + FieldsUsedInNested.staticField = "bar"; + parent.field = true; + } + } + } + + [Test] + public void FieldsUsedInNestedType () + { + AssertRuleSuccess<FieldsUsedInNested> (); + } + + class CompilerGenerated { + public string Name { get; set; } + } + + [Test] + public void ClassWithCompilerGeneratedFields () + { + AssertRuleSuccess<CompilerGenerated> (); + } + + class CompilerGeneratedAndUnused { + private int number; + public string Name { get; set; } + } + + [Test] + public void ClassWithCompilerGeneratedFieldsAndUnusedPrivate () + { + AssertRuleFailure<CompilerGeneratedAndUnused> (1); + } } } |