27

I'm making an extension to Visual Studio. Within the code I'm using Code Contracts to make assertions and checks. I set the warning option level to high.

What I would like to do is maintain that warning level while ignoring any checks made on EnvDTE references.

Consider the following code example:

public static string GetAbsoluteOutputFolder(EnvDTE.Project project)
{
    if (project == null) throw new ArgumentNullException("project");

    var path =
        project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
    //...
}

With my current settings, CC would require me to add the following checks before assigning the path variable:

Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);

Therefore what I'd like to do here is to tell CC to "trust" EnvDTE and ignore these types and their properties.

I thought the "Be optimistic on external API" CC option served this very purpose; turns out it doesn't.

Is there a way to make it behave the way I want that would not require a lower warning level?

EDIT: I want a solution that would work at project level and that would still allow "regular" checks to be performed.

2
  • 1
    If it was me I would just add the Checks you want to omit. If your code blows up because of a Null Reference someplace in EnvDTE.Project having those checks should let you know exactly where the problem is instead of trying to guess where the Null is. Commented Dec 4, 2014 at 20:51
  • @MikeBurdick The thing is that some of these properties are very likely never null. But since that assembly wasn't compiled with contracts, there's no way for the engine to tell. Therefore it treats these as it would any properties without contracts, forcing the use of pointless checks for the same property over and over again. If there was a global, do-it-once way to enforce that Configuration.Properties (for example) never returns null I'd gladly use it but there isn't. So IMHO the lesser evil would be to tell CC to simply ignore any code that belongs to that specific assembly. Commented Mar 5, 2015 at 17:20

3 Answers 3

4

Can´t provide a detailed solution but this should be solvable by using either the Baseline Feature or System.Diagnostics.CodeAnalysis.SuppressMessage on assembly level:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")]

You can use the "Target" Property of the SuppressMessageAttribute to only ignore the Message on specific Types / Methods / Namespaces:

[SuppressMessage("Microsoft.Contracts", 
                 "CC1055", 
                 Scope="Member", 
                 Target="YouNamespace.EnvDTE.Project")]

Note that the Parameters i used are just a good bet, you´ll have to figure out the correct Scope, MessageId and Target yourself :) On a sidenote, i think the Attribute is Conditional("CODE_ANALYSIS").

The official suggested solution to this problem is to create some sort of wrapper, in your case probably a repository that would create or contain your EnvDTE.Project objects. Then you can add the required Contract.Ensures there.

Sign up to request clarification or add additional context in comments.

2 Comments

How can I place an assembly level warning if I don't own the code for said assembly?
@Crono: You can suppress Messages on external libs by using the "Target" Property of the SuppressMessageAttribute, i´ll add that to the answer.
1

I don't think it's possible to solve the problem but since C# 6.0 there is a workaround which at least eases the pain a bit:

Instead of

Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);

you can now write

Contract.Assume(project.ConfigurationManager?.ActiveConfiguration?.Properties != null);

Comments

0

Have you tried something with : [assembly: Contracts.ContractVerification(false)] at the assembly level ?

You should be able to do it dynamically : https://msdn.microsoft.com/en-us/library/bb458043.aspx

Hope this helps,

1 Comment

If I understand this attribute correctly it will only prevent contract verification in that assembly. What OP wants is to ignore all warnings created by using the assembly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.