SergeyTeplyakov / ReSharperContractExtensions

Set of extensions for R# that simplifies Design by Contract programming using Code Contracts.
MIT License
69 stars 10 forks source link

Bogus Malformed Method Contract Error #43

Closed mcetkovsky closed 10 years ago

mcetkovsky commented 10 years ago

The line "Contract.Ensures" generates a warning. However, I do not see it as a bogus as it, based on my opinion, matches the sample at http://msdn.microsoft.com/EN-US/library/dd412873(v=VS.110,d=hv.2).aspx.

[ContractClass(typeof(CDeleteCommandContract<>))]
public interface IDeleteCommand<T>
    where T : class
{
    [NotNull]
    Task<bool> RunAsync(int id);
}

[ContractClassFor(typeof(IDeleteCommand<>))]
public abstract class CDeleteCommandContract<T> : IDeleteCommand<T>
    where T : class
{
 public Task<bool> RunAsync(int id)
    {
        Contract.Ensures(Contract.Result<Task<bool>>() != null);

        return Task.FromResult(false);
    }
}

The warning states: Detected a call to to Contract.Result() in method RunAsync with return type Task.

The issues are the following: 1) You do not seem to support a generic type as a return type. 2) The text is not helpful at all (it reports an observation, not an issue).

SergeyTeplyakov commented 10 years ago

Thanks a lot. It is a definitely a bug.

Will change an error message as well.

For instance, for the following code:

public string Foo()
{
    Contract.Ensures(Contract.Result<StringBuilder>() != null);
    throw new NotImplementedException();
}

Code Contract Compiler emmits following error: Detected a call to Result with 'System.Text.StringBuilder', should be 'System.String'.

mcetkovsky commented 10 years ago

I vote for a text like: The type System.Text.StringBuilder used in Contract.Result<System.Text.StringBuilder>() does not match the method's return type System.Text.String.

SergeyTeplyakov commented 10 years ago

I really like your version, except two points: 1) wrong type presented twice in the message (please note, that I shoudl try to show this message in one line) and 2) this message is far from the error from the Code Contract Complier.

I'm trying to stay as close as possible to Code Contract Compiler error messages. Unfortunately in some cases they're inconsistent and cryptic. For instance, some of them do have a method name, but some of them don't.

So for know I'll stay with following version: "Detected a call to Result with 'Task' in method 'Foo', should be Task.

Later on, I'll create a separate task and refine all error messages that I have (and I would like to discuss all of them at once. In this case I would be able to change them consistently).

SergeyTeplyakov commented 10 years ago

FIx will be available during next release.

image