Author: spouliot Date: 2008-01-18 19:33:30 -0500 (Fri, 18 Jan 2008) New Revision: 93308
Added: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/EnsureSymmetryForOverloadedOperatorsRule.cs trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OperatorEqualsShouldBeOverloadedRule.cs trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OverrideEqualsMethodRule.cs trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ProvideAlternativeNamesForOperatorOverloadsRule.cs Removed: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableHelper.cs Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ChangeLog trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableFieldsShouldBeDisposedRule.cs trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Gendarme.Rules.Design.xml.in trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Makefile.am trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithDisposableFieldsShouldBeDisposableRule.cs trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithNativeFieldsShouldBeDisposableRule.cs Log: 2008-01-18 Sebastien Pouliot <[EMAIL PROTECTED]> * DisposableHelper.cs: Removed. * EnsureSymmetryForOverloadedOperatorsTest.cs: New. Rule that ensure operators are overloaded in symmetry [Andreas Noever]. * DisposableFieldsShouldBeDisposedRule.cs: Adapted to use rocks instead of DisposableHelper. * OperatorEqualsShouldBeOverloadedTest.cs: New. Rule that ensure that operator == is overloaded when required [Andreas Noever]. * OverrideEqualsMethodTest.cs: New. Rule that ensure that method Equals is overriden when required [Andreas Noever]. * ProvideAlternativeNamesForOperatorOverloadsTest.cs: New. Rule that ensure alternate methods are provided for operators [Andreas Noever]. * TypesWithDisposableFieldsShouldBeDisposableRule.cs: Adapted to use rocks instead of DisposableHelper. * TypesWithNativeFieldsShouldBeDisposableRule.cs: Adapted to use rocks instead of DisposableHelper. * Gendarme.Rules.Design.xml.in: Add new rule descriptions. * Makefile.am: Add new rules/tests to the build. Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ChangeLog =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ChangeLog 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ChangeLog 2008-01-19 00:33:30 UTC (rev 93308) @@ -1,3 +1,23 @@ +2008-01-18 Sebastien Pouliot <[EMAIL PROTECTED]> + + * DisposableHelper.cs: Removed. + * EnsureSymmetryForOverloadedOperatorsTest.cs: New. Rule that + ensure operators are overloaded in symmetry [Andreas Noever]. + * DisposableFieldsShouldBeDisposedRule.cs: Adapted to use rocks + instead of DisposableHelper. + * OperatorEqualsShouldBeOverloadedTest.cs: New. Rule that ensure + that operator == is overloaded when required [Andreas Noever]. + * OverrideEqualsMethodTest.cs: New. Rule that ensure that method + Equals is overriden when required [Andreas Noever]. + * ProvideAlternativeNamesForOperatorOverloadsTest.cs: New. Rule + that ensure alternate methods are provided for operators [Andreas Noever]. + * TypesWithDisposableFieldsShouldBeDisposableRule.cs: Adapted to + use rocks instead of DisposableHelper. + * TypesWithNativeFieldsShouldBeDisposableRule.cs: Adapted to use + rocks instead of DisposableHelper. + * Gendarme.Rules.Design.xml.in: Add new rule descriptions. + * Makefile.am: Add new rules/tests to the build. + 2008-01-14 Sebastien Pouliot <[EMAIL PROTECTED]> * DisposableFieldsShouldBeDisposedRule.cs: Exclude generated code Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableFieldsShouldBeDisposedRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableFieldsShouldBeDisposedRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableFieldsShouldBeDisposedRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -53,8 +53,8 @@ if (!type.Implements ("System.IDisposable")) return runner.RuleSuccess; - MethodDefinition implicitDisposeMethod = type.GetImplicitDisposeMethod (); - MethodDefinition explicitDisposeMethod = type.GetExplicitDisposeMethod (); + MethodDefinition implicitDisposeMethod = type.GetMethod (MethodSignatures.Dispose); + MethodDefinition explicitDisposeMethod = type.GetMethod (MethodSignatures.DisposeExplicit); if (implicitDisposeMethod == null || implicitDisposeMethod.IsAbstract) implicitDisposeMethod = null; @@ -74,7 +74,7 @@ break; //TODO Implements for TypeReference if (!baseType.Implements ("System.IDisposable")) break; //also checks parents, so no need to search further - MethodDefinition baseDisposeMethod = baseType.GetImplicitDisposeMethod (); //we just check for Dispose() here + MethodDefinition baseDisposeMethod = baseType.GetMethod (MethodSignatures.Dispose); //we just check for Dispose() here if (baseDisposeMethod == null) continue; //no dispose method (yet) if (baseDisposeMethod.IsAbstract) Deleted: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableHelper.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableHelper.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/DisposableHelper.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -1,65 +0,0 @@ -// -// Gendarme.Rules.Design.DisposableHelper -// -// Authors: -// Andreas Noever <[EMAIL PROTECTED]> -// -// (C) 2008 Andreas Noever -// -// 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 Gendarme.Framework.Rocks; - -namespace Gendarme.Rules.Design { - - public static class DisposableHelper { - - public static MethodDefinition GetImplicitDisposeMethod (this TypeDefinition self) - { - return self.GetDisposeMethod ("Dispose"); - } - - public static MethodDefinition GetExplicitDisposeMethod (this TypeDefinition self) - { - return self.GetDisposeMethod ("System.IDisposable.Dispose"); - } - - private static MethodDefinition GetDisposeMethod (this TypeDefinition self, string methodName) - { - if (!self.Implements ("System.IDisposable")) - return null; - - foreach (MethodDefinition method in self.Methods) { - if (method.Name != methodName) - continue; - if (method.Parameters.Count != 0) - continue; - if (method.ReturnType.ReturnType.FullName != "System.Void") - continue; - return method; - } - return null; - } - } -} Added: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/EnsureSymmetryForOverloadedOperatorsRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/EnsureSymmetryForOverloadedOperatorsRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/EnsureSymmetryForOverloadedOperatorsRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -0,0 +1,88 @@ +// +// Gendarme.Rules.Design.EnsureSymmetryForOverloadedOperatorsRule +// +// Authors: +// Andreas Noever <[EMAIL PROTECTED]> +// +// (C) 2008 Andreas Noever +// +// 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.Generic; +using Mono.Cecil; +using Gendarme.Framework; +using Gendarme.Framework.Rocks; + +namespace Gendarme.Rules.Design { + + public class EnsureSymmetryForOverloadedOperatorsRule : ITypeRule { + + static KeyValuePair<MethodSignature, MethodSignature> [] SymmetricOperators_Warning = new KeyValuePair<MethodSignature, MethodSignature> [] { + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Addition, MethodSignatures.op_Subtraction), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Multiply, MethodSignatures.op_Division), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Division, MethodSignatures.op_Modulus), + }; + static KeyValuePair<MethodSignature, MethodSignature> [] SymmetricOperators_Error = new KeyValuePair<MethodSignature, MethodSignature> [] { + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_GreaterThan, MethodSignatures.op_LessThan), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_GreaterThanOrEqual, MethodSignatures.op_LessThanOrEqual), + new KeyValuePair<MethodSignature, MethodSignature> (MethodSignatures.op_Equality, MethodSignatures.op_Inequality), + new KeyValuePair<MethodSignature, MethodSignature> (MethodSignatures.op_True, MethodSignatures.op_False), + }; + + public MessageCollection CheckType (TypeDefinition type, Runner runner) + { + if (type.IsInterface || type.IsEnum) + return runner.RuleSuccess; + + MessageCollection results = null; + + foreach (var kv in SymmetricOperators_Warning) + CheckOperatorPair (kv, type, MessageType.Warning, ref results); + foreach (var kv in SymmetricOperators_Error) + CheckOperatorPair (kv, type, MessageType.Error, ref results); + + return results; + } + + private static void CheckOperatorPair (KeyValuePair<MethodSignature, MethodSignature> pair, TypeDefinition type, + MessageType msgType, ref MessageCollection results) + { + MethodDefinition op = type.GetMethod (pair.Key); + if (op == null) { //first one not defined + pair = new KeyValuePair<MethodSignature, MethodSignature> (pair.Value, pair.Key); //reverse + op = type.GetMethod (pair.Key); + if (op == null) + return; //neither one is defined + } else { + if (type.HasMethod (pair.Value)) + return; //both are defined + } + if (results == null) + results = new MessageCollection (); + Location loc = new Location (op); + string s = string.Format ("This type implements the '{0}' operator so, for symmetry, it should also implement the '{1}' operator.", + pair.Key.Name, pair.Value.Name); + Message msg = new Message (s, loc, msgType); + results.Add (msg); + } + } +} Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Gendarme.Rules.Design.xml.in =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Gendarme.Rules.Design.xml.in 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Gendarme.Rules.Design.xml.in 2008-01-19 00:33:30 UTC (rev 93308) @@ -53,6 +53,12 @@ <problem>The sealed class '{0}' contains protected field(s).</problem> <solution>Change the access specifier to public or private to represent the true use for the field.</solution> </rule> + <rule Name="EnsureSymmetryForOverloadedOperatorsRule" + Type="Gendarme.Rules.Design.EnsureSymmetryForOverloadedOperatorsRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" + Uri="" > + <problem>The type '{0}' should overload operators in symmetry (e.g. == and !=, + and -).</problem> + <solution>Add an overloaded for the missing operator and keep the type symmetrical.</solution> + </rule> <rule Name="EnumsShouldDefineAZeroValueRule" Type="Gendarme.Rules.Design.EnumsShouldDefineAZeroValueRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" Uri="" > @@ -77,6 +83,12 @@ <problem>The finalizer (destructor) for type '{0}' does not call it's base class finalizer.</problem> <solution>All finalizer should call it's base class finalizer.</solution> </rule> + <rule Name="FlagsShouldNotDefineAZeroValueRule" + Type="Gendarme.Rules.Design.FlagsShouldNotDefineAZeroValueRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" + Uri="" > + <problem>The enumeration flag '{0}' defines a value of 0, which cannot be used as a real value.</problem> + <solution>Remove the 0 value from the flag.</solution> + </rule> <rule Name="MainShouldNotBePublicRule" Type="Gendarme.Rules.Design.MainShouldNotBePublicRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" Uri="" > @@ -89,6 +101,24 @@ <problem></problem> <solution></solution> </rule> + <rule Name="OperatorEqualsShouldBeOverloadedRule" + Type="Gendarme.Rules.Design.OperatorEqualsShouldBeOverloadedRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" + Uri="" > + <problem>The type '{0}' is a value type (struct) that override Equals, or both overloads + and - operators, but doesn't overload == and != operators.</problem> + <solution>Add overloads for the missing == and != operators.</solution> + </rule> + <rule Name="OverrideEqualsMethodRule" + Type="Gendarme.Rules.Design.OverrideEqualsMethodRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" + Uri="" > + <problem>The type '{0}' overloads the == operator but doesn't override the Equals method.</problem> + <solution>Override the Equals method to match the results of the == operator.</solution> + </rule> + <rule Name="ProvideAlternativeNamesForOperatorOverloadsRule" + Type="Gendarme.Rules.Design.ProvideAlternativeNamesForOperatorOverloadsRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" + Uri="" > + <problem>The type '{0}' contains overloads for some operators but doesn't provide named alternatives.</problem> + <solution>Add named methods equivalent to the operators for language that do not support them (e.g. VS.NET).</solution> + </rule> <rule Name="TypesShouldBeInsideNamespacesRule" Type="Gendarme.Rules.Design.TypesShouldBeInsideNamespacesRule, Gendarme.Rules.Design, [EMAIL PROTECTED]@, Culture=neutral, PublicKeyToken=null" Uri="" > Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Makefile.am =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Makefile.am 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/Makefile.am 2008-01-19 00:33:30 UTC (rev 93308) @@ -14,15 +14,17 @@ AbstractTypesShouldNotHavePublicConstructorsRule.cs AvoidEmptyInterfaceRule.cs TypesShouldBeInsideNamespacesRule.cs \ AvoidPropertiesWithoutGetAccessorRule.cs MainShouldNotBePublicRule.cs ConsiderConvertingMethodToPropertyRule.cs \ AvoidPublicInstanceFieldsRule.cs MissingAttributeUsageOnCustomAttributeRule.cs \ - AttributeArgumentsShouldHaveAccessorsRule.cs DisposableHelper.cs TypesWithNativeFieldsShouldBeDisposableRule.cs \ + AttributeArgumentsShouldHaveAccessorsRule.cs TypesWithNativeFieldsShouldBeDisposableRule.cs \ TypesWithDisposableFieldsShouldBeDisposableRule.cs DisposableTypesShouldHaveFinalizerRule.cs \ - DisposableFieldsShouldBeDisposedRule.cs FinalizersShouldBeProtectedRule.cs FinalizersShouldCallBaseClassFinalizerRule.cs + DisposableFieldsShouldBeDisposedRule.cs FinalizersShouldBeProtectedRule.cs FinalizersShouldCallBaseClassFinalizerRule.cs \ + EnsureSymmetryForOverloadedOperatorsRule.cs OperatorEqualsShouldBeOverloadedRule.cs \ + OverrideEqualsMethodRule.cs ProvideAlternativeNamesForOperatorOverloadsRule.cs design_rules_build_sources = $(addprefix $(srcdir)/, $(design_rules_sources)) design_rules_build_sources += $(design_rules_generated_sources) ../../bin/Gendarme.Rules.Design.dll: $(design_rules_build_sources) - $(MCS) -debug -target:library -langversion:linq -pkg:mono-cecil -r:../../bin/Gendarme.Framework.dll -out:$@ $(design_rules_build_sources) + $(MCS) -debug -target:library -langversion:linq -pkg:mono-cecil -r:System.Core.dll -r:../../bin/Gendarme.Framework.dll -out:$@ $(design_rules_build_sources) cp Gendarme.Rules.*.xml ../../bin/ # Install Unstable Mono Libraries (see configure.ac) @@ -46,7 +48,9 @@ AvoidPublicInstanceFieldsTest.cs MissingAttributeUsageOnCustomAttributeTest.cs \ AttributeArgumentsShouldHaveAccessorsTest.cs TypesWithNativeFieldsShouldBeDisposableTest.cs \ TypesWithDisposableFieldsShouldBeDisposableTest.cs DisposableTypesShouldHaveFinalizerTest.cs \ - DisposableFieldsShouldBeDisposedTest.cs FinalizersShouldBeProtectedTest.cs FinalizersShouldCallBaseClassFinalizerTest.cs + DisposableFieldsShouldBeDisposedTest.cs FinalizersShouldBeProtectedTest.cs FinalizersShouldCallBaseClassFinalizerTest.cs \ + EnsureSymmetryForOverloadedOperatorsTest.cs OperatorEqualsShouldBeOverloadedTest.cs OverrideEqualsMethodTest.cs \ + ProvideAlternativeNamesForOperatorOverloadsTest.cs design_test_build_sources = $(addprefix $(srcdir)/Test/, $(design_test_sources)) Added: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OperatorEqualsShouldBeOverloadedRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OperatorEqualsShouldBeOverloadedRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OperatorEqualsShouldBeOverloadedRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -0,0 +1,67 @@ +// +// Gendarme.Rules.Design.OperatorEqualsShouldBeOverloadedRule +// +// Authors: +// Andreas Noever <[EMAIL PROTECTED]> +// +// (C) 2008 Andreas Noever +// +// 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 Gendarme.Framework; +using Gendarme.Framework.Rocks; + +namespace Gendarme.Rules.Design { + + public class OperatorEqualsShouldBeOverloadedRule : ITypeRule { + + public MessageCollection CheckType (TypeDefinition type, Runner runner) + { + if (type.IsEnum || type.IsInterface) + return runner.RuleSuccess; + + MessageCollection results = null; + + if (type.HasMethod (MethodSignatures.op_Addition) && type.HasMethod (MethodSignatures.op_Subtraction)) { + if (!type.HasMethod (MethodSignatures.op_Equality)) { + results = new MessageCollection (); + Location loc = new Location (type); + Message msg = new Message ("This type implements the addition (+) and subtraction (-) operators. It should also implement the equality (==) operator.", loc, MessageType.Warning); + results.Add (msg); + } + } + + if (type.IsValueType) { + if (type.HasMethod (MethodSignatures.Equals) && !type.HasMethod (MethodSignatures.op_Equality)) { + if (results == null) + results = new MessageCollection (); + Location loc = new Location (type); + Message msg = new Message ("This type overrides Object.Equals. It should also implement the equality (==) operator.", loc, MessageType.Warning); + results.Add (msg); + } + } + + return results; + } + } +} Added: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OverrideEqualsMethodRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OverrideEqualsMethodRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/OverrideEqualsMethodRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -0,0 +1,53 @@ +// +// Gendarme.Rules.Design.OverrideEqualsMethodRule +// +// Authors: +// Andreas Noever <[EMAIL PROTECTED]> +// +// (C) 2008 Andreas Noever +// +// 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 Gendarme.Framework; +using Gendarme.Framework.Rocks; + +namespace Gendarme.Rules.Design { + + public class OverrideEqualsMethodRule : ITypeRule { + + public MessageCollection CheckType (TypeDefinition type, Runner runner) + { + if (type.IsEnum || type.IsInterface) + return runner.RuleSuccess; + + if (type.HasMethod (MethodSignatures.op_Equality)) { + if (!type.HasMethod (MethodSignatures.Equals)) { + Location loc = new Location (type); + Message msg = new Message ("This type implements the equality (==) operator. It should also override the Object.Equals method.", loc, MessageType.Warning); + return new MessageCollection (msg); + } + } + return runner.RuleSuccess; + } + } +} Added: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ProvideAlternativeNamesForOperatorOverloadsRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ProvideAlternativeNamesForOperatorOverloadsRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/ProvideAlternativeNamesForOperatorOverloadsRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -0,0 +1,112 @@ +// +// Gendarme.Rules.Design.ProvideAlternativeNamesForOperatorOverloadsRule +// +// Authors: +// Andreas Noever <[EMAIL PROTECTED]> +// +// (C) 2008 Andreas Noever +// +// 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.Generic; +using Mono.Cecil; +using Gendarme.Framework; +using Gendarme.Framework.Rocks; + +namespace Gendarme.Rules.Design { + + public class ProvideAlternativeNamesForOperatorOverloadsRule : ITypeRule { + + static string [] NoParameter = new string [] { }; + static string [] OneParameter = new string [] { null }; //new string [1] = one parameter of any type + + + static MethodSignature Compare = new MethodSignature () { Name = "Compare", Parameters = OneParameter }; + + static KeyValuePair<MethodSignature, MethodSignature> [] AlternativeMethodNames = new KeyValuePair<MethodSignature, MethodSignature> [] { + //unary + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_UnaryPlus, new MethodSignature() { Name = "Plus", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_UnaryNegation, new MethodSignature() { Name = "Negate", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_LogicalNot, new MethodSignature() { Name = "LogicalNot", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_OnesComplement, new MethodSignature() { Name = "OnesComplement", Parameters = NoParameter }), + + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Increment, new MethodSignature() { Name = "Increment", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Decrement, new MethodSignature() { Name = "Decrement", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_True, new MethodSignature() { Name = "IsTrue", Parameters = NoParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_False, new MethodSignature() { Name = "IsFalse", Parameters = NoParameter }), + + //binary + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Addition, new MethodSignature() { Name = "Add", Parameters = OneParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Subtraction, new MethodSignature() { Name = "Subtract", Parameters = OneParameter } ), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Multiply, new MethodSignature() { Name = "Multiply", Parameters = OneParameter } ), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Division, new MethodSignature() { Name = "Divide", Parameters = OneParameter } ), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Modulus, new MethodSignature() { Name = "Modulus", Parameters = OneParameter }), + + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_BitwiseAnd, new MethodSignature() { Name = "BitwiseAnd", Parameters = OneParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_BitwiseOr, new MethodSignature() { Name = "BitwiseOr", Parameters = OneParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_ExclusiveOr, new MethodSignature() { Name = "ExclusiveOr", Parameters = OneParameter }), + + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_LeftShift, new MethodSignature() { Name = "LeftShift", Parameters = OneParameter }), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_RightShift, new MethodSignature() { Name = "RightShift", Parameters = OneParameter }), + + // new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Equality, Compare), //handled by OverrideEqualsMethodRule + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_Inequality, Compare), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_GreaterThan, Compare), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_LessThan, Compare), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_GreaterThanOrEqual, Compare), + new KeyValuePair<MethodSignature,MethodSignature> (MethodSignatures.op_LessThanOrEqual,Compare), + }; + + public MessageCollection CheckType (TypeDefinition type, Runner runner) + { + if (type.IsEnum || type.IsInterface) + return runner.RuleSuccess; + + MessageCollection results = null; + + foreach (var kv in AlternativeMethodNames) { + MethodDefinition op = type.GetMethod (kv.Key); + if (op == null) + continue; + bool alternativeDefined = false; + foreach (MethodDefinition alternative in type.Methods) { + if (kv.Value.Matches (alternative)) { + alternativeDefined = true; + break; + } + } + + if (!alternativeDefined) { + if (results == null) + results = new MessageCollection (); + Location loc = new Location (op); + string s = String.Format ("This type implements the '{0}' operator. Some languages do not support overloaded operators so an alternative '{1}' method should be provided.", + kv.Key.Name, kv.Value.Name); + Message msg = new Message (s, loc, MessageType.Warning); + results.Add (msg); + } + } + + return results; + } + } +} Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithDisposableFieldsShouldBeDisposableRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithDisposableFieldsShouldBeDisposableRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithDisposableFieldsShouldBeDisposableRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -53,8 +53,8 @@ bool abstractWarning = false; if (type.Implements ("System.IDisposable")) { - implicitDisposeMethod = type.GetImplicitDisposeMethod (); - explicitDisposeMethod = type.GetExplicitDisposeMethod (); + implicitDisposeMethod = type.GetMethod (MethodSignatures.Dispose); + explicitDisposeMethod = type.GetMethod (MethodSignatures.DisposeExplicit); if (IsAbstractMethod (implicitDisposeMethod)) abstractWarning = true; Modified: trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithNativeFieldsShouldBeDisposableRule.cs =================================================================== --- trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithNativeFieldsShouldBeDisposableRule.cs 2008-01-19 00:30:17 UTC (rev 93307) +++ trunk/cecil/gendarme/rules/Gendarme.Rules.Design/TypesWithNativeFieldsShouldBeDisposableRule.cs 2008-01-19 00:33:30 UTC (rev 93308) @@ -47,8 +47,8 @@ bool abstractWarning = false; if (type.Implements ("System.IDisposable")) { - implicitDisposeMethod = type.GetImplicitDisposeMethod (); - explicitDisposeMethod = type.GetExplicitDisposeMethod (); + implicitDisposeMethod = type.GetMethod (MethodSignatures.Dispose); + explicitDisposeMethod = type.GetMethod (MethodSignatures.DisposeExplicit); if (IsAbstractMethod (implicitDisposeMethod)) abstractWarning = true; _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches