How to fix violation of StyleCop SA1305 (Hungarian) - c#

My code contains a variable named "m_d3dDevice".
StyleCop complains about this name:
SA1305: The variable name
'm_d3dDevice' begins with a prefix
that looks like Hungarian notation.
Remove the prefix or add it to the
list of allowed prefixes.
(Note I have manually disabled SA1308 ("m_"), one of the few rules I'm willing to disobey.)
I can't allow "d3d" as an exception in the Hungarian tab, as it only allows 1 or 2 char prefixes, and allowing "d3" didn't help. I've tried everything I can think of to add "d3d" to my CustomDictionary file (and anyway the docs imply the CustomDict isn't used for rule 1305).
Any suggestions to make StyleCop allow this one? It is a matter of pride now to not have to F2 my variable.

You can also suppress stylecop on a case-by-case basis. e.g.
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "Using Win32 naming for consistency.")]
IntPtr hFile;
This might not be an attractive option if you have numerous offending names, but for one or two, it's generally fine.

You can also use the Settings.StyleCop in the package files to configure the settings.
You can suppress specific words by adding below code to the Settings.StyleCop file:
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
<AnalyzerSettings>
<CollectionProperty Name="Hungarian">
<Value>as</Value>
<Value>do</Value>
<Value>id</Value>
<Value>if</Value>
<Value>in</Value>
<Value>ip</Value>
<Value>is</Value>
<Value>mx</Value>
<Value>my</Value>
<Value>no</Value>
<Value>on</Value>
<Value>to</Value>
<Value>ui</Value>
<Value>vs</Value>
<Value>x</Value>
<Value>y</Value>
<Value>z</Value>
<Value>iOS</Value>
<Value>IOS</Value>
</CollectionProperty>
</AnalyzerSettings>
</Analyzer>
You can suppress the Hungarain Rule itself by adding the following to the Settings.StyleCop file
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
<Rules>
<Rule Name="FieldNamesMustNotUseHungarianNotation">
<RuleSettings>
<BooleanProperty Name="Enabled">
False
</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
</Analyzer>

You could take a look at StyleCop+.
It contains flexible naming rules that will allow you to force all private fields be named starting with "m_" (or whatever you wish) instead of disabling name checking (like you did).
Regarding "d3dDevice" - it's a very interesting case. Logically, it splits to the following words - { "d", "3", "d", "Device" } or { "d3", "d", "Device" }. And the second "d" seems not to follow "camelNotation".
But, I strongly believe that static analysis (particularly naming) should be flexible enough to satisfy user needs. Currently StyleCop+ can support your case in the following way - for example, you can add "exception" (as many as you want) to naming template for private fields, so that it will look like:
m_$(aaBb)
m_d3d$(AaBb)
This is more likely to be workaround, but I will think about your "d3d" case - and maybe StyleCop+ will support something like this.
Thank you for the interesting example!

Adding suppression attribute should be done on top of all methods which will take time and a long process.
If you would like to remove this rule from your project try this
Right click on your project
Select Stylecop Settings
Find SA1305
Uncheck the rule from result set
Click Apply - OK
Rerun style cop rules again.

Related

Custom naming rules in ReSharper

