I recently installed Code Contracts Tools (Code Contracts for .NET) and Code Contracts Editor Extensions VS2012, and I'm having some trouble getting the static checker to work properly.
When I run Code Contracts' static checker on the following code (with the second assumption commented out)
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
public class TestClass
{
public ReadOnlyCollection<byte> Foo()
{
Contract.Ensures(Contract.Result<ReadOnlyCollection<byte>>().Count == 4);
IList<byte> list = new byte[4];
Contract.Assume(list.Count == 4);
var returnValue = new ReadOnlyCollection<byte>(list);
//Contract.Assume(returnValue.Count == 4);
return returnValue;
}
}
I get an "ensures unproven" warning reading:
CodeContracts: ensures unproven:
Contract.Result<ReadOnlyCollection<byte>>().Count == 4
It claims that the ensures of the Foo
method is unproven. However, when I mouse over the constructor of ReadOnlyCollection<T>
, I can tell that the Count
property of the constructed object is ensured to be equal to the Count
property of the list
parameter:
That is, the static checker ought to be able to tell that returnValue.Count == 4
(i.e. the ensures of Foo
) holds true. If I uncomment the second assumption, the warning does disappear, but assuming that the ensures of my method holds true very much defeats the purpose of the static checker.
I think that the problem might be that only the editor extension is aware of the contract reference assembly containing the ensures for the constructor (mscorlib.Contracts.dll), so it lists contracts that the static checker is unaware of.
I've tried tinkering with the project-wide Extra Contract Library Paths setting to no avail, and I don't think that that is the right way to solve the problem.
Am I right in my reasoning that the static checker is not configured properly with the contract reference assembly or am I missing something else? If I'm right, how would I go about fixing the configuration?
I'm using
- Visual Studio Ultimate 2012 Update 3
- Code Contracts Tools version 1.5.60502.11
- Code Contracts Editor Extensions VS2012 version 1.5.64024.12
Edit: The static checker does seem to find the contract reference assemblies, and it works as I first expected it would with other classes and even methods of the ReadOnlyCollection<T>
class. Static analysis of, for instance, the following method works just fine.
public int Boo()
{
Contract.Ensures(-1 <= Contract.Result<int>());
Contract.Ensures(Contract.Result<int>() < 4);
IList<byte> list = new byte[4];
var collection = new ReadOnlyCollection<byte>(list);
Contract.Assume(collection.Count == 4);
return collection.IndexOf(0);
}
The assumption about the Count
property is required because the ensures of the constructor still does not work. The ensures of the IndexOf
method, on the other hand, works very well.
Now all I wonder is why the static checker does not recognize the ensures of the ReadOnlyCollection<T>
constructor. Could it be a bug in the static analyzer?