Author: spouliot
Date: 2008-02-15 14:40:31 -0500 (Fri, 15 Feb 2008)
New Revision: 95803
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ChangeLog
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DetectNonAlphaNumericsInTypeNamesRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotPrefixValuesWithEnumNameRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotUseReservedInEnumValueNamesRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/EnumNotEndsWithEnumOrFlagsSuffixRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ParameterNamesShouldMatchOverridenMethodRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectCasingRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectPrefixRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectSuffixRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePluralNameInEnumFlagsRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePreferredTermsRule.cs
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseSingularNameInEnumsUnlessAreFlagsRule.cs
Log:
2008-02-15 Sebastien Pouliot <[EMAIL PROTECTED]>
* DetectNonAlphaNumericsInTypeNamesRule.cs
* DoNotPrefixValuesWithEnumNameRule.cs
* DoNotUseReservedInEnumValueNamesRule.cs
* EnumNotEndsWithEnumOrFlagsSuffixRule.cs
* ParameterNamesShouldMatchOverridenMethodRule.cs
* UseCorrectCasingRule.cs
* UseCorrectPrefixRule.cs
* UseCorrectSuffixRule.cs
* UsePluralNameInEnumFlagsRule.cs
* UsePreferredTermsRule.cs
* UseSingularNameInEnumsUnlessAreFlagsRule.cs:
Update rules wrt framework changes.
Modified: trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ChangeLog
===================================================================
--- trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ChangeLog
2008-02-15 19:36:37 UTC (rev 95802)
+++ trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ChangeLog
2008-02-15 19:40:31 UTC (rev 95803)
@@ -1,3 +1,18 @@
+2008-02-15 Sebastien Pouliot <[EMAIL PROTECTED]>
+
+ * DetectNonAlphaNumericsInTypeNamesRule.cs
+ * DoNotPrefixValuesWithEnumNameRule.cs
+ * DoNotUseReservedInEnumValueNamesRule.cs
+ * EnumNotEndsWithEnumOrFlagsSuffixRule.cs
+ * ParameterNamesShouldMatchOverridenMethodRule.cs
+ * UseCorrectCasingRule.cs
+ * UseCorrectPrefixRule.cs
+ * UseCorrectSuffixRule.cs
+ * UsePluralNameInEnumFlagsRule.cs
+ * UsePreferredTermsRule.cs
+ * UseSingularNameInEnumsUnlessAreFlagsRule.cs:
+ Update rules wrt framework changes.
+
2008-01-18 Sebastien Pouliot <[EMAIL PROTECTED]>
* DetectNonAlphaNumericsInTypeNamesRule.cs: Add checks for generated
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DetectNonAlphaNumericsInTypeNamesRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DetectNonAlphaNumericsInTypeNamesRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DetectNonAlphaNumericsInTypeNamesRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -1,5 +1,5 @@
//
-// Gendarme.Rules.Naming.DetectNonAlphaNumericsInTypeNamesRule
+// Gendarme.Rules.Naming.DetectNonAlphaNumericInTypeNamesRule
//
// Authors:
// Nidhi Rawal <[EMAIL PROTECTED]>
@@ -36,43 +36,45 @@
namespace Gendarme.Rules.Naming {
- public class DetectNonAlphaNumericsInTypeNamesRule: IMethodRule,
ITypeRule {
+ [Problem ("This type, or method, name contains underscore(s) in its
name.")]
+ [Solution ("Remove the underscore from the name.")]
+ public class DetectNonAlphanumericInTypeNamesRule: Rule, IMethodRule,
ITypeRule {
+ private const string Underscore = "Name should not contain
underscore.";
+
// Compiler generates an error for any other non alpha-numerics
than underscore ('_'),
// so we just need to check the presence of underscore in
method names
private static bool CheckName (string name)
{
- return (name.IndexOf ("_") == -1);
+ return (name.IndexOf ("_", StringComparison.Ordinal) ==
-1);
}
- public MessageCollection CheckType (TypeDefinition type, Runner
runner)
+ public RuleResult CheckType (TypeDefinition type)
{
- // type must be public and, if nested, public too
- if (type.IsNotPublic || type.IsNestedPrivate ||
type.IsGeneratedCode ())
- return runner.RuleSuccess;
+ // type must be visible and not generated by the
compiler (or a tool)
+ if (!type.IsVisible () || type.IsGeneratedCode ())
+ return RuleResult.DoesNotApply;
// check the type name
if (CheckName (type.Name))
- return runner.RuleSuccess;
+ return RuleResult.Success;
- Location location = new Location (type);
- Message message = new Message ("Type name should not
contain underscore.", location, MessageType.Error);
- return new MessageCollection (message);
+ Runner.Report (type, Severity.Medium, Confidence.High,
Underscore);
+ return RuleResult.Failure;
}
- public MessageCollection CheckMethod (MethodDefinition method,
Runner runner)
+ public RuleResult CheckMethod (MethodDefinition method)
{
// exclude non-public methods and special names (like
Getter and Setter)
if (!method.IsPublic || method.IsSpecialName ||
method.IsGeneratedCode ())
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
// check the method name
if (CheckName (method.Name))
- return runner.RuleSuccess;
+ return RuleResult.Success;
- Location location = new Location (method);
- Message message = new Message ("Method name should not
contain an underscore.", location, MessageType.Error);
- return new MessageCollection (message);
+ Runner.Report (method, Severity.Medium,
Confidence.High, Underscore);
+ return RuleResult.Failure;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotPrefixValuesWithEnumNameRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotPrefixValuesWithEnumNameRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotPrefixValuesWithEnumNameRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -33,30 +33,26 @@
namespace Gendarme.Rules.Naming {
- public class DoNotPrefixValuesWithEnumNameRule : ITypeRule {
+ [Problem ("This enumeration contains value names that starts with the
enum's name.")]
+ [Solution ("hange the value name(s) not to include the enum's type
name.")]
+ public class DoNotPrefixValuesWithEnumNameRule : Rule, ITypeRule {
- public MessageCollection CheckType (TypeDefinition type, Runner
runner)
+ public RuleResult CheckType (TypeDefinition type)
{
if (!type.IsEnum)
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
- MessageCollection results = null;
-
foreach (FieldDefinition field in type.Fields) {
// this excludes special "value__"
if (!field.IsStatic)
continue;
if (field.Name.StartsWith (type.Name,
StringComparison.OrdinalIgnoreCase)) {
- if (results == null)
- results = new MessageCollection
();
- Location loc = new Location (field);
- Message msg = new Message
(string.Format ("Enum values should not be prefixed with the enum's name.",
type.FullName), loc, MessageType.Warning);
- results.Add (msg);
+ Runner.Report (field, Severity.Medium,
Confidence.High, String.Empty);
}
}
- return results;
+ return Runner.CurrentRuleResult;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotUseReservedInEnumValueNamesRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotUseReservedInEnumValueNamesRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/DoNotUseReservedInEnumValueNamesRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -33,30 +33,27 @@
namespace Gendarme.Rules.Naming {
- public class DoNotUseReservedInEnumValueNamesRule : ITypeRule {
+ [Problem ("This type is an enumeration that contains value(s) named
'reserved'.")]
+ [Solution ("The 'reserved' value should be removed since there is no
need to reserve enums values.")]
+ public class DoNotUseReservedInEnumValueNamesRule : Rule, ITypeRule {
- public MessageCollection CheckType (TypeDefinition type, Runner
runner)
+ public RuleResult CheckType (TypeDefinition type)
{
if (!type.IsEnum)
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
- MessageCollection results = null;
-
foreach (FieldDefinition field in type.Fields) {
// this excludes special "value__"
if (!field.IsStatic)
continue;
- if (field.Name.ToLowerInvariant ().Contains
("reserved")) {
- if (results == null)
- results = new MessageCollection
();
- Location loc = new Location (field);
- Message msg = new Message
(string.Format ("Enum should not contain fields for reserved values.",
type.FullName), loc, MessageType.Warning);
- results.Add (msg);
+ if (field.Name.ToUpperInvariant ().Contains
("RESERVED")) {
+ // High since removing/renaming the
field can be a breaking change
+ Runner.Report (field, Severity.High,
Confidence.High, String.Empty);
}
}
- return results;
+ return Runner.CurrentRuleResult;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/EnumNotEndsWithEnumOrFlagsSuffixRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/EnumNotEndsWithEnumOrFlagsSuffixRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/EnumNotEndsWithEnumOrFlagsSuffixRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -27,6 +27,7 @@
//
using System;
+using System.Globalization;
using Mono.Cecil;
@@ -35,33 +36,35 @@
namespace Gendarme.Rules.Naming {
- public class EnumNotEndsWithEnumOrFlagsSuffixRule : ITypeRule {
+ [Problem ("This type is an enumeration and, by convention, its name
should not end with either Enum or Flags.")]
+ [Solution ("Remove the Enum or Flags suffix in enumeration name.")]
+ public class EnumNotEndsWithEnumOrFlagsSuffixRule : Rule, ITypeRule {
private static bool EndsWithSuffix (string suffix, string
typeName)
{
- return typeName.EndsWith (suffix) || typeName.ToLower
().EndsWith (suffix.ToLower ());
+ int pos = typeName.Length - suffix.Length;
+ if (pos < 0)
+ return false;
+
+ return (String.Compare (typeName, pos, suffix, 0,
suffix.Length, true, CultureInfo.InvariantCulture) == 0);
}
- public MessageCollection CheckType (TypeDefinition
typeDefinition, Runner runner)
+ public RuleResult CheckType (TypeDefinition type)
{
// rule applies only to enums
- if (!typeDefinition.IsEnum)
- return runner.RuleSuccess;
+ if (!type.IsEnum)
+ return RuleResult.DoesNotApply;
- if (!typeDefinition.IsFlags ()) {
- if (EndsWithSuffix ("Enum",
typeDefinition.Name)) {
- Location location = new Location
(typeDefinition);
- Message message = new Message ("Enum
name should not end with the Enum suffix.", location, MessageType.Error);
- return new MessageCollection (message);
+ if (!type.IsFlags ()) {
+ if (EndsWithSuffix ("Enum", type.Name)) {
+ Runner.Report (type, Severity.Medium,
Confidence.High, "Enum name should not end with the 'Enum'.");
}
} else {
- if (EndsWithSuffix ("Flags",
typeDefinition.Name)) {
- Location location = new Location
(typeDefinition);
- Message message = new Message ("Enum
name should not end with the Flags suffix.", location, MessageType.Error);
- return new MessageCollection (message);
+ if (EndsWithSuffix ("Flags", type.Name)) {
+ Runner.Report (type, Severity.Medium,
Confidence.High, "Enum name should not end with the 'Flags'.");
}
}
- return runner.RuleSuccess;
+ return Runner.CurrentRuleResult;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ParameterNamesShouldMatchOverridenMethodRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ParameterNamesShouldMatchOverridenMethodRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/ParameterNamesShouldMatchOverridenMethodRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -1,5 +1,5 @@
//
-// Gendarme.Rules.Naming.ParameterNamesShouldMatchOverridenMethodRule
+// Gendarme.Rules.Naming.ParameterNamesShouldMatchOverriddenMethodRule
//
// Authors:
// Andreas Noever <[EMAIL PROTECTED]>
@@ -27,13 +27,17 @@
//
using System;
+using System.Globalization;
+
using Mono.Cecil;
using Gendarme.Framework;
using Gendarme.Framework.Rocks;
namespace Gendarme.Rules.Naming {
- public class ParameterNamesShouldMatchOverridenMethodRule : IMethodRule
{
+ [Problem ("This method overrides (or implement) an existing method but
does not use the same parameter names as the original.")]
+ [Solution ("Keep parameter names consistent when overriding a class or
implementing an interface.")]
+ public class ParameterNamesShouldMatchOverriddenMethodRule : Rule,
IMethodRule {
private static bool SignatureMatches (MethodDefinition method,
MethodDefinition baseMethod, bool explicitInterfaceCheck)
{
@@ -54,18 +58,17 @@
break;
}
}
- if (!paramtersMatch)
- return false;
- return true;
+ return paramtersMatch;
}
private static MethodDefinition GetBaseMethod (MethodDefinition
method)
{
- TypeDefinition baseType = (TypeDefinition)
method.DeclaringType;
- while (baseType != baseType.BaseType) { //System.Object
extends System.Object in cecil
- baseType = baseType.BaseType as TypeDefinition;
- if (baseType == null) //TODO: ToTypeDefinition
()
- break;
+ TypeDefinition baseType = method.DeclaringType.Resolve
();
+ if (baseType == null)
+ return null;
+
+ while ((baseType.BaseType != null) && (baseType !=
baseType.BaseType)) {
+ baseType = baseType.BaseType.Resolve ();
foreach (MethodDefinition baseMethodCandidate
in baseType.Methods) {
if (SignatureMatches (method,
baseMethodCandidate, false))
return baseMethodCandidate;
@@ -78,9 +81,9 @@
{
TypeDefinition type = (TypeDefinition)
method.DeclaringType;
foreach (TypeReference interfaceReference in
type.Interfaces) {
- TypeDefinition interfaceCandidate =
interfaceReference as TypeDefinition;
+ TypeDefinition interfaceCandidate =
interfaceReference.Resolve ();
if (interfaceCandidate == null)
- continue; //TODO: ToTypeDefinition ();
+ continue;
foreach (MethodDefinition
interfaceMethodCandidate in interfaceCandidate.Methods) {
if (SignatureMatches (method,
interfaceMethodCandidate, true))
return interfaceMethodCandidate;
@@ -89,10 +92,10 @@
return null;
}
- public MessageCollection CheckMethod (MethodDefinition method,
Runner runner)
+ public RuleResult CheckMethod (MethodDefinition method)
{
if (!method.IsVirtual)
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
MethodDefinition baseMethod = null;
if (!method.IsNewSlot)
@@ -100,20 +103,17 @@
if (baseMethod == null)
baseMethod = GetInterfaceMethod (method);
if (baseMethod == null)
- return runner.RuleSuccess;
+ return RuleResult.Success;
- MessageCollection results = null;
-
for (int i = 0; i < method.Parameters.Count; i++) {
if (method.Parameters [i].Name !=
baseMethod.Parameters [i].Name) {
- if (results == null)
- results = new MessageCollection
();
- Location loc = new Location (method);
- Message msg = new Message
(string.Format ("The name of parameter {0} ({1}) does not match the name of the
parameter in the overriden method ({2}).", i + 1, method.Parameters [i].Name,
baseMethod.Parameters [i].Name), loc, MessageType.Warning);
- results.Add (msg);
+ string s = string.Format
(CultureInfo.InstalledUICulture,
+ "The name of parameter #{0}
({1}) does not match the name of the parameter in the overriden method ({2}).",
+ i + 1, method.Parameters
[i].Name, baseMethod.Parameters [i].Name);
+ Runner.Report (method, Severity.Medium,
Confidence.High, s);
}
}
- return results;
+ return Runner.CurrentRuleResult;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectCasingRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectCasingRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectCasingRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -38,7 +38,9 @@
namespace Gendarme.Rules.Naming {
- public class UseCorrectCasingRule : ITypeRule, IMethodRule {
+ [Problem ("This identifier violates .NET naming conventions.")]
+ [Solution ("Make all type and method names pascal-cased (like MyClass),
and all parameter names must be camel-cased (like myParameter).")]
+ public class UseCorrectCasingRule : Rule, ITypeRule, IMethodRule {
// check if name is PascalCased
private static bool IsPascalCase (string name)
@@ -93,74 +95,67 @@
return (index == s.Length) ? 0 : index;
}
- public MessageCollection CheckType (TypeDefinition
typeDefinition, Runner runner)
+ public RuleResult CheckType (TypeDefinition type)
{
// rule does not apply to generated code (outside
developer's control)
- if (typeDefinition.IsGeneratedCode ())
- return runner.RuleSuccess;
+ if (type.IsGeneratedCode ())
+ return RuleResult.DoesNotApply;
// <Module> isn't tagged as generated by the compiler
but still must be ignored
- if (typeDefinition.Name == Constants.ModuleType)
- return runner.RuleSuccess;
+ if (type.Name == Constants.ModuleType)
+ return RuleResult.DoesNotApply;
// ok, rule applies
// types should all be PascalCased
- if (IsPascalCase (typeDefinition.Name))
- return runner.RuleSuccess;
+ if (IsPascalCase (type.Name))
+ return RuleResult.Success;
- Location location = new Location (typeDefinition);
- string errorMessage = string.Format ("By existing
naming conventions, the type names should all be pascal-cased (e.g. MyClass).
Rename '{0}' type to '{1}'.",
-
typeDefinition.Name, PascalCase (typeDefinition.Name));
- return new MessageCollection (new Message
(errorMessage, location, MessageType.Error));
+ string s = String.Format ("Type names should all be
pascal-cased. Rename '{0}' type to '{1}'.", type.Name, PascalCase (type.Name));
+ Runner.Report (type, Severity.Medium, Confidence.High,
s);
+ return RuleResult.Failure;
}
- public MessageCollection CheckMethod (MethodDefinition
methodDefinition, Runner runner)
+ public RuleResult CheckMethod (MethodDefinition method)
{
- if (methodDefinition.IsConstructor)
- return runner.RuleSuccess;
+ if (method.IsConstructor)
+ return RuleResult.DoesNotApply;
- string name = methodDefinition.Name;
- MethodSemanticsAttributes attrs =
methodDefinition.SemanticsAttributes;
+ string name = method.Name;
+ MethodSemanticsAttributes attrs =
method.SemanticsAttributes;
MethodSemanticsAttributes mask =
MethodSemanticsAttributes.Getter | MethodSemanticsAttributes.Setter
| MethodSemanticsAttributes.AddOn |
MethodSemanticsAttributes.RemoveOn;
if ((attrs & mask) != 0) {
// it's something special
- int underscore = methodDefinition.Name.IndexOf
('_');
+ int underscore = method.Name.IndexOf ('_');
if (underscore != -1)
name = name.Substring (underscore + 1);
- } else if (methodDefinition.IsSpecialName ||
methodDefinition.IsGeneratedCode ()) {
- return runner.RuleSuccess;
+ } else if (method.IsSpecialName ||
method.IsGeneratedCode ()) {
+ return RuleResult.Success;
}
- MessageCollection messages = null;
- Location location = new Location (methodDefinition);
-
// like types, methods/props should all be PascalCased,
too
if (!IsPascalCase (name)) {
string errorMessage = string.Format ("By
existing naming conventions, all the method and property names should all be
pascal-cased (e.g. MyOperation). Rename '{0}' to '{1}'.",
name,
PascalCase (name));
- messages = new MessageCollection (new Message
(errorMessage, location, MessageType.Error));
+ Runner.Report (method, Severity.Medium,
Confidence.High, errorMessage);
}
// check parameters
List<string> parameterNames = new List<string> ();
- foreach (ParameterDefinition paramDefinition in
methodDefinition.Parameters) {
+ foreach (ParameterDefinition paramDefinition in
method.Parameters) {
if (!parameterNames.Contains
(paramDefinition.Name)) // somewhy they duplicate sometimes
parameterNames.Add
(paramDefinition.Name);
}
foreach (string param in parameterNames) {
// params should all be camelCased
if (!IsCamelCase (param)) {
- if (messages == null)
- messages = new
MessageCollection ();
-
string errorMessage = string.Format
("By existing naming conventions, the parameter names should all be camel-cased
(e.g. myParameter). Rename '{0}' parameter to '{1}'.",
param, CamelCase (param));
- messages.Add (new Message
(errorMessage, location, MessageType.Error));
+ Runner.Report (method, Severity.Medium,
Confidence.High, errorMessage);
}
}
- return messages;
+ return Runner.CurrentRuleResult;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectPrefixRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectPrefixRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectPrefixRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -33,7 +33,9 @@
namespace Gendarme.Rules.Naming {
- public class UseCorrectPrefixRule : ITypeRule {
+ [Problem ("This type starts with an incorrect prefix or does not start
with the required one. All interface names should start with the 'I' letter,
followed by another capital letter. All other type names should not have any
specific prefix.")]
+ [Solution ("Rename the type to have the correct prefix.")]
+ public class UseCorrectPrefixRule : Rule, ITypeRule {
private static bool IsCorrectTypeName (string name)
{
@@ -50,21 +52,22 @@
return name [0] == 'I' && char.IsUpper (name [1]);
}
- public MessageCollection CheckType (TypeDefinition
typeDefinition, Runner runner)
+ public RuleResult CheckType (TypeDefinition type)
{
- Location location = new Location (typeDefinition);
- if (typeDefinition.IsInterface) {
- if (!IsCorrectInterfaceName
(typeDefinition.Name)) { // interfaces should look like 'ISomething'
- Message message = new Message
(string.Format ("The '{0}' interface name doesn't have the required 'I' prefix.
Acoording to existing naming conventions, all interface names should begin with
the 'I' letter followed by another capital letter.", typeDefinition.Name),
location, MessageType.Error);
- return new MessageCollection (message);
+ if (type.IsInterface) {
+ if (!IsCorrectInterfaceName (type.Name)) { //
interfaces should look like 'ISomething'
+ string s = String.Format ("The '{0}'
interface name doesn't have the required 'I' prefix. Acoording to existing
naming conventions, all interface names should begin with the 'I' letter
followed by another capital letter.", type.Name);
+ Runner.Report (type, Severity.Critical,
Confidence.High, s);
+ return RuleResult.Failure;
}
} else {
- if (!IsCorrectTypeName (typeDefinition.Name)) {
// class should _not_ look like 'CSomething"
- Message message = new Message
(string.Format ("The '{0}' type name starts with 'C' prefix but, according to
existing naming conventions, type names should not have any specific prefix.",
typeDefinition.Name), location, MessageType.Error);
- return new MessageCollection (message);
+ if (!IsCorrectTypeName (type.Name)) { // class
should _not_ look like 'CSomething"
+ string s = String.Format ("The '{0}'
type name starts with 'C' prefix but, according to existing naming conventions,
type names should not have any specific prefix.", type.Name);
+ Runner.Report (type, Severity.Medium,
Confidence.High, s);
+ return RuleResult.Failure;
}
}
- return runner.RuleSuccess;
+ return RuleResult.Success;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectSuffixRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectSuffixRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseCorrectSuffixRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -37,33 +37,32 @@
namespace Gendarme.Rules.Naming {
- public class UseCorrectSuffixRule : ITypeRule {
+ [Problem ("This type does not end with the correct suffix. That usually
happens when you define a custom attribute or exception and forget appending
suffixes like 'Attribute' or 'Exception' to the type name.")]
+ [Solution ("Rename the type and append the correct suffix.")]
+ public class UseCorrectSuffixRule : Rule, ITypeRule {
// keys are base class names, values are arrays of possible
suffixes
- private Dictionary<string, string []> definedSuffixes =
- new Dictionary<string, string []> ();
+ private static Dictionary<string, string []> definedSuffixes =
+ new Dictionary<string, string []> () {
+ { "System.Attribute", new string [] {
"Attribute" } },
+ { "System.EventArgs", new string [] {
"EventArgs" } },
+ { "System.Exception", new string [] {
"Exception" } },
+ { "System.Collections.Queue", new string [] {
"Collection", "Queue" } },
+ { "System.Collections.Stack", new string [] {
"Collection", "Stack" } },
+ { "System.Data.DataSet", new string [] {
"DataSet" } },
+ { "System.Data.DataTable", new string [] {
"DataTable", "Collection" } },
+ { "System.IO.Stream", new string [] { "Stream"
} },
+ { "System.Security.IPermission", new string []
{ "Permission" } },
+ {
"System.Security.Policy.IMembershipCondition", new string [] { "Condition" } },
+ { "System.Collections.IDictionary", new string
[] { "Dictionary" } },
+ { "System.Collections.Generic.IDictionary", new
string [] { "Dictionary" } },
+ { "System.Collections.ICollection", new string
[] { "Collection" } },
+ { "System.Collections.Generic.ICollection", new
string [] { "Collection" } },
+ { "System.Collections.IEnumerable", new string
[] { "Collection" } }
+ };
- public UseCorrectSuffixRule ()
+ private static string [] GetSuffixes (string baseTypeName)
{
- definedSuffixes.Add ("System.Attribute", new string []
{ "Attribute" });
- definedSuffixes.Add ("System.EventArgs", new string []
{ "EventArgs" });
- definedSuffixes.Add ("System.Exception", new string []
{ "Exception" });
- definedSuffixes.Add ("System.Collections.Queue", new
string [] { "Collection", "Queue" });
- definedSuffixes.Add ("System.Collections.Stack", new
string [] { "Collection", "Stack" });
- definedSuffixes.Add ("System.Data.DataSet", new string
[] { "DataSet" });
- definedSuffixes.Add ("System.Data.DataTable", new
string [] { "DataTable", "Collection" });
- definedSuffixes.Add ("System.IO.Stream", new string []
{ "Stream" });
- definedSuffixes.Add ("System.Security.IPermission", new
string [] { "Permission" });
- definedSuffixes.Add
("System.Security.Policy.IMembershipCondition", new string [] { "Condition" });
- definedSuffixes.Add ("System.Collections.IDictionary",
new string [] { "Dictionary" });
- definedSuffixes.Add
("System.Collections.Generic.IDictionary", new string [] { "Dictionary" });
- definedSuffixes.Add ("System.Collections.ICollection",
new string [] { "Collection" });
- definedSuffixes.Add
("System.Collections.Generic.ICollection", new string [] { "Collection" });
- definedSuffixes.Add ("System.Collections.IEnumerable",
new string [] { "Collection" });
- }
-
- private string [] GetSuffixes (string baseTypeName)
- {
if (definedSuffixes.ContainsKey (baseTypeName)) {
return definedSuffixes [baseTypeName];
} else {
@@ -73,48 +72,48 @@
// checks if type name ends with an approriate suffix
// returns array of proposed suffixes via out suffixes
parameter or empty list (if none)
- private bool HasRequiredSuffix (TypeDefinition type, out
List<string> suffixes)
+ private static bool HasRequiredSuffix (TypeDefinition type,
List<string> suffixes)
{
- suffixes = new List<string> ();
TypeDefinition current = type;
while (current != null && current.BaseType != null) {
// if we have any suffixes defined by base
type, we select them
if (definedSuffixes.ContainsKey
(current.BaseType.FullName)) {
- suffixes.AddRange (GetSuffixes
(current.BaseType.FullName));
+ suffixes.AddRangeIfNew (GetSuffixes
(current.BaseType.FullName));
} else {
// if no suffix for base type is found,
we start looking through interfaces
foreach (TypeReference iface in
current.Interfaces)
if (definedSuffixes.ContainsKey
(iface.FullName))
- suffixes.AddRange
(GetSuffixes (iface.FullName));
+ suffixes.AddRangeIfNew
(GetSuffixes (iface.FullName));
}
if (suffixes.Count > 0) {
// if any suffixes found
// check whether type name ends with
any of these suffixes
return suffixes.Exists (delegate
(string suffix) { return type.Name.EndsWith (suffix); });
} else {
- current = current.BaseType as
TypeDefinition; // inspect base type
+ // inspect base type
+ current = current.BaseType.Resolve ();
}
}
// by default, return true
return true;
}
- public MessageCollection CheckType (TypeDefinition
typeDefinition, Runner runner)
+ private List<string> proposedSuffixes = new List<string> ();
+
+ public RuleResult CheckType (TypeDefinition type)
{
// rule does not apply to generated code (outside
developer's control)
- if (typeDefinition.IsGeneratedCode ())
- return runner.RuleSuccess;
+ if (type.IsGeneratedCode ())
+ return RuleResult.DoesNotApply;
// ok, rule applies
- List<string> proposedSuffixes;
- if (HasRequiredSuffix (typeDefinition, out
proposedSuffixes))
- return runner.RuleSuccess;
+ proposedSuffixes.Clear ();
+ if (HasRequiredSuffix (type, proposedSuffixes))
+ return RuleResult.Success;
- RemoveDuplicates (ref proposedSuffixes);
// there must be some suffixes defined, but type name
doesn't end with any of them
- Location location = new Location (typeDefinition);
string messageText;
if (proposedSuffixes.Count > 0) {
string joinedSuffixes = proposedSuffixes [0];
@@ -128,18 +127,8 @@
} else {
messageText = "The class name does not end with
the correct suffix. However Gendarme could not determine what suffix should it
end with. Contact the author of the rule to fix this bug.";
}
- Message message = new Message (messageText, location,
MessageType.Error);
- return new MessageCollection (message);
+ Runner.Report (type, Severity.Medium, Confidence.High,
messageText);
+ return RuleResult.Failure;
}
-
- private static void RemoveDuplicates (ref List<string> list)
- {
- List<string> newList = new List<string> ();
- foreach (string s in list) {
- if (!newList.Contains (s))
- newList.Add (s);
- }
- list = newList;
- }
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePluralNameInEnumFlagsRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePluralNameInEnumFlagsRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePluralNameInEnumFlagsRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -36,28 +36,29 @@
namespace Gendarme.Rules.Naming {
- public class UsePluralNameInEnumFlagsRule : ITypeRule {
+ [Problem ("This type is an enumeration and, by convention, enums should
have a singular name.")]
+ [Solution ("Convert this enumeration type name from plural to
singular.")]
+ public class UsePluralNameInEnumFlagsRule : Rule, ITypeRule {
private static bool IsPlural (string typeName)
{
- int stringComparation = String.Compare (typeName,
typeName.Length -1, "s", 0, 1, true, CultureInfo.CurrentCulture);
- return stringComparation == 0;
+ return String.Compare (typeName, typeName.Length - 1,
"s", 0, 1, true, CultureInfo.CurrentCulture) == 0;
}
- public MessageCollection CheckType (TypeDefinition type, Runner
runner)
+ public RuleResult CheckType (TypeDefinition type)
{
// rule applies only to enums with [Flags] attribute
if (!type.IsFlags ())
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
// rule applies
if (IsPlural (type.Name))
- return runner.RuleSuccess;
+ return RuleResult.Success;
- Location location = new Location (type);
- Message message = new Message ("The Enum Flags has
singular name.", location, MessageType.Error);
- return new MessageCollection (message);
+ // Confidence == Normal because valid names may end
with 's'
+ Runner.Report (type, Severity.Low, Confidence.Normal,
String.Empty);
+ return RuleResult.Failure;
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePreferredTermsRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePreferredTermsRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UsePreferredTermsRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -28,67 +28,58 @@
using System;
using System.Collections.Generic;
+using System.Text;
using Mono.Cecil;
using Gendarme.Framework;
namespace Gendarme.Rules.Naming {
- public class UsePreferredTermsRule : ITypeRule, IMethodRule {
+ [Problem ("The identifier contains some obsolete terms.")]
+ [Solution ("For consistency replace any obsolete terms with the
preferred ones.")]
+ public class UsePreferredTermsRule : Rule, ITypeRule, IMethodRule {
+ private const string Message = "Obsolete term '{0}' should be
replaced with '{1}'.";
+
// keys are obsolete terms, values are preferred ones
- private Dictionary<string, string> preferredTerms =
- new Dictionary<string, string> ();
+ // list is based on the FxCop naming rule (as the whole rule is
inspired by it)
+ //
http://www.gotdotnet.com/Team/FxCop/Docs/Rules/Naming/UsePreferredTerms.html
+ private static Dictionary<string, string> preferredTerms =
+ new Dictionary<string, string> () {
+ { "ComPlus", "EnterpriseServices" },
+ { "Cancelled", "Canceled" },
+ { "Indices", "Indexes" },
+ { "LogIn", "LogOn" },
+ { "LogOut", "LogOff" },
+ { "SignOn", "SignIn" },
+ { "SignOff", "SignOut" },
+ { "Writeable", "Writable" }
+ };
- public UsePreferredTermsRule ()
- {
- // list is based on the FxCop naming rule (as the whole
rule is inspired by it)
- //
http://www.gotdotnet.com/Team/FxCop/Docs/Rules/Naming/UsePreferredTerms.html
- preferredTerms.Add ("ComPlus", "EnterpriseServices");
- preferredTerms.Add ("Cancelled", "Canceled");
- preferredTerms.Add ("Indices", "Indexes");
- preferredTerms.Add ("LogIn", "LogOn");
- preferredTerms.Add ("LogOut", "LogOff");
- preferredTerms.Add ("SignOn", "SignIn");
- preferredTerms.Add ("SignOff", "SignOut");
- preferredTerms.Add ("Writeable", "Writable");
- }
-
// common function checking any identifier
- private MessageCollection CheckIdentifier (string identifier,
Location location, Runner runner)
+ private RuleResult CheckIdentifier (TypeDefinition type,
MethodDefinition method, string identifier)
{
- Dictionary<string, string> foundTerms = new
Dictionary<string, string> ();
// scan for any obsolete terms
foreach (KeyValuePair<string, string> pair in
preferredTerms) {
- if (identifier.IndexOf (pair.Key,
StringComparison.InvariantCultureIgnoreCase) != -1) {
- foundTerms.Add (pair.Key, pair.Value);
+ if (identifier.IndexOf (pair.Key,
StringComparison.OrdinalIgnoreCase) != -1) {
+ string s = String.Format (Message,
pair.Key, pair.Value);
+ if (type != null)
+ Runner.Report (type,
Severity.Low, Confidence.High, s);
+ else
+ Runner.Report (method,
Severity.Low, Confidence.High, s);
}
}
- if (foundTerms.Count == 0)
- return runner.RuleSuccess;
-
- // form our messages
- MessageCollection messages = new MessageCollection ();
- foreach (KeyValuePair<string, string> pair in
foundTerms) {
- string errorMessage = string.Format (
- "Obsolete term '{0}' is used in the
identifier. Replace it with the preferred term '{1}'.",
- pair.Key, pair.Value);
- Message message = new Message (errorMessage,
location, MessageType.Error);
- messages.Add (message);
- }
- return messages;
+ return Runner.CurrentRuleResult;
}
- public MessageCollection CheckType (TypeDefinition
typeDefinition, Runner runner)
+ public RuleResult CheckType (TypeDefinition type)
{
- Location location = new Location (typeDefinition);
- return CheckIdentifier (typeDefinition.Name, location,
runner);
+ return CheckIdentifier (type, null, type.Name);
}
- public MessageCollection CheckMethod (MethodDefinition
methodDefinition, Runner runner)
+ public RuleResult CheckMethod (MethodDefinition method)
{
- Location location = new Location (methodDefinition);
- return CheckIdentifier (methodDefinition.Name,
location, runner);
+ return CheckIdentifier (null, method, method.Name);
}
}
}
Modified:
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseSingularNameInEnumsUnlessAreFlagsRule.cs
===================================================================
---
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseSingularNameInEnumsUnlessAreFlagsRule.cs
2008-02-15 19:36:37 UTC (rev 95802)
+++
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/UseSingularNameInEnumsUnlessAreFlagsRule.cs
2008-02-15 19:40:31 UTC (rev 95803)
@@ -36,28 +36,28 @@
namespace Gendarme.Rules.Naming {
- public class UseSingularNameInEnumsUnlessAreFlagsRule : ITypeRule {
+ [Problem ("This type is an enumeration and by convention it should have
a singular name.")]
+ [Solution ("Change the enumeration name from the plural to the singular
form.")]
+ public class UseSingularNameInEnumsUnlessAreFlagsRule : Rule, ITypeRule
{
private static bool IsPlural (string typeName)
{
- int stringComparation = String.Compare (typeName,
typeName.Length -1, "s", 0, 1, true, CultureInfo.CurrentCulture);
- return stringComparation == 0;
+ return (String.Compare (typeName, typeName.Length - 1,
"s", 0, 1, true, CultureInfo.CurrentCulture) == 0);
}
- public MessageCollection CheckType (TypeDefinition type, Runner
runner)
+ public RuleResult CheckType (TypeDefinition type)
{
// rule applies only to enums - but not enums marked
with [Flags] attribute
if (!type.IsEnum || type.IsFlags ())
- return runner.RuleSuccess;
+ return RuleResult.DoesNotApply;
// rule applies
if (!IsPlural (type.Name))
- return runner.RuleSuccess;
+ return RuleResult.Success;
- Location location = new Location (type);
- Message message = new Message ("The enum should not
have a plural name.", location, MessageType.Error);
- return new MessageCollection (message);
+ Runner.Report (type, Severity.Medium,
Confidence.Normal, String.Empty);
+ return RuleResult.Failure;
}
}
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches