Implementation of parameter parser#234
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the AnalysisOptionsLoader and LintOptions classes to parse and manage lint configurations from analysis_options.yaml. The review identifies critical issues with the current caching strategy, noting that a global cache will cause incorrect behavior in monorepos and lacks a mechanism for invalidation when configuration files change. Further recommendations include renaming variables for clarity and consistently using the analyzer's ResourceProvider API instead of dart:io to ensure better compatibility and testability.
|
|
||
| /// Loads and parses analysis options from a Dart project's YAML file. | ||
| class AnalysisOptionsLoader { | ||
| Map<String, LintOptions> _rulesCache = {}; |
There was a problem hiding this comment.
The current caching mechanism does not support cache invalidation. In a long-running Analysis Server session (e.g., in an IDE), changes to analysis_options.yaml will not be detected, and the plugin will continue using stale configuration until the server is restarted. Consider checking the file's modification timestamp or implementing a file watcher to refresh the cache when the configuration changes.
There was a problem hiding this comment.
@Dariaa14, have you investigated the problem described here? Looks pretty relevant overall, but I'm not sure if changing analysis_options.yaml would restart the analysis server and reload the configuration.
solid-vovabeloded
left a comment
There was a problem hiding this comment.
Great start, @Dariaa14! Please, take a look at the following suggestions and let me know what you think.
|
|
||
| /// Loads and parses analysis options from a Dart project's YAML file. | ||
| class AnalysisOptionsLoader { | ||
| Map<String, LintOptions> _rulesCache = {}; |
There was a problem hiding this comment.
@Dariaa14, have you investigated the problem described here? Looks pretty relevant overall, but I'm not sure if changing analysis_options.yaml would restart the analysis server and reload the configuration.
style: improve variable names refactor: use root package path instead of library path refactor: use pattern matching to reduce nesting
refactor: allow mocking resource provider refactor: extract CachedPackageRules model
refactor: use Map<String, Object?> instead of LintOptions as the enabled field is implicitly true for all rules that the analyzer processes remove RuleConfig as it is no longer needed
refactor: use for loop to register rules
d51e1bf to
0975ba7
Compare
1cd1032
into
analysis_server_migration
* Migrate/avoid global state (#227) * Add analysis_server_plugin dependency * Migrate avoid_global_state rule and tests * applied code review suggestions * applied suggestions from code review * edited main documentation and changed avoid_global_state visitor naming * migrated avoid non null assertion rule and tests (#230) * migrated avoid non null assertion rule and tests * applied code review suggestions * applied code review suggestions regarding making lintCode private * Migrate/avoid debug print in release mode (#228) * Add analysis_server_plugin dependency * Migrate avoid_global_state rule and tests * applied code review suggestions * applied code review suggestions * applied suggestions from code review * migrated avoid debug print in release and tests * edited main documentation and changed avoid_global_state visitor naming * fixed main.dart conflict * applied suggestions from review * refactored code according to suggestions from review * applied code review suggestions * applied latest changes according to code review * remove unnecessary comments in AvoidDebugPrintInReleaseVisitor * Migrate/proper super calls (#229) * Migrate avoid_global_state rule and tests * applied code review suggestions * migrated avoid debug print in release and tests * applied suggestions from code review * edited main documentation and changed avoid_global_state visitor naming * migrated proper super calls rule and tests * registered ProperSuperCallsRule in the Plugin * applied code review suggestions * Fix tests structure * Remove unnecessary file --------- Co-authored-by: vova-beloded-solid <vova.beloded@solid.software> * Migrated prefer_early_return and its tests (#233) * Updated prefer_early_return rule and its visitor to use AnalysisRule . * Added tests and fixed visitor for prefer early return * Added the suggested changes * Migrate avoid unnecessary return variable rule and its tests (#237) * Updated avoid_unnecessary_return_variable rule and its visitor to use AnalysisRule. * Updated tests for avoid_unnecessary_return_variable rule * Deleted previous test file for avoid_unnecessary_return_variable rule. * Updated ReturnVariableUsageVisitor description. * Updated avoid_unnecessary_return_variable visitor from recursive to simple visitor. * Address PR suggestions * Updated rule to private in the visitor. * Migrate avoid unnecessary set state rule and its tests (#238) * Updated avoid_unnecessary_set_state rule and its visitor to use AnalysisRule. * Fixed previous commit. * Updated tests for avoid_unnecessary_set_state rule. * Delete previous test file for avoid_unnecessary_set_state rule * Updated the avoid_unnecessary_set_state visitor from recursive to simple. * Removed unnecessary set up from avoid_unnecessary_set_state rule tests * Update lib/src/lints/avoid_unnecessary_setstate/avoid_unnecessary_set_state_rule.dart Co-authored-by: danylo-safonov-solid <116712879+danylo-safonov-solid@users.noreply.github.com> * Address PR suggestions * Updated sdk requirements * Updated rule to private in visitor --------- Co-authored-by: danylo-safonov-solid <116712879+danylo-safonov-solid@users.noreply.github.com> * migrate prefer early return rule with tests (#232) * migrate prefer early return rule with tests * fix: remove flutter dependency to allow running reflective tests * test: migrate all old tests * feat: migrate old lint code improve readability when possible * refactor: extract variable for readability * style: formatting * test: remove unnecessary test file test: add nested 3 ifs test case --------- Co-authored-by: Andrew Bekhiet <andrew.bekhiet@solid.software> * Migrate avoid unrelated type assertions and its tests (#239) * Updated avoid_unrelated_type_assertions and its visitor to use AnalysisRule. * Updated tests for avoid_unrelated_type_assertions rule * Delete previous test file for avoid_unrelated_type_assertions * Update variable modifiers to private * Updated avoid_unrelared_type_assertions visitor from recursive to simple * Migrate newline before return rule and its tests (#240) * Updated newline_before_return_visitor rule and its visitor * Merged tests for newline_return_rule * Delete previous test file for newline_before_return * Updated min version of sdk * Added safety handle for the null case * Update newline_before_return_rule_test.dart * Added test for multiple comments and for a newline before a comment. * Migrate no equal then else rule and its tests (#241) * Updated no_equal_then_else rule and its visitor * Merged tests for no_equal_then_else rule * Delete previous test file for no_equal_then_else * Applied PR suggestions from Gemini * refactor: migrate double_literal_format to analysis_server_plugin (#281) * refactor: migrate double_literal_format to analysis_server_plugin docs: improve code docs * fix: handle literals with capital E test: handle exponentials in test cases * fix: include unnecessary leading zeroes in lint description * Implementation of parameter parser (#234) * Created analysis_options.yaml rules parser * Improved yaml parser and added the analysis_options loader * Improved rules loader from yaml * Added verification before looking for .yaml's path * Fields and getters are now declared before the constructor * Added method to get options of a rule by it's name * Made suggested changes to file upward finder * Removed top-level variable * Improved name of variable in loadRuleFromContext * Updated analysis options to have rules for each configuration file path * Updated file upward finder to not mix File from dart.io with file from analyzer * Added usage example in avoid_global_state_rule * style: move getters and fields before constructor * style: improve readability * fix: don't parse enabled if the rule has configured options style: improve variable names refactor: use root package path instead of library path refactor: use pattern matching to reduce nesting * feat: reload rules from file if newer refactor: allow mocking resource provider refactor: extract CachedPackageRules model * test: add AnalysisOptionsLoaderTest * feat(SolidLintRule): add parameter parsing refactor: use Map<String, Object?> instead of LintOptions as the enabled field is implicitly true for all rules that the analyzer processes remove RuleConfig as it is no longer needed * fix: use Map<String, Object?> for raw rule config * fix: method name * fix: make sure rules options are loaded before getting parameters * refactor: remove unused AnalysisOptionsLoader from AvoidGlobalStateRule refactor: use for loop to register rules * refactor: extract duplicate logic --------- Co-authored-by: Andrew Bekhiet <andrew.bekhiet@solid.software> * feat: migrate avoid_final_with_getter (#242) * feat: migrate avoid_final_with_getter refactor: extract GetterVariableVisitor into a file refactor: extract GetterReferenceId into a file test(avoid_final_with_getter): migrate tests * fix: also check block getters with one return statements fix: also check getter returning private final fields with this keyword * fix: also rename private field references * refactor: migrate avoid_returning_widgets rule (#243) feat: also check FunctionDeclarationStatement * refactor: migrate avoid_unnecessary_type_assertions (#282) * refactor: migrate unnecessary_type_assertion * refactor: migrate unnecessary_type_assertion fix * fix: use fix kind instead of assist kind * fix: use thisOrAncestorOfType to get the nearest node of type T fix: remove leading space when removing is operator * feat: display removed part in the fix message refactor: simplify removal code * fix: handle custom iterable types * test: add test for custom iterables with subtypes * refactor: improve readability * fix: improve AutoTestLintOffsets reliability handles edge cases when there are multiple similar code fragments * fix: update avoid_unnecessary_return_variable (#236) * fix: update avoid_unnecessary_return_variable to correctly traverse FunctionBody (#236) * refactor: simplify block retrieval in avoid_unnecessary_return_variable visitor * test: add test case for avoid_unnecessary_return_variable when variable is reused in nested blocks --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * fix: support await expressions in proper_super_calls (#291) Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate avoid_unused_parameters (#290) * refactor: migrate avoid_unused_parameters * fix: check if current function expression is inside an excluded declaration * remove avoid_unnecessary_type_casts (#289) * refactor: migrate avoid_unnecessary_type_casts * fix: incorrect node * docs: improve code documentation * remove avoid_unnecessary_type_casts use dart linter's `unnecessary_cast` instead * docs: update changelog * replace avoid_unnecessary_type_casts rule with dart analyzer's unnecessary_cast docs: update changelog * remove no deleted rule * remove references to unnecessary_type_casts * feat: add use_nearest_context rule (#293) * feat: add use_nearest_context rule (#190) * fix: separate rename/replace quick fix applicability for use_nearest_context * refactor: simplify use_nearest_context test files * refactor: migrate use_nearest_context tests to AutoTestLintOffsets * refactor: simplify logic in use_nearest_context_visitor * refactor: move AST identifier utilities to node_utils and expose as SimpleIdentifier extension --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate cyclomatic_complexity (#294) * refactor: migrate cyclomatic_complexity (#250) * test: add coverage for nested closures in cyclomatic complexity rule and remove obsolete issue link * fix: update cyclomatic complexity rule to support constructors and do-statements * refactor: migrate CyclomaticComplexityRuleTest to AutoTestLintOffsets and add additional test cases * feat: include collection elements, logical patterns, and null-aware operators in cyclomatic complexity calculation * feat: include null check and null assert patterns in cyclomatic complexity analysis * refactor: migrate cyclomatic complexity visitor to SimpleAstVisitor and target individual declaration types * chore: refactor test files formatting * test: add cyclomatic complexity test case for nested for-in loops * refactor: use inclusive comparison for cyclomatic complexity threshold --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate prefer_first (#286) * refactor: migrate prefer_first and tests * refactor: migrate prefer_first fix * refactor: prefer firstOrNull * fix: only apply one fix to one node at a time * fix: handle null awareness * refactor: use AutoTestLintOffsets * refactor: migrate function_lines_of_code rule (#296) * refactor: migrate function_lines_of_code rule (#251) * refactor: update function expression visitor logic * refactor: migrate function_lines_of_code tests to AutoTestLintOffsets * refactor: optimize currentUnit access in function lines of code visitor * feat: update description and add test case for function lines of code excluding comments * refactor: simplify lines of code visitor logic * refactor: migrate function_lines_of_code rule tests to a table-driven approach * refactor: introduce TableDrivenRuleTest base class to consolidate table-driven test logic * refactor: simplify test code generation by introducing string extensions and moving lint markers into generation logic * refactor: move parameter parser initialization into FunctionLinesOfCodeRule constructor * refactor: move cyclomatic complexity parameters initialization inside the rule constructor --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: rename table_driven_rule_test to table_driven_rule_test_base (#301) Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate no_empty_block (#299) * refactor: migrate no_empty_block * fix: allow multiple preceding comments to satisfy the todo check in no_empty_block rule * docs: add configuration examples to no_empty_block rule documentation * test: rename excluded method in no_empty_block_rule_test --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate prefer last (#287) * refactor: migrate prefer_last rule & visitor * refactor: migrate prefer_last test * refactor: migrate prefer_last fix * fix: handle null awareness * fix: prefer firstOrNull * feat: handle cascade & null aware expressions * refactor: use AutoTestLintOffsets * refactor: use return with switch expression * refactor: migrate no_magic_number rule (#300) * refactor: migrate no_magic_number rule * fix: ignore magic numbers in annotations and update boolean configuration parsing * fix: allow negative numbers in list index expressions for no_magic_number rule * feat: ignore magic numbers within record literals and named record fields * refactor: migrate no_magic_number test cases to unit tests and remove legacy integration tests * refactor: move AST inspection logic to AstNode extension and simplify magic number validation checks * refactor: cleanup code formatting, reorder imports, and adjust indentation across linting utilities and rules --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Migrate avoid_late_keyword rule (default behavior) and tests (#231) * Migrate avoid_late_keyword rule (default behavior) and tests * feat: read parameter by extending SolidLintRule fix: add old behavior test: migrate avoid late keyword rule tests * refactor: use AutoTestLintOffsets * style: inline methods --------- Co-authored-by: Andrew Bekhiet <andrew.bekhiet@solid.software> * refactor: migrate number_of_parameters (#302) Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate member_ordering rule (#297) * refactor: migrate member_ordering rule * refactor: extract member group satisfaction logic to extensions and simplify visitor reporting methods * refactor: unify member ordering diagnostic reporting with a shared helper method * refactor: simplify member group satisfaction checks * refactor: replace member group satisfaction logic with a formal implies utility * refactor: replace switch expression with type check in implies methods and clean up formatting * refactor: use switch expression to determine field keyword in FieldMemberGroupUtils * refactor: modularize member ordering visitor logic --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate named_parameters_ordering (#298) * refactor: migrate named_parameters_ordering * refactor: improve named parameters ordering fix to preserve trailing comments and fix configuration parsing logic * fix: prevent incorrect parameter reordering when comments are present and ensure unique parameter types in config parser * fix: improve trailing comment detection by iterating through the entire comment chain in named parameters fix * refactor: extract correction and iterable utilities and optimize named parameters ordering fix logic * style: fix doc comment line length in correction_utils.dart * refactor: simplify pairwise implementation to use indexed element access * refactor: extract comment handling logic to correction utilities --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate prefer_conditional_expressions (#303) * refactor: migrate prefer_conditional_expressions * fix: add parentheses to inverted conditional expressions for complex conditions and update tests * refactor: extract logic from prefer_conditional_expressions_visitor into separate model and visitor classes --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * test: add test for type promotion in avoid_unnecessary_return_variable (#308) * test: add test for type promotion in avoid_unnecessary_return_variable * test: refactor test name and remove whitespace in avoid_unnecessary_return_variable rule test * test: add test for avoid_unnecessary_return_variable rule when variable is used in string interpolation * test: update test cases for avoid_unnecessary_return_variable lint to improve type safety and parameter usage --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * fix: resolve rules configuration being ignored in nested directories (#310) * fix: resolve rules configuration being ignored in nested directories * refactor: use pattern matching for yaml parsing to improve robustness and prevent crashes on invalid configurations * fix: improve robustness of analysis options loader by filtering non-string keys and fixing infinite loop in path traversal * refactor: move file reading inside the try-catch block in analysis_options_loader --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: use AutoTestLintOffsets in remaining AnalysisRuleTest suites (#311) * refactor: use AutoTestLintOffsets in remaining AnalysisRuleTest suites * refactor: revert test files movement back to test/lints --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * feat: add exclude_annotation support to avoid_unused_parameters (#312) * feat: add exclude_annotation support to avoid_unused_parameters lint to ignore generated classes * feat: allow configuration parameters to accept single strings in addition to lists and add associated parsing tests * feat: support checking inherited annotations for all declaration types in avoid_unused_parameters lint * refactor: simplify excluded annotations check by iterating through all declarations * feat: allow map values in exclude parameters, generalize Iterable parsing, and fix operator precedence in unused parameter visitor * test: simplify freezed class definitions in avoid_unused_parameters test cases * fix: allow excluded annotations to be matched by full qualified name --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * feat: avoid non null assertion ignored types (#313) * feat: add ignored_types configuration to avoid_non_null_assertion lint rule * refactor: extract analysis options configuration to a constant in avoid_non_null_assertion test * refactor: update ignoredTypes to a Set and improve JSON parsing to support string or map inputs * refactor: update avoid_non_null_assertion parameter parsing to correctly extract keys from maps * refactor: improve type safety and readability of AvoidNonNullAssertionParameters JSON decoding using typed patterns --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate prefer_match_file_name (#305) * refactor: migrate prefer_match_file_name * refactor: improve prefer_match_file_name lint logic with switch expressions and centralized parameter initialization * test: add test cases for prefer_match_file_name rule * refactor: move normalization logic to visitor and add multi-sort utility to improve PreferMatchFileName rule encapsulation * refactor: replace hardcoded exclude_entity key with constant in ExcludedEntitiesListParameter --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: migrate avoid_using_api (#304) * refactor: migrate avoid_using_api * refactor: update rootPath parameter to nullable in avoid_using_api_visitor * fix: upgrade avoid_using_api to support per-entry severity levels and multiple lint codes * test: implement getRuleOptionsForFile in FakeAnalysisOptionsLoader * refactor: simplify logic and reduce nesting in AvoidUsingApiVisitor methods * refactor: replace conditional logic with switch expression in AvoidUsingApiVisitor to improve readability and structure * refactor: simplify visitor logic by abstracting reporting into a unified traversal method and moving member checks to extensions * refactor: simplify visitor logic by offloading API matching to node extension methods * refactor: use record destructuring to simplify AvoidUsingApiEntryParameters access in node extensions * style: wrap doc comment for NoMagicNumberRuleVisitor at 80 characters --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: consolidate lint fix registration logic (#316) * refactor: consolidate lint fix registration logic using a new RuleWithFixes interface * refactor: simplify lint rule fix registration by removing redundant type cast variable * refactor: introduce FixesForCodes typedef and replace Iterable return types in RuleWithFixes implementation --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * refactor: update automatic documentation generation (#315) * feat: handle docs parser structured parameters * feat: implement macro and template support in documentation parser and update parameter metadata * docs: update documentation and examples for analysis_server_plugin migration * refactor: move and modularize documentation parsing utilities and improve rule parsing logic * fix: handle null field types in parameters parser and refine macro circular dependency detection logic * refactor: enhance documentation error reporting by including source context and specific field names * refactor: use toSource for type parsing and improve file name suffix extraction logic * refactor: extract parser extensions and optimize AST navigation and comment processing logic * refactor: extract file reading logic into FileUtils and modernize ParserUtils implementation --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * fix: support package-level analysis options and rule suppression (#318) * fix: support package-level analysis options and rule suppression * refactor: improve analysis options parsing robustness with type standardization and fix path resolution logic * refactor: implement file-change detection for package configs and support multiple analysis option includes * fix: improve robustness of configuration parsing and URI resolution to prevent crashes on malformed input * refactor: replace constants file with a consolidated SolidLintsConstants class * refactor: update AnalysisOptionsLoader to use a private constructor and factory pattern for cleaner dependency injection * refactor: remove explicit generic type from _withNearestAnalysisOptionsFilePathForContext call * refactor: simplify package URI parsing using pattern matching in package config resolver * refactor: simplify package config path resolution loop logic * refactor: simplify package config parsing using pattern matching and extract uri resolution logic * refactor: simplify _toStandardMap using map entry pattern matching * refactor: simplify rule merging logic in analysis options parser using spread operators * refactor: simplify loop iterations using map entry pattern matching in analysis options parser * refactor: simplify map merging logic in analysis options parser using spread operator and pattern matching * refactor: simplify diagnostic configuration extraction by iterating over potential plugin source locations * refactor: introduce MapExtensions for type-safe filtering and refactor analysis options parser to utilize new utilities --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Add new rule: use_descriptive_names_for_type_parameters (#319) * feat: add new rule use_descriptive_names_for_type_parameters * refactor code * use cascade notattion * Add test case with nested functions * Add parameter for minimum number of type parameters * docs: add missing period to fromJson documentation comment * refactor: migrate use_descriptive_names_for_type_parameters rule * feat: extend use_descriptive_names_for_type_parameters to check class type aliases and include configuration for min_type_parameters * feat: add use_descriptive_names_for_type_parameters rule and bump version to 1.0.0 * chore: remove use_descriptive_names_for_type_parameters test files * refactor: simplify visitor implementation using pattern matching and cascade notation for registry registration --------- Co-authored-by: xJac0b <kubap1402@gmail.com> Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Fix GitHub Actions workflow (#322) * style: format code with updated dart formatter rules * chore: add ignore_for_file directive for todo comments in no_empty_block_rule.dart * chore: remove custom lint analysis step from CI workflow * chore: migrate flutter analyze and test commands to dart CLI in CI workflow * chore: upgrade actions/checkout to v4 in flutter workflow * chore: update actions/checkout to v7 in GitHub workflow * refactor: reorganize test directory structure and remove deprecated lint testing package * refactor: throw FormatException instead of Exception when type parsing fails * refactor: update todo ignore comments in no_empty_block lint documentation examples --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Add new rule avoid_similar_names (#321) * feat: add avoid_similar_names lint rule * refactor: optimize variable collection and improve tokenization logic in avoid_similar_names lint * fix: improve acronym tokenization in avoid_similar_names lint to support camelCase suffixes * refactor: support linting of declared identifiers and extract variable collection logic * feat: update avoid_similar_names lint to ignore nullability differences when comparing variable types * refactor: switch to SimpleAstVisitor and remove redundant super calls in AvoidSimilarNamesVisitor * feat: add support for detecting similar names in pattern variable declarations * fix: clear reported nodes in avoid similar names visitor to prevent stale lint reports * feat: improve name similarity detection by refining NameTokenizer and adding related tests * refactor: simplify avoid_similar_names visitor logic * refactor: decouple lint reporting logic from token comparison methods in avoid_similar_names visitor * refactor: simplify avoid_similar_names visitor methods * refactor: simplify avoid_similar_names test suite using helper methods --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Add new rule avoid_duplicate_code (#320) * feat: add avoid_duplicate_code lint rule * feat: increase default min_statements for avoid_duplicate_code from 3 to 10 * feat: enable cross-file duplicate code detection by implementing a global hash registry * chore: remove avoid_using_api from analysis exclude list * refactor: introduce SolidDiagnosticMessage to encapsulate diagnostic reporting and improve code formatting * feat: register SolidLintsPlugin in pubspec and remove redundant analyzer plugin configuration * refactor: optimize duplicate code detection with Jenkins hashing, structural config validation, and improved caching settings. * refactor: simplify avoid_duplicate_code parameters by removing default method exclusions and cleaning up JSON parsing logic * refactor: simplify duplicate code detection logic by extracting visitor helper methods and improving cache handling * refactor: modularize duplicate detection logic by introducing specialized visitors and utility extensions * chore: remove exclusion for avoid_using_api lint rules * fix: use stable strings instead of runtime hash codes in AST structural hashing to prevent cache invalidation * fix: improve accuracy and stability of duplicate code detection by implementing robust cache invalidation, parameter equality checks, and collision guarding. * refactor: remove unnecessary empty line in global_hash_registry.dart * refactor: fix indentation in AvoidDuplicateCodeParameters hashCode method * docs: update changelog with avoid_duplicate_code rule and formatting improvements * chore: update default minimum tokens to 30 for avoid_duplicate_code lint * feat: add equality operators and hashCode overrides to parameter models for reliable comparison * fix: handle corrupted cache files in HashCacheStorage and add regression test * test: update avoid_duplicate_code_rule_test to include excluded identifiers and context root * fix: use set for deletedFiles and skip them when building the inverted index * fix: prevent infinite loop in token counting by returning count when a cycle is detected * fix: improve path precision in duplicate code detection to avoid sibling directory collisions and encapsulate utility methods. * refactor: enable independent debounce logic for different package roots in GlobalHashRegistry * fix: catch all exceptions during file operations in hash cache storage to prevent analysis crashes * fix: target specific DuplicateLocation for removal in global hash registry instead of filtering by path * fix: resolve package-specific parameter retrieval during debounced cache saves in multi-package workspaces * refactor: inject ResourceProvider into avoid_duplicate_code services to support testability * refactor: simplify toJson method in ExcludedIdentifierParameter * refactor: improve FileCacheEntry JSON parsing safety with tryMap * refactor: simplify isFileExcluded method * refactor: optimize JenkinsHasher by extracting mix logic and simplifying method implementations * refactor: migrate TokenUtils to AstNode extension for cleaner token count retrieval * refactor: extract redundant visitation logic into private helper method in DescendantVisitor * chore: add trailing newline to pubspec.yaml * refactor: convert AvoidDuplicateCodeParameters.fromJson factory to arrow syntax * refactor: consolidate code duplication candidate visitation logic into a generic method * refactor: introduce SetDictionary for inverted index and modernize code with pattern matching * refactor: improve cache storage robustness with new utility helpers and cleaner file handling logic * refactor: modernize AstStructuralHashVisitor using pattern matching and streamlined visitor logic * refactor: simplify duplicate code detection logic using collection utilities and extract message generation * refactor: convert FileCacheEntry.fromJson factory to a generative constructor * refactor: convert HashEntry.fromJson factory constructor to a generative constructor * refactor: convert HashCacheStorage from static utility to instance-based service * refactor: implement Equatable for ExcludedIdentifierParameter * refactor: add batch update methods to SetDictionary and implement via new HashEntryListExtension * refactor: simplify DuplicateLocation instantiation in hash entry list extension * refactor: reorder HashCacheStorage constructor and optimize GlobalHashRegistry setup/teardown using cascades --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * Add feature_envy rule (#323) * feat: add feature_envy rule * refactor: simplify feature envy logic and improve code readability using pattern matching and collection methods * refactor: simplify metrics calculation and use multiSortedBy for external access evaluation * refactor: convert FeatureEnvyParameters.fromJson factory to a generative constructor * refactor: simplify public member extraction using extension methods and set operations * refactor: simplify instance member checks, element traversal, and member element resolution logic * refactor: simplify test code in IsDataClassTest by introducing a shared _test helper method * refactor: introduce _expectMetrics helper to simplify feature envy metrics unit tests * refactor: reorder constructor parameters and convert empty factory to generative constructor for FeatureEnvyParameters --------- Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> * feat: add avoid_similar_names and feature_envy rules to changelog (#324) Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> --------- Co-authored-by: Eslam Shaaban <159810907+Islam-Shaaban-Ibrahim@users.noreply.github.com> Co-authored-by: vova-beloded-solid <vova.beloded@solid.software> Co-authored-by: Trușcă Daria Maria <115713732+Dariaa14@users.noreply.github.com> Co-authored-by: daria-trusca-solid <daria-maria.trusca@solid.software> Co-authored-by: danylo-safonov-solid <116712879+danylo-safonov-solid@users.noreply.github.com> Co-authored-by: Andrew Bekhiet <andrew.bekhiet@solid.software> Co-authored-by: Illia Aihistov <illia.aihistov-us@solid.software> Co-authored-by: xJac0b <kubap1402@gmail.com>
Implementation:
Since the analysis_server_plugin currently lacks a direct way to retrieve the context root (noted by the TODO in the official source code), I explored two strategies for resolving analysis_options.yaml:
Plugin Register: I found this too restrictive, as it only functions correctly when 'dart analyze' is executed from the project root.
Rule Registration with Caching (Chosen): By resolving the configuration at the rule level, we can leverage the RuleContext to identify the file path currently under analysis. To prevent the performance overhead of re-parsing for every file, I implemented a caching layer. The YAML is only parsed once per 'dart analyze'; subsequent files retrieve the configuration from the cache.
Research of other packages:
I researched the approach of others:
custom_lint and dart_code_metrics both utilize a custom server architecture built on the legacy analyzer_plugin package.
I found no existing public implementations for dynamic parameter injection for analysis_server_plugin users.
Configuration Structure
Regarding our previous discussion on YAML structure: I tested the older formats used by other analyzers, but they were not recognized by the current server plugin. I have reverted to the structure specified in the official Dart documentation, which I have verified as functional in this implementation.