The project I'm working on (C# on VS 2015 with ReSharper 2016.1.2) has a new requirement which requires us to remove all usages of p_ prefixes in parameter names (p_Param becomes param).
I'd like to create a ReSharper Code Inspection Custom Pattern to take care of this for me (to match the string pattern with squiggly lines and auto-fix in the solution).
I've followed the tutorial at https://www.jetbrains.com/help/resharper/2016.1/Code_Inspection__Creating_Custom_Inspections_and_QuickFixes.html but I'm a bit stuck.
I've tried the following patterns:
Var 1
Find: $prefix$$varName$ ($prefix$ - identifier, matching regex [^p_*] (start with p_, continue with anything, $varName$ - identifier)
Replace $varName$
Var 2
Find: p_$varName$ ($varName$ - identifier)
Replace $varName
I'd also need to transform the $varName$ identifier from PascalCase to cammelCase (no ideea how to do this).
When searching via 'Search now' - no results are found in either situation.
Any help is appreciated.
Using ReSharper, you can change the naming style of variables and have it apply to an entire solution.
The location of this option will (probably) vary but for my version of R# (2016.1.2), it's under ReSharper->Options->Code Editing->C#->Naming Style:
From there, change the Entity Kinds to how you want them to appear. In mine, I prefer _lowerCamelCase for private instance fields for example.
Once your changes are made, find any field of that type in code (I'll use a private variable) that doesn't follow that format, click it and then click the light bulb to the left. From there mouse-over the arrow on "Rename to ......" and select Fix naming in solution.
You might have to do it a few times but that's how I rename stuff based on my preferred code style.

Automated refactoring: Add an argument to all method invocations

So, in my ASP.NET C# code base I have possibly hundreds of bits of code like this:
Response.Redirect("something.aspx?Error=" + ex.Message);
I want to automatically add an argument to all of these method calls to add 'true' as the second parameter to this method, like this:
Response.Redirect("sometihng.aspx?Error=" + ex.Message, true);
I have Visual Studio 2010 and the latest version of Resharper at my disposal.
I tried using the 'Search with Pattern' feature in Resharper (VS menu -> ReSharper -> Find -> Search with Pattern) to see if this would automatically refactor my codebase, but I'm not sure exactly how or if it works. Here's what I tried:
On the right-hand side, I created an 'Argument' placeholder called 'anyString', in the hope that this would find and replace all invocations of Response.Redirect that have a string in the first argument, but this found no matches in my code-base.
Any ideas on how I might solve this without resorting to manually changing all references?
As per the Jetbrains Resharper documentation on 'Searching a Code with Pattern':
Pay attention, that when you use a placeholder, its name should be
enclosed with dollar signs (use the syntax $xx$, where xx represents
placeholder name),whereas when you create a new placeholder, you
should omit these special symbols.
Therefore, I was on the right track. Also for the placeholder I just need '$anyString$' and it will find all invocations of the method, even if they are made up multiple string objects (e.g. string literals and string objects). So this is how it would look:
The 'anyString' placeholder pattern was created by performing the following steps:
1) Click 'Add Placeholder' -> Argument
2) Give it a name, e.g. 'anyString'
For my case, I also checked the 'Limit minimal number of arguments' and selected 1, and I also checked the 'Maximal' box and set that to 1 also.
The 'Save' button is also useful if you intend on reusing the pattern again.

How do I make FxCop understand a 'multi-case' word?

I work in a company that their acronym is something like XyZ (uppercase followed by lowercase than followed by uppercase again).
This word is spread across all our namespaces. When I run FxCop against our projects it accuses IdentifiersShouldBeCasedCorrectly (CA1709). The suggestion is to capitalize just the first letter (what I don't want).
How do I make FxCop understand that the word XyZ is known, spelled correctly and properly cased? (In other words, that is well-written).
I added the word to the CustomDictionary.xml file: I've added to Recognized words; Unrecognized words; and alsoAcronyms with CasingExceptions. None of these made any effect.
I also verified that FxCop is indeed reading the custom dictionary file, when I add another word in the acronym it stops reporting as a casing error as expected (but only for all caps words).
I'm using FxCop 1.36 (the GUI one) with C# projects.
Update
Adding just Xy to casing exceptions seems to make FxCop ignore XyZ as I want.
Still not a great solution since it will allow wrong words like XyX or XyW when the (only) correct one is XyZ.
You can add XyZ to an FxCop dictionary - see How to: Customize the Code Analysis Dictionary.
Code Analysis uses a built-in dictionary to check identifiers in your code for
errors in spelling, grammatical case, and other naming conventions of the .NET
Framework guidelines. You can create a custom dictionary Xml file to add,
remove, or modify terms, abbreviations, and acronyms to the built-in dictionary.
Dictionary/Acronyms/CasingExceptions/Acronym
<Dictionary>
<Acronyms>
<CasingExceptions>
<Acronym>NESW</Acronym> <!-- North East South West -->
...
</CasingExceptions>
...
</Acronyms>
...
</Dictionary>
Terms in the Dictionary/Acronyms/CasingExceptions node are applied to the following code analysis rules:
CA1709: Identifiers should be cased correctly

Dictionary<string,List<service>> not allowed in staruml

I am using whitestaruml 5.4
with class diagram, i can't seem to be able to type this attribute
ServiceCategory: Dictionary<string,List<service>>
But Dictionary<string,List<service>> is a valid type for C#, how to get over this?
I suppose you are getting a lexical error on '<' as currently the input analyzer in WhiteStarUML does not accept embedded delimiters ( <[( style ) in the entity names to better handle matching opening/closing at lexer level. In the future this may get more sophisticated but currently the best way to skip parsing is to select the attribute in Model Explorer and fill the "Type" field in Property Inspector. As no parsing happens there it will be accepted. Just make sure not to modify the attribute in the Model View on the Diagram again.
It's June 2022 - still not fixed. Very disappointing.
When directly entering attributes, I just put a placeholder type (e.g., 'foo'). After which, you can go click on the attribute on the right pane and go down to the Editors / type field and replace it with what you want.
I use a lot of map<string,string> and have to do this often. If you try to directly edit a method and its arguments later, it will block you again and you'll have to repeat the procedure - but it can be done to make your diagrams correct. It's just a PITA.

StyleCop/FxCop 10 - How do you properly suppress a message only on a namespace level?

FxCop 10 is complaining about the following:
using XYZ.Blah; //CA1709 - "XYZ"
using Xyz.Blah; //No complaint.
using XylophoneSuperDuperLongFullName.Blah; //I don't want to have a long full name for my company name.
The problem is... I want my company name to show up in all UPPERCASE because XYZ is an abbreviation. The long version of the name is much too long to be a useful namespace. Microsoft gets away with this kind of stuff because their acronym is only 2 letters.
using MS.Something; //No Complaint.
using Microsoft.SomethingElse; //No Complaint.
So, I was looking at adding a SuppressMessageAttribute to suppress this warning. But, I'm not sure how to do so properly to only (or where to even stick it) so that it ONLY affects this one instance. I don't want to Suppress anything within that namespace because I want to catch any other mistakes I make. I did look at at the msdn and google searched but I can't find anything that shows how to specifically just target this instance. The closest I found was Scope = "namespace" but I wasn't sure if that means it affects the actual namespace name or if it affects everything WITHIN that namespace.
MSDN - CA1709: Identifiers should be cased correctly:
It is safe to suppress this warning if
you have your own naming conventions,
or if the identifier represents a
proper name, for example, the name of
a company or a technology.
You can also add specific terms,
abbreviations, and acronyms that to a
code analysis custom dictionary. Terms
specified in the custom dictionary
will not cause violations of this
rule. For more information, see How
to: Customize the Code Analysis
Dictionary.
That being said, if you feel justified to suppress the message, it really isn't hard at all. In FxCop 10 right click on any message you want to suppress and go to Copy As>Suppress-Message or Copy As>Module-level Suppress Message.
You should place the SuppressMessageAttributes in the appropriate locations. Attributes that suppress a single location should be placed on that location, for example, above a method, field, property, or class.
In you're instance, there is no specific location to place the attribute (by default it should copy over as [module: SuppressMessage(...)]. This is a good indication that it belongs either at the top of a file if it is a module-level suppression particular to a file (for example, to a resource specific to a file). Or, and more likely, it belongs in a GlobalSuppressions.cs file.
using System.Diagnostics.CodeAnalysis;
[module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Justification = "Because I said so!", MessageId = "XYZ", Scope = "namespace", Target = "XYZ.Blah")]
You can also shorten the CheckId property if you want to, but it's good to know what CA1709 means. If you don't feel like it, this also works:
using System.Diagnostics.CodeAnalysis;
[module: SuppressMessage("Microsoft.Naming", "CA1709", Justification = "Because I said so!", MessageId = "XYZ", Scope = "namespace", Target = "XYZ.Blah")]
And lastly... all this will be fruitless unless you include the 'CODE_ANALYSIS' symbol in your build. Go to Properties>Build and add the conditional compilation symbol.
Acryonyms aren't meant to be all upper case in .NET naming conventions. For example HttpResponse etc.
From the capitalization conventions:
Casing of acronyms depends on the length of the acronym. All acronyms are at least two characters long. For the purposes of these guidelines, if an acronym is exactly two characters, it is considered a short acronym. An acronym of three or more characters is a long acronym.
The following guidelines specify the proper casing for short and long acronyms. The identifier casing rules take precedence over acronym casing rules.
Do capitalize both characters of two-character acronyms, except the first word of a camel-cased identifier.
A property named DBRate is an example of a short acronym (DB) used as the first word of a Pascal-cased identifier. A parameter named ioChannel is an example of a short acronym (IO) used as the first word of a camel-cased identifier.
Do capitalize only the first character of acronyms with three or more characters, except the first word of a camel-cased identifier.
A class named XmlWriter is an example of a long acronym used as the first word of a Pascal-cased identifier. A parameter named htmlReader is an example of a long acronym used as the first word of a camel-cased identifier.
If you were checking names via StyleCop, you could use StyleCop+ (custom rules) which supports configurable abbreviations list.

Categories