Updated patch (0002-...) according to review.

New patch (0003-) over 0002, which renames ToStringReturnsNullRule to
ToStringShouldNotReturnNullRule, and improves text and consistency between
ReturnNullRule inheritors.

Please review,

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Gendarme" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/gendarme?hl=en
-~----------~----~----~----~------~----~------~--~---

From c27c45f931346d36c45536f69db5ff147291d44f Mon Sep 17 00:00:00 2001
From: Cedric Vivier <[email protected]>
Date: Sun, 21 Dec 2008 18:46:03 +0800
Subject: [PATCH] WIP in 'PreferEmptyInstanceOverNullRule' branch.

2008-12-21  Cedric Vivier  <[email protected]>

	* PreferEmptyInstanceOverNullRule.cs: New. This rule checks that
	methods/properties returning a string, an array, a collection, or
	an enumerable, do not return null.
---
 .../rules/Gendarme.Rules.BadPractice/ChangeLog     |    6 +
 .../rules/Gendarme.Rules.BadPractice/Makefile.am   |    2 +
 .../PreferEmptyInstanceOverNullRule.cs             |  160 ++++++++++++++
 .../Gendarme.Rules.BadPractice/ReturnNullRule.cs   |   15 +-
 .../Test/PreferEmptyInstanceOverNullTest.cs        |  226 ++++++++++++++++++++
 5 files changed, 402 insertions(+), 7 deletions(-)
 create mode 100644 gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
 create mode 100644 gendarme/rules/Gendarme.Rules.BadPractice/Test/PreferEmptyInstanceOverNullTest.cs

diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/ChangeLog b/gendarme/rules/Gendarme.Rules.BadPractice/ChangeLog
index b236a0f..c87e28d 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/ChangeLog
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/ChangeLog
@@ -1,3 +1,9 @@
+2008-12-21  Cedric Vivier  <[email protected]>
+
+	* PreferEmptyInstanceOverNullRule.cs: New. This rule checks that
+	methods/properties returning a string, an array, a collection, or
+	an enumerable, do not return null.
+
 2008-12-13  Jesse Jones  <[email protected]> 
 
 	* ObsoleteMessagesShouldNotBeEmptyRule.cs, 
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/Makefile.am b/gendarme/rules/Gendarme.Rules.BadPractice/Makefile.am
index cff78da..4b07729 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/Makefile.am
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/Makefile.am
@@ -14,6 +14,7 @@ rules_sources =  \
 	EqualShouldHandleNullArgRule.cs \
 	GetEntryAssemblyMayReturnNullRule.cs \
 	ObsoleteMessagesShouldNotBeEmptyRule.cs \
+	PreferEmptyInstanceOverNullRule.cs \
 	ReplaceIncompleteOddnessCheckRule.cs \
 	ReturnNullRule.cs \
 	ToStringReturnsNullRule.cs 
@@ -32,5 +33,6 @@ tests_sources = \
 	EqualShouldHandleNullArgTest.cs \
 	GetEntryAssemblyMayReturnNullTest.cs \
 	ObsoleteMessagesShouldNotBeEmptyTest.cs \
+	PreferEmptyInstanceOverNullTest.cs \
 	ReplaceIncompleteOddnessCheckTest.cs \
 	ToStringReturnsNullTest.cs 
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
new file mode 100644
index 0000000..b60b305
--- /dev/null
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
@@ -0,0 +1,160 @@
+//
+// Gendarme.Rules.BadPractice.PreferEmptyInstanceOverNullRule
+//
+// Authors:
+//	Cedric Vivier <[email protected]>
+//
+// Copyright (C) 2008 Cedric Vivier
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+using Gendarme.Framework;
+using Gendarme.Framework.Rocks;
+using Gendarme.Framework.Engines;
+using Gendarme.Framework.Helpers;
+
+namespace Gendarme.Rules.BadPractice {
+
+	/// <summary>
+	/// This rule checks that methods and properties returning a string, an array,
+	/// a collection, or an enumerable, do not return null.
+	/// It is usually easier to use when such methods return an empty instance
+	/// instead, the caller being able to use the result directly without having
+	/// to perform a null-check first.
+	/// </summary>
+	/// <example>
+	/// Bad example (string):
+	/// <code>
+	/// public string DisplayName {
+	/// 	get {
+	/// 		if (IsAnonymous)
+	/// 			return null;
+	/// 		return name;
+	///		}
+	/// }
+	/// </code>
+	/// </example>
+	/// <example>
+	/// Good example (string):
+	/// <code>
+	/// public string DisplayName {
+	/// 	get {
+	/// 		if (IsAnonymous)
+	/// 			return string.Empty;
+	/// 		return name;
+	///		}
+	/// }
+	/// </code>
+	/// </example>
+	/// <example>
+	/// Bad example (array):
+	/// <code>
+	/// public int [] GetOffsets () {
+	/// 	if (!store.HasOffsets)
+	/// 		return null;
+	/// 	store.LoadOffsets ();
+	/// 	return store.Offsets;
+	/// }
+	/// </code>
+	/// </example>
+	/// <example>
+	/// Good example (array):
+	/// <code>
+	/// static const int [] Empty = new int [0];
+	/// public int [] GetOffsets () {
+	/// 	if (!store.HasOffsets)
+	/// 		return Empty;
+	/// 	store.LoadOffsets ();
+	/// 	return store.Offsets.ToArray ();
+	/// }
+	/// </code>
+	/// </example>
+	/// <example>
+	/// Bad example (enumerable):
+	/// <code>
+	/// public IEnumerable&lt;int&gt; GetOffsets () {
+	/// 	if (!store.HasOffsets)
+	/// 		return null;
+	/// 	store.LoadOffsets ();
+	/// 	return store.Offsets;
+	/// }
+	/// </code>
+	/// </example>
+	/// <example>
+	/// Good example (enumerable):
+	/// <code>
+	/// public IEnumerable&lt;int&gt; GetOffsets () {
+	/// 	if (!store.HasOffsets)
+	/// 		yield break;
+	/// 	store.LoadOffsets ();
+	/// 	foreach (int offset in store.Offsets)
+	/// 		yield return offset;
+	/// }
+	/// </code>
+	/// </example>
+
+	[Problem ("This method returns null whereas returning an empty instance would make it easier to use.")]
+	[Solution ("Return an empty instance rather than null.")]
+	public class PreferEmptyInstanceOverNullRule : ReturnNullRule, IMethodRule {
+
+		TypeReference returnType;
+
+		public override RuleResult CheckMethod (MethodDefinition method)
+		{
+			if (!method.HasBody)
+				return RuleResult.DoesNotApply;
+
+			//the rule does not apply to the particular case of ToString()
+			//that have its own ToStringShouldNotReturnNullRule
+			if (!method.HasParameters && method.Name == "ToString")
+				return RuleResult.DoesNotApply;
+
+			//only apply to methods returning string, array, or IEnumerable-impl
+			returnType = method.ReturnType.ReturnType;
+			if (returnType.FullName != "System.String"
+			    && !returnType.IsArray ()
+			    && !returnType.Implements ("System.Collections.IEnumerable"))
+				return RuleResult.DoesNotApply;
+
+			return base.CheckMethod (method);
+		}
+
+		protected override void Report (MethodDefinition method, Instruction ins)
+		{
+			string msg = string.Format ("Replace null with {0}.", GetReturnTypeSuggestion ());
+			Runner.Report (method, ins, method.IsVisible () ? Severity.Medium : Severity.Low, Confidence.High, msg);
+		}
+
+		string GetReturnTypeSuggestion ()
+		{
+			if (returnType.FullName == "System.String")
+				return "string.Empty";
+			else if (returnType.IsArray ())
+				return string.Format ("an empty {0} array", returnType.Name);
+			else if (returnType.FullName.StartsWith ("System.Collections.Generic.IEnumerable"))
+				return "yield break (or equivalent)";
+			return "an empty collection";
+		}
+	}
+}
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
index 26206f7..b797422 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
@@ -34,12 +34,8 @@ using Gendarme.Framework.Rocks;
 namespace Gendarme.Rules.BadPractice {
 
 	// Notes: 
-	// * We don't implement IMethodRule on purpose since both rules that inherit 
-	//   from us are ITypeRule (that check for a specific method in the type)
-	// * Both rules used Severity.Medium and Confidence.Normal so they are, right
-	//   now, hardcoded. If anyone else needs them they should be made abstract
-	//   properties. Severity is likely to change but Confidence should stay the
-	//   same unless addional logic change it.
+	// * We don't implement IMethodRule on purpose since a rule that inherit
+	//   from us can be an ITypeRule (checking for a specific method in the type)
 
 	[EngineDependency (typeof (OpCodeEngine))]
 	abstract public class ReturnNullRule : Rule {
@@ -60,7 +56,7 @@ namespace Gendarme.Rules.BadPractice {
 				while (previous != null) {
 					// most of the time we'll find the null value on the first trace back call
 					if (previous.OpCode.Code == Code.Ldnull) {
-						Runner.Report (method, ins, Severity.Medium, Confidence.Normal);
+						Report (method, ins);
 						break;
 					}
 
@@ -76,5 +72,10 @@ namespace Gendarme.Rules.BadPractice {
 
 			return Runner.CurrentRuleResult;
 		}
+
+		protected virtual void Report (MethodDefinition method, Instruction ins)
+		{
+			Runner.Report (method, ins, Severity.Medium, Confidence.Normal);
+		}
 	}
 }
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/Test/PreferEmptyInstanceOverNullTest.cs b/gendarme/rules/Gendarme.Rules.BadPractice/Test/PreferEmptyInstanceOverNullTest.cs
new file mode 100644
index 0000000..a452365
--- /dev/null
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/Test/PreferEmptyInstanceOverNullTest.cs
@@ -0,0 +1,226 @@
+//
+// Unit tests for PreferEmptyInstanceOverNullRule
+//
+// Authors:
+//	Cedric Vivier <[email protected]>
+//
+// Copyright (C) 2008 Cedric Vivier
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using Gendarme.Rules.BadPractice;
+
+using NUnit.Framework;
+using Test.Rules.Fixtures;
+using Test.Rules.Definitions;
+
+namespace Test.Rules.BadPractice {
+
+	[TestFixture]
+	public class PreferEmptyInstanceOverNullTest : MethodRuleTestFixture<PreferEmptyInstanceOverNullRule> {
+
+		public class DoesNotApplyCases {
+			bool foo;
+			string x;
+
+			public void Void () {
+				Console.WriteLine ("Foo");
+			}
+
+			public int Int () {
+				return 0;
+			}
+
+			public Type Type () {
+				return null;
+			}
+
+			public string StringProperty {
+				set {
+					x = value;
+				}
+			}
+
+			public IEnumerable<int> GetOffsets () {
+				if (!foo)
+					yield break;
+				//store.LoadOffsets ();
+				foreach (int offset in GetOffsets ())
+					yield return offset;
+			}
+
+			public override string ToString () {
+				return null;
+			}
+		}
+
+		public class SuccessCases {
+			bool foo;
+			string x;
+
+			public int [] IntArray () {
+				x = null;
+				return new int [0];
+			}
+
+			public string StringProperty {
+				get {
+					x = null;
+					return "foo";
+				}
+			}
+
+			public string String (string s) {
+				x = null;
+				return "foo";
+			}
+
+			public string String2 () {
+				x = null;
+				return string.Empty;
+			}
+
+			public string String3 () {
+				x = String (null);
+				return this.ToString ();
+			}
+
+			public ArrayList Collection () {
+				if (!foo)
+					return new ArrayList ();
+				var list = new ArrayList ();
+				list.Add (4);
+				list.Add (8);
+				String (null);
+				return list;
+			}
+
+			public List<int> GenericCollection () {
+				if (!foo)
+					return new List<int> ();
+				String (null);
+				var list = new List<int> ();
+				list.Add (4);
+				list.Add (8);
+				return list;
+			}
+		}
+
+		public class FailureCases {
+			bool foo = false;
+			string s;
+
+			public int [] IntArray () {
+				if (!foo)
+					return null;
+				return new int [1];
+			}
+
+			public string StringProperty {
+				get {
+					return null;
+				}
+			}
+
+			public string String () {
+				return null;
+			}
+
+			public string String2 () {
+				if (!foo)
+					return null;
+				return "foo";
+			}
+
+			public string String3 () {
+				if (!foo)
+					return null;
+				if (s == "N/A")
+					return null;
+				return s;
+			}
+
+			public IEnumerable<int> GetOffsets () {
+				if (!foo)
+					return null;
+				//store.LoadOffsets ();
+				return GetOffsets ();
+			}
+
+			public ArrayList Collection () {
+				if (!foo)
+					return null;
+				var list = new ArrayList ();
+				list.Add (4);
+				list.Add (8);
+				return list;
+			}
+
+			public List<int> GenericCollection () {
+				if (!foo)
+					return null;
+				var list = new List<int> ();
+				list.Add (4);
+				list.Add (8);
+				return list;
+			}
+		}
+
+		[Test]
+		public void DoesNotApply ()
+		{
+			AssertRuleDoesNotApply (SimpleMethods.EmptyMethod);
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("Void");
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("Int");
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("Type");
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("set_StringProperty");
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("GetOffsets");
+			AssertRuleDoesNotApply<DoesNotApplyCases> ("ToString");
+		}
+
+		[Test]
+		public void Success ()
+		{
+			AssertRuleSuccess<SuccessCases> ("IntArray");
+			AssertRuleSuccess<SuccessCases> ("get_StringProperty");
+			AssertRuleSuccess<SuccessCases> ("String");
+			AssertRuleSuccess<SuccessCases> ("String2");
+			AssertRuleSuccess<SuccessCases> ("String3");
+			AssertRuleSuccess<SuccessCases> ("Collection");
+			AssertRuleSuccess<SuccessCases> ("GenericCollection");
+		}
+
+		[Test]
+		public void Failure ()
+		{
+			AssertRuleFailure<FailureCases> ("IntArray", 1);
+			AssertRuleFailure<FailureCases> ("get_StringProperty", 1);
+			AssertRuleFailure<FailureCases> ("String", 1);
+			AssertRuleFailure<FailureCases> ("String2", 1);
+			AssertRuleFailure<FailureCases> ("String3", 2);
+			AssertRuleFailure<FailureCases> ("GetOffsets", 1);
+			AssertRuleFailure<FailureCases> ("Collection", 1);
+			AssertRuleFailure<FailureCases> ("GenericCollection", 1);
+		}
+	}
+}
-- 
1.6.0.3

From 91911bad2a32ac13d338b64f93aaed21d6f2dc7b Mon Sep 17 00:00:00 2001
From: Cedric Vivier <[email protected]>
Date: Mon, 22 Dec 2008 03:17:23 +0800
Subject: [PATCH] Rename ToStringReturnsNullRule to ToStringShouldNotReturnNullRule.
 Improve text/consistency between ReturnNullRule inheritors.

---
 .../CloneMethodShouldNotReturnNullRule.cs          |   14 +++++++++-----
 .../PreferEmptyInstanceOverNullRule.cs             |   11 +++++------
 .../Gendarme.Rules.BadPractice/ReturnNullRule.cs   |    5 +----
 .../Test/ToStringReturnsNullTest.cs                |    4 ++--
 .../ToStringReturnsNullRule.cs                     |   20 ++++++++++++++------
 5 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
index c1fb4c3..c08fbca 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
@@ -27,6 +27,7 @@
 // THE SOFTWARE.
 
 using Mono.Cecil;
+using Mono.Cecil.Cil;
 
 using Gendarme.Framework;
 using Gendarme.Framework.Helpers;
@@ -35,8 +36,7 @@ using Gendarme.Framework.Rocks;
 namespace Gendarme.Rules.BadPractice {
 
 	/// <summary>
-	/// This rule check that a <c>Clone()</c> method, if existing, never returns a <c>null</c> 
-	/// value.
+	/// This rule checks that no <c>Clone()</c> method returns <c>null</c>.
 	/// </summary>
 	/// <example>
 	/// Bad example:
@@ -65,8 +65,8 @@ namespace Gendarme.Rules.BadPractice {
 	/// </code>
 	/// </example>
 
-	[Problem ("The implementation ICloneable.Clone() seems to return null in some circumstances.")]
-	[Solution ("Return an appropriate object instead of returning null.")]
+	[Problem ("This implementation of ICloneable.Clone() could return null in some circumstances.")]
+	[Solution ("Return an appropriate object rather than returning null.")]
 	public class CloneMethodShouldNotReturnNullRule : ReturnNullRule, IMethodRule {
 
 		private const string ICloneable = "System.ICloneable";
@@ -96,6 +96,10 @@ namespace Gendarme.Rules.BadPractice {
 			// call base class to detect if the method can return null
 			return base.CheckMethod (method);
 		}
+
+		protected override void Report (MethodDefinition method, Instruction ins)
+		{
+			Runner.Report (method, ins, Severity.Medium, Confidence.Normal);
+		}
 	}
 }
-
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
index b60b305..0d8a60d 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/PreferEmptyInstanceOverNullRule.cs
@@ -37,11 +37,10 @@ using Gendarme.Framework.Helpers;
 namespace Gendarme.Rules.BadPractice {
 
 	/// <summary>
-	/// This rule checks that methods and properties returning a string, an array,
-	/// a collection, or an enumerable, do not return null.
-	/// It is usually easier to use when such methods return an empty instance
-	/// instead, the caller being able to use the result directly without having
-	/// to perform a null-check first.
+	/// This rule checks that no method or property returning a string, an array,
+	/// a collection, or an enumerable, returns <c>null</c>.
+	/// It is usually better to rather return an empty instance as this allows
+	/// the caller to use the result without having to perform a null-check first.
 	/// </summary>
 	/// <example>
 	/// Bad example (string):
@@ -143,7 +142,7 @@ namespace Gendarme.Rules.BadPractice {
 		protected override void Report (MethodDefinition method, Instruction ins)
 		{
 			string msg = string.Format ("Replace null with {0}.", GetReturnTypeSuggestion ());
-			Runner.Report (method, ins, method.IsVisible () ? Severity.Medium : Severity.Low, Confidence.High, msg);
+			Runner.Report (method, ins, method.IsVisible () ? Severity.Medium : Severity.Low, Confidence.Normal, msg);
 		}
 
 		string GetReturnTypeSuggestion ()
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
index b797422..e78d70d 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/ReturnNullRule.cs
@@ -73,9 +73,6 @@ namespace Gendarme.Rules.BadPractice {
 			return Runner.CurrentRuleResult;
 		}
 
-		protected virtual void Report (MethodDefinition method, Instruction ins)
-		{
-			Runner.Report (method, ins, Severity.Medium, Confidence.Normal);
-		}
+		protected abstract void Report (MethodDefinition method, Instruction ins);
 	}
 }
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/Test/ToStringReturnsNullTest.cs b/gendarme/rules/Gendarme.Rules.BadPractice/Test/ToStringReturnsNullTest.cs
index ee60133..eca979d 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/Test/ToStringReturnsNullTest.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/Test/ToStringReturnsNullTest.cs
@@ -1,5 +1,5 @@
 // 
-// Unit tests for ToStringReturnsNullRule
+// Unit tests for ToStringShouldNotReturnNullRule
 //
 // Authors:
 //	Sebastien Pouliot <[email protected]>
@@ -35,7 +35,7 @@ using Test.Rules.Fixtures;
 namespace Test.Rules.BadPractice {
 
 	[TestFixture]
-	public class ToStringReturnsNullTest : TypeRuleTestFixture<ToStringReturnsNullRule> {
+	public class ToStringShouldNotReturnNullTest : TypeRuleTestFixture<ToStringShouldNotReturnNullRule> {
 
 		abstract class ToStringAbstract {
 			public abstract override string ToString ();
diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/ToStringReturnsNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/ToStringReturnsNullRule.cs
index 466b49f..7272e5e 100644
--- a/gendarme/rules/Gendarme.Rules.BadPractice/ToStringReturnsNullRule.cs
+++ b/gendarme/rules/Gendarme.Rules.BadPractice/ToStringReturnsNullRule.cs
@@ -1,5 +1,5 @@
 //
-// Gendarme.Rules.BadPractice.ToStringReturnsNullRule
+// Gendarme.Rules.BadPractice.ToStringShouldNotReturnNullRule
 //
 // Authors:
 //	Nidhi Rawal <[email protected]>
@@ -27,6 +27,7 @@
 // THE SOFTWARE.
 
 using Mono.Cecil;
+using Mono.Cecil.Cil;
 
 using Gendarme.Framework;
 using Gendarme.Framework.Helpers;
@@ -35,8 +36,9 @@ using Gendarme.Framework.Rocks;
 namespace Gendarme.Rules.BadPractice {
 
 	/// <summary>
-	/// This rule is used for ensure that no overriden <c>ToString()</c> method returns a 
-	/// null value. This makes the value more useful in debugging.
+	/// This rule checks that no overriden <c>ToString()</c> method returns <c>null</c>.
+	/// An appropriately descriptive string, or <c>string.Empty</c>, should be returned
+	/// in order to make the value more useful (especially in debugging).
 	/// </summary>
 	/// <example>
 	/// Bad example:
@@ -56,10 +58,11 @@ namespace Gendarme.Rules.BadPractice {
 	/// }
 	/// </code>
 	/// </example>
+	/// <remarks>This rule was previously named ToStringReturnsNull.</remarks>
 
-	[Problem ("This type contains a ToString () method that could returns null.")]
-	[Solution ("Return an empty string or other appropriate string rather than returning null.")]
-	public class ToStringReturnsNullRule: ReturnNullRule, ITypeRule {
+	[Problem ("This type contains a ToString() method that could return null.")]
+	[Solution ("Return an appropriately descriptive string or an empty string rather than returning null.")]
+	public class ToStringShouldNotReturnNullRule: ReturnNullRule, ITypeRule {
 
 		public RuleResult CheckType (TypeDefinition type)
 		{
@@ -71,5 +74,10 @@ namespace Gendarme.Rules.BadPractice {
 			// call base class to detect if the method can return null
 			return CheckMethod (method);
 		}
+
+		protected override void Report (MethodDefinition method, Instruction ins)
+		{
+			Runner.Report (method, ins, Severity.High, Confidence.Normal);
+		}
 	}
 }
-- 
1.6.0.3

Reply via email to