10

I'm writing in C# with ReSharper 8.0 and VS2012 for .NET 4.0.

ReSharper includes an attribute: JetBrains.Annotations.PureAttribute. This is used to provide the inspection "Return value of Pure method is not used".

Code Contracts includes an attribute: System.Diagnostics.Contracts.PureAttribute. This is used by the code contract checking to ensure that the call will produce no visible state changes, and therefore will not require re-checking the object's state.

Currently, to get the functionality of both of these tools, methods need to be annotated with attribute from each. Worse, because they both share the same type name, you need to qualify each attribute.

[Pure]
[Jetbrains.Annotations.Pure]
public bool isFinished() {
    ...

To avoid this situation, there should be three approaches:

  1. write a placeholder recognized by both ReSharper and Contracts
  2. get ReSharper to recognize the Contracts attribute
  3. get Contracts to recognize the ReSharper attribute

Are any of these possible?

Pang
  • 9,564
  • 146
  • 81
  • 122
Varon
  • 33
  • 1
  • 10

2 Answers2

8

ReSharper already understands System.Diagnostics.Contracts.PureAttribute and treats it the same way as JetBrains.Annotations.PureAttribute, so you can just use the one from Code Contracts, and both tools will be happy.

Pang
  • 9,564
  • 146
  • 81
  • 122
citizenmatt
  • 18,085
  • 5
  • 55
  • 60
  • 3
    `System.Diagnostics.Contracts.PureAttribute` is defined with `[Conditional("CONTRACTS_FULL")]`. This means that it won't be visible to ReSharper unless you build with full runtime contract checking, which is not something always desirable. – Varon Mar 04 '14 at 12:30
  • Ah, well spotted. This means ReSharper won't see `PureAttribute` on compiled methods, unless `CONTRACTS_FULL` was defined at the time of compilation. However, ReSharper will still see it in source code - ReSharper only looks at the name of the attribute, not any Conditional settings. – citizenmatt Mar 04 '14 at 13:22
  • It seems that R# 9.2 has forgotten how to interpret `System.Diagnostics.Contracts.PureAttribute` :) – porges Sep 17 '15 at 10:12
2

Approach 3 offers the solution: Jetbrains.Annotations.PureAttribute IS recognized by Contracts.

However, you still will encounter the name conflict problem when using Contracts and PureAttribute in your code. This can be shorthanded with a using statement:using RPure = Jetbrains.Annotation.PureAttribute;

Here's some code that demonstrates the attribute successfully working for Contracts and ReSharper.

public class StatefulExample {

    public int value { get; private set; }

    public StatefulExample() { value = 1; }

    //Example method that would need to be annotated
    [Jetbrains.Annotations.PureAttribute]
    public int negativeValue() { return -value; }

    public static void useSpecificState(StatefulExample test) {
        Contract.Requires(test.value == 1);
    }

    // ---

    public static void pureMethodRequirementDemonstration() {
        StatefulExample initialState = new StatefulExample();
        useSpecificState(initialState);

        StatefulExample possiblyChangedState = new StatefulExample();
        //"Return value of Pure method is not used" here if annotated.
        possiblyChangedState.negativeValue();

        // "Requires unproven: test.value == 1" if NOT annotated.
        useSpecificState(possiblyChangedState);
    }

}
Varon
  • 33
  • 1
  • 10