Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Four Gendarme rules to check for operators overloading #76

Closed
GoogleCodeExporter opened this issue Jun 3, 2015 · 14 comments
Closed

Four Gendarme rules to check for operators overloading #76

GoogleCodeExporter opened this issue Jun 3, 2015 · 14 comments

Comments

@GoogleCodeExporter
Copy link

This task is to create four (4) rules for Gendarme [1] to check for some
common issue around operator overloading.

1. Gendarme.Rules.Design.OperatorEqualsShouldBeOverloadedRule

This rule should trigger a warning in two cases:
(a) if operators add (+) and subtract (-) are overloaded (note: if only one
is then rule #2 will kick in)
(b) if method Equals is overidden on a struct (value type)


2. Gendarme.Rules.Design.EnsureSymmetryForOverloadedOperatorsRule

This rule ensure that overloads for both:
(a) == and != (note: the C# compiler will give an error for this rule - but
other languages, like IL, can do this)
(b) + and -, * and /, < and >, <= and >=
are always supplied in pair. (a) should return an error, while (b) should
be warnings.


3. Gendarme.Rules.Design.OverrideEqualsMethodRule

The rule should warn if equals operator has been overloaded but the Equals
method wasn't.


4. Gendarme.Rules.Design.ProvideAlternativeNamesForOperatorOverloadsRule
Some languages (like VB.NET) cannot use overloaded operators. Having named
methods is the only way to provide the same level of functionality to those
languages. E.g. Add, Subtract, Multiply, Divide, Mod, Compare (note: #3 is
taking care of Equals)


So four rules for Gendarme, most of them easy. Rule #2 is a bit tricker
because it requires to use Cecil to build the test case, since it cannot be
done using C# itself.

To complete the task it must include:
- the rules source code;
- unit tests to ensure the rules works correctly;
- documentation for the web site (see [2] for an example)

This tasks should take between 2-5 days (depending if you already know
Gendarme/Cecil or not).

[1] http://www.mono-project.com/Gendarme
[2] http://groups.google.com/group/gendarme

Original issue reported on code.google.com by sebastie...@gmail.com on 15 Jan 2008 at 2:06

@GoogleCodeExporter
Copy link
Author

I claim this task.

Original comment by andreas....@gmail.com on 15 Jan 2008 at 10:36

@GoogleCodeExporter
Copy link
Author

It's yours!

Original comment by sebastie...@gmail.com on 15 Jan 2008 at 12:47

  • Changed state: Claimed
  • Added labels: ClaimedBy-andreas.noever, DueDate-2008-01-22

@GoogleCodeExporter
Copy link
Author

EnsureSymmetryForOverloadedOperatorsRule

It seems that using one of >,< or <=, >= without implementing the corresponding
operator also yields an error in c#. Maybe those should be promoted to
MessageType.Error in the rule?

Documentation follows in a few hours :-)

Andreas Noever

Original comment by andreas....@gmail.com on 15 Jan 2008 at 3:26

Attachments:

@GoogleCodeExporter
Copy link
Author

> Maybe those should be promoted to MessageType.Error in the rule?

yes (I hadn't tested them all :-)

Original comment by sebastie...@gmail.com on 15 Jan 2008 at 3:33

@GoogleCodeExporter
Copy link
Author

It's not part of the task but it would be nice to generalize the method
    public static MethodDefinition GetEquals (this TypeDefinition self)

into a (or a few) rock(s) for TypeDefinition (which would be reusable in quite 
a few
rules :-)

E.g. an extention method where you can specify the method name (string), return 
value
(as a string), mask (as MethodAttribute) and parameter types (as params string).

So if you have a bit of time before I can review the task tonight feel free to 
"rock" :-)

Original comment by sebastie...@gmail.com on 15 Jan 2008 at 8:03

@GoogleCodeExporter
Copy link
Author

This is a small usage experiment for the discussed MethodSignature class. I have
converted all four rules.

Note: MethodSignature and TypeRocks do currently not have UnitTests for 
themselves.
They are only tested through the rule's tests.

The only other change is the MessageType change for <,> etc.

Andreas Noever

Original comment by andreas....@gmail.com on 15 Jan 2008 at 10:44

Attachments:

@GoogleCodeExporter
Copy link
Author

General note: Oops, it seems I really underestimated the numbers of operator 
that can
be overloaded.
ref: http://msdn2.microsoft.com/en-us/library/8edha89s(VS.80).aspx
I'm glad your code is nicely structured. It should be easy to add them :)

OperatorHelper.cs
* I like them :) so much that I think, for MethodSignature, that you should add 
a
HasMethod rock returning a boolean (simply a GetMethod != null) - since it 
seems most
of the time we're checking for the method existence only (and that would help
readability ;-)

EnsureSymmetryForOverloadedOperatorsTest.cs
* EverythingOk doesn't contains operators == and !=
* >, >=, < and <= should return bool (actually I'm amazed this compiles... maybe
another rule should check this, but that's outside this task ;-)

OperatorEqualsShouldBeOverloadedRule
* great :)

OverrideEqualsMethodRule
* great :)

ProvideAlternativeNamesForOperatorOverloadsRule
will review it later...

Original comment by sebastie...@gmail.com on 16 Jan 2008 at 2:02

@GoogleCodeExporter
Copy link
Author

ProvideAlternativeNamesForOperatorOverloadsRule
* nice design, it should be easy to add all missing operators :)
* new string[1] should be defined once (static) and re-used (nice trick, needs 
to be
documented)
* unit tests have comparison operators returning non-bool (same comment as 
before)

I'll test for false-positives tomorrow but I don't expect to see much - since
operator overloading isn't very common in the .net framework. A part from that 
only
the documentation is missing.

Original comment by sebastie...@gmail.com on 16 Jan 2008 at 3:25

@GoogleCodeExporter
Copy link
Author

EnsureSymmetryForOverloadedOperatorsRule
* output message isn't helpful, e.g. "This type implements an operator
(Gendarme.Rules.Design.MethodSignature). It should also implement the symmetric
operator Gendarme.Rules.Design.MethodSignature."

ProvideAlternativeNamesForOperatorOverloadsRule
same, e.g. "This type implements an operator 
(Gendarme.Rules.Design.MethodSignature).
Some .Net languages do not support overloaded operators. An alternative named 
method
(Gendarme.Rules.Design.MethodSignature) should be provided."

Otherwise results are fine :)

Original comment by sebastie...@gmail.com on 16 Jan 2008 at 2:27

@GoogleCodeExporter
Copy link
Author

Gendarme.Rules.Design.OperatorEqualsShouldBeOverloadedRule

This rule checks if the operators add (+) and subtract (-) are overloaded OR if 
a
value type overrides Object.Equals and warns if the equals (==) operator is not
overloaded.

Bad Example:

class DoesNotOverloadOperatorEquals {
    public static int operator + (DoesNotOverloadOperatorEquals a) { return 0; }
    public static int operator - (DoesNotOverloadOperatorEquals a) { return 0; }
}

struct OverridesEquals {
    public override bool Equals(object obj)
    {
        return base.Equals (obj);
    }
}

Good Example:

struct OverloadsOperatorEquals {

    public static int operator + (OverloadsOperatorEquals a) { return 0; }
    public static int operator - (OverloadsOperatorEquals a) { return 0; }
    public static bool operator == (OverloadsOperatorEquals a, OverloadsOperatorEquals
b) { return a.Equals (b); }

    public override bool Equals (object obj)
    {
        return base.Equals (obj);
    }
}

Gendarme.Rules.Design.EnsureSymmetryForOverloadedOperatorsRule

This rule checks for operators that are not overloaded in pairs. The C# compiler
forces you to implement some of the pairs, but other languages might not.
The following pairs are checked:

Warnings:
Addition / Subtraction
Multiply / Division
Division / Modulus

Errors:
Equality / InEquality
True / False
GreaterThan / LessThan
GreaterThanOrEqual / LessThanOrEqual

Bad Example:

class DoesNotOverloadAdd {
    public static int operator - (DoesNotOverloadOperatorEquals a) { return 0; }
}

Good Example:

struct OverloadsAdd {
    public static int operator + (OverloadsOperatorEquals a) { return 0; }
    public static int operator - (OverloadsOperatorEquals a) { return 0; }
}


Gendarme.Rules.Design.OverrideEqualsMethodRule

This rule generates a warning if a type overloads the Equality (==) operator 
but does
not override the Object.Equals method.

Bad Example:

class DoesNotOverrideEquals {
    public static bool operator == (DoesNotOverloadOperatorEquals a,
DoesNotOverloadOperatorEquals b) { return true; }
}

Good Example:

class OverridesEquals {
    public static bool operator == (DoesNotOverloadOperatorEquals a,
DoesNotOverloadOperatorEquals b) { return true; }

    public override bool Equals (object obj)
    {
        OverridesEquals other = obj as OverridesEquals;
        if (other == null)
            return base.Equals (obj);
        else
            return this == (OverridesEquals)obj;
    }
}


Gendarme.Rules.Design.ProvideAlternativeNamesForOperatorOverloadsRule

Some languages (like VB.NET) cannot use overloaded operators. For those 
languages
named methods should be implemented that provide the same functionality. This 
rule
checks for a named alternative for each overloaded operator.

op_UnaryPlus => "Plus"
op_UnaryNegation => "Negate"
op_LogicalNot => "LogicalNot"
op_OnesComplement => "OnesComplement"

op_Increment => "Increment"
op_Decrement => "Decrement"
op_True => "IsTrue"
op_False => "IsFalse"

op_Addition => "Add" 
op_Subtraction => "Subtract"
op_Multiply => "Multiply"
op_Division => "Divide"
op_Modulus => "Modulus"

op_BitwiseAnd => "BitwiseAnd"
op_BitwiseOr => "BitwiseOr"
op_ExclusiveOr => "ExclusiveOr"

op_LeftShift => "LeftShift"
op_RightShift => "RightShift"

op_Inequality => "Compare"
op_GreaterThan => "Compare"
op_LessThan => "Compare"
op_GreaterThanOrEqual => "Compare"
op_LessThanOrEqual => "Compare"

Bad Example:

class DoesNotImplementAlternative {
    public static int operator + (DoesNotOverloadOperatorEquals a,
DoesNotOverloadOperatorEquals b) { return 0; }
}

Good Example:

class DoesImplementAdd {
    public static int operator + (DoesNotOverloadOperatorEquals a,
DoesNotOverloadOperatorEquals b) { return 0; }
    public int Add (DoesNotOverloadOperatorEquals a) { return this + a; }
}

Original comment by andreas....@gmail.com on 16 Jan 2008 at 8:16

Attachments:

@GoogleCodeExporter
Copy link
Author

Hey, I wonder if your last archive was totally up to date.
EnsureSymmetryForOverloadedOperatorsRule fails 4 tests and doesn't seems to use 
the
new HasMethod rock ? could it be an old version ?

Original comment by sebastie...@gmail.com on 17 Jan 2008 at 1:06

@GoogleCodeExporter
Copy link
Author

ParameterNamesShouldMatchOverridenMethodRule.SignatureMatches should be static 
(a
gendarme rule ;-)

Otherwise all else seems fine!

Original comment by sebastie...@gmail.com on 17 Jan 2008 at 6:24

@GoogleCodeExporter
Copy link
Author

Added documentation and test cases for the rocks / MethodSignature. The file is 
still
called OperatorHelper.cs. needs to be merged with TypeRocks.

Andreas Noever

Original comment by andreas....@gmail.com on 17 Jan 2008 at 7:51

Attachments:

@GoogleCodeExporter
Copy link
Author

Closing

thanks a lot!

Original comment by sebastie...@gmail.com on 17 Jan 2008 at 9:02

  • Changed state: Closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant