Skip to content

Commit

Permalink
Merge branch 'master' into rule/add-RSPEC-S7091
Browse files Browse the repository at this point in the history
  • Loading branch information
irina-batinic-sonarsource authored Sep 26, 2024
2 parents 1f81144 + 6907a79 commit c3df287
Show file tree
Hide file tree
Showing 11 changed files with 382 additions and 48 deletions.
94 changes: 86 additions & 8 deletions frontend/public/covered_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,84 @@
"S4670": "sonar-css 1.0.0.457",
"S5362": "sonar-css 1.4.0.1899"
},
"DART": {
"S101": "sonar-dart 0.1.0.1359",
"S106": "sonar-dart 0.1.0.1359",
"S1065": "sonar-dart 0.1.0.1359",
"S1068": "sonar-dart 0.1.0.1359",
"S107": "sonar-dart 0.1.0.1359",
"S1116": "sonar-dart 0.1.0.1359",
"S1118": "sonar-dart 0.1.0.1359",
"S1123": "sonar-dart 0.1.0.1359",
"S1128": "sonar-dart 0.1.0.1359",
"S1133": "sonar-dart 0.1.0.1359",
"S1134": "sonar-dart 0.1.0.1359",
"S1135": "sonar-dart 0.1.0.1359",
"S1143": "sonar-dart 0.1.0.1359",
"S115": "sonar-dart 0.1.0.1359",
"S1155": "sonar-dart 0.1.0.1359",
"S1161": "sonar-dart 0.1.0.1359",
"S1185": "sonar-dart 0.1.0.1359",
"S1192": "sonar-dart 0.1.0.1359",
"S120": "sonar-dart 0.2.0.1567",
"S1206": "sonar-dart 0.1.0.1359",
"S121": "sonar-dart 0.1.0.1359",
"S1481": "sonar-dart 0.1.0.1359",
"S1578": "sonar-dart 0.1.0.1359",
"S1679": "sonar-dart 0.1.0.1359",
"S1854": "sonar-dart 0.1.0.1359",
"S1874": "sonar-dart 0.1.0.1359",
"S2159": "sonar-dart 0.1.0.1359",
"S2175": "sonar-dart 0.1.0.1359",
"S2260": "sonar-dart 0.1.0.1359",
"S2358": "sonar-dart 0.1.0.1359",
"S2432": "sonar-dart 0.1.0.1359",
"S2471": "sonar-dart 0.1.0.1359",
"S2486": "sonar-dart 0.1.0.1359",
"S2933": "sonar-dart 0.1.0.1359",
"S2963": "sonar-dart 0.1.0.1359",
"S2971": "sonar-dart 0.1.0.1359",
"S3240": "sonar-dart 0.1.0.1359",
"S3257": "sonar-dart 0.1.0.1359",
"S3358": "sonar-dart 0.1.0.1359",
"S3512": "sonar-dart 0.1.0.1359",
"S3562": "sonar-dart 0.1.0.1359",
"S3689": "sonar-dart 0.1.0.1359",
"S3776": "sonar-dart 0.1.0.1359",
"S3962": "sonar-dart 0.1.0.1359",
"S4123": "sonar-dart 0.1.0.1359",
"S4647": "sonar-dart 0.1.0.1359",
"S4977": "sonar-dart 0.1.0.1359",
"S5416": "sonar-dart 0.1.0.1359",
"S5856": "sonar-dart 0.1.0.1359",
"S6207": "sonar-dart 0.1.0.1359",
"S6531": "sonar-dart 0.1.0.1359",
"S6535": "sonar-dart 0.1.0.1359",
"S6582": "sonar-dart 0.1.0.1359",
"S6606": "sonar-dart 0.1.0.1359",
"S6619": "sonar-dart 0.1.0.1359",
"S7045": "sonar-dart 0.1.0.1359",
"S7046": "sonar-dart 0.1.0.1359",
"S7047": "sonar-dart 0.1.0.1359",
"S7048": "sonar-dart 0.1.0.1359",
"S7049": "sonar-dart 0.1.0.1359",
"S7050": "sonar-dart 0.1.0.1359",
"S7051": "sonar-dart 0.1.0.1359",
"S7052": "sonar-dart 0.1.0.1359",
"S7053": "sonar-dart 0.1.0.1359",
"S7054": "sonar-dart 0.1.0.1359",
"S7055": "sonar-dart 0.1.0.1359",
"S7057": "sonar-dart 0.1.0.1359",
"S7058": "sonar-dart 0.1.0.1359",
"S7061": "sonar-dart 0.1.0.1359",
"S7062": "sonar-dart 0.1.0.1359",
"S7064": "sonar-dart 0.1.0.1359",
"S7066": "sonar-dart 0.1.0.1359",
"S7067": "sonar-dart 0.1.0.1359",
"S7068": "sonar-dart 0.1.0.1359",
"S7069": "sonar-dart 0.1.0.1359",
"S927": "sonar-dart 0.1.0.1359"
},
"DOCKER": {
"S1135": "sonar-iac 1.13.0.3464",
"S2260": "sonar-iac 1.10.0.2836",
Expand Down Expand Up @@ -5374,7 +5452,7 @@
"S6396": "sonar-python 3.12.0.9583",
"S6397": "sonar-python 3.12.0.9583",
"S6417": "sonar-dataflow-bug-detection 1.6.0.2275",
"S6418": "sonar-python master",
"S6418": "sonar-python 4.22.0.16914",
"S6437": "sonar-python 4.3.0.11660",
"S6463": "sonar-python 3.19.0.10254",
"S6464": "sonar-dataflow-bug-detection 1.8.0.2712",
Expand Down Expand Up @@ -5420,7 +5498,7 @@
"S6786": "sonar-python 4.11.0.13826",
"S6792": "sonar-python 4.10.0.13725",
"S6794": "sonar-python 4.10.0.13725",
"S6795": "sonar-python master",
"S6795": "sonar-python 4.22.0.16914",
"S6796": "sonar-python 4.10.0.13725",
"S6799": "sonar-python 4.10.0.13725",
"S6839": "sonar-security 10.4.0.30099",
Expand All @@ -5445,12 +5523,12 @@
"S6972": "sonar-python 4.18.0.15334",
"S6973": "sonar-python 4.18.0.15334",
"S6974": "sonar-python 4.18.0.15334",
"S6978": "sonar-python master",
"S6979": "sonar-python master",
"S6982": "sonar-python master",
"S6983": "sonar-python master",
"S6984": "sonar-python master",
"S6985": "sonar-python master",
"S6978": "sonar-python 4.22.0.16914",
"S6979": "sonar-python 4.22.0.16914",
"S6982": "sonar-python 4.22.0.16914",
"S6983": "sonar-python 4.22.0.16914",
"S6984": "sonar-python 4.22.0.16914",
"S6985": "sonar-python 4.22.0.16914",
"S7044": "sonar-security 10.7.0.32997",
"S905": "sonar-python 2.11.0.6843",
"S930": "sonar-python 2.4.0.5513",
Expand Down
2 changes: 1 addition & 1 deletion rspec-tools/rspec_tools/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from rspec_tools.utils import (load_json, pushd)

REPOS = ['sonar-abap','sonar-cpp','sonar-cobol','sonar-dotnet','sonar-css','sonar-flex','slang-enterprise','sonar-java','SonarJS','sonar-php','sonar-pli','sonar-plsql','sonar-python','sonar-rpg','sonar-swift','sonar-text','sonar-tsql','sonar-vb','sonar-html','sonar-xml','sonar-kotlin', 'sonar-secrets', 'sonar-security', 'sonar-dataflow-bug-detection', 'sonar-iac']
REPOS = ['sonar-abap','sonar-cpp','sonar-cobol','sonar-dart','sonar-dotnet','sonar-css','sonar-flex','slang-enterprise','sonar-java','SonarJS','sonar-php','sonar-pli','sonar-plsql','sonar-python','sonar-rpg','sonar-swift','sonar-text','sonar-tsql','sonar-vb','sonar-html','sonar-xml','sonar-kotlin', 'sonar-secrets', 'sonar-security', 'sonar-dataflow-bug-detection', 'sonar-iac']

CANONICAL_NAMES = {
'CLOUD_FORMATION': 'CLOUDFORMATION',
Expand Down
4 changes: 2 additions & 2 deletions rules/S7027/java/metadata.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "Cyclic dependencies between classes should be resolved",
"title": "Circular dependencies between classes in the same package should be resolved",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
Expand All @@ -15,7 +15,7 @@
"sqKey": "S7027",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"quickfix": "infeasible",
"code": {
"impacts": {
"MAINTAINABILITY": "HIGH"
Expand Down
24 changes: 13 additions & 11 deletions rules/S7027/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
== Why is this an issue?

Circular dependencies happen when two classes, directly or indirectly, reference each other in their definitions.
This rule reports circular dependencies between classes within the same package.

This cyclical relationship means class boundaries cannot be expressed as an intuitive hierarchy. This degrades your code’s structure and makes it harder to manage and extend over time.
== Why is this an issue?

These dependencies can lead to unexpected behavior, which complicates debugging, and makes your code more error-prone.
Circular dependencies occur when two classes reference each other, either directly or indirectly.
This means that the classes' dependency structure does not represent an intuitive hierarchy, which makes it harder to understand and maintain.

=== What is the potential impact?

Circular dependencies complicate code maintenance, making it difficult to change one class without inadvertently affecting others and increasing the risk of defects.
Circular dependencies increase the architectural complexity of the code, reducing its readability, extensibility, and maintainability.
As the project grows, circular dependencies often lead to more circular dependencies, further complication of the architecture and increasing technical debt.
Over time, untangling these dependencies becomes increasingly difficult.

In some cases, they can even prevent your code from compiling or cause runtime failures. As your project grows, these cycles become harder to untangle, further degrading the codebase and increasing technical debt.
=== Exceptions

This structural issue can significantly hinder your ability to adapt and improve the code in the future.
Circular dependencies between an inner class and its outer class, or between inner classes within the same enclosing class, are not flagged as issues.

== How to fix it

1. Extract an interface: If two classes share similar functionality, move that functionality to an interface that both can implement. This allows each class to depend on the interface rather than on each other.
1. **Extract an interface**: If two classes share similar functionality, move that functionality to an interface that both can implement. This allows each class to depend on the interface rather than on each other.

2. Use dependency injection: Replace direct references between classes with dependency injection. By passing necessary objects as parameters through constructors or setters, you break the circular reference, making your code more flexible and easier to test.
2. **Use dependency injection**: Replace direct references between classes with dependency injection. By passing necessary objects as parameters through constructors or setters, you break the circular reference, making your code more flexible and easier to test.

3. Split responsibilities: Evaluate whether each class is handling too many responsibilities. If so, break them down into smaller, more focused classes. This not only eliminates circular dependencies but makes sure your code has fewer reasons to change, making it easier to manage and extend.
3. **Split responsibilities**: Evaluate whether each class is handling too many responsibilities. If so, break them down into smaller, more focused classes. This eliminates circular dependencies and makes sure your code has fewer reasons to change, making it easier to manage and extend.

=== Code examples

Expand Down Expand Up @@ -64,3 +65,4 @@ interface OrderService {

- Wikipedia - https://en.wikipedia.org/wiki/Acyclic_dependencies_principle[Acyclic dependencies principle]
- STAN - https://stan4j.com/advanced/adp/[Acyclic dependencies principle]
- RSPEC - https://sonarsource.github.io/rspec/#/rspec/S7091/java[S7091: Circular dependencies between classes across package boundaries should be resolved]
52 changes: 26 additions & 26 deletions rules/S7036/text/rule.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@ Clean code should not make use of offensive language but instead use neutral and

Code is meant to be understandable and clear to the reader.
Discriminatory and offensive language is often used for expressiveness.
Such language has made its way into technical jargon and code despite being derived
from specific cultural contexts that carry discriminatory connotations.
These terms do not accurately convey the intended meaning in technical contexts
and are often idiomatic expressions that can be confusing or misleading.
Using such terms can perpetuate negative biases and hinder effective communication.

For instance, the term `sanity check` is not meaningful in a software context as the term
sane relates to mental health, which is irrelevant to code functionality.
More precise and descriptive alternatives, such as validation check or verification check,
exist and provide a clearer meaning. By choosing unambiguous and neutral terminology,
we promote inclusivity and improve the clarity and maintainability of code.

Companies with a mandate for inclusivity need to build products for everyone with
the following considerations:

* *Brand reputation*
** The adoption of respectful language in code aligns with evolving industry standards to
position a brand as a leader in innovation and professionalism and avoid reputational damage and backlash.

* *Employee Relations*
** Respectful and inclusive language in code reflects a respectful and inclusive workplace culture.
** Clear language in code fosters better understanding and communication among team members.

* *Legal/Regulatory Compliance*
** Compliance with legal requirements and industry regulations
** Neutral and inclusive terminology minimizes the risk of litigation
Such language has made its way into technical jargon
and code despite being derived from specific cultural contexts that carry discriminatory connotations.
These terms are often idiomatic expressions that can be misleading
and using such terms can perpetuate negative biases and hinder effective communication.

For instance, the term sanity check is derived from psychiatric sanity,
which can have a negative connotation with respect to a person’s mental health.
Code itself cannot be in a state of sanity or, conversely, insanity.
In the context of code, more precise and descriptive alternatives,
such as validation check or verification check, exist and provide a clearer meaning.
By choosing unambiguous and neutral terminology, we promote inclusivity and reduce the ambiguity of code.

Companies with a mandate for inclusivity need to build products for everyone with the following considerations:

* *Brand reputation*:
** The adoption of respectful language in code aligns with evolving industry standards to position a brand as a leader in innovation and professionalism and avoid reputational damage and backlash.
** Example: https://www.technologyreview.com/2019/04/05/1175/facebook-algorithm-discriminates-ai-bias/[Facebook’s ad-serving algorithm discriminates by gender and race | MIT Technology Review]

* *Employee Relations*:
** Respectful and inclusive language in code reflects a respectful and inclusive workplace culture.
** Clear language in code fosters better understanding and communication among team members.

* *Legal/Regulatory Compliance*:
** Compliance with legal requirements and industry regulations.
** Neutral and inclusive terminology minimizes the risk of litigation.
** Example: https://accessibility.blog.gov.uk/2022/12/09/some-changes-to-the-public-sector-digital-accessibility-regulations/[Some changes to the public sector digital accessibility regulations]

== How to fix it

Expand Down
24 changes: 24 additions & 0 deletions rules/S7075/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"title": "Non-constant names should comply with a naming convention",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "2min"
},
"tags": [
"convention"
],
"defaultSeverity": "Minor",
"ruleSpecification": "RSPEC-7075",
"sqKey": "S7075",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "LOW"
},
"attribute": "IDENTIFIABLE"
}
}
82 changes: 82 additions & 0 deletions rules/S7075/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Non-constant identifiers should be in https://en.wikipedia.org/wiki/Camel_case[lowerCamelCase].

== Why is this an issue?

A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes.

The goal of a naming convention is to make the code more readable and understandable, which makes it easier to maintain and debug. It also ensures consistency in the code, especially when multiple developers are working on the same project.

Dart recommends using lowerCamelCase for all non-constant identifiers:

* members of classes and mixins, such as constructors, methods, fields and properties
* top-level functions and variables
* parameters of functions and methods

This means that the first letter of the identifier is lowercase, and the first letter of each subsequent word is capitalized, using no separators such as `_`.

The rule doesn't check `enum` values. Those are implicitly defined as constants, but treated separately

=== What is the potential impact?

Using the wrong casing can lead to confusion and wrong assumptions about the code. For example naming a top-level function in Pascal Case may mislead the reader to think it's a type, like a class or a mixin.

== How to fix it

Rename the identifier to use camel case.

=== Code examples

==== Noncompliant code example

[source,dart,diff-id=1,diff-type=noncompliant]
----
var ATopLevelVariable = 42; // Noncompliant
void ATopLevelFunction() {} // Noncompliant
class AClass {
void AMemberFunction() {} // Noncompliant
}
----

==== Compliant solution

[source,dart,diff-id=1,diff-type=compliant]
----
var aTopLevelVariable = 42;
void aTopLevelFunction() {}
class AClass {
void aMemberFunction() {}
}
----

== Resources

=== Documentation

* Dart Docs - https://dart.dev/tools/linter-rules/non_constant_identifier_names[Linter rules - non_constant_identifier_names]
* Wikipedia - https://en.wikipedia.org/wiki/Camel_case[Camel case]

=== Related rules

* S101 - Class names should comply with a naming convention
* S7046 - Extension identifiers should comply with a naming convention


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

* The variable name '<identifierName>' isn't a lowerCamelCase identifier.

=== Highlighting

The identifier name. If a generic method, the name doesn't include the type parameters.

'''
== Comments And Links
(visible only on this page)

endif::env-github,rspecator-view[]
2 changes: 2 additions & 0 deletions rules/S7075/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
23 changes: 23 additions & 0 deletions rules/S7096/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"title": "Initialization formals shouldn't be unnecessarily type annotated",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Minor",
"ruleSpecification": "RSPEC-7096",
"sqKey": "S7096",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "LOW"
},
"attribute": "CONVENTIONAL"
}
}
Loading

0 comments on commit c3df287

Please sign in to comment.