Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

feat: add static code diagnostic prefer-static-class #1086

Merged
merged 4 commits into from
Dec 1, 2022
Merged

feat: add static code diagnostic prefer-static-class #1086

merged 4 commits into from
Dec 1, 2022

Conversation

roman-petrov
Copy link
Contributor

@roman-petrov roman-petrov commented Dec 1, 2022

Suggests to use static class member instead of global constants, variables and functions.

Pros:

  • Easy to search: great help from IDE autocomplete. Type class/file name to find domain, and type dot to list all members.
  • Easy to import: name conflicts will happen less often since all names are scoped to file name/class name. No need to use import 'file.dart' as 'file' to resolve name conflicts.
  • Easy to read: declarations in code will be always shown paired with domain they belong to. Compare Circle.getArea and getArea or getCircleArea.
  • member-ordering rule will be applied to class members.

Cons:

  • The code amount might somehow increase.

When fixing rule issues and moving global members into a class, consider also renaming to avoid duplicating context.
For example, getCircleArea global function should become Circle.getArea, not Circle.getCircleArea.

For this rule it's recommended to exclude the test folder.

Use ignore-private configuration to ignore private global declarations.

Use ignore-names to ignore names matching regular expressions (for example, Riverpod providers, flutter hooks, etc).

Use ignore-annotations configuration to override default ignored annotation list.

⚙️ Config example {#config-example}

dart_code_metrics:
  ...
  rules:
    ...
    - prefer-static-class
        ignore-annotations:
          - allowedAnnotation
        ignore-private: true
        ignore-names:
          - (.*)Provider
          - use(.*)

Example {#example}

❌ Bad:

// circle.dart
int getCircleArea() {} // LINT
int getPerimeter() // LINT

const _PI = 3.14; // LINT

✅ Good:

// circle.dart
class Circle {
    static int getArea() {}
    static int getPerimeter() {}

    static const _PI = 3.14;
}

@roman-petrov roman-petrov changed the title [WIP] feat: add static code diagnostic prefer-static-class feat: add static code diagnostic prefer-static-class Dec 1, 2022
@roman-petrov roman-petrov marked this pull request as draft December 1, 2022 04:36
@codecov
Copy link

codecov bot commented Dec 1, 2022

Codecov Report

Merging #1086 (f4de0ef) into master (37902ea) will increase coverage by 0.04%.
The diff coverage is 91.07%.

❗ Current head f4de0ef differs from pull request most recent head c57cc88. Consider uploading reports for the commit c57cc88 to get more accurate results

@@            Coverage Diff             @@
##           master    #1086      +/-   ##
==========================================
+ Coverage   84.85%   84.89%   +0.04%     
==========================================
  Files         330      333       +3     
  Lines        7275     7331      +56     
==========================================
+ Hits         6173     6224      +51     
- Misses       1102     1107       +5     
Impacted Files Coverage Δ
...c/analyzers/lint_analyzer/rules/rules_factory.dart 75.00% <ø> (ø)
...eturning_widgets/avoid_returning_widgets_rule.dart 77.27% <ø> (ø)
...es_list/avoid_returning_widgets/config_parser.dart 100.00% <ø> (ø)
.../prefer_static_class/prefer_static_class_rule.dart 78.26% <78.26%> (ø)
.../rules_list/prefer_static_class/config_parser.dart 100.00% <100.00%> (ø)
.../rules/rules_list/prefer_static_class/visitor.dart 100.00% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@roman-petrov roman-petrov marked this pull request as ready for review December 1, 2022 12:05
@roman-petrov
Copy link
Contributor Author

roman-petrov commented Dec 1, 2022

I just have finished rule implementation. I also tested this rule on our code base and not found any false positives. I got ~90 true positives which we really should fix. @dkrutskikh , @incendial - can you please take a look?

Copy link
Member

@incendial incendial left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks amazing! 🔥 Left a few small comments

],
}).check(unit);

RuleTestHelper.verifyIssues(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use verifyNoIssues instead.

],
}).check(unit);

RuleTestHelper.verifyIssues(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for NoIssues

'ignore-private': true,
}).check(unit);

RuleTestHelper.verifyIssues(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

final unit = await RuleTestHelper.resolveFromFile(_correctExamplePath);
final issues = PreferStaticClassRule().check(unit);

RuleTestHelper.verifyIssues(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here 🙂

if (node.parent is CompilationUnit &&
!_hasIgnoredAnnotation(node) &&
!_shouldIgnoreName(nodeName) &&
nodeName != 'main') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe isEnitrypoint helper function should be used here. It covers not only main, but also other possible entry points.

}

bool _shouldIgnoreName(String name) =>
(_ignorePrivate && name.startsWith('_')) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Identifier.isPrivateName instead of name.startsWith('_')

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@incendial incendial merged commit 4900412 into dart-code-checker:master Dec 1, 2022
@incendial incendial added type: enhancement New feature or request area-rules labels Dec 1, 2022
@incendial incendial added this to the 5.1.0 milestone Dec 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-rules type: enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants