This repository contains Code Fixes for Roslyn that help to remove CodeContracts from source code.
List of provided analyzers and code fixes (in the order of application):
- CR01_RetrieveCodeContractFromBase - indicates that the
Contract.Requires
method can be retrieved from Contract class of from base class; - CR02_RequiresGenericToIfThrow - indicates that
Contract.Requires<TException>()
method should be replaced with if...throw statement; - CR03_ContractToDebugAssertReplace - indicates that
Contract.Requires()
,Contract.Assert()
andContract.Assume()
should be replaced withDebug.Assert()
; - CR04_EliminateCallsToContractMethods - indicates that all other
Contract
methods (Ensure, EnsureOnThrow, etc.) should be removed from source code; - CR05_EliminateContractClass - indicates that Contract class (class that marked with
ContractClassForAttribute
) can be removed from source code; - CR06_EliminateInvariantMethods - indicates that Contract invariant method (method marked with
ContractInvariantMethodAttribute
) can be removed from source code.
Download compiled version of library from binary folder or compile it from sources. Add ContractRemover.dll as roslyn analyzer to your project. Apply all fixes in the order stated above.
- CR01_RetrieveCodeContractFromBase
public class TestImpl : TestAbstract
{
public override void Method1(string val)
{
throw new NotImplementedException();
}
}
[ContractClass(typeof(TestAbstractCC))]
public abstract class TestAbstract
{
public abstract void Method1(string val);
}
[ContractClassFor(typeof(TestAbstract))]
abstract class TestAbstractCC : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null);
throw new NotImplementedException();
}
}
will be translated to
public class TestImpl : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null); // This line was extracted from TestAbstractCC
throw new NotImplementedException();
}
}
[ContractClass(typeof(TestAbstractCC))]
public abstract class TestAbstract
{
public abstract void Method1(string val);
}
[ContractClassFor(typeof(TestAbstract))]
abstract class TestAbstractCC : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null);
throw new NotImplementedException();
}
}
- CR02_RequiresGenericToIfThrow
static void Method(string val, int data)
{
Contract.Requires<ArgumentNullException>(val != null);
Contract.Requires<ArgumentOutOfRangeException>(data >= 0);
}
will be translated to
static void Method(string val, int data)
{
if (val == null)
throw new ArgumentNullException(nameof(val));
if (data < 0)
throw new ArgumentOutOfRangeException(nameof(data), "data >= 0");
}
- CR03_ContractToDebugAssertReplace
static void Method(string val, int data)
{
Contract.Requires(val != null);
Contract.Assert(data >= 0);
}
will be translated to
static void Method(string val, int data)
{
Debug.Assert(val != null, "val != null");
Debug.Assert(data >= 0, "data >= 0");
}
- CR04_EliminateCallsToContractMethods
static int Method(string val, int data)
{
Contract.Ensures(Contract.Result<int>() > 0);
}
will be translated to
static int Method(string val, int data)
{
}
- CR05_EliminateContractClass
public class TestImpl : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null);
throw new NotImplementedException();
}
}
[ContractClass(typeof(TestAbstractCC))]
public abstract class TestAbstract
{
public abstract void Method1(string val);
}
[ContractClassFor(typeof(TestAbstract))]
abstract class TestAbstractCC : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null);
throw new NotImplementedException();
}
}
will be translated to
public class TestImpl : TestAbstract
{
public override void Method1(string val)
{
Contract.Requires(val != null);
throw new NotImplementedException();
}
}
public abstract class TestAbstract
{
public abstract void Method1(string val);
}
- CR06_EliminateInvariantMethods
public class TestImpl : TestAbstract
{
public string Data { get; set; }
[ContractInvariantMethod]
private void Invariant()
{
Contract.Invariant(Data != null);
}
}
will be translated to
public class TestImpl : TestAbstract
{
public string Data { get; set; }
}