-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DON'T MERGE] Review additional coding style suggestions #8347
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -39,6 +39,8 @@ int CallerTwo() => Leaf() + PublicMethod(); | |||||||||
int Leaf() => 42; | ||||||||||
``` | ||||||||||
|
||||||||||
Do not use auto-implemented private properties. Use fields instead. | ||||||||||
|
||||||||||
### Local functions | ||||||||||
|
||||||||||
There are no strict rules on when to use local functions. It should be decided on a case-by-case basis. | ||||||||||
|
@@ -97,18 +99,42 @@ public void MethodB() | |||||||||
|
||||||||||
## Naming conventions | ||||||||||
|
||||||||||
Generic words in class names that don't convey meaning (e.g. `Helper`) should be avoided. Overwordy and complex names should be avoided as well. | ||||||||||
### Principles | ||||||||||
|
||||||||||
Keep it minimal and suggestive. | ||||||||||
- Generic words that don't convey meaning (e.g. `Helper`) should be avoided. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
- Overwordy and complex names should be avoided as well. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
- Use positive naming when possible. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an example:
|
||||||||||
|
||||||||||
### Casing | ||||||||||
|
||||||||||
Protected fields should start with lowercase letter. | ||||||||||
|
||||||||||
### Parameters and variables | ||||||||||
|
||||||||||
Single variable lambdas should use `x` as the variable name (based on lambda calculus λx). Multi variable lambdas should use descriptive names, where `x` can be used for the main iterated item like `(x, index) => ...`. Name `c` can be used for context of Roslyn callback. | ||||||||||
|
||||||||||
Short names can be used as parameter and variable names, namely `SyntaxTree tree`, `SemanticModel model`, `SyntaxNode node` and `CancellationToken cancel`. | ||||||||||
|
||||||||||
### Method names | ||||||||||
|
||||||||||
FIXME Avoid Get prefixes for method names. Save three characters when it only gets x.Foo.Bar. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to vote about this one in the 4th step of our process. |
||||||||||
|
||||||||||
### Unit tests | ||||||||||
|
||||||||||
Unit tests for common C# and VB.NET rules should use two aliases `using CS = SonarAnalyzer.Rules.CSharp` and `using VB = SonarAnalyzer.Rules.VisualBasic`. Test method names should have `_CS` and `_VB` suffixes. | ||||||||||
|
||||||||||
Unit tests for single language rule should not use alias nor language method suffix. | ||||||||||
|
||||||||||
Variable name `sut` (System Under Test) is recommended in unit tests that really tests a single unit (contrary to our usual rule integration unit tests). | ||||||||||
|
||||||||||
FIXME - Avoid names without meaning like `foo`, `bar`, `baz`. OR KISS? | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to vote about this one in the 4th step of our process. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to avoid these names then let's add some examples for what to use instead. e.g. for an analyzer that raises on methods with empty bodies: public void Foo() // Noncompliant
{
}
public void Bar() // Compliant
{
// Some explanation
}
public void Baz() // Compliant
{
Console.WriteLine();
}
public override void Kiss() // Compliant
{
} Instead use names that show how the given member is relevant to the analyzer that's being tested: public void Empty() // Noncompliant
{
}
public override void HasComment() // Compliant
{
// Some explanation
}
public void NotEmpty() // Compliant
{
Console.WriteLine();
}
public override void Overriden() // Compliant
{
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we agree not to use these names then let's add an internal analyzer that enforces it (or make it part of the Verifier). |
||||||||||
|
||||||||||
Unit test method names: | ||||||||||
- Underscore in UT names separates logical groups, not individual words. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an example (after we voted on the convention). |
||||||||||
- FIXME: what should the name pattern be? NEEDS DISCUSSION ([many patterns](https://dzone.com/articles/7-popular-unit-test-naming) and also [Microsoft convention](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices#naming-your-tests) - I'd go for MS convention) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to vote about this one in the 4th step of our process. |
||||||||||
|
||||||||||
|
||||||||||
## Multi-line statements | ||||||||||
|
||||||||||
* Operators (`&&`, `||`, `and`, `or`, `+`, `:`, `?`, `??` and others) are placed at the beginning of a line. | ||||||||||
|
@@ -179,6 +205,14 @@ Variable name `sut` (System Under Test) is recommended in unit tests that really | |||||||||
|
||||||||||
## Code structure | ||||||||||
|
||||||||||
### Principles | ||||||||||
|
||||||||||
* When to factorize: two is a group, three is a crowd. | ||||||||||
* Less is more. | ||||||||||
* Rely on Roslyn Type inference to reduce used characters. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by "used characters"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an example for:
|
||||||||||
|
||||||||||
### Style | ||||||||||
|
||||||||||
* Field and property initializations are done directly in the member declaration instead of in a constructor. | ||||||||||
* `if`/`else if` and explicit `else` is used | ||||||||||
* when it helps to understand overall structure of the method, | ||||||||||
|
@@ -193,13 +227,46 @@ Variable name `sut` (System Under Test) is recommended in unit tests that really | |||||||||
* Var pattern `is var o` can be used only where variable declarations would require additional nesting. | ||||||||||
* Var pattern `o is { P: var p }` can be used only where `o` can be `null` and `p` is used at least 3 times. | ||||||||||
* Do not use `nullable`. | ||||||||||
* Avoid single-use variables, unless they really bring readability value. | ||||||||||
* Use file-scoped namespaces. | ||||||||||
* Tested variable is on the left, like `iterated == searchParameter` (where `iterated` is the tested variable) | ||||||||||
* If a string is multiline, use raw string literals, indented one tab-in from the declaration: | ||||||||||
``` | ||||||||||
var raw = """ | ||||||||||
hello | ||||||||||
my friend | ||||||||||
"""; | ||||||||||
``` | ||||||||||
* Always use multi-line initializers for collection and objects, e.g.: | ||||||||||
``` | ||||||||||
var thingy = new Thingy | ||||||||||
{ | ||||||||||
x = "hello", | ||||||||||
y = 42, | ||||||||||
} | ||||||||||
|
||||||||||
var collection = new Dictionary<string, int> | ||||||||||
{ | ||||||||||
{ "hey" : 1 }, | ||||||||||
{ "there": 42 }, | ||||||||||
Comment on lines
+250
to
+251
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrong sytnax.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's my typo, sorry for that Andrei. var dict = new Dictionary<int,int>
{
{ 1, 2 },
{ 3, 4 },
}; |
||||||||||
} | ||||||||||
``` | ||||||||||
* FIXME - align on how to use collection initializers int[] x = [ 1, 2, 3 ] or old style (see [slack discussion](https://sonarsource.slack.com/archives/C01H2B58DE1/p1697103918957899?thread_ts=1696951023.295859&cid=C01H2B58DE1)) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to vote about this one in the 4th step of our process. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Additional suggestions:
|
||||||||||
|
||||||||||
### Unit Tests | ||||||||||
* VerifierBuilder.AddSnippet should not be used to assert compliant/noncomplaint test cases. Move it to a TestCases file. | ||||||||||
|
||||||||||
|
||||||||||
## Comments | ||||||||||
|
||||||||||
* Code should contain as few comments as necessary in favor of well-named members and variables. | ||||||||||
* Comments should generally be on separate lines. | ||||||||||
* Comments on the same line with code are acceptable for short lines of code and short comments. | ||||||||||
* Documentation comments for abstract methods and their implementations should be placed only on the abstract method, to avoid duplication. _When reading the implementation, the IDE offers the tooling to peek in the base class and read the method comment._ | ||||||||||
* Avoid using comments for "Arrange, Act, Assert" in UTs, unless the test is complex. | ||||||||||
* Use single-line comments. Exception: `Internal /* for testing */ void Something()`. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The naming here is confusing since this is a single line.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe rather "Do not use |
||||||||||
* Prefer well-named members instead of documentation. | ||||||||||
* When writing [xmldoc](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags) for methods, avoid adding superflous tags (e.g. members that have self-explanatory names). | ||||||||||
|
||||||||||
## FIXME and ToDo | ||||||||||
|
||||||||||
|
@@ -217,6 +284,15 @@ It can still be used when and where it makes sense. For instance, when a class h | |||||||||
implementing generic interfaces (such as `IComparable`, `IDisposable`), it can make sense to have regions | ||||||||||
for the implementation of these interfaces. | ||||||||||
|
||||||||||
## Spacing | ||||||||||
|
||||||||||
* Avoid spaces unless they bring clarity and help the reader understand logical groups. Prefer spaces over comments. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By spaces you mean newlines? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, empty lines, I will update |
||||||||||
|
||||||||||
## Type definition | ||||||||||
|
||||||||||
* If a class is a POCO data-container, use a record. | ||||||||||
* Do not use primary constructors on normal classes and structs, use standard constructor + field/properties. | ||||||||||
|
||||||||||
## ValueTuples | ||||||||||
|
||||||||||
Do not use `ValueTuples` in production code. The usage in test projects is fine. `ValueTuples` are not supported in MsBuild 14 and while MsBuild 14 is not officially supported anymore, we still don't want to break it, if we can avoid it. | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is easy to check with an internal analyzer.