├── .fvmrc ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── 1-report-issue.md │ ├── 2-request-new-feature.md │ ├── 3-documentation.md │ └── config.yml ├── dependabot.yml └── workflows │ ├── Handler-Comment-Issues.yml │ ├── Handler-Issue-Creation.yml │ ├── build.yaml │ ├── release.yaml │ └── toolkit.yml ├── .gitignore ├── .pubignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── GETTINGSTARTED.md ├── GOVERNANCE.md ├── LICENSE ├── NOTICE.md ├── README.md ├── TROUBLESHOOTING.md ├── analysis_options.yaml ├── assets ├── .gitattributes └── quick-fixes.png ├── bin └── metrics.dart ├── example ├── .gitignore ├── LICENSE ├── README.md ├── analysis_options.yaml ├── lib │ ├── main.dart │ └── src │ │ ├── unnecessary_nullable_widget.dart │ │ ├── unused_code_widget.dart │ │ └── unused_widget.dart ├── lib_example │ └── lib │ │ └── main.dart └── pubspec.yaml ├── innactive-issues-closure.yaml ├── lib ├── analyzer_plugin.dart ├── cli_runner.dart ├── config.dart ├── lint_analyzer.dart ├── presets │ ├── all.yaml │ ├── analysis_options.1.0.0.yaml │ ├── dart_all.yaml │ ├── flame.yaml │ ├── flutter_all.yaml │ ├── intl.yaml │ ├── metrics_recommended.yaml │ └── recommended.yaml ├── reporters.dart ├── src │ ├── analyzer_plugin │ │ ├── analyzer_plugin.dart │ │ ├── analyzer_plugin_starter.dart │ │ └── analyzer_plugin_utils.dart │ ├── analyzers │ │ ├── lint_analyzer │ │ │ ├── anti_patterns │ │ │ │ ├── anti_patterns_list │ │ │ │ │ ├── long_method.dart │ │ │ │ │ └── long_parameter_list.dart │ │ │ │ ├── models │ │ │ │ │ └── pattern.dart │ │ │ │ ├── pattern_utils.dart │ │ │ │ └── patterns_factory.dart │ │ │ ├── base_visitors │ │ │ │ └── source_code_visitor.dart │ │ │ ├── lint_analysis_config.dart │ │ │ ├── lint_analysis_options_validator.dart │ │ │ ├── lint_analyzer.dart │ │ │ ├── lint_config.dart │ │ │ ├── lint_utils.dart │ │ │ ├── metrics │ │ │ │ ├── metric_utils.dart │ │ │ │ ├── metrics_factory.dart │ │ │ │ ├── metrics_list │ │ │ │ │ ├── cyclomatic_complexity │ │ │ │ │ │ ├── cyclomatic_complexity_flow_visitor.dart │ │ │ │ │ │ └── cyclomatic_complexity_metric.dart │ │ │ │ │ ├── halstead_volume │ │ │ │ │ │ ├── halstead_volume_ast_visitor.dart │ │ │ │ │ │ └── halstead_volume_metric.dart │ │ │ │ │ ├── lines_of_code │ │ │ │ │ │ └── lines_of_code_metric.dart │ │ │ │ │ ├── maintainability_index │ │ │ │ │ │ └── maintainability_index_metric.dart │ │ │ │ │ ├── maximum_nesting_level │ │ │ │ │ │ ├── maximum_nesting_level_metric.dart │ │ │ │ │ │ └── nesting_level_visitor.dart │ │ │ │ │ ├── number_of_methods │ │ │ │ │ │ └── number_of_methods_metric.dart │ │ │ │ │ ├── number_of_parameters │ │ │ │ │ │ └── number_of_parameters_metric.dart │ │ │ │ │ ├── source_lines_of_code │ │ │ │ │ │ └── source_lines_of_code_metric.dart │ │ │ │ │ ├── technical_debt │ │ │ │ │ │ ├── technical_debt_metric.dart │ │ │ │ │ │ └── visitor.dart │ │ │ │ │ └── weight_of_class │ │ │ │ │ │ └── weight_of_class_metric.dart │ │ │ │ ├── models │ │ │ │ │ ├── class_metric.dart │ │ │ │ │ ├── file_metric.dart │ │ │ │ │ ├── function_metric.dart │ │ │ │ │ ├── metric.dart │ │ │ │ │ ├── metric_computation_result.dart │ │ │ │ │ ├── metric_documentation.dart │ │ │ │ │ ├── metric_value.dart │ │ │ │ │ └── metric_value_level.dart │ │ │ │ ├── scope_utils.dart │ │ │ │ └── scope_visitor.dart │ │ │ ├── models │ │ │ │ ├── class_type.dart │ │ │ │ ├── context_message.dart │ │ │ │ ├── entity_type.dart │ │ │ │ ├── function_type.dart │ │ │ │ ├── internal_resolved_unit_result.dart │ │ │ │ ├── issue.dart │ │ │ │ ├── lint_file_report.dart │ │ │ │ ├── replacement.dart │ │ │ │ ├── report.dart │ │ │ │ ├── scoped_class_declaration.dart │ │ │ │ ├── scoped_function_declaration.dart │ │ │ │ ├── severity.dart │ │ │ │ ├── summary_lint_report_record.dart │ │ │ │ └── summary_lint_report_record_status.dart │ │ │ ├── reporters │ │ │ │ ├── lint_report_params.dart │ │ │ │ ├── reporter_factory.dart │ │ │ │ ├── reporters_list │ │ │ │ │ ├── checkstyle │ │ │ │ │ │ └── lint_checkstyle_reporter.dart │ │ │ │ │ ├── code_climate │ │ │ │ │ │ ├── lint_code_climate_reporter.dart │ │ │ │ │ │ └── models │ │ │ │ │ │ │ ├── code_climate_issue.dart │ │ │ │ │ │ │ ├── code_climate_issue_category.dart │ │ │ │ │ │ │ ├── code_climate_issue_location.dart │ │ │ │ │ │ │ └── code_climate_issue_severity.dart │ │ │ │ │ ├── console │ │ │ │ │ │ ├── lint_console_reporter.dart │ │ │ │ │ │ └── lint_console_reporter_helper.dart │ │ │ │ │ ├── github │ │ │ │ │ │ └── lint_github_reporter.dart │ │ │ │ │ ├── html │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ ├── icon.dart │ │ │ │ │ │ │ ├── issue_details_tooltip.dart │ │ │ │ │ │ │ └── report_details_tooltip.dart │ │ │ │ │ │ ├── lint_html_reporter.dart │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ ├── file_metrics_report.dart │ │ │ │ │ │ │ ├── function_metrics_report.dart │ │ │ │ │ │ │ ├── icon_type.dart │ │ │ │ │ │ │ └── report_table_record.dart │ │ │ │ │ │ └── utility_functions.dart │ │ │ │ │ └── json │ │ │ │ │ │ └── lint_json_reporter.dart │ │ │ │ └── utility_selector.dart │ │ │ ├── rules │ │ │ │ ├── base_visitors │ │ │ │ │ └── intl_base_visitor.dart │ │ │ │ ├── models │ │ │ │ │ ├── dart_rule.dart │ │ │ │ │ ├── flame_rule.dart │ │ │ │ │ ├── flutter_rule.dart │ │ │ │ │ ├── intl_rule.dart │ │ │ │ │ ├── rule.dart │ │ │ │ │ └── rule_type.dart │ │ │ │ ├── node_utils.dart │ │ │ │ ├── rule_utils.dart │ │ │ │ ├── rules_factory.dart │ │ │ │ └── rules_list │ │ │ │ │ ├── always_remove_listener │ │ │ │ │ ├── always_remove_listener_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── arguments_ordering │ │ │ │ │ ├── arguments_ordering_rule.dart │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_banned_imports │ │ │ │ │ ├── avoid_banned_imports_rule.dart │ │ │ │ │ ├── utils │ │ │ │ │ │ └── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_border_all │ │ │ │ │ ├── avoid_border_all_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_cascade_after_if_null │ │ │ │ │ ├── avoid_cascade_after_if_null_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_collection_methods_with_unrelated_types │ │ │ │ │ ├── avoid_collection_methods_with_unrelated_types_rule.dart │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_creating_vector_in_update │ │ │ │ │ ├── avoid_creating_vector_in_update_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_double_slash_imports │ │ │ │ │ ├── avoid_double_slash_imports_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_duplicate_exports │ │ │ │ │ ├── avoid_duplicate_exports_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_dynamic │ │ │ │ │ ├── avoid_dynamic_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_expanded_as_spacer │ │ │ │ │ ├── avoid_expanded_as_spacer_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_global_state │ │ │ │ │ ├── avoid_global_state_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_ignoring_return_values │ │ │ │ │ ├── avoid_ignoring_return_values_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_initializing_in_on_mount │ │ │ │ │ ├── avoid_initializing_in_on_mount_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_late_keyword │ │ │ │ │ ├── avoid_late_keyword_rule.dart │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_missing_enum_constant_in_map │ │ │ │ │ ├── avoid_missing_enum_constant_in_map_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_nested_conditional_expressions │ │ │ │ │ ├── avoid_nested_conditional_expressions_rule.dart │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_non_ascii_symbols │ │ │ │ │ ├── avoid_non_ascii_symbols_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_non_null_assertion │ │ │ │ │ ├── avoid_non_null_assertion_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_passing_async_when_sync_expected │ │ │ │ │ ├── avoid_passing_async_when_sync_expected_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_redundant_async │ │ │ │ │ ├── avoid_redundant_async_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_redundant_async_on_load │ │ │ │ │ ├── avoid_redundant_async_on_load_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_returning_widgets │ │ │ │ │ ├── avoid_returning_widgets_rule.dart │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── visit_declaration.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_shrink_wrap_in_lists │ │ │ │ │ ├── avoid_shrink_wrap_in_lists_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_substring │ │ │ │ │ ├── avoid_substring_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_throw_in_catch_block │ │ │ │ │ ├── avoid_throw_in_catch_block_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_top_level_members_in_tests │ │ │ │ │ ├── avoid_top_level_members_in_tests_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unnecessary_conditionals │ │ │ │ │ ├── avoid_unnecessary_conditionals_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unnecessary_setstate │ │ │ │ │ ├── avoid_unnecessary_setstate_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unnecessary_type_assertions │ │ │ │ │ ├── avoid_unnecessary_type_assertions_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unnecessary_type_casts │ │ │ │ │ ├── avoid_unnecessary_type_casts_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unrelated_type_assertions │ │ │ │ │ ├── avoid_unrelated_type_assertions_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_unused_parameters │ │ │ │ │ ├── avoid_unused_parameters_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── avoid_wrapping_in_padding │ │ │ │ │ ├── avoid_wrapping_in_padding_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── ban_name │ │ │ │ │ ├── ban_name_rule.dart │ │ │ │ │ ├── utils │ │ │ │ │ │ └── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── binary_expression_operand_order │ │ │ │ │ ├── binary_expression_operand_order_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── check_for_equals_in_render_object_setters │ │ │ │ │ ├── check_for_equals_in_render_object_setters_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── common_config.dart │ │ │ │ │ ├── consistent_update_render_object │ │ │ │ │ ├── consistent_update_render_object_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── correct_game_instantiating │ │ │ │ │ ├── correct_game_instantiating_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── double_literal_format │ │ │ │ │ ├── double_literal_format_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── format_comment │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── format_comment_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── list_all_equatable_fields │ │ │ │ │ ├── list_all_equatable_fields_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── member_ordering │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── member_ordering_rule.dart │ │ │ │ │ ├── models │ │ │ │ │ │ ├── annotation.dart │ │ │ │ │ │ ├── field_keyword.dart │ │ │ │ │ │ ├── member_group.dart │ │ │ │ │ │ ├── member_type.dart │ │ │ │ │ │ └── modifier.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── missing_test_assertion │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── missing_test_assertion_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── newline_before_return │ │ │ │ │ ├── newline_before_return_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_blank_line_before_single_return │ │ │ │ │ ├── no_blank_line_before_single_return_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_boolean_literal_compare │ │ │ │ │ ├── no_boolean_literal_compare_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_empty_block │ │ │ │ │ ├── no_empty_block_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_equal_arguments │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── no_equal_arguments_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_equal_then_else │ │ │ │ │ ├── no_equal_then_else_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_magic_number │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── no_magic_number_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── no_object_declaration │ │ │ │ │ ├── no_object_declaration_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_async_await │ │ │ │ │ ├── prefer_async_await_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_commenting_analyzer_ignores │ │ │ │ │ ├── prefer_commenting_analyzer_ignores.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_conditional_expressions │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_conditional_expressions_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_const_border_radius │ │ │ │ │ ├── prefer_const_border_radius_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_correct_edge_insets_constructor │ │ │ │ │ ├── models │ │ │ │ │ │ ├── edge_insets_data.dart │ │ │ │ │ │ └── edge_insets_param.dart │ │ │ │ │ ├── prefer_correct_edge_insets_constructor_rule.dart │ │ │ │ │ ├── validator.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_correct_identifier_length │ │ │ │ │ ├── prefer_correct_identifier_length_rule.dart │ │ │ │ │ ├── utils │ │ │ │ │ │ └── config_parser.dart │ │ │ │ │ ├── validator.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_correct_test_file_name │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_correct_test_file_name_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_correct_type_name │ │ │ │ │ ├── prefer_correct_type_name_rule.dart │ │ │ │ │ ├── utils │ │ │ │ │ │ └── config_parser.dart │ │ │ │ │ ├── validator.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_define_hero_tag │ │ │ │ │ ├── prefer_define_hero_tag_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_enums_by_name │ │ │ │ │ ├── prefer_enums_by_name_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_extracting_callbacks │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_extracting_callbacks_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_first │ │ │ │ │ ├── prefer_first_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_first_or_null │ │ │ │ │ ├── prefer_first_or_null_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_immediate_return │ │ │ │ │ ├── prefer_immediate_return_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_intl_name │ │ │ │ │ ├── prefer_intl_name_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_iterable_of │ │ │ │ │ ├── prefer_iterable_of_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_last │ │ │ │ │ ├── prefer_last_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_match_file_name │ │ │ │ │ ├── prefer_match_file_name_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_moving_to_variable │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_moving_to_variable_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_provide_intl_description │ │ │ │ │ ├── prefer_provide_intl_description_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_single_quotes │ │ │ │ │ ├── prefer_single_qoutes.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_single_widget_per_file │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_single_widget_per_file_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_static_class │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_static_class_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_trailing_comma │ │ │ │ │ ├── config_parser.dart │ │ │ │ │ ├── prefer_trailing_comma_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── prefer_using_list_view │ │ │ │ │ ├── prefer_using_list_view_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── provide_correct_intl_args │ │ │ │ │ ├── provide_correct_intl_args_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ ├── tag_name │ │ │ │ │ ├── tag_name_rule.dart │ │ │ │ │ ├── utils │ │ │ │ │ │ └── config_parser.dart │ │ │ │ │ └── visitor.dart │ │ │ │ │ └── use_setstate_synchronously │ │ │ │ │ ├── config.dart │ │ │ │ │ ├── fact.dart │ │ │ │ │ ├── helpers.dart │ │ │ │ │ ├── use_setstate_synchronously_rule.dart │ │ │ │ │ └── visitor.dart │ │ │ └── utils │ │ │ │ └── report_utils.dart │ │ ├── unnecessary_nullable_analyzer │ │ │ ├── declarations_visitor.dart │ │ │ ├── invocations_visitor.dart │ │ │ ├── models │ │ │ │ ├── invocations_usage.dart │ │ │ │ ├── unnecessary_nullable_file_report.dart │ │ │ │ └── unnecessary_nullable_issue.dart │ │ │ ├── reporters │ │ │ │ ├── reporter_factory.dart │ │ │ │ ├── reporters_list │ │ │ │ │ ├── console │ │ │ │ │ │ └── unnecessary_nullable_console_reporter.dart │ │ │ │ │ └── json │ │ │ │ │ │ └── unnecessary_nullable_json_reporter.dart │ │ │ │ └── unnecessary_nullable_report_params.dart │ │ │ ├── unnecessary_nullable_analysis_config.dart │ │ │ ├── unnecessary_nullable_analyzer.dart │ │ │ └── unnecessary_nullable_config.dart │ │ ├── unused_code_analyzer │ │ │ ├── models │ │ │ │ ├── file_elements_usage.dart │ │ │ │ ├── unused_code_file_report.dart │ │ │ │ └── unused_code_issue.dart │ │ │ ├── public_code_visitor.dart │ │ │ ├── reporters │ │ │ │ ├── reporter_factory.dart │ │ │ │ ├── reporters_list │ │ │ │ │ ├── console │ │ │ │ │ │ └── unused_code_console_reporter.dart │ │ │ │ │ └── json │ │ │ │ │ │ └── unused_code_json_reporter.dart │ │ │ │ └── unused_code_report_params.dart │ │ │ ├── unused_code_analysis_config.dart │ │ │ ├── unused_code_analyzer.dart │ │ │ ├── unused_code_config.dart │ │ │ └── used_code_visitor.dart │ │ ├── unused_files_analyzer │ │ │ ├── models │ │ │ │ └── unused_files_file_report.dart │ │ │ ├── reporters │ │ │ │ ├── reporter_factory.dart │ │ │ │ ├── reporters_list │ │ │ │ │ ├── console │ │ │ │ │ │ └── unused_files_console_reporter.dart │ │ │ │ │ └── json │ │ │ │ │ │ └── unused_files_json_reporter.dart │ │ │ │ └── unused_files_report_params.dart │ │ │ ├── unused_files_analysis_config.dart │ │ │ ├── unused_files_analyzer.dart │ │ │ ├── unused_files_config.dart │ │ │ └── unused_files_visitor.dart │ │ └── unused_l10n_analyzer │ │ │ ├── models │ │ │ ├── unused_l10n_file_report.dart │ │ │ └── unused_l10n_issue.dart │ │ │ ├── reporters │ │ │ ├── reporter_factory.dart │ │ │ ├── reporters_list │ │ │ │ ├── console │ │ │ │ │ └── unused_l10n_console_reporter.dart │ │ │ │ └── json │ │ │ │ │ └── unused_l10n_json_reporter.dart │ │ │ └── unused_l10n_report_params.dart │ │ │ ├── unused_l10n_analysis_config.dart │ │ │ ├── unused_l10n_analyzer.dart │ │ │ ├── unused_l10n_config.dart │ │ │ └── unused_l10n_visitor.dart │ ├── cli │ │ ├── cli_runner.dart │ │ ├── commands │ │ │ ├── analyze_command.dart │ │ │ ├── base_command.dart │ │ │ ├── check_unnecessary_nullable_command.dart │ │ │ ├── check_unused_code_command.dart │ │ │ ├── check_unused_files_command.dart │ │ │ ├── check_unused_l10n_command.dart │ │ │ └── fix_lints_command.dart │ │ ├── exceptions │ │ │ └── invalid_argument_exception.dart │ │ ├── models │ │ │ ├── flag_names.dart │ │ │ └── parsed_arguments.dart │ │ └── utils │ │ │ └── detect_sdk_path.dart │ ├── config_builder │ │ ├── analysis_options_utils.dart │ │ ├── config_builder.dart │ │ └── models │ │ │ └── analysis_options.dart │ ├── logger │ │ ├── logger.dart │ │ └── progress.dart │ ├── reporters │ │ ├── github_workflow_commands.dart │ │ ├── models │ │ │ ├── checkstyle_reporter.dart │ │ │ ├── code_climate_reporter.dart │ │ │ ├── console_reporter.dart │ │ │ ├── file_report.dart │ │ │ ├── github_reporter.dart │ │ │ ├── html_reporter.dart │ │ │ ├── json_reporter.dart │ │ │ └── reporter.dart │ │ └── resources │ │ │ ├── base.css │ │ │ ├── main.css │ │ │ ├── normalize.css │ │ │ └── variables.css │ ├── utils │ │ ├── analyzer_utils.dart │ │ ├── dart_types_utils.dart │ │ ├── exclude_utils.dart │ │ ├── flame_type_utils.dart │ │ ├── flutter_types_utils.dart │ │ ├── node_utils.dart │ │ ├── object_extensions.dart │ │ ├── path_utils.dart │ │ ├── string_extensions.dart │ │ ├── suppression.dart │ │ └── yaml_utils.dart │ └── version.dart ├── unnecessary_nullable_analyzer.dart ├── unused_code_analyzer.dart ├── unused_files_analyzer.dart └── unused_l10n_analyzer.dart ├── pubspec.yaml ├── test ├── resources │ ├── abstract_class.dart │ ├── analysis_options_common.yaml │ ├── analysis_options_pkg.yaml │ ├── analysis_options_repo.yaml │ ├── analysis_options_with_extends.yaml │ ├── analysis_options_with_import.yaml │ ├── class_with_factory_constructors.dart │ ├── cyclomatic_complexity_metric_example.dart │ ├── extension.dart │ ├── file_paths_folder │ │ ├── first_file.dart │ │ ├── inner_folder │ │ │ └── first_inner_file.dart │ │ └── second_file.dart │ ├── functions.dart │ ├── halstead_volume_metric_example.dart │ ├── lines_of_code_metric_example.dart │ ├── lint_analyzer │ │ ├── lint_analyzer_example.dart │ │ ├── lint_analyzer_exclude_example.dart │ │ ├── lint_fix_fixed_example.dart │ │ └── lint_fix_original_example.dart │ ├── maintability_index_metric_example.dart │ ├── maximum_nesting_level_metric_example.dart │ ├── mixin.dart │ ├── number_of_parameters_metric_example.dart │ ├── source_lines_of_code_metric_example.dart │ ├── suppression_all_example.dart │ ├── suppression_example.dart │ ├── technical_debt_metric_example.dart │ ├── technical_debt_metric_example2.dart │ ├── test_lints │ │ ├── lib │ │ │ ├── analysis_options.1.0.0.yaml │ │ │ ├── analysis_options.yaml │ │ │ └── presets.yaml │ │ └── pubspec.yaml │ ├── unnecessary_nullable_analyzer │ │ ├── generated │ │ │ └── some_file.freezed.dart │ │ ├── nullable_class_parameters.dart │ │ ├── nullable_function_parameters.dart │ │ ├── nullable_method_parameters.dart │ │ ├── nullable_widget_key_parameters.dart │ │ ├── suppressed_file.dart │ │ └── unnecessary_nullable_example.dart │ ├── unused_code_analyzer │ │ ├── conditional_file.dart │ │ ├── conditional_prefixed_file.dart │ │ ├── export.dart │ │ ├── exported_members.dart │ │ ├── generated │ │ │ └── some_file.freezed.dart │ │ ├── library │ │ │ ├── entry_point.dart │ │ │ ├── resources │ │ │ │ ├── app_icons.dart │ │ │ │ ├── app_strings.dart │ │ │ │ └── resources.dart │ │ │ └── src │ │ │ │ └── usage.dart │ │ ├── not_used.dart │ │ ├── public_members.dart │ │ ├── suppressed_file.dart │ │ ├── unconditional_file.dart │ │ ├── unconditional_prefixed_file.dart │ │ └── unused_code_example.dart │ ├── unused_files_analyzer │ │ ├── annotation_file.dart │ │ ├── conditional_file.dart │ │ ├── enrtypoint_file.dart │ │ ├── exported_file.dart │ │ ├── generated │ │ │ └── intl │ │ │ │ ├── messages_all.dart │ │ │ │ ├── messages_en.dart │ │ │ │ └── messages_ru.dart │ │ ├── imported_file.dart │ │ ├── part_file.dart │ │ ├── suppressed_file.dart │ │ ├── unconditional_file.dart │ │ ├── unused_file.dart │ │ └── unused_files_example.dart │ ├── unused_l10n_analyzer │ │ ├── base_localization.dart │ │ ├── test_i18n.dart │ │ └── unused_l10n_analyzer_example.dart │ └── weight_of_class_example.dart ├── src │ ├── analyzer_plugin │ │ └── analyzer_plugin_utils_test.dart │ ├── analyzers │ │ ├── lint_analyzer │ │ │ ├── anti_patterns │ │ │ │ ├── anti_patterns_list │ │ │ │ │ ├── long_method │ │ │ │ │ │ ├── examples │ │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ │ └── widget.dart │ │ │ │ │ │ └── long_method_test.dart │ │ │ │ │ └── long_parameter_list │ │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ │ └── long_parameter_list_test.dart │ │ │ │ ├── pattern_utils_test.dart │ │ │ │ └── patterns_factory_test.dart │ │ │ ├── lint_analyzer_test.dart │ │ │ ├── lint_config_test.dart │ │ │ ├── lint_utils_test.dart │ │ │ ├── metrics │ │ │ │ ├── metric_utils_test.dart │ │ │ │ ├── metrics_factory_test.dart │ │ │ │ ├── metrics_list │ │ │ │ │ ├── cyclomatic_complexity │ │ │ │ │ │ ├── cyclomatic_complexity_flow_visitor_test.dart │ │ │ │ │ │ └── cyclomatic_complexity_metric_test.dart │ │ │ │ │ ├── halstead_volume │ │ │ │ │ │ ├── halstead_volume_ast_visitor_test.dart │ │ │ │ │ │ └── halstead_volume_metric_test.dart │ │ │ │ │ ├── lines_of_code_metric_test.dart │ │ │ │ │ ├── maintainability_index_metric_test.dart │ │ │ │ │ ├── maximum_nesting_level │ │ │ │ │ │ ├── maximum_nesting_level_metric_test.dart │ │ │ │ │ │ └── nesting_level_visitor_test.dart │ │ │ │ │ ├── number_of_methods_test.dart │ │ │ │ │ ├── number_of_parameters_metric_test.dart │ │ │ │ │ ├── source_lines_of_code │ │ │ │ │ │ ├── source_code_visitor_test.dart │ │ │ │ │ │ └── source_lines_of_code_metric_test.dart │ │ │ │ │ ├── technical_debt │ │ │ │ │ │ └── technical_debt_metric_test.dart │ │ │ │ │ └── weight_of_class_test.dart │ │ │ │ └── models │ │ │ │ │ └── metric_value_level_test.dart │ │ │ ├── models │ │ │ │ ├── report_test.dart │ │ │ │ ├── severity_test.dart │ │ │ │ └── suppression_test.dart │ │ │ ├── reporters │ │ │ │ ├── reporter_factory_test.dart │ │ │ │ ├── reporters_list │ │ │ │ │ ├── checkstyle │ │ │ │ │ │ └── lint_checkstyle_reporter_test.dart │ │ │ │ │ ├── code_climate │ │ │ │ │ │ └── lint_code_climate_reporter_test.dart │ │ │ │ │ ├── console │ │ │ │ │ │ ├── lint_console_reporter_helper_test.dart │ │ │ │ │ │ └── lint_console_reporter_test.dart │ │ │ │ │ ├── html │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ ├── icon_test.dart │ │ │ │ │ │ │ ├── issue_details_tooltip_test.dart │ │ │ │ │ │ │ └── report_details_tooltip_test.dart │ │ │ │ │ │ └── utility_functions_test.dart │ │ │ │ │ ├── json │ │ │ │ │ │ └── lint_json_reporter_test.dart │ │ │ │ │ ├── lint_github_reporter_test.dart │ │ │ │ │ └── report_example.dart │ │ │ │ └── utility_selector_test.dart │ │ │ ├── rules │ │ │ │ ├── rule_utils_test.dart │ │ │ │ ├── rules_factory_test.dart │ │ │ │ └── rules_list │ │ │ │ │ ├── always_remove_listener │ │ │ │ │ ├── always_remove_listener_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── value_notifier_example.dart │ │ │ │ │ ├── arguments_ordering │ │ │ │ │ ├── arguments_ordering_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── class_example.dart │ │ │ │ │ │ ├── function_example.dart │ │ │ │ │ │ ├── mixed_example.dart │ │ │ │ │ │ ├── widget_example.dart │ │ │ │ │ │ └── widget_example_child_last.dart │ │ │ │ │ ├── avoid_banned_imports │ │ │ │ │ ├── avoid_banned_imports_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_border_all │ │ │ │ │ ├── avoid_border_all_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── example_with_final_variables.dart │ │ │ │ │ ├── avoid_cascade_after_if_null │ │ │ │ │ ├── avoid_cascade_after_if_null_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_collection_methods_with_unrelated_types │ │ │ │ │ ├── avoid_collection_methods_with_unrelated_types_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── dynamic_example.dart │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── nullable_example.dart │ │ │ │ │ ├── avoid_creating_vector_in_update │ │ │ │ │ ├── avoid_creating_vector_in_update_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_double_slash_imports │ │ │ │ │ ├── avoid_double_slash_imports_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_duplicate_exports │ │ │ │ │ ├── avoid_duplicate_exports_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_dynamic │ │ │ │ │ ├── avoid_dynamic_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_expanded_as_spacer │ │ │ │ │ ├── avoid_expanded_as_spacer_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_global_state │ │ │ │ │ ├── avoid_global_state_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_ignoring_return_values │ │ │ │ │ ├── avoid_ignoring_return_values_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_initializing_in_on_mount │ │ │ │ │ ├── avoid_initializing_in_on_mount_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_late_keyword │ │ │ │ │ ├── avoid_late_keyword_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_missing_enum_constant_in_map │ │ │ │ │ ├── avoid_missing_enum_constant_in_map_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_nested_conditional_expressions │ │ │ │ │ ├── avoid_nested_conditional_expressions_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_non_ascii_symbols │ │ │ │ │ ├── avoid_non_ascii_symbols_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_non_null_assertion │ │ │ │ │ ├── avoid_non_null_assertion_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_passing_async_when_sync_expected │ │ │ │ │ ├── avoid_passing_async_when_sync_expected_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_redundant_async │ │ │ │ │ ├── avoid_redundant_async_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_redundant_async_on_load │ │ │ │ │ ├── avoid_redundant_async_on_load_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_returning_widgets │ │ │ │ │ ├── avoid_returning_widgets_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── not_named_parameter_example.dart │ │ │ │ │ │ ├── nullable_example.dart │ │ │ │ │ │ └── provider_example.dart │ │ │ │ │ ├── avoid_shrink_wrap_in_lists │ │ │ │ │ ├── avoid_shrink_wrap_in_lists_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_substring │ │ │ │ │ ├── avoid_substring_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_throw_in_catch_block │ │ │ │ │ ├── avoid_throw_in_catch_block_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_top_level_members_in_tests │ │ │ │ │ ├── avoid_top_level_members_in_tests_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_unnecessary_conditionals │ │ │ │ │ ├── avoid_unnecessary_conditionals_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_unnecessary_setstate │ │ │ │ │ ├── avoid_unnecessary_setstate_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── state_subclass_example.dart │ │ │ │ │ ├── avoid_unnecessary_type_assertions │ │ │ │ │ ├── avoid_unnecessary_type_assertions_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── example_cases.dart │ │ │ │ │ │ ├── example_with_is.dart │ │ │ │ │ │ └── example_with_not_is.dart │ │ │ │ │ ├── avoid_unnecessary_type_casts │ │ │ │ │ ├── avoid_unnecessary_type_casts_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_unrelated_type_assertions │ │ │ │ │ ├── avoid_unrelated_type_assertions_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── avoid_unused_parameters │ │ │ │ │ ├── avoid_unused_parameters_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ ├── incorrect_example.dart │ │ │ │ │ │ └── tear_off_example.dart │ │ │ │ │ ├── avoid_wrapping_in_padding │ │ │ │ │ ├── avoid_wrapping_in_padding_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── ban_name │ │ │ │ │ ├── ban_name_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── classes.dart │ │ │ │ │ │ ├── dialogs.dart │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── binary_expression_operand_order │ │ │ │ │ ├── binary_expression_operand_order_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── check_for_equals_in_render_object_setters │ │ │ │ │ ├── check_for_equals_in_render_object_setters_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── consistent_update_render_object │ │ │ │ │ ├── consistent_update_render_object_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ ├── correct_game_instantiating │ │ │ │ │ ├── correct_game_instantiating_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── double_literal_format │ │ │ │ │ ├── double_literal_format_rule_test.dart │ │ │ │ │ └── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ ├── format_comment │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── example_documentation.dart │ │ │ │ │ │ ├── example_without_issue.dart │ │ │ │ │ │ └── multiline_example.dart │ │ │ │ │ └── format_comment_rule_test.dart │ │ │ │ │ ├── list_all_equatable_fields │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── list_all_equatable_fields_rule_test.dart │ │ │ │ │ ├── member_ordering │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── alphabetical_correct_example.dart │ │ │ │ │ │ ├── alphabetical_example.dart │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── flutter_widget_example.dart │ │ │ │ │ │ ├── multiple_classes_example.dart │ │ │ │ │ │ ├── not_widget_example.dart │ │ │ │ │ │ └── type_alphabetical_example.dart │ │ │ │ │ └── member_ordering_rule_test.dart │ │ │ │ │ ├── missing_test_assertion │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ ├── custom_assertions_example.dart │ │ │ │ │ │ ├── custom_methods_example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── missing_test_assertion_test.dart │ │ │ │ │ ├── newline_before_return │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── newline_before_return_rule_test.dart │ │ │ │ │ ├── no_blank_line_before_single_return │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── no_blank_line_before_single_return_rule_test.dart │ │ │ │ │ ├── no_boolean_literal_compare │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── no_boolean_literal_compare_rule_test.dart │ │ │ │ │ ├── no_empty_block │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── no_empty_block_rule_test.dart │ │ │ │ │ ├── no_equal_arguments │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── incorrect_example.dart │ │ │ │ │ │ ├── named_parameters_example.dart │ │ │ │ │ │ └── provider_example.dart │ │ │ │ │ └── no_equal_arguments_rule_test.dart │ │ │ │ │ ├── no_equal_then_else │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── no_equal_then_else_rule_test.dart │ │ │ │ │ ├── no_magic_number │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── array_example.dart │ │ │ │ │ │ ├── enum_example.dart │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── exceptions_example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── no_magic_number_rule_test.dart │ │ │ │ │ ├── no_object_declaration │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── no_object_declaration_rule_test.dart │ │ │ │ │ ├── prefer_async_await │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_async_await_rule_test.dart │ │ │ │ │ ├── prefer_commenting_analyzer_ignores │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_commenting_analyzer_ignores_rule_test.dart │ │ │ │ │ ├── prefer_conditional_expressions │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── nested_example.dart │ │ │ │ │ └── prefer_conditional_expressions_rule_test.dart │ │ │ │ │ ├── prefer_const_border_radius │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_const_border_radius_rule_test.dart │ │ │ │ │ ├── prefer_correct_edge_insets_constructor │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example_direction_only.dart │ │ │ │ │ │ ├── example_ltrb.dart │ │ │ │ │ │ ├── example_only.dart │ │ │ │ │ │ ├── example_steb.dart │ │ │ │ │ │ ├── example_symmetric.dart │ │ │ │ │ │ └── flutter_defines.dart │ │ │ │ │ └── prefer_correct_edge_insets_constructor_rule_test.dart │ │ │ │ │ ├── prefer_correct_identifier_length │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── class_example.dart │ │ │ │ │ │ ├── common_example.dart │ │ │ │ │ │ ├── enum_example.dart │ │ │ │ │ │ ├── extension_example.dart │ │ │ │ │ │ ├── mixin_example.dart │ │ │ │ │ │ └── without_error_example.dart │ │ │ │ │ └── prefer_correct_identifier_length_rule_test.dart │ │ │ │ │ ├── prefer_correct_test_file_name │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_correct_test_file_name_rule_test.dart │ │ │ │ │ ├── prefer_correct_type_name │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── class_example.dart │ │ │ │ │ │ ├── enum_example.dart │ │ │ │ │ │ ├── extension_example.dart │ │ │ │ │ │ └── mixin_example.dart │ │ │ │ │ └── prefer_correct_type_name_rule_test.dart │ │ │ │ │ ├── prefer_define_hero_tag │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_define_hero_tag_rule_test.dart │ │ │ │ │ ├── prefer_enums_by_name │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_enums_by_name_rule_test.dart │ │ │ │ │ ├── prefer_extracting_callbacks │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── example_max_line_count.dart │ │ │ │ │ └── prefer_extracting_callbacks_rule_test.dart │ │ │ │ │ ├── prefer_first │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_first_rule_test.dart │ │ │ │ │ ├── prefer_first_or_null │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_first_or_null_rule_test.dart │ │ │ │ │ ├── prefer_immediate_return │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_immediate_return_rule_test.dart │ │ │ │ │ ├── prefer_intl_name │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── incorrect_example.dart │ │ │ │ │ │ └── not_existing_example.dart │ │ │ │ │ └── prefer_intl_name_rule_test.dart │ │ │ │ │ ├── prefer_iterable_of │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── double_linked_queue_example.dart │ │ │ │ │ │ ├── hash_set_example.dart │ │ │ │ │ │ ├── linked_hash_set_example.dart │ │ │ │ │ │ ├── list_example.dart │ │ │ │ │ │ ├── list_queue_example.dart │ │ │ │ │ │ ├── queue_example.dart │ │ │ │ │ │ ├── queue_list_example.dart │ │ │ │ │ │ ├── set_example.dart │ │ │ │ │ │ └── splay_tree_set_example.dart │ │ │ │ │ └── prefer_iterable_of_rule_test.dart │ │ │ │ │ ├── prefer_last │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── double_linked_queue_example.dart │ │ │ │ │ │ ├── hash_set_example.dart │ │ │ │ │ │ ├── iterable_example.dart │ │ │ │ │ │ ├── linked_hash_set_example.dart │ │ │ │ │ │ ├── list_example.dart │ │ │ │ │ │ ├── list_queue_example.dart │ │ │ │ │ │ ├── queue_example.dart │ │ │ │ │ │ ├── set_example.dart │ │ │ │ │ │ ├── splay_tree_set_example.dart │ │ │ │ │ │ ├── unmodifiable_list_view_example.dart │ │ │ │ │ │ └── unmodifiable_set_view_example.dart │ │ │ │ │ └── prefer_last_rule_test.dart │ │ │ │ │ ├── prefer_match_file_name │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── empty_file.dart │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── example_with_issue.dart │ │ │ │ │ │ ├── example_with_state.dart │ │ │ │ │ │ ├── multiple_classes_example.dart │ │ │ │ │ │ ├── multiple_enums.dart │ │ │ │ │ │ ├── multiple_extensions.dart │ │ │ │ │ │ ├── multiple_mixins.dart │ │ │ │ │ │ ├── private_class.dart │ │ │ │ │ │ └── some_widget.codegen.dart │ │ │ │ │ └── prefer_match_file_name_rule_test.dart │ │ │ │ │ ├── prefer_moving_to_variable │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── arguments_example.dart │ │ │ │ │ │ ├── arguments_with_object_example.dart │ │ │ │ │ │ ├── assignment_example.dart │ │ │ │ │ │ ├── cascade_example.dart │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ ├── generics_example.dart │ │ │ │ │ │ ├── prefix_example.dart │ │ │ │ │ │ ├── provider_example.dart │ │ │ │ │ │ ├── scope_example.dart │ │ │ │ │ │ └── while_example.dart │ │ │ │ │ └── prefer_moving_to_variable_rule_test.dart │ │ │ │ │ ├── prefer_provide_intl_description │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── prefer_provide_intl_description_rule_test.dart │ │ │ │ │ ├── prefer_single_quotes │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_single_quotes_rule_test.dart │ │ │ │ │ ├── prefer_single_widget_per_file │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── correct_statefull_widget_example.dart │ │ │ │ │ │ ├── correct_stateless_widget_example.dart │ │ │ │ │ │ ├── flutter_defines.dart │ │ │ │ │ │ ├── incorrect_example.dart │ │ │ │ │ │ └── multi_widgets_example.dart │ │ │ │ │ └── prefer_single_widget_per_file_rule_test.dart │ │ │ │ │ ├── prefer_static_class │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ ├── correct_ignore_annotation_example.dart │ │ │ │ │ │ ├── correct_ignore_names_example.dart │ │ │ │ │ │ ├── correct_ignore_private_example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── prefer_static_class_rule_test.dart │ │ │ │ │ ├── prefer_trailing_comma │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── correct_example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── prefer_trailing_comma_rule_test.dart │ │ │ │ │ ├── prefer_using_list_view │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── prefer_using_list_view_rule_test.dart │ │ │ │ │ ├── provide_correct_intl_args │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── example.dart │ │ │ │ │ │ └── incorrect_example.dart │ │ │ │ │ └── provide_correct_intl_args_rule_test.dart │ │ │ │ │ ├── tag_name │ │ │ │ │ ├── examples │ │ │ │ │ │ └── example.dart │ │ │ │ │ └── tag_name_rule_test.dart │ │ │ │ │ └── use_setstate_synchronously │ │ │ │ │ ├── examples │ │ │ │ │ ├── assert_example.dart │ │ │ │ │ ├── context_mounted.dart │ │ │ │ │ ├── example.dart │ │ │ │ │ ├── extras_try_switch.dart │ │ │ │ │ └── known_errors.dart │ │ │ │ │ └── use_setstate_synchronously_rule_test.dart │ │ │ ├── scope_visitor_test.dart │ │ │ └── utils │ │ │ │ └── report_utils_test.dart │ │ ├── unnecessary_nullable_analyzer │ │ │ └── unnecessary_nullable_analyzer_test.dart │ │ ├── unused_code_analyzer │ │ │ ├── reporters │ │ │ │ ├── reporter_factory_test.dart │ │ │ │ └── reporters_list │ │ │ │ │ ├── console │ │ │ │ │ └── unused_code_console_reporter_test.dart │ │ │ │ │ └── unused_code_json_reporter_test.dart │ │ │ ├── unused_code_analyzer_test.dart │ │ │ └── unused_code_config_test.dart │ │ ├── unused_files_analyzer │ │ │ ├── reporters │ │ │ │ ├── reporter_factory_test.dart │ │ │ │ └── reporters_list │ │ │ │ │ ├── console │ │ │ │ │ └── unused_files_console_reporter_test.dart │ │ │ │ │ └── json │ │ │ │ │ └── unused_files_json_reporter_test.dart │ │ │ ├── unused_files_analyzer_test.dart │ │ │ └── unused_files_config_test.dart │ │ └── unused_l10n_analyzer │ │ │ ├── reporters │ │ │ ├── reporter_factory_test.dart │ │ │ └── reporters_list │ │ │ │ ├── console │ │ │ │ └── unused_l10n_console_reporter_test.dart │ │ │ │ └── unused_l10n_json_reporter_test.dart │ │ │ ├── unused_l10n_analyzer_test.dart │ │ │ └── unused_l10n_config_test.dart │ ├── cli │ │ ├── cli_runner_test.dart │ │ ├── commands │ │ │ ├── analyze_command_test.dart │ │ │ ├── base_command_test.dart │ │ │ ├── check_unnecessary_nullable_command_test.dart │ │ │ ├── check_unused_code_command_test.dart │ │ │ ├── check_unused_files_command_test.dart │ │ │ ├── check_unused_l10n_command_test.dart │ │ │ └── fix_command_test.dart │ │ └── utils │ │ │ └── detect_sdk_path_test.dart │ ├── config_builder │ │ ├── analysis_options_utils_test.dart │ │ └── models │ │ │ └── analysis_options_test.dart │ ├── helpers │ │ ├── anti_patterns_test_helper.dart │ │ ├── file_resolver.dart │ │ └── rule_test_helper.dart │ ├── reporters │ │ └── resources │ │ │ └── github_workflow_commands_test.dart │ └── utils │ │ ├── analyzer_utils_test.dart │ │ ├── exclude_utils_test.dart │ │ ├── path_utils_test.dart │ │ ├── string_extensions_test.dart │ │ └── yaml_utils_test.dart └── stubs_builders.dart ├── tool └── uncovered_coverage.dart └── tools └── analyzer_plugin ├── analysis_options.yaml ├── bin └── plugin.dart └── pubspec.yaml /.fvmrc: -------------------------------------------------------------------------------- 1 | { 2 | "flutter": "3.13.8" 3 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-report-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report Bug 3 | about: Report bugs found 4 | title: '' 5 | labels: Error 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the error** 11 | Please clearly describe the error found. 12 | 13 | **How ​​to replicate the bug** 14 | Step by step to reproduce the error: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. View error 19 | 20 | **Screen shots** 21 | If you have please add screenshots. 22 | 23 | **Runtime environment** 24 | - OS: Operating system, Firmware 25 | - Browser: [chrome, safari, firefox] 26 | - Version: -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-request-new-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request new functionality or improvement 3 | about: Write us your idea 4 | title: '' 5 | labels: Improvement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Description** 11 | Clearly describe the new functionality or enhancement. 12 | **Why do you consider it necessary?** 13 | Describe why you consider this new functionality or improvement necessary. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: Add more content or improvements to the documentation 4 | title: '' 5 | labels: Doc 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Clear and detailed description of the request** -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Support Request 3 | url: https://github.com/bancolombia/dart-code-linter/discussions 4 | about: Request support o help 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | - package-ecosystem: pub 8 | directory: / 9 | schedule: 10 | interval: daily 11 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: "flutter-actions" 2 | on: 3 | pull_request: 4 | branches: 5 | - trunk 6 | jobs: 7 | build: 8 | permissions: 9 | id-token: write 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 14 | - name: Setup Flutter SDK 15 | uses: flutter-actions/setup-flutter@v3 16 | with: 17 | channel: stable 18 | version: 3.13.8 19 | - name: Install dependencies 20 | run: dart pub get 21 | - name: Run tests 22 | run: dart test -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | # .github/workflows/publish.yml 2 | name: Publish to pub.dev 3 | 4 | on: 5 | push: 6 | tags: 7 | - 'v[0-9]+.[0-9]+.[0-9]+*' 8 | jobs: 9 | publish: 10 | name: 'Publish to pub.dev' 11 | environment: pub.dev 12 | permissions: 13 | id-token: write 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 18 | - name: Setup Flutter SDK 19 | uses: flutter-actions/setup-flutter@v3 20 | with: 21 | channel: stable 22 | version: 3.13.8 23 | - name: Install dependencies 24 | run: dart pub get 25 | - name: Publish to pub.dev 26 | run: dart pub publish -f 27 | -------------------------------------------------------------------------------- /.github/workflows/toolkit.yml: -------------------------------------------------------------------------------- 1 | name: Toolkit InnerSource-OpenSource 2 | on: workflow_dispatch 3 | jobs: 4 | build-repo: 5 | runs-on: ubuntu-latest 6 | name: Download tools and templates Innersource-Opensource 7 | steps: 8 | - name: Generate a Token 9 | id: generate_token 10 | uses: tibdex/github-app-token@v2 11 | with: 12 | app_id: ${{ secrets.APP_ID_ADMIN_GITHUB }} 13 | private_key: ${{ secrets.APP_PRIVATE_KEY_ADMIN_GITHUB }} 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | with: 17 | token: ${{ steps.generate_token.outputs.token }} 18 | - id: TestToolkit 19 | uses: bancolombia/opensource-innersource-toolkit@main 20 | with: 21 | GH_TOKEN: ${{ steps.generate_token.outputs.token }} 22 | TYPE_REPOSITORY: 'innersource' 23 | USERS_REVIEWERS: '@santitigaga @ajtortolero' 24 | TEMPLATE_LANGUAGE: 'EN' 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://www.dartlang.org/guides/libraries/private-files 2 | 3 | # JetBrains IDEs 4 | .idea/ 5 | *.iml 6 | 7 | # Files and directories created by pub 8 | .dart_tool/ 9 | .packages 10 | build/ 11 | # If you're building an application, you may want to check-in your pubspec.lock 12 | pubspec.lock 13 | 14 | # Directory created by dartdoc 15 | # If you don't generate documentation locally you can remove this line. 16 | doc/api/ 17 | 18 | # Avoid committing generated Javascript files: 19 | *.dart.js 20 | *.info.json # Produced by the --dump-info flag. 21 | *.js # When generated by dart2js. Don't specify *.js if your 22 | # project includes source files written in JavaScript. 23 | *.js_ 24 | *.js.deps 25 | *.js.map 26 | 27 | /coverage/* 28 | /metrics/* 29 | 30 | .DS_Store 31 | 32 | .vscode/launch.json 33 | test/fake_test.dart 34 | 35 | # FVM Version Cache 36 | .fvm/ -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | # See https://dart.dev/tools/pub/publishing#what-files-are-published 2 | 3 | /coverage/* 4 | /doc/* 5 | /metrics/* 6 | /tool/* 7 | /website/* 8 | /codecov.yaml 9 | /dart_dependency_validator.yaml 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.flutterSdkPath": ".fvm/versions/3.13.8" 3 | } -------------------------------------------------------------------------------- /GETTINGSTARTED.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | In this document we will explain how you can adapt your local environment. 3 | ## Tools you need to install 4 | List of software tools necessary to be able to execute the code in the local environment. You should also comment which software version will be used. 5 | ## Installation guide 6 | This section describes the step by step to raise the local environment. 7 | ## Document Authors 8 | A list of authors and documentation update dates, for example: 9 | - Daniel Herrera 6/17/2023 and network user 10 | - Esteban Toledo 3/3/2023 and network user 11 | - Diana Patricia 12/12/2022 and network user -------------------------------------------------------------------------------- /GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Government model 2 | 3 | ## Roles and Community Members 4 | 5 | ![Modelo de Gobierno](Roles-EN.png) 6 | 7 | | Roles | Responsibilities | 8 | | ---------------- | ------------------------------------------------------------ | 9 | | Product Owners | lead the open initiative and its projects, have a short, medium and long-term vision of the initiative and projects. Have criteria when making decisions. abdicate when it is for the good of the community and the project. 10 | | Maintainers | Maintainers have greater authority and responsibility in overall project management and coordination. 11 | | Trusted Committer | "Trusted committers" are contributors who have the ability to commit changes directly to the project repository and review others' contributions, but their authority is limited compared to maintainers | 12 | Contributors | Actively contribute with *commits*, *reviews* | 13 | Community Leader | Promotes *participation*, *collaboration*, provides necessary tools that facilitate communication with the community | 14 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 COMPANY NAME. This software and all of its components are protected by copyright and are the exclusive property of the rights holder. Exclusive use with internal fines of the organization. 2 | 3 | The NOTICE file content is for informational purposes only and does not modify the License. • You may add your own attribution notices as long as such additional attribution notices cannot be construed as a modification of the License. • You may add your own copyright statement to your modifications, and you may provide additional or different license terms and conditions for the use, reproduction, or distribution of your modifications, or for any such derivative works in their entirety, provided that its use, reproduction and distribution complies with the conditions established in this License. -------------------------------------------------------------------------------- /assets/.gitattributes: -------------------------------------------------------------------------------- 1 | * -text 2 | -------------------------------------------------------------------------------- /assets/quick-fixes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/dart-code-linter/976665473056877f5bb2bf088542a6d5258e90ee/assets/quick-fixes.png -------------------------------------------------------------------------------- /bin/metrics.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_code_linter/src/cli/cli_runner.dart'; 2 | 3 | Future main(List args) async { 4 | await CliRunner().run(args); 5 | } 6 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://www.dartlang.org/guides/libraries/private-files 2 | 3 | # Files and directories created by pub 4 | .dart_tool/ 5 | .packages 6 | build/ 7 | # If you're building an application, you may want to check-in your pubspec.lock 8 | pubspec.lock 9 | 10 | # Directory created by dartdoc 11 | # If you don't generate documentation locally you can remove this line. 12 | doc/api/ 13 | 14 | # Avoid committing generated Javascript files: 15 | *.dart.js 16 | *.info.json # Produced by the --dump-info flag. 17 | *.js # When generated by dart2js. Don't specify *.js if your 18 | # project includes source files written in JavaScript. 19 | *.js_ 20 | *.js.deps 21 | *.js.map 22 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | DCL is a static analysis tool and code from it is not expected to be used directly. Instead, it should be added as a dev dependency and installed [as described here](https://github.com/bancolombia/dart-code-linter/blob/trunk/GETTINGSTARTED.md). 4 | 5 | ## Preferred way: plugin and CLI 6 | 7 | To use DCL as a plugin or a CLI, check out [this repository](https://github.com/bancolombia/dart-code-linter/blob/trunk/example/lib/main.dart) with the example Flutter app. It covers DCL setup and shows all commands output. 8 | 9 | ## Additional way: as a library 10 | 11 | **Note:** usually you don't need to use DCL directly. 12 | 13 | DCL can be used directly as a library, imported and called from your code. Continue with [this example](https://github.com/bancolombia/dart-code-linter/blob/trunk/example/lib_example/lib/main.dart) in order to get more details. 14 | 15 | ## Presets 16 | 17 | Presets can be enabled with `extends` config, more details [can be found here](https://github.com/bancolombia/dart-code-linter/wiki/Presets). 18 | -------------------------------------------------------------------------------- /example/lib/src/unnecessary_nullable_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class UnnecessaryNullableWidget extends StatelessWidget { 4 | const UnnecessaryNullableWidget({super.key}); 5 | 6 | /// This callback declares a nullable parameter `value`, 7 | /// but it's actually always used with non-nullable argument. 8 | /// Run `dart run dart_code_linter:metrics check-unnecessary-nullable lib` to see the report. 9 | void someCallback(String? value) { 10 | print(value); 11 | } 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return TextButton( 16 | onPressed: () => someCallback('Hello'), 17 | child: Text('From world'), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/lib/src/unused_code_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/src/widgets/container.dart'; 2 | import 'package:flutter/src/widgets/framework.dart'; 3 | 4 | /// This variable is not referenced in any file and is actually unused. 5 | /// In order to spot such declarations, 6 | /// run `dart run dart_code_linter:metrics check-unused-code lib`. 7 | const someVariable = '1'; 8 | 9 | /// This function is not referenced in any file and is actually unused. 10 | /// In order to spot such declarations, 11 | /// run `dart run dart_code_linter:metrics check-unused-code lib`. 12 | String topLevelFunction() { 13 | print('Actually unused'); 14 | 15 | return 'Unused'; 16 | } 17 | 18 | /// This widget is used by `main.dart`. 19 | class UnusedCodeWidget extends StatelessWidget { 20 | const UnusedCodeWidget({super.key}); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return Container(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/lib/src/unused_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// This widget is not imported by any other file and is not a project entry point. 4 | /// It will be reported by `check-unused-files` command. 5 | /// Run `dart run dart_code_linter:metrics check-unused-files lib` to see the report. 6 | class UnusedWidget extends StatelessWidget { 7 | const UnusedWidget({super.key}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_example 2 | description: Example app with DCL setup. 3 | 4 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: ">=3.0.0 <4.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | cupertino_icons: ^1.0.2 15 | 16 | dev_dependencies: 17 | #dart_code_linter: 18 | dart_code_linter: 19 | path: ../ 20 | 21 | flutter: 22 | uses-material-design: true 23 | -------------------------------------------------------------------------------- /innactive-issues-closure.yaml: -------------------------------------------------------------------------------- 1 | name: Close inactive issues 2 | on: 3 | schedule: 4 | - cron: "30 1 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/stale@v9 14 | with: 15 | days-before-issue-stale: 60 16 | days-before-issue-close: 30 17 | stale-issue-label: "stale" 18 | stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." 19 | close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale." 20 | days-before-pr-stale: -1 21 | days-before-pr-close: -1 22 | repo-token: ${{ secrets.GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /lib/analyzer_plugin.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/analyzer_plugin/analyzer_plugin_starter.dart'; 2 | -------------------------------------------------------------------------------- /lib/cli_runner.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/cli/cli_runner.dart'; 2 | export 'package:dart_code_linter/src/logger/logger.dart'; 3 | export 'package:dart_code_linter/src/logger/progress.dart'; 4 | -------------------------------------------------------------------------------- /lib/config.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/config_builder/config_builder.dart'; 2 | export 'package:dart_code_linter/src/config_builder/models/analysis_options.dart'; 3 | -------------------------------------------------------------------------------- /lib/presets/all.yaml: -------------------------------------------------------------------------------- 1 | dart_code_linter: 2 | extends: 3 | - ./dart_all.yaml 4 | - ./flutter_all.yaml 5 | -------------------------------------------------------------------------------- /lib/presets/flame.yaml: -------------------------------------------------------------------------------- 1 | dart_code_linter: 2 | rules: 3 | - avoid-creating-vector-in-update 4 | - avoid-initializing-in-on-mount 5 | - avoid-redundant-async-on-load 6 | - correct-game-instantiating -------------------------------------------------------------------------------- /lib/presets/intl.yaml: -------------------------------------------------------------------------------- 1 | dart_code_linter: 2 | rules: 3 | - prefer-intl-name 4 | - prefer-provide-intl-description 5 | - provide-correct-intl-args -------------------------------------------------------------------------------- /lib/presets/metrics_recommended.yaml: -------------------------------------------------------------------------------- 1 | dart_code_linter: 2 | metrics: 3 | cyclomatic-complexity: 20 4 | halstead-volume: 150 5 | maintainability-index: 50 6 | maximum-nesting-level: 5 7 | number-of-parameters: 4 8 | number-of-methods: 10 9 | source-lines-of-code: 250 10 | metrics-exclude: 11 | - test/** 12 | 13 | -------------------------------------------------------------------------------- /lib/reporters.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/reporters/models/file_report.dart'; 2 | export 'package:dart_code_linter/src/reporters/models/reporter.dart'; 3 | -------------------------------------------------------------------------------- /lib/src/analyzer_plugin/analyzer_plugin_starter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:isolate'; 2 | 3 | import 'package:analyzer/file_system/physical_file_system.dart'; 4 | import 'package:analyzer_plugin/starter.dart'; 5 | 6 | import 'analyzer_plugin.dart'; 7 | 8 | void start(Iterable _, SendPort sendPort) { 9 | ServerPluginStarter( 10 | AnalyzerPlugin(resourceProvider: PhysicalResourceProvider.INSTANCE), 11 | ).start(sendPort); 12 | } 13 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/anti_patterns/pattern_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | import '../models/issue.dart'; 4 | import 'models/pattern.dart'; 5 | 6 | Issue createIssue({ 7 | required Pattern pattern, 8 | required SourceSpan location, 9 | required String message, 10 | String? verboseMessage, 11 | }) => 12 | Issue( 13 | ruleId: pattern.id, 14 | documentation: documentation(pattern), 15 | location: location, 16 | severity: pattern.severity, 17 | message: message, 18 | verboseMessage: verboseMessage, 19 | ); 20 | 21 | /// Returns a url of a page containing documentation associated with [pattern] 22 | Uri documentation(Pattern pattern) => Uri( 23 | scheme: 'https', 24 | host: 'dcl.apps.bancolombia.com', 25 | pathSegments: [ 26 | 'docs', 27 | 'anti-patterns', 28 | pattern.id, 29 | ], 30 | ); 31 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/metrics/models/class_metric.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | import 'package:collection/collection.dart'; 3 | 4 | import '../../models/scoped_class_declaration.dart'; 5 | import '../../models/scoped_function_declaration.dart'; 6 | import 'metric.dart'; 7 | 8 | /// An interface for metrics that compute a value for a class node. 9 | abstract class ClassMetric extends Metric { 10 | /// Initialize a newly created [ClassMetric]. 11 | const ClassMetric({ 12 | required super.id, 13 | required super.documentation, 14 | required super.threshold, 15 | required super.levelComputer, 16 | }); 17 | 18 | @override 19 | String? nodeType( 20 | AstNode node, 21 | Iterable classDeclarations, 22 | Iterable functionDeclarations, 23 | ) => 24 | classDeclarations 25 | .firstWhereOrNull((declaration) => declaration.declaration == node) 26 | ?.type 27 | .toString(); 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/metrics/models/function_metric.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | import 'package:collection/collection.dart'; 3 | 4 | import '../../models/scoped_class_declaration.dart'; 5 | import '../../models/scoped_function_declaration.dart'; 6 | import 'metric.dart'; 7 | 8 | /// An interface for metrics that compute a value for a function node. 9 | abstract class FunctionMetric extends Metric { 10 | /// Initialize a newly created [FunctionMetric]. 11 | const FunctionMetric({ 12 | required super.id, 13 | required super.documentation, 14 | required super.threshold, 15 | required super.levelComputer, 16 | }); 17 | 18 | @override 19 | String? nodeType( 20 | AstNode node, 21 | Iterable classDeclarations, 22 | Iterable functionDeclarations, 23 | ) => 24 | functionDeclarations 25 | .firstWhereOrNull((declaration) => declaration.declaration == node) 26 | ?.type 27 | .toString(); 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/metrics/models/metric_computation_result.dart: -------------------------------------------------------------------------------- 1 | import '../../models/context_message.dart'; 2 | 3 | /// An internal model for representing a value computed by a metric. 4 | class MetricComputationResult { 5 | /// The actual value computed by the metric. 6 | final T value; 7 | 8 | /// The additional information associated with the value. 9 | final Iterable context; 10 | 11 | /// Initialize a newly created [MetricComputationResult]. 12 | const MetricComputationResult({ 13 | required this.value, 14 | this.context = const [], 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/metrics/models/metric_documentation.dart: -------------------------------------------------------------------------------- 1 | import '../../models/entity_type.dart'; 2 | 3 | /// Represents any metric documentation. 4 | class MetricDocumentation { 5 | /// The name of the metric. 6 | final String name; 7 | 8 | /// The short name of the metric. 9 | final String shortName; 10 | 11 | /// The type of entities which will be measured by the metric. 12 | final EntityType measuredType; 13 | 14 | /// The recommended threshold value for this metric. 15 | final num recommendedThreshold; 16 | 17 | /// Initialize a newly created [MetricDocumentation]. 18 | /// 19 | /// This data object is used for a documentation generating from a source code. 20 | const MetricDocumentation({ 21 | required this.name, 22 | required this.shortName, 23 | required this.measuredType, 24 | required this.recommendedThreshold, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/metrics/scope_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | 3 | import '../models/scoped_function_declaration.dart'; 4 | 5 | /// Returns functions belonging to the passed [classNode] 6 | Iterable classMethods( 7 | AstNode classNode, 8 | Iterable functionDeclarations, 9 | ) => 10 | functionDeclarations 11 | .where((func) => func.enclosingDeclaration?.declaration == classNode) 12 | .toList(growable: false); 13 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/class_type.dart: -------------------------------------------------------------------------------- 1 | /// Enum class for type of a class entity. 2 | /// 3 | /// Used when reporting. 4 | class ClassType { 5 | /// The class entity representing a generic class. 6 | static const generic = ClassType._('class'); 7 | 8 | /// The class entity representing a mixin. 9 | static const mixin = ClassType._('mixin'); 10 | 11 | /// The class entity representing a extension. 12 | static const extension = ClassType._('extension'); 13 | 14 | final String _value; 15 | 16 | const ClassType._(this._value); 17 | 18 | @override 19 | String toString() => _value; 20 | } 21 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/context_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | /// Represents a message with a relevant information associated with a diagnostic. 4 | class ContextMessage { 5 | /// The message to be displayed to the user. 6 | final String message; 7 | 8 | /// The source location associated with or referenced by the message. 9 | final SourceSpan location; 10 | 11 | /// Initialize a newly created [ContextMessage] with the given [message] and [location]. 12 | const ContextMessage({ 13 | required this.message, 14 | required this.location, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/entity_type.dart: -------------------------------------------------------------------------------- 1 | /// Enum class for type of a type of entity. 2 | /// 3 | /// Used for classification of a metric. 4 | class EntityType { 5 | /// The entity representing a class, mixin or extension. 6 | static const classEntity = EntityType._('class'); 7 | 8 | /// The entity representing a whole file. 9 | static const fileEntity = EntityType._('file'); 10 | 11 | /// The entity representing a class method or constructor, function, getter or setter. 12 | static const methodEntity = EntityType._('method'); 13 | 14 | /// A list containing all of the enum values that are defined. 15 | static const values = [classEntity, fileEntity, methodEntity]; 16 | 17 | final String _value; 18 | 19 | const EntityType._(this._value); 20 | 21 | @override 22 | String toString() => _value; 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/function_type.dart: -------------------------------------------------------------------------------- 1 | /// Enum class for type of a function entity. 2 | /// 3 | /// Used when reporting. 4 | class FunctionType { 5 | /// The function entity representing a class constructor. 6 | static const constructor = FunctionType._('constructor'); 7 | 8 | /// The function entity representing a class method. 9 | static const method = FunctionType._('method'); 10 | 11 | /// The function entity representing a generic function. 12 | static const function = FunctionType._('function'); 13 | 14 | /// The function entity representing a getter. 15 | static const getter = FunctionType._('getter'); 16 | 17 | /// The function entity representing a setter. 18 | static const setter = FunctionType._('setter'); 19 | 20 | final String _value; 21 | 22 | const FunctionType._(this._value); 23 | 24 | @override 25 | String toString() => _value; 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/internal_resolved_unit_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | import 'package:analyzer/source/line_info.dart'; 3 | 4 | /// Represents a resolved unit from an AST analysis. 5 | class InternalResolvedUnitResult { 6 | final String path; 7 | final String content; 8 | final CompilationUnit unit; 9 | final LineInfo lineInfo; 10 | 11 | const InternalResolvedUnitResult( 12 | this.path, 13 | this.content, 14 | this.unit, 15 | this.lineInfo, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/replacement.dart: -------------------------------------------------------------------------------- 1 | /// Represents a single change. 2 | class Replacement { 3 | /// The human-readable description of the change to be applied. 4 | final String comment; 5 | 6 | /// The code with changes to replace original code with. 7 | final String replacement; 8 | 9 | /// Initialize a newly created [Replacement] with the given [comment] and [replacement]. 10 | const Replacement({ 11 | required this.comment, 12 | required this.replacement, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/scoped_class_declaration.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | 3 | import 'class_type.dart'; 4 | 5 | /// Represents a declaration of a class / mixin / extension. 6 | class ScopedClassDeclaration { 7 | /// The type of the declared class entity. 8 | final ClassType type; 9 | 10 | /// The node that represents a dart code snippet in the AST structure. 11 | final CompilationUnitMember declaration; 12 | 13 | /// Returns the user defined name. 14 | String get name { 15 | final node = declaration; 16 | String? name; 17 | 18 | if (node is ExtensionDeclaration) { 19 | name = node.name?.lexeme; 20 | } else if (node is NamedCompilationUnitMember) { 21 | name = node.name.lexeme; 22 | } 23 | 24 | return name ?? ''; 25 | } 26 | 27 | /// Initialize a newly created [ScopedClassDeclaration] with the given [type] and [declaration]. 28 | const ScopedClassDeclaration(this.type, this.declaration); 29 | } 30 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/models/summary_lint_report_record.dart: -------------------------------------------------------------------------------- 1 | import 'summary_lint_report_record_status.dart'; 2 | 3 | /// Represents a summary for a lint report. 4 | class SummaryLintReportRecord { 5 | final SummaryLintReportRecordStatus status; 6 | 7 | final String title; 8 | 9 | final T value; 10 | final int violations; 11 | 12 | const SummaryLintReportRecord({ 13 | this.status = SummaryLintReportRecordStatus.none, 14 | required this.title, 15 | required this.value, 16 | this.violations = 0, 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/lint_report_params.dart: -------------------------------------------------------------------------------- 1 | import '../models/summary_lint_report_record.dart'; 2 | 3 | /// Represents additional lint reporter params. 4 | class LintReportParams { 5 | final bool congratulate; 6 | final Iterable> summary; 7 | 8 | const LintReportParams({required this.congratulate, required this.summary}); 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/models/code_climate_issue_category.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unused-code 2 | 3 | /// Represents a Code Climate issue category. 4 | class CodeClimateIssueCategory { 5 | static const bugRisk = CodeClimateIssueCategory._('Bug Risk'); 6 | static const clarity = CodeClimateIssueCategory._('Clarity'); 7 | static const compatibility = CodeClimateIssueCategory._('Compatibility'); 8 | static const complexity = CodeClimateIssueCategory._('Complexity'); 9 | static const duplication = CodeClimateIssueCategory._('Duplication'); 10 | static const performance = CodeClimateIssueCategory._('Performance'); 11 | static const security = CodeClimateIssueCategory._('Security'); 12 | static const style = CodeClimateIssueCategory._('Style'); 13 | 14 | final String _value; 15 | 16 | const CodeClimateIssueCategory._(this._value); 17 | 18 | @override 19 | String toString() => _value; 20 | } 21 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/models/code_climate_issue_location.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | /// Represents a Code Climate issue location. 4 | class CodeClimateIssueLocation { 5 | final String path; 6 | final SourceSpan location; 7 | 8 | const CodeClimateIssueLocation(this.path, this.location); 9 | 10 | /// Converts the location to JSON format. 11 | Map toJson() => { 12 | 'path': path, 13 | 'positions': { 14 | 'begin': { 15 | 'line': location.start.line, 16 | 'column': location.start.column, 17 | }, 18 | 'end': { 19 | 'line': location.end.line, 20 | 'column': location.end.column, 21 | }, 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/models/code_climate_issue_severity.dart: -------------------------------------------------------------------------------- 1 | /// Represents a Code Climate issue severity. 2 | class CodeClimateIssueSeverity { 3 | static const blocker = CodeClimateIssueSeverity._('blocker'); 4 | static const critical = CodeClimateIssueSeverity._('critical'); 5 | static const major = CodeClimateIssueSeverity._('major'); 6 | static const minor = CodeClimateIssueSeverity._('minor'); 7 | static const info = CodeClimateIssueSeverity._('info'); 8 | 9 | final String _value; 10 | 11 | const CodeClimateIssueSeverity._(this._value); 12 | 13 | @override 14 | String toString() => _value; 15 | } 16 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/models/function_metrics_report.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../../../../metrics/models/metric_value.dart'; 4 | 5 | class FunctionMetricsReport { 6 | final MetricValue cyclomaticComplexity; 7 | final MetricValue sourceLinesOfCode; 8 | final MetricValue maintainabilityIndex; 9 | final MetricValue argumentsCount; 10 | final MetricValue maximumNestingLevel; 11 | 12 | const FunctionMetricsReport({ 13 | required this.cyclomaticComplexity, 14 | required this.sourceLinesOfCode, 15 | required this.maintainabilityIndex, 16 | required this.argumentsCount, 17 | required this.maximumNestingLevel, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/models/icon_type.dart: -------------------------------------------------------------------------------- 1 | enum IconType { 2 | complexity, 3 | issue, 4 | } 5 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/models/report_table_record.dart: -------------------------------------------------------------------------------- 1 | import 'file_metrics_report.dart'; 2 | 3 | /// A table record 4 | /// 5 | /// used by html reporter to represent file system entiry with accomulated metrics 6 | class ReportTableRecord { 7 | final String title; 8 | final String link; 9 | 10 | final FileMetricsReport report; 11 | 12 | const ReportTableRecord({ 13 | required this.title, 14 | required this.link, 15 | required this.report, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/models/dart_rule.dart: -------------------------------------------------------------------------------- 1 | import 'rule.dart'; 2 | import 'rule_type.dart'; 3 | 4 | /// Represents a base class for common rules. 5 | abstract class DartRule extends Rule { 6 | const DartRule({ 7 | required super.id, 8 | required super.severity, 9 | required super.excludes, 10 | required super.includes, 11 | }) : super( 12 | type: RuleType.dart, 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/models/flame_rule.dart: -------------------------------------------------------------------------------- 1 | import 'rule.dart'; 2 | import 'rule_type.dart'; 3 | 4 | /// Represents a base class for Flame-specific rules. 5 | /// link: https://pub.dev/packages/flame 6 | abstract class FlameRule extends Rule { 7 | const FlameRule({ 8 | required super.id, 9 | required super.severity, 10 | required super.excludes, 11 | required super.includes, 12 | }) : super( 13 | type: RuleType.flame, 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/models/flutter_rule.dart: -------------------------------------------------------------------------------- 1 | import 'rule.dart'; 2 | import 'rule_type.dart'; 3 | 4 | /// Represents a base class for Flutter-specific rules. 5 | abstract class FlutterRule extends Rule { 6 | const FlutterRule({ 7 | required super.id, 8 | required super.severity, 9 | required super.excludes, 10 | required super.includes, 11 | }) : super( 12 | type: RuleType.flutter, 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/models/intl_rule.dart: -------------------------------------------------------------------------------- 1 | import 'rule.dart'; 2 | import 'rule_type.dart'; 3 | 4 | /// Represents a base class for intl-specific rules. 5 | abstract class IntlRule extends Rule { 6 | const IntlRule({ 7 | required super.id, 8 | required super.severity, 9 | required super.excludes, 10 | required super.includes, 11 | }) : super( 12 | type: RuleType.intl, 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/models/rule_type.dart: -------------------------------------------------------------------------------- 1 | /// Represents a rule type. Used by documentation path construction. 2 | class RuleType { 3 | final String value; 4 | 5 | const RuleType._(this.value); 6 | 7 | static const dart = RuleType._('dart'); 8 | static const flutter = RuleType._('flutter'); 9 | static const intl = RuleType._('intl'); 10 | static const angular = RuleType._('angular'); 11 | static const flame = RuleType._('flame'); 12 | } 13 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/node_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | 3 | String humanReadableNodeType(AstNode? node) { 4 | if (node is ClassDeclaration) { 5 | return 'Class'; 6 | } else if (node is EnumDeclaration) { 7 | return 'Enum'; 8 | } else if (node is ExtensionDeclaration) { 9 | return 'Extension'; 10 | } else if (node is MixinDeclaration) { 11 | return 'Mixin'; 12 | } 13 | 14 | return 'Node'; 15 | } 16 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'arguments_ordering_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _childLast = 'child-last'; 5 | static const _childLastDefault = false; 6 | 7 | static bool parseChildLast(Map config) => 8 | config[_childLast] as bool? ?? _childLastDefault; 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_banned_imports/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_banned_imports_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final List<_AvoidBannedImportsConfigEntry> _activeEntries; 5 | 6 | final _nodes = <_NodeWithMessage>[]; 7 | 8 | Iterable<_NodeWithMessage> get nodes => _nodes; 9 | 10 | _Visitor(this._activeEntries); 11 | 12 | @override 13 | void visitImportDirective(ImportDirective node) { 14 | final uri = node.uri.stringValue; 15 | if (uri == null) { 16 | return; 17 | } 18 | 19 | for (final entry in _activeEntries) { 20 | if (entry.deny.any((deny) => deny.hasMatch(uri))) { 21 | _nodes.add(_NodeWithMessage( 22 | node, 23 | 'Avoid banned imports (${entry.message}).', 24 | )); 25 | } 26 | } 27 | } 28 | } 29 | 30 | class _NodeWithMessage { 31 | final AstNode node; 32 | final String message; 33 | 34 | _NodeWithMessage(this.node, this.message); 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_cascade_after_if_null/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_cascade_after_if_null_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _expressions = []; 5 | 6 | Iterable get expressions => _expressions; 7 | 8 | @override 9 | void visitBinaryExpression(BinaryExpression node) { 10 | super.visitBinaryExpression(node); 11 | 12 | if (node.operator.type != TokenType.QUESTION_QUESTION) { 13 | return; 14 | } 15 | 16 | final parent = node.parent; 17 | if (parent is CascadeExpression) { 18 | _expressions.add(parent); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_collection_methods_with_unrelated_types_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _strictConfig = 'strict'; 5 | 6 | static bool parseIsStrictMode(Map config) => 7 | config[_strictConfig] == null || config[_strictConfig] == true; 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_double_slash_imports/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_double_slash_imports_rule.dart'; 2 | 3 | class _Visitor extends GeneralizingAstVisitor { 4 | final _nodes = []; 5 | 6 | Iterable get nodes => _nodes; 7 | 8 | _Visitor(); 9 | 10 | @override 11 | void visitUriBasedDirective(UriBasedDirective node) { 12 | final uri = node.uri.stringValue; 13 | if (uri == null) { 14 | return; 15 | } 16 | 17 | if (uri.contains('//') || (uri.contains(r'\\') && !uri.startsWith(r'\\'))) { 18 | _nodes.add(node); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_duplicate_exports/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_duplicate_exports_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _exports = {}; 5 | 6 | final _nodes = []; 7 | 8 | Iterable get nodes => _nodes; 9 | 10 | @override 11 | void visitExportDirective(ExportDirective node) { 12 | super.visitExportDirective(node); 13 | 14 | final uri = node.uri.stringValue; 15 | if (uri == null) { 16 | return; 17 | } 18 | 19 | if (_exports.contains(uri)) { 20 | _nodes.add(node); 21 | } 22 | 23 | _exports.add(uri); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_global_state/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_global_state_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _declarations = []; 5 | 6 | Iterable get declarations => _declarations; 7 | 8 | @override 9 | void visitVariableDeclaration(VariableDeclaration node) { 10 | super.visitVariableDeclaration(node); 11 | 12 | if (node.declaredElement?.enclosingElement is CompilationUnitElement) { 13 | if (_isNodeValid(node)) { 14 | _declarations.add(node); 15 | } 16 | } else if ((node.declaredElement?.isStatic ?? false) && 17 | _isNodeValid(node)) { 18 | _declarations.add(node); 19 | } 20 | } 21 | 22 | bool _isNodeValid(VariableDeclaration node) => 23 | !node.isFinal && 24 | !node.isConst && 25 | !(node.declaredElement?.isPrivate ?? false); 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_late_keyword/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_late_keyword_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _allowInitializedConfig = 'allow-initialized'; 5 | static const _ignoredTypesConfig = 'ignored-types'; 6 | 7 | static bool parseAllowInitialized(Map config) => 8 | config[_allowInitializedConfig] as bool? ?? false; 9 | 10 | static Iterable parseIgnoredTypes(Map config) => 11 | config.containsKey(_ignoredTypesConfig) && 12 | config[_ignoredTypesConfig] is Iterable 13 | ? List.from(config[_ignoredTypesConfig] as Iterable) 14 | : ['AnimationController']; 15 | } 16 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_nested_conditional_expressions/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_nested_conditional_expressions_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _acceptableLevelConfig = 'acceptable-level'; 5 | 6 | static const _defaultAcceptableLevel = 1; 7 | 8 | static int parseAcceptableLevel(Map config) { 9 | final level = _parseIntConfig(config, _acceptableLevelConfig); 10 | 11 | return level != null && level > 0 ? level : _defaultAcceptableLevel; 12 | } 13 | 14 | static int? _parseIntConfig(Map config, String name) => 15 | config[name] != null ? int.tryParse(config[name].toString()) : null; 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_nested_conditional_expressions/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_nested_conditional_expressions_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _nestingLevels = {}; 5 | 6 | final int _acceptableLevel; 7 | 8 | Iterable get expressions => _nestingLevels.entries 9 | .where((entry) => entry.value > _acceptableLevel) 10 | .map((entry) => entry.key); 11 | 12 | _Visitor(this._acceptableLevel); 13 | 14 | @override 15 | void visitConditionalExpression(ConditionalExpression node) { 16 | final parent = _getParentConditionalExpression(node); 17 | 18 | final level = (_nestingLevels[parent] ?? 0) + 1; 19 | _nestingLevels[node] = level; 20 | 21 | super.visitConditionalExpression(node); 22 | } 23 | 24 | ConditionalExpression? _getParentConditionalExpression( 25 | ConditionalExpression expression, 26 | ) => 27 | expression.parent?.thisOrAncestorOfType(); 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_ascii_symbols/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_non_ascii_symbols_rule.dart'; 2 | 3 | final _onlyAsciiSymbolsRegExp = RegExp(r'^[\u0000-\u007f]*$'); 4 | 5 | class _Visitor extends RecursiveAstVisitor { 6 | final _literals = []; 7 | 8 | Iterable get literals => _literals; 9 | 10 | @override 11 | void visitSimpleStringLiteral(SimpleStringLiteral node) { 12 | super.visitSimpleStringLiteral(node); 13 | 14 | if (!_onlyAsciiSymbolsRegExp.hasMatch(node.value)) { 15 | _literals.add(node); 16 | } 17 | } 18 | 19 | @override 20 | void visitStringInterpolation(StringInterpolation node) { 21 | super.visitStringInterpolation(node); 22 | 23 | for (final element in node.elements) { 24 | if (element is InterpolationString && 25 | !_onlyAsciiSymbolsRegExp.hasMatch(element.value)) { 26 | _literals.add(node); 27 | break; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_non_null_assertion_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _expressions = []; 5 | 6 | Iterable get expressions => _expressions; 7 | 8 | @override 9 | void visitPostfixExpression(PostfixExpression node) { 10 | super.visitPostfixExpression(node); 11 | 12 | if (node.operator.type == TokenType.BANG && 13 | !_isMapIndexOperator(node.operand)) { 14 | _expressions.add(node); 15 | } 16 | } 17 | 18 | bool _isMapIndexOperator(Expression operand) { 19 | if (operand is IndexExpression) { 20 | final type = operand.target?.staticType; 21 | 22 | return type is InterfaceType && 23 | (_isMapOrSubclassOfMap(type) || 24 | type.allSupertypes.any(_isMapOrSubclassOfMap)); 25 | } 26 | 27 | return false; 28 | } 29 | 30 | bool _isMapOrSubclassOfMap(DartType type) => type.isDartCoreMap; 31 | } 32 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_returning_widgets/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_returning_widgets_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignoredNamesConfig = 'ignored-names'; 5 | static const _ignoredAnnotationsConfig = 'ignored-annotations'; 6 | static const _allowNullable = 'allow-nullable'; 7 | 8 | static Iterable getIgnoredNames(Map config) => 9 | _getIterable(config, _ignoredNamesConfig) ?? []; 10 | 11 | static Iterable getIgnoredAnnotations(Map config) => 12 | _getIterable(config, _ignoredAnnotationsConfig) ?? 13 | functionalWidgetAnnotations; 14 | 15 | static bool getAllowNullable(Map config) => 16 | config[_allowNullable] as bool? ?? false; 17 | 18 | static Iterable? _getIterable( 19 | Map config, 20 | String name, 21 | ) => 22 | config[name] is Iterable 23 | ? List.from(config[name] as Iterable) 24 | : null; 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_substring/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_substring_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _expressions = []; 5 | 6 | Iterable get expressions => _expressions; 7 | 8 | @override 9 | void visitMethodInvocation(MethodInvocation node) { 10 | super.visitMethodInvocation(node); 11 | if (_isNotSubstringMethod(node)) { 12 | return; 13 | } 14 | _expressions.add(node); 15 | } 16 | 17 | bool _isNotSubstringMethod(MethodInvocation node) => 18 | node.methodName.name != 'substring'; 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_throw_in_catch_block/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'avoid_throw_in_catch_block_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _throwExpression = []; 5 | 6 | Iterable get throwExpression => _throwExpression; 7 | 8 | @override 9 | void visitCatchClause(CatchClause node) { 10 | super.visitCatchClause(node); 11 | 12 | final visitor = _CatchClauseVisitor(); 13 | node.visitChildren(visitor); 14 | 15 | _throwExpression.addAll(visitor.throwExpression); 16 | } 17 | } 18 | 19 | class _CatchClauseVisitor extends RecursiveAstVisitor { 20 | final _throwExpression = []; 21 | 22 | Iterable get throwExpression => _throwExpression; 23 | 24 | @override 25 | void visitThrowExpression(ThrowExpression node) { 26 | super.visitThrowExpression(node); 27 | 28 | _throwExpression.add(node); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/common_config.dart: -------------------------------------------------------------------------------- 1 | const functionalWidgetAnnotations = [ 2 | 'FunctionalWidget', 3 | 'swidget', 4 | 'hwidget', 5 | 'hcwidget', 6 | ]; 7 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/double_literal_format/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'double_literal_format_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _literals = []; 5 | 6 | Iterable get literals => _literals; 7 | 8 | @override 9 | void visitDoubleLiteral(DoubleLiteral node) { 10 | _literals.add(node); 11 | 12 | super.visitDoubleLiteral(node); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'format_comment_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignoredPatternsConfig = 'ignored-patterns'; 5 | static const _onlyDocComments = 'only-doc-comments'; 6 | 7 | static Iterable parseIgnoredPatterns(Map config) => 8 | config[_ignoredPatternsConfig] is Iterable 9 | ? List.from( 10 | config[_ignoredPatternsConfig] as Iterable, 11 | ).map(RegExp.new) 12 | : const []; 13 | 14 | static bool parseOnlyDocComments(Map config) => 15 | config[_onlyDocComments] == true; 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/models/annotation.dart: -------------------------------------------------------------------------------- 1 | part of '../member_ordering_rule.dart'; 2 | 3 | class _Annotation { 4 | final String name; 5 | final String? publicName; 6 | 7 | static const override = _Annotation._('override', 'overridden'); 8 | static const protected = _Annotation._('protected'); 9 | static const unset = _Annotation._('unset'); 10 | 11 | static const all = [ 12 | override, 13 | protected, 14 | unset, 15 | ]; 16 | 17 | const _Annotation._(this.name, [this.publicName]); 18 | 19 | static _Annotation parse(String? name) => all.firstWhere( 20 | (annotation) => 21 | annotation.name == name || 22 | (annotation.publicName != null && annotation.publicName == name), 23 | orElse: () => _Annotation.unset, 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/models/field_keyword.dart: -------------------------------------------------------------------------------- 1 | part of '../member_ordering_rule.dart'; 2 | 3 | class _FieldKeyword { 4 | final String type; 5 | 6 | static const isFinal = _FieldKeyword('final'); 7 | static const isConst = _FieldKeyword('const'); 8 | static const isVar = _FieldKeyword('var'); 9 | static const unset = _FieldKeyword('unset'); 10 | 11 | static const all = [ 12 | isFinal, 13 | isConst, 14 | isVar, 15 | unset, 16 | ]; 17 | 18 | const _FieldKeyword(this.type); 19 | 20 | static _FieldKeyword parse(String? name) => all.firstWhere( 21 | (type) => type.type == name, 22 | orElse: () => _FieldKeyword.unset, 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/models/member_type.dart: -------------------------------------------------------------------------------- 1 | part of '../member_ordering_rule.dart'; 2 | 3 | class _MemberType { 4 | final String type; 5 | final String? typeAlias; 6 | 7 | static const field = _MemberType._('fields'); 8 | static const method = _MemberType._('methods', typeAlias: 'method'); 9 | static const constructor = _MemberType._('constructors'); 10 | static const getter = _MemberType._('getters'); 11 | static const setter = _MemberType._('setters'); 12 | static const getterAndSetter = _MemberType._('getters-setters'); 13 | 14 | static const all = [ 15 | field, 16 | method, 17 | constructor, 18 | getter, 19 | setter, 20 | getterAndSetter, 21 | ]; 22 | 23 | const _MemberType._(this.type, {this.typeAlias}); 24 | 25 | static _MemberType? parse(String? name) => all 26 | .firstWhereOrNull((type) => name == type.type || name == type.typeAlias); 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/models/modifier.dart: -------------------------------------------------------------------------------- 1 | part of '../member_ordering_rule.dart'; 2 | 3 | class _Modifier { 4 | final String type; 5 | 6 | const _Modifier(this.type); 7 | 8 | static const public = _Modifier('public'); 9 | static const private = _Modifier('private'); 10 | static const unset = _Modifier('unset'); 11 | 12 | static const all = [ 13 | public, 14 | private, 15 | unset, 16 | ]; 17 | 18 | static _Modifier parse(String? name) => all 19 | .firstWhere((type) => type.type == name, orElse: () => _Modifier.unset); 20 | } 21 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/missing_test_assertion/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'missing_test_assertion_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _includeAssertionsConfig = 'include-assertions'; 5 | static const _includeMethodsConfig = 'include-methods'; 6 | 7 | static Iterable parseIncludeAssertions(Map config) => 8 | config.containsKey(_includeAssertionsConfig) && 9 | config[_includeAssertionsConfig] is Iterable 10 | ? List.from(config[_includeAssertionsConfig] as Iterable) 11 | : []; 12 | 13 | static Iterable parseIncludeMethods(Map config) => 14 | config.containsKey(_includeMethodsConfig) && 15 | config[_includeMethodsConfig] is Iterable 16 | ? List.from(config[_includeMethodsConfig] as Iterable) 17 | : []; 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/newline_before_return/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'newline_before_return_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _statements = []; 5 | 6 | Iterable get statements => _statements; 7 | 8 | @override 9 | void visitReturnStatement(ReturnStatement node) { 10 | super.visitReturnStatement(node); 11 | _statements.add(node); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_blank_line_before_single_return/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_blank_line_before_single_return_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _statements = []; 5 | 6 | Iterable get statements => _statements; 7 | 8 | @override 9 | void visitReturnStatement(ReturnStatement node) { 10 | super.visitReturnStatement(node); 11 | _statements.add(node); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_boolean_literal_compare/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_boolean_literal_compare_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | static const _scannedTokenTypes = {TokenType.EQ_EQ, TokenType.BANG_EQ}; 5 | 6 | final _expressions = []; 7 | 8 | Iterable get expressions => _expressions; 9 | 10 | @override 11 | void visitBinaryExpression(BinaryExpression node) { 12 | super.visitBinaryExpression(node); 13 | 14 | if (!_scannedTokenTypes.contains(node.operator.type)) { 15 | return; 16 | } 17 | 18 | if ((node.leftOperand is BooleanLiteral && 19 | _isTypeBoolean(node.rightOperand.staticType)) || 20 | (_isTypeBoolean(node.leftOperand.staticType) && 21 | node.rightOperand is BooleanLiteral)) { 22 | _expressions.add(node); 23 | } 24 | } 25 | 26 | bool _isTypeBoolean(DartType? type) => 27 | type != null && type.isDartCoreBool && !isNullableType(type); 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_empty_block/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_empty_block_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _emptyBlocks = []; 5 | 6 | Iterable get emptyBlocks => _emptyBlocks; 7 | 8 | @override 9 | void visitBlock(Block node) { 10 | super.visitBlock(node); 11 | 12 | if (node.statements.isEmpty && 13 | node.parent is! CatchClause && 14 | !(node.endToken.precedingComments?.lexeme.contains('TODO') ?? false)) { 15 | _emptyBlocks.add(node); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_equal_arguments/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'no_equal_arguments_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignoredParametersConfig = 'ignored-parameters'; 5 | static const _ignoredArgumentsConfig = 'ignored-arguments'; 6 | 7 | static Iterable parseIgnoredArguments(Map config) => 8 | config.containsKey(_ignoredArgumentsConfig) && 9 | config[_ignoredArgumentsConfig] is Iterable 10 | ? List.from(config[_ignoredArgumentsConfig] as Iterable) 11 | : []; 12 | 13 | static Iterable parseIgnoredParameters(Map config) => 14 | config.containsKey(_ignoredParametersConfig) && 15 | config[_ignoredParametersConfig] is Iterable 16 | ? List.from(config[_ignoredParametersConfig] as Iterable) 17 | : []; 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_equal_then_else/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_equal_then_else_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _nodes = []; 5 | 6 | Iterable get nodes => _nodes; 7 | 8 | @override 9 | void visitIfStatement(IfStatement node) { 10 | super.visitIfStatement(node); 11 | 12 | if (node.elseStatement != null && 13 | node.elseStatement is! IfStatement && 14 | node.thenStatement.toString() == node.elseStatement.toString()) { 15 | _nodes.add(node); 16 | } 17 | } 18 | 19 | @override 20 | void visitConditionalExpression(ConditionalExpression node) { 21 | super.visitConditionalExpression(node); 22 | 23 | if (node.thenExpression.toString() == node.elseExpression.toString()) { 24 | _nodes.add(node); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'no_magic_number_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _allowedConfigName = 'allowed'; 5 | 6 | static const _allowOnlyOnce = 'allow-only-once'; 7 | 8 | static const _defaultMagicNumbers = [-1, 0, 1]; 9 | 10 | static Iterable parseAllowedNumbers(Map config) => 11 | (config[_allowedConfigName] as Iterable?)?.cast() ?? 12 | _defaultMagicNumbers; 13 | 14 | static bool parseAllowOnlyOnce(Map config) => 15 | (config[_allowOnlyOnce] as bool?) ?? false; 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_magic_number_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _literals = []; 5 | 6 | Iterable get literals => _literals; 7 | 8 | @override 9 | void visitDoubleLiteral(DoubleLiteral node) { 10 | _literals.add(node); 11 | super.visitDoubleLiteral(node); 12 | } 13 | 14 | @override 15 | void visitIntegerLiteral(IntegerLiteral node) { 16 | _literals.add(node); 17 | super.visitIntegerLiteral(node); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/no_object_declaration/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'no_object_declaration_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _members = []; 5 | 6 | Iterable get members => _members; 7 | 8 | @override 9 | void visitFieldDeclaration(FieldDeclaration node) { 10 | super.visitFieldDeclaration(node); 11 | 12 | if (_hasObjectType(node.fields.type)) { 13 | _members.add(node); 14 | } 15 | } 16 | 17 | @override 18 | void visitMethodDeclaration(MethodDeclaration node) { 19 | super.visitMethodDeclaration(node); 20 | 21 | if (_hasObjectType(node.returnType)) { 22 | _members.add(node); 23 | } 24 | } 25 | 26 | bool _hasObjectType(TypeAnnotation? type) => 27 | type?.type?.isDartCoreObject ?? 28 | (type is NamedType && type.name2.lexeme == 'Object'); 29 | } 30 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_async_await/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_async_await_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _invocations = []; 5 | 6 | Iterable get invocations => _invocations; 7 | 8 | @override 9 | void visitMethodInvocation(MethodInvocation node) { 10 | super.visitMethodInvocation(node); 11 | 12 | final target = node.realTarget; 13 | 14 | if ((target?.staticType?.isDartAsyncFuture ?? false) && 15 | node.methodName.name == 'then') { 16 | _invocations.add(node); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_conditional_expressions/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_conditional_expressions_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignoreNestedConfig = 'ignore-nested'; 5 | 6 | static bool parseIgnoreNested(Map config) => 7 | (config[_ignoreNestedConfig] as bool?) ?? false; 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_edge_insets_constructor/models/edge_insets_data.dart: -------------------------------------------------------------------------------- 1 | part of '../prefer_correct_edge_insets_constructor_rule.dart'; 2 | 3 | @immutable 4 | class EdgeInsetsData { 5 | final String className; 6 | final String constructorName; 7 | final List params; 8 | 9 | const EdgeInsetsData(this.className, this.constructorName, this.params); 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_edge_insets_constructor/models/edge_insets_param.dart: -------------------------------------------------------------------------------- 1 | part of '../prefer_correct_edge_insets_constructor_rule.dart'; 2 | 3 | @immutable 4 | class EdgeInsetsParam { 5 | final String? name; 6 | final num? value; 7 | 8 | const EdgeInsetsParam({required this.value, this.name}); 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/validator.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_correct_identifier_length_rule.dart'; 2 | 3 | class _Validator { 4 | final int maxLength; 5 | final int minLength; 6 | final Iterable exceptions; 7 | 8 | _Validator({ 9 | required this.maxLength, 10 | required this.minLength, 11 | required this.exceptions, 12 | }); 13 | 14 | bool isValid(String name) => _validate(_getNameWithoutUnderscore(name)); 15 | 16 | bool _validate(String name) => 17 | exceptions.contains(name) || 18 | (name.length >= minLength && name.length <= maxLength); 19 | 20 | String _getNameWithoutUnderscore(String name) => 21 | name.startsWith('_') ? name.replaceFirst('_', '') : name; 22 | } 23 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_test_file_name/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_correct_test_file_name_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _namePatternConfig = 'name-pattern'; 5 | 6 | static String parseNamePattern(Map config) { 7 | final raw = config[_namePatternConfig]; 8 | 9 | return raw is String ? raw : '_test.dart'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_test_file_name/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_correct_test_file_name_rule.dart'; 2 | 3 | class _Visitor extends GeneralizingAstVisitor { 4 | final String path; 5 | final String pattern; 6 | 7 | final _declarations = []; 8 | 9 | Iterable get declaration => _declarations; 10 | 11 | _Visitor(this.path, this.pattern); 12 | 13 | @override 14 | void visitFunctionDeclaration(FunctionDeclaration node) { 15 | if (node.name.lexeme != 'main' || _matchesTestName(path)) { 16 | return; 17 | } 18 | 19 | _declarations.add(node); 20 | } 21 | 22 | bool _matchesTestName(String path) => path.endsWith(pattern); 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_type_name/validator.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_correct_type_name_rule.dart'; 2 | 3 | class _Validator { 4 | final int maxLength; 5 | final int minLength; 6 | final Iterable exceptions; 7 | 8 | _Validator({ 9 | required this.maxLength, 10 | required this.minLength, 11 | required this.exceptions, 12 | }); 13 | 14 | bool isValid(String name) => 15 | name.isEmpty || 16 | exceptions.contains(name) || 17 | (isUpperCase(name) && 18 | withoutUnderscore(name).length >= minLength && 19 | withoutUnderscore(name).length <= maxLength); 20 | 21 | bool isUpperCase(String name) { 22 | final className = withoutUnderscore(name); 23 | 24 | return className[0] == className[0].toUpperCase(); 25 | } 26 | 27 | String withoutUnderscore(String name) => 28 | name.startsWith('_') ? name.replaceFirst('_', '') : name; 29 | } 30 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_enums_by_name/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_enums_by_name_rule.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _invocations = []; 5 | 6 | Iterable get invocations => _invocations; 7 | 8 | @override 9 | void visitMethodInvocation(MethodInvocation node) { 10 | super.visitMethodInvocation(node); 11 | 12 | final target = node.target; 13 | if (target is PrefixedIdentifier) { 14 | if (_isEnum(target.prefix) && _hasValuesTarget(target.identifier)) { 15 | if (node.methodName.name == 'firstWhere') { 16 | _invocations.add(node); 17 | } 18 | } 19 | } 20 | } 21 | 22 | bool _isEnum(SimpleIdentifier prefix) => 23 | prefix.staticElement?.kind == ElementKind.ENUM; 24 | 25 | bool _hasValuesTarget(SimpleIdentifier identifier) => 26 | identifier.name == 'values'; 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_extracting_callbacks/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_extracting_callbacks_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignoredArgumentsConfig = 'ignored-named-arguments'; 5 | static const _allowedLineCountConfig = 'allowed-line-count'; 6 | 7 | static Iterable parseIgnoredArguments(Map config) => 8 | config.containsKey(_ignoredArgumentsConfig) && 9 | config[_ignoredArgumentsConfig] is Iterable 10 | ? List.from(config[_ignoredArgumentsConfig] as Iterable) 11 | : []; 12 | 13 | static int? parseAllowedLineCount(Map config) { 14 | final raw = config[_allowedLineCountConfig]; 15 | 16 | return raw is int? ? raw : null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_moving_to_variable_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _allowedDuplicatedChains = 'allowed-duplicated-chains'; 5 | 6 | static int? parseAllowedDuplicatedChains(Map config) { 7 | final raw = config[_allowedDuplicatedChains]; 8 | 9 | return raw is int? ? raw : null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_quotes/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_single_qoutes.dart'; 2 | 3 | class _Visitor extends RecursiveAstVisitor { 4 | final _expressions = []; 5 | 6 | Iterable get expressions => _expressions; 7 | 8 | @override 9 | void visitSimpleStringLiteral(SimpleStringLiteral node) { 10 | super.visitSimpleStringLiteral(node); 11 | 12 | if (node.isSingleQuoted) { 13 | return; // Already using single quotes 14 | } 15 | 16 | _expressions.add(node); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_single_widget_per_file_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _ignorePrivateWidgetsName = 'ignore-private-widgets'; 5 | 6 | static bool parseIgnorePrivateWidgets(Map config) => 7 | config[_ignorePrivateWidgetsName] == true; 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/visitor.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_single_widget_per_file_rule.dart'; 2 | 3 | class _Visitor extends SimpleAstVisitor { 4 | final bool _ignorePrivateWidgets; 5 | 6 | final _nodes = []; 7 | 8 | _Visitor({required bool ignorePrivateWidgets}) 9 | : _ignorePrivateWidgets = ignorePrivateWidgets; 10 | 11 | Iterable get nodes => 12 | _nodes.length > 1 ? _nodes.skip(1) : []; 13 | 14 | @override 15 | void visitClassDeclaration(ClassDeclaration node) { 16 | super.visitClassDeclaration(node); 17 | 18 | final classType = node.extendsClause?.superclass.type; 19 | if (isWidgetOrSubclass(classType) && 20 | (!_ignorePrivateWidgets || 21 | !Identifier.isPrivateName(node.name.lexeme))) { 22 | _nodes.add(node); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_trailing_comma/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of 'prefer_trailing_comma_rule.dart'; 2 | 3 | class _ConfigParser { 4 | static const _breakOnConfigName = 'break-on'; 5 | static const _oldBreakOnConfigName = 'break_on'; 6 | 7 | static int? parseBreakpoint(Map config) { 8 | final breakpoint = config.containsKey(_breakOnConfigName) 9 | ? config[_breakOnConfigName] 10 | : config[_oldBreakOnConfigName]; 11 | 12 | return breakpoint != null ? int.tryParse(breakpoint.toString()) : null; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/tag_name/utils/config_parser.dart: -------------------------------------------------------------------------------- 1 | part of '../tag_name_rule.dart'; 2 | 3 | const _varNamesLabel = 'var-names'; 4 | const _stripPrefixLabel = 'strip-prefix'; 5 | const _stripPostfixLabel = 'strip-postfix'; 6 | 7 | /// Parser for rule configuration. 8 | class _ConfigParser { 9 | static _ParsedConfig _parseConfig(Map value) => _ParsedConfig( 10 | varNames: (value[_varNamesLabel] as List? ?? []) 11 | .map((item) => item as String) 12 | .toList(), 13 | stripPrefix: value[_stripPrefixLabel] as String? ?? '', 14 | stripPostfix: value[_stripPostfixLabel] as String? ?? '', 15 | ); 16 | } 17 | 18 | class _ParsedConfig { 19 | final List varNames; 20 | final String stripPrefix; 21 | final String stripPostfix; 22 | 23 | _ParsedConfig({ 24 | required this.varNames, 25 | required this.stripPrefix, 26 | required this.stripPostfix, 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/analyzers/lint_analyzer/rules/rules_list/use_setstate_synchronously/config.dart: -------------------------------------------------------------------------------- 1 | part of 'use_setstate_synchronously_rule.dart'; 2 | 3 | Set readMethods(Map options) { 4 | final methods = options['methods']; 5 | 6 | return methods != null && methods is Iterable 7 | ? methods.whereType().toSet() 8 | : {'setState'}; 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/analyzers/unnecessary_nullable_analyzer/models/invocations_usage.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/ast/ast.dart'; 2 | import 'package:analyzer/dart/element/element.dart'; 3 | 4 | /// A container with information about used imports prefixes and used imported 5 | /// elements. 6 | class InvocationsUsage { 7 | /// The set of referenced top-level elements. 8 | final Map?> elements = {}; 9 | 10 | final Set exports = {}; 11 | 12 | void addElementUsage(Element element, Set? expressions) { 13 | elements.update( 14 | element, 15 | (value) { 16 | if (expressions == null || value == null) { 17 | return null; 18 | } 19 | 20 | return value..addAll(expressions); 21 | }, 22 | ifAbsent: () => expressions, 23 | ); 24 | } 25 | 26 | void merge(InvocationsUsage other) { 27 | other.elements.forEach(addElementUsage); 28 | exports.addAll(other.exports); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/src/analyzers/unnecessary_nullable_analyzer/models/unnecessary_nullable_file_report.dart: -------------------------------------------------------------------------------- 1 | import '../../../reporters/models/file_report.dart'; 2 | import 'unnecessary_nullable_issue.dart'; 3 | 4 | /// Represents unused code report collected for a file. 5 | class UnnecessaryNullableFileReport implements FileReport { 6 | /// The path to the target file. 7 | @override 8 | final String path; 9 | 10 | /// The path to the target file relative to the package root. 11 | @override 12 | final String relativePath; 13 | 14 | /// The issues detected in the target file. 15 | final Iterable issues; 16 | 17 | const UnnecessaryNullableFileReport({ 18 | required this.path, 19 | required this.relativePath, 20 | required this.issues, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /lib/src/analyzers/unnecessary_nullable_analyzer/models/unnecessary_nullable_issue.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | /// Represents an issue detected by the unused code check. 4 | class UnnecessaryNullableIssue { 5 | /// The name of the unused declaration. 6 | final String declarationName; 7 | 8 | /// The type of the unused declaration. 9 | final String declarationType; 10 | 11 | final Iterable parameters; 12 | 13 | /// The source location associated with this issue. 14 | final SourceLocation location; 15 | 16 | /// Initialize a newly created [UnnecessaryNullableIssue]. 17 | /// 18 | /// The issue is associated with the given [location]. Used for 19 | /// creating an unused code report. 20 | const UnnecessaryNullableIssue({ 21 | required this.declarationName, 22 | required this.declarationType, 23 | required this.parameters, 24 | required this.location, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unnecessary_nullable_analyzer/reporters/unnecessary_nullable_report_params.dart: -------------------------------------------------------------------------------- 1 | /// Represents additional unnecessary nullable reporter params. 2 | class UnnecessaryNullableReportParams { 3 | final bool congratulate; 4 | 5 | const UnnecessaryNullableReportParams({required this.congratulate}); 6 | } 7 | -------------------------------------------------------------------------------- /lib/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analysis_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:glob/glob.dart'; 2 | 3 | /// Represents converted unused code config which contains parsed entities. 4 | class UnnecessaryNullableAnalysisConfig { 5 | final Iterable globalExcludes; 6 | final Iterable analyzerExcludedPatterns; 7 | final bool isMonorepo; 8 | 9 | const UnnecessaryNullableAnalysisConfig( 10 | this.globalExcludes, 11 | this.analyzerExcludedPatterns, { 12 | required this.isMonorepo, 13 | }); 14 | 15 | Map toJson() => { 16 | 'global-excludes': globalExcludes.map((glob) => glob.pattern).toList(), 17 | 'analyzer-excluded-patterns': 18 | analyzerExcludedPatterns.map((glob) => glob.pattern).toList(), 19 | 'is-monorepo': isMonorepo, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/models/file_elements_usage.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/element/element.dart'; 2 | 3 | /// A container with information about used imports prefixes and used imported 4 | /// elements. 5 | class FileElementsUsage { 6 | /// The set of referenced top-level elements. 7 | final Set elements = {}; 8 | 9 | /// The set of extensions defining members that are referenced. 10 | final Set usedExtensions = {}; 11 | 12 | final Set exports = {}; 13 | 14 | final Map, Set> conditionalElements = {}; 15 | 16 | /// The map of referenced prefix elements and the elements that they prefix. 17 | final Map> prefixMap = {}; 18 | 19 | void merge(FileElementsUsage other) { 20 | elements.addAll(other.elements); 21 | usedExtensions.addAll(other.usedExtensions); 22 | exports.addAll(other.exports); 23 | conditionalElements.addAll(other.conditionalElements); 24 | prefixMap.addAll(other.prefixMap); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/models/unused_code_file_report.dart: -------------------------------------------------------------------------------- 1 | import '../../../reporters/models/file_report.dart'; 2 | import 'unused_code_issue.dart'; 3 | 4 | /// Represents unused code report collected for a file. 5 | class UnusedCodeFileReport implements FileReport { 6 | /// The path to the target file. 7 | @override 8 | final String path; 9 | 10 | /// The path to the target file relative to the package root. 11 | @override 12 | final String relativePath; 13 | 14 | /// The issues detected in the target file. 15 | final Iterable issues; 16 | 17 | const UnusedCodeFileReport({ 18 | required this.path, 19 | required this.relativePath, 20 | required this.issues, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/models/unused_code_issue.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | /// Represents an issue detected by the unused code check. 4 | class UnusedCodeIssue { 5 | /// The name of the unused declaration. 6 | final String declarationName; 7 | 8 | /// The type of the unused declaration. 9 | final String declarationType; 10 | 11 | /// The source location associated with this issue. 12 | final SourceLocation location; 13 | 14 | /// Initialize a newly created [UnusedCodeIssue]. 15 | /// 16 | /// The issue is associated with the given [location]. Used for 17 | /// creating an unused code report. 18 | const UnusedCodeIssue({ 19 | required this.declarationName, 20 | required this.declarationType, 21 | required this.location, 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/reporters/reporter_factory.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import '../../../reporters/models/console_reporter.dart'; 4 | import '../../../reporters/models/json_reporter.dart'; 5 | import '../../../reporters/models/reporter.dart'; 6 | import '../models/unused_code_file_report.dart'; 7 | import 'reporters_list/console/unused_code_console_reporter.dart'; 8 | import 'reporters_list/json/unused_code_json_reporter.dart'; 9 | import 'unused_code_report_params.dart'; 10 | 11 | final _implementedReports = Function( 13 | IOSink output, 14 | )>{ 15 | ConsoleReporter.id: UnusedCodeConsoleReporter.new, 16 | JsonReporter.id: UnusedCodeJsonReporter.new, 17 | }; 18 | 19 | Reporter? reporter({ 20 | required String name, 21 | required IOSink output, 22 | }) { 23 | final constructor = _implementedReports[name]; 24 | 25 | return constructor != null ? constructor(output) : null; 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/reporters/unused_code_report_params.dart: -------------------------------------------------------------------------------- 1 | /// Represents additional unused code reporter params. 2 | class UnusedCodeReportParams { 3 | final bool congratulate; 4 | 5 | const UnusedCodeReportParams({required this.congratulate}); 6 | } 7 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_code_analyzer/unused_code_analysis_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:glob/glob.dart'; 2 | 3 | /// Represents converted unused code config which contains parsed entities. 4 | class UnusedCodeAnalysisConfig { 5 | final Iterable globalExcludes; 6 | final Iterable analyzerExcludedPatterns; 7 | final bool isMonorepo; 8 | 9 | const UnusedCodeAnalysisConfig( 10 | this.globalExcludes, 11 | this.analyzerExcludedPatterns, { 12 | required this.isMonorepo, 13 | }); 14 | 15 | Map toJson() => { 16 | 'global-excludes': globalExcludes.map((glob) => glob.pattern).toList(), 17 | 'analyzer-excluded-patterns': 18 | analyzerExcludedPatterns.map((glob) => glob.pattern).toList(), 19 | 'is-monorepo': isMonorepo, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_files_analyzer/models/unused_files_file_report.dart: -------------------------------------------------------------------------------- 1 | import '../../../reporters/models/file_report.dart'; 2 | 3 | /// Represents the unused files report collected for a file. 4 | class UnusedFilesFileReport implements FileReport { 5 | /// The path to the target file. 6 | @override 7 | final String path; 8 | 9 | /// The path to the target file relative to the package root. 10 | @override 11 | final String relativePath; 12 | 13 | const UnusedFilesFileReport({ 14 | required this.path, 15 | required this.relativePath, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import '../../../reporters/models/console_reporter.dart'; 4 | import '../../../reporters/models/json_reporter.dart'; 5 | import '../../../reporters/models/reporter.dart'; 6 | import '../models/unused_files_file_report.dart'; 7 | import 'reporters_list/console/unused_files_console_reporter.dart'; 8 | import 'reporters_list/json/unused_files_json_reporter.dart'; 9 | import 'unused_files_report_params.dart'; 10 | 11 | final _implementedReports = Function( 13 | IOSink output, 14 | )>{ 15 | ConsoleReporter.id: UnusedFilesConsoleReporter.new, 16 | JsonReporter.id: UnusedFilesJsonReporter.new, 17 | }; 18 | 19 | Reporter? reporter({ 20 | required String name, 21 | required IOSink output, 22 | }) { 23 | final constructor = _implementedReports[name]; 24 | 25 | return constructor != null ? constructor(output) : null; 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_files_analyzer/reporters/unused_files_report_params.dart: -------------------------------------------------------------------------------- 1 | /// Represents additional unused files reporter params. 2 | class UnusedFilesReportParams { 3 | final bool congratulate; 4 | final bool deleteUnusedFiles; 5 | 6 | const UnusedFilesReportParams({ 7 | required this.congratulate, 8 | required this.deleteUnusedFiles, 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:glob/glob.dart'; 2 | 3 | /// Represents converted unused files config which contains parsed entities. 4 | class UnusedFilesAnalysisConfig { 5 | final Iterable globalExcludes; 6 | final bool isMonorepo; 7 | 8 | const UnusedFilesAnalysisConfig( 9 | this.globalExcludes, { 10 | required this.isMonorepo, 11 | }); 12 | 13 | Map toJson() => { 14 | 'global-excludes': globalExcludes.map((glob) => glob.pattern).toList(), 15 | 'is-monorepo': isMonorepo, 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_l10n_analyzer/models/unused_l10n_file_report.dart: -------------------------------------------------------------------------------- 1 | import '../../../reporters/models/file_report.dart'; 2 | import 'unused_l10n_issue.dart'; 3 | 4 | /// Represents unused localization report collected for a file. 5 | class UnusedL10nFileReport implements FileReport { 6 | /// The path to the target file. 7 | @override 8 | final String path; 9 | 10 | /// The path to the target file relative to the package root. 11 | @override 12 | final String relativePath; 13 | 14 | /// The issues detected in the target file. 15 | final Iterable issues; 16 | 17 | /// The name of a class with issues. 18 | final String className; 19 | 20 | const UnusedL10nFileReport({ 21 | required this.path, 22 | required this.relativePath, 23 | required this.issues, 24 | required this.className, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_l10n_analyzer/models/unused_l10n_issue.dart: -------------------------------------------------------------------------------- 1 | import 'package:source_span/source_span.dart'; 2 | 3 | /// Represents an issue detected by the unused localization check. 4 | class UnusedL10nIssue { 5 | /// The name of a class member, which is unused. 6 | final String memberName; 7 | 8 | /// The source location associated with this issue. 9 | final SourceLocation location; 10 | 11 | /// Initialize a newly created [UnusedL10nIssue]. 12 | /// 13 | /// The issue is associated with the given [location]. Used for 14 | /// creating an unused localization report. 15 | const UnusedL10nIssue({ 16 | required this.memberName, 17 | required this.location, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import '../../../reporters/models/console_reporter.dart'; 4 | import '../../../reporters/models/json_reporter.dart'; 5 | import '../../../reporters/models/reporter.dart'; 6 | import '../models/unused_l10n_file_report.dart'; 7 | import 'reporters_list/console/unused_l10n_console_reporter.dart'; 8 | import 'reporters_list/json/unused_l10n_json_reporter.dart'; 9 | import 'unused_l10n_report_params.dart'; 10 | 11 | final _implementedReports = Function( 13 | IOSink output, 14 | )>{ 15 | ConsoleReporter.id: UnusedL10nConsoleReporter.new, 16 | JsonReporter.id: UnusedL10nJsonReporter.new, 17 | }; 18 | 19 | Reporter? reporter({ 20 | required String name, 21 | required IOSink output, 22 | }) { 23 | final constructor = _implementedReports[name]; 24 | 25 | return constructor != null ? constructor(output) : null; 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_l10n_analyzer/reporters/unused_l10n_report_params.dart: -------------------------------------------------------------------------------- 1 | /// Represents additional unused l10n reporter params. 2 | class UnusedL10NReportParams { 3 | final bool congratulate; 4 | 5 | const UnusedL10NReportParams({required this.congratulate}); 6 | } 7 | -------------------------------------------------------------------------------- /lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:glob/glob.dart'; 2 | 3 | /// Represents converted unused localization config, 4 | /// which contains parsed entities. 5 | class UnusedL10nAnalysisConfig { 6 | final Iterable globalExcludes; 7 | final RegExp classPattern; 8 | 9 | UnusedL10nAnalysisConfig( 10 | this.globalExcludes, 11 | String? classPattern, 12 | ) : classPattern = RegExp(classPattern ?? r'I18n$'); 13 | 14 | Map toJson() => { 15 | 'global-excludes': globalExcludes.map((glob) => glob.pattern).toList(), 16 | 'class-pattern': classPattern.pattern, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/cli/exceptions/invalid_argument_exception.dart: -------------------------------------------------------------------------------- 1 | /// Exception thrown when an arguments not pass validation. 2 | class InvalidArgumentException implements Exception { 3 | /// Detailed message of what happened. 4 | final String message; 5 | 6 | /// Initialize a newly created [InvalidArgumentException]. 7 | /// 8 | /// The passed [message] helps user figure out in aproblem. 9 | const InvalidArgumentException(this.message); 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/reporters/models/checkstyle_reporter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:meta/meta.dart'; 4 | 5 | import 'file_report.dart'; 6 | import 'reporter.dart'; 7 | 8 | /// Creates reports in Checkstyle format widely understood by various CI and analysis tools 9 | abstract class CheckstyleReporter 10 | extends Reporter { 11 | static const String id = 'checkstyle'; 12 | 13 | @protected 14 | final IOSink output; 15 | 16 | const CheckstyleReporter(this.output); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/reporters/models/code_climate_reporter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:meta/meta.dart'; 4 | 5 | import 'file_report.dart'; 6 | import 'reporter.dart'; 7 | 8 | // Code Climate Engine Specification https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md 9 | 10 | /// Creates reports in Code Climate format widely understood by various CI and analysis tools 11 | abstract class CodeClimateReporter 12 | extends Reporter { 13 | static const String id = 'codeclimate'; 14 | static const String alternativeId = 'gitlab'; 15 | 16 | @protected 17 | final IOSink output; 18 | 19 | /// If true will report in GitLab Code Quality format. 20 | @protected 21 | final bool gitlabCompatible; 22 | 23 | const CodeClimateReporter( 24 | this.output, { 25 | this.gitlabCompatible = false, 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/reporters/models/console_reporter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:ansicolor/ansicolor.dart'; 4 | import 'package:meta/meta.dart'; 5 | 6 | import 'file_report.dart'; 7 | import 'reporter.dart'; 8 | 9 | /// Plain terminal reporter. 10 | abstract class ConsoleReporter extends Reporter { 11 | static const String id = 'console'; 12 | static const String verboseId = 'console-verbose'; 13 | 14 | final alarmPen = AnsiPen()..rgb(r: 0.88, g: 0.32, b: 0.36); 15 | final warningPen = AnsiPen()..rgb(r: 0.98, g: 0.68, b: 0.4); 16 | final okPen = AnsiPen()..rgb(r: 0.23, g: 0.61, b: 0.16); 17 | 18 | @protected 19 | final IOSink output; 20 | 21 | ConsoleReporter(this.output); 22 | } 23 | -------------------------------------------------------------------------------- /lib/src/reporters/models/file_report.dart: -------------------------------------------------------------------------------- 1 | /// Represents a report collected for a file. 2 | abstract class FileReport { 3 | /// The path to the target file. 4 | final String path; 5 | 6 | /// The path to the target file relative to the package root. 7 | final String relativePath; 8 | 9 | const FileReport({ 10 | required this.path, 11 | required this.relativePath, 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/reporters/models/github_reporter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:meta/meta.dart'; 4 | 5 | import '../github_workflow_commands.dart'; 6 | import 'file_report.dart'; 7 | import 'reporter.dart'; 8 | 9 | /// Creates report about issues in pull request based on GitHub Actions Workflow commands. 10 | abstract class GitHubReporter extends Reporter { 11 | static const String id = 'github'; 12 | 13 | static final commands = GitHubWorkflowCommands(); 14 | 15 | @protected 16 | final IOSink output; 17 | 18 | const GitHubReporter(this.output); 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/reporters/models/json_reporter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:meta/meta.dart'; 4 | 5 | import 'file_report.dart'; 6 | import 'reporter.dart'; 7 | 8 | /// Machine-readable report in JSON format. 9 | abstract class JsonReporter extends Reporter { 10 | static const String id = 'json'; 11 | 12 | @protected 13 | final IOSink output; 14 | 15 | @protected 16 | final int formatVersion; 17 | 18 | const JsonReporter(this.output, this.formatVersion); 19 | 20 | /// Returns a string representation of a timestamp. 21 | String getTimestamp() { 22 | final nowTime = DateTime.now(); 23 | 24 | return DateTime( 25 | nowTime.year, 26 | nowTime.month, 27 | nowTime.day, 28 | nowTime.hour, 29 | nowTime.minute, 30 | nowTime.second, 31 | ).toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/src/reporters/models/reporter.dart: -------------------------------------------------------------------------------- 1 | import 'file_report.dart'; 2 | 3 | /// Abstract reporter interface. 4 | abstract class Reporter { 5 | Future report( 6 | Iterable records, { 7 | Params? additionalParams, 8 | }); 9 | 10 | const Reporter(); 11 | } 12 | -------------------------------------------------------------------------------- /lib/src/reporters/resources/base.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | padding: var(--dart-code-linter-body-padding); 9 | font-family: var(--dart-code-linter-font-family); 10 | font-size: var(--dart-code-linter-body-font-size); 11 | } 12 | 13 | table { 14 | width: 100%; 15 | margin: 0; 16 | border-spacing: 0; 17 | font-size: inherit; 18 | table-layout: fixed; 19 | } 20 | 21 | table td { 22 | vertical-align: top; 23 | } 24 | 25 | pre, 26 | code { 27 | margin: 0; 28 | } 29 | -------------------------------------------------------------------------------- /lib/src/utils/exclude_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:glob/glob.dart'; 2 | import 'package:path/path.dart' as p; 3 | 4 | bool isIncluded(String absolutePath, Iterable includes) => 5 | includes.isEmpty || _hasMatch(absolutePath, includes); 6 | 7 | bool isExcluded(String absolutePath, Iterable excludes) => 8 | _hasMatch(absolutePath, excludes); 9 | 10 | Iterable createAbsolutePatterns( 11 | Iterable patterns, 12 | String root, 13 | ) => 14 | patterns 15 | .map((pattern) => 16 | Glob(p.normalize(p.join(root, pattern)).replaceAll(r'\', '/'))) 17 | .toList(); 18 | 19 | bool _hasMatch(String absolutePath, Iterable excludes) { 20 | final path = absolutePath.replaceAll(r'\', '/'); 21 | 22 | return excludes.any((exclude) => exclude.matches(path)); 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/utils/flame_type_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:analyzer/dart/element/type.dart'; 2 | 3 | bool isComponentOrSubclass(DartType? type) => 4 | _isComponent(type) || _isSubclassOfComponent(type); 5 | 6 | bool isVector(DartType? type) => 7 | type?.getDisplayString(withNullability: false) == 'Vector2'; 8 | 9 | bool _isComponent(DartType? type) => 10 | type?.getDisplayString(withNullability: false) == 'Component'; 11 | 12 | bool _isSubclassOfComponent(DartType? type) => 13 | type is InterfaceType && type.allSupertypes.any(_isComponent); 14 | -------------------------------------------------------------------------------- /lib/src/utils/object_extensions.dart: -------------------------------------------------------------------------------- 1 | extension ObjectExtensions on Object { 2 | T? as([T? defaultValue]) => (this is T) ? this as T : defaultValue; 3 | } 4 | -------------------------------------------------------------------------------- /lib/src/utils/path_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | String? uriToPath(Uri? uri) { 4 | if (uri == null) { 5 | return null; 6 | } 7 | 8 | if (uri.scheme == 'file') { 9 | return uri.toFilePath(); 10 | } 11 | 12 | return File(uri.path).absolute.path; 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/utils/string_extensions.dart: -------------------------------------------------------------------------------- 1 | final _camelRegExp = RegExp('(?=[A-Z])'); 2 | 3 | /// Various useful string extensions. 4 | extension StringExtensions on String { 5 | /// Returns a text from phrases in camel case. 6 | /// 7 | /// Example: print('camelCaseToText'.camelCaseToText()); => 'camel case to text' 8 | String camelCaseToText() => split(_camelRegExp).join(' ').toLowerCase(); 9 | 10 | /// Returns a string with capitalized first character. 11 | /// 12 | /// Example: print('capitalize'.capitalize()); => 'Capitalize' 13 | String capitalize() => this[0].toUpperCase() + substring(1); 14 | 15 | /// Returns a string in kebab case 16 | /// 17 | /// Example: print('snake_case'.snakeCaseToKebab()); => 'snake-case' 18 | String snakeCaseToKebab() => replaceAll('_', '-'); 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/version.dart: -------------------------------------------------------------------------------- 1 | const packageVersion = '2.0.0'; 2 | -------------------------------------------------------------------------------- /lib/unnecessary_nullable_analyzer.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/models/unnecessary_nullable_file_report.dart'; 2 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/models/unnecessary_nullable_issue.dart'; 3 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/reporters/reporters_list/console/unnecessary_nullable_console_reporter.dart'; 4 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/reporters/reporters_list/json/unnecessary_nullable_json_reporter.dart'; 5 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analysis_config.dart'; 6 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analyzer.dart'; 7 | export 'package:dart_code_linter/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_config.dart'; 8 | -------------------------------------------------------------------------------- /lib/unused_code_analyzer.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/models/unused_code_file_report.dart'; 2 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/models/unused_code_issue.dart'; 3 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/reporters/reporters_list/console/unused_code_console_reporter.dart'; 4 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/reporters/reporters_list/json/unused_code_json_reporter.dart'; 5 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/unused_code_analysis_config.dart'; 6 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart'; 7 | export 'package:dart_code_linter/src/analyzers/unused_code_analyzer/unused_code_config.dart'; 8 | -------------------------------------------------------------------------------- /lib/unused_files_analyzer.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/models/unused_files_file_report.dart'; 2 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart'; 3 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart'; 4 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart'; 5 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart'; 6 | export 'package:dart_code_linter/src/analyzers/unused_files_analyzer/unused_files_config.dart'; 7 | -------------------------------------------------------------------------------- /lib/unused_l10n_analyzer.dart: -------------------------------------------------------------------------------- 1 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/models/unused_l10n_file_report.dart'; 2 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/models/unused_l10n_issue.dart'; 3 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart'; 4 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart'; 5 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart'; 6 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart'; 7 | export 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/unused_l10n_config.dart'; 8 | -------------------------------------------------------------------------------- /test/resources/abstract_class.dart: -------------------------------------------------------------------------------- 1 | abstract class Doer { 2 | // Define instance variables and methods... 3 | 4 | void doSomething(); // Define an abstract method. 5 | } 6 | -------------------------------------------------------------------------------- /test/resources/analysis_options_common.yaml: -------------------------------------------------------------------------------- 1 | include: package:lints/recommended.yaml 2 | 3 | analyzer: 4 | exclude: 5 | - example/** 6 | strong-mode: 7 | implicit-casts: false 8 | implicit-dynamic: false 9 | 10 | dart_code_linter: 11 | metrics-exclude: 12 | - test/** 13 | rules: 14 | - rule-id4 15 | - rule-id5 16 | -------------------------------------------------------------------------------- /test/resources/analysis_options_pkg.yaml: -------------------------------------------------------------------------------- 1 | include: ./analysis_options_repo.yaml 2 | 3 | dart_code_linter: 4 | metrics: 5 | metric-id1: 10 6 | metrics-exclude: 7 | - documentation/** 8 | rules: 9 | rule-id1: true 10 | rule-id2: false 11 | rule-id4: true 12 | rule-id5: true 13 | -------------------------------------------------------------------------------- /test/resources/analysis_options_repo.yaml: -------------------------------------------------------------------------------- 1 | include: ./analysis_options_common.yaml 2 | 3 | linter: 4 | # rules: 5 | # avoid_print: true 6 | 7 | analyzer: 8 | plugins: 9 | - code_checker 10 | 11 | dart_code_linter: 12 | metrics: 13 | metric-id1: 20 14 | metric-id2: 30 15 | metric-id3: 4 16 | rules: 17 | rule-id3: 18 | alphabetize: true 19 | order: 20 | - first 21 | - third 22 | - second 23 | rule-id4: true 24 | rule-id5: false 25 | -------------------------------------------------------------------------------- /test/resources/analysis_options_with_extends.yaml: -------------------------------------------------------------------------------- 1 | include: package:lints/recommended.yaml 2 | 3 | analyzer: 4 | exclude: 5 | - example/** 6 | strong-mode: 7 | implicit-casts: false 8 | implicit-dynamic: false 9 | 10 | dart_code_linter: 11 | extends: 12 | - package:test_lints/presets.yaml 13 | metrics-exclude: 14 | - test/** 15 | rules: 16 | - rule-id4: 17 | exclude: 18 | - test/** 19 | - rule-id5 20 | -------------------------------------------------------------------------------- /test/resources/analysis_options_with_import.yaml: -------------------------------------------------------------------------------- 1 | include: package:test_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /test/resources/class_with_factory_constructors.dart: -------------------------------------------------------------------------------- 1 | class Logger { 2 | final String name; 3 | bool mute = false; 4 | 5 | // _cache is library-private, thanks to 6 | // the _ in front of its name. 7 | static final Map _cache = {}; 8 | 9 | factory Logger(String name) => 10 | _cache.putIfAbsent(name, () => Logger._internal(name)); 11 | 12 | factory Logger.fromJson(Map json) => 13 | Logger(json['name'].toString()); 14 | 15 | Logger._internal(this.name); 16 | 17 | void log(String msg) { 18 | if (!mute) { 19 | print(msg); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/resources/extension.dart: -------------------------------------------------------------------------------- 1 | extension NumberParsing on String { 2 | int parseInt() => int.parse(this); 3 | } 4 | -------------------------------------------------------------------------------- /test/resources/file_paths_folder/first_file.dart: -------------------------------------------------------------------------------- 1 | // ignore: no-empty-block 2 | void main() {} 3 | -------------------------------------------------------------------------------- /test/resources/file_paths_folder/inner_folder/first_inner_file.dart: -------------------------------------------------------------------------------- 1 | // ignore: no-empty-block 2 | void main() {} 3 | -------------------------------------------------------------------------------- /test/resources/file_paths_folder/second_file.dart: -------------------------------------------------------------------------------- 1 | // ignore: no-empty-block 2 | void main() {} 3 | -------------------------------------------------------------------------------- /test/resources/functions.dart: -------------------------------------------------------------------------------- 1 | // Define a function. 2 | void printInteger(int aNumber) { 3 | print('The number is $aNumber.'); // Print to console. 4 | } 5 | 6 | // This is where the app starts executing. 7 | void main() { 8 | const number = 42; // Declare and initialize a variable. 9 | printInteger(number); // Call a function. 10 | } 11 | -------------------------------------------------------------------------------- /test/resources/lint_analyzer/lint_analyzer_example.dart: -------------------------------------------------------------------------------- 1 | class LintAnalyzerExample {} 2 | -------------------------------------------------------------------------------- /test/resources/lint_analyzer/lint_analyzer_exclude_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_declarations, literal_only_boolean_expressions 2 | class ExcludeExample { 3 | void test() { 4 | late final int value; 5 | 6 | if (5 > 0) { 7 | value = 123; 8 | } 9 | 10 | print(value.toString()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/resources/lint_analyzer/lint_fix_fixed_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_declarations, literal_only_boolean_expressions 2 | class ExcludeExample { 3 | void test() { 4 | final value = [1, 2, 3]; 5 | 6 | print(value.firstOrNull); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/resources/lint_analyzer/lint_fix_original_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_declarations, literal_only_boolean_expressions 2 | class ExcludeExample { 3 | void test() { 4 | final value = [1, 2, 3]; 5 | 6 | print(value.first); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/resources/mixin.dart: -------------------------------------------------------------------------------- 1 | mixin Musical { 2 | bool canPlayPiano = false; 3 | bool canCompose = false; 4 | bool canConduct = false; 5 | 6 | void entertainMe() { 7 | if (canPlayPiano) { 8 | print('Playing piano'); 9 | } else if (canConduct) { 10 | print('Waving hands'); 11 | } else { 12 | print('Humming to self'); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/resources/suppression_all_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: type=lint 2 | 3 | void main() { 4 | const a = 5; 5 | const b = a + 5; 6 | } 7 | -------------------------------------------------------------------------------- /test/resources/suppression_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file:rule_id1 2 | 3 | void main() { 4 | // ignore: rule_id4 5 | const a = 5; // ignore: RULE_ID5 6 | 7 | // ignore comment 8 | // ignore:rule_id6 ,rule_id7, some comment about ignores 9 | const b = a + 5; // ignore: RULE_ID8, rule_id9, unused_local_variable 10 | } 11 | 12 | // ignore_for_file: rule_id2 , RULE_ID3 13 | -------------------------------------------------------------------------------- /test/resources/technical_debt_metric_example.dart: -------------------------------------------------------------------------------- 1 | // @dart=2.9 2 | 3 | // ignore_for_file: always_declare_return_types 4 | 5 | @Deprecated('Use Bar class') 6 | class Foo {} 7 | 8 | // TODO: todo comment 9 | // TODO(developer): flutter style todo comment 10 | // HACK: hack comment 11 | // FIXME: fixme comment 12 | // UNDONE: undone comment 13 | void fooBar() { 14 | // ignore: always_put_control_body_on_new_line 15 | final a = Foo() as dynamic; 16 | } 17 | -------------------------------------------------------------------------------- /test/resources/technical_debt_metric_example2.dart: -------------------------------------------------------------------------------- 1 | // @dart=2.12 2 | 3 | // commet 4 | 5 | /// Foo class 6 | class Foo {} 7 | 8 | void fooBar() { 9 | final a = Foo() as Object; 10 | } 11 | -------------------------------------------------------------------------------- /test/resources/test_lints/lib/analysis_options.1.0.0.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | plugins: 3 | - dart_code_linter 4 | -------------------------------------------------------------------------------- /test/resources/test_lints/lib/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:test_lints/analysis_options.1.0.0.yaml 2 | -------------------------------------------------------------------------------- /test/resources/test_lints/lib/presets.yaml: -------------------------------------------------------------------------------- 1 | dart_code_linter: 2 | rules: 3 | - rule-id10 4 | - rule-id4 5 | -------------------------------------------------------------------------------- /test/resources/test_lints/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: test_lints 2 | description: Lints for Dart and Flutter based on software industry standards and best practices. 3 | version: 1.0.0 4 | 5 | environment: 6 | sdk: ">=2.14.0 <3.0.0" 7 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/generated/some_file.freezed.dart: -------------------------------------------------------------------------------- 1 | void freeze() { 2 | print('brr'); 3 | } 4 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/nullable_class_parameters.dart: -------------------------------------------------------------------------------- 1 | class NullableClassParameters { 2 | final String? value; 3 | 4 | const NullableClassParameters(this.value); 5 | } 6 | 7 | // LINT 8 | class AlwaysUsedAsNonNullable { 9 | final String? anotherValue; 10 | 11 | const AlwaysUsedAsNonNullable(this.anotherValue); 12 | } 13 | 14 | class DefaultNonNullable { 15 | final String value; 16 | 17 | const DefaultNonNullable({this.value = '123'}); 18 | } 19 | 20 | // LINT 21 | class NamedNonNullable { 22 | final String? value; 23 | 24 | const NamedNonNullable({this.value}); 25 | } 26 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/nullable_function_parameters.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: avoid-unused-parameters, no-empty-block 2 | 3 | void doSomething(String? value) {} 4 | 5 | // LINT 6 | void alwaysNonNullableDoSomething(String? anotherValue) {} 7 | 8 | void multipleParametersUsed( 9 | String value, 10 | int anotherValue, { 11 | required String? name, 12 | String? secondName, 13 | String? thirdName, 14 | }) {} 15 | 16 | // LINT 17 | void multipleParametersWithNamed( 18 | String? value, 19 | int anotherValue, { 20 | required String? name, 21 | String? secondName, 22 | }) {} 23 | 24 | // LINT 25 | void multipleParametersWithOptional( 26 | String? value, 27 | int anotherValue, [ 28 | String? name, 29 | String? secondName, 30 | ]) {} 31 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/nullable_method_parameters.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: avoid-unused-parameters, no-empty-block 2 | 3 | class ClassWithMethods { 4 | final inner = ClassWithMethods(); 5 | 6 | void someMethod(String? value) {} 7 | 8 | // LINT 9 | void alwaysNonNullable(String? anotherValue) {} 10 | 11 | void multipleParametersUsed( 12 | String value, 13 | int anotherValue, { 14 | required String? name, 15 | }) {} 16 | 17 | // LINT 18 | void multipleParametersWithNamed( 19 | String? value, 20 | int anotherValue, { 21 | required String? name, 22 | String? secondName, 23 | }) {} 24 | 25 | // ignore: unnecessary-nullable 26 | void ignoredAlwaysNonNullable(String? anotherValue) {} 27 | 28 | void tearOff(String? anotherValue) {} 29 | 30 | void anotherTearOff(String? anotherValue) {} 31 | } 32 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/nullable_widget_key_parameters.dart: -------------------------------------------------------------------------------- 1 | class MyWidget extends StatelessWidget { 2 | const MyWidget(super.key); 3 | } 4 | 5 | class Widget { 6 | final Key? key; 7 | 8 | const Widget(this.key); 9 | } 10 | 11 | class StatelessWidget extends Widget { 12 | const StatelessWidget(super.key); 13 | } 14 | 15 | class Key {} 16 | 17 | class GlobalKey extends Key {} 18 | 19 | class AnotherWidget extends Widget { 20 | final void Function(String?) onSubmit; 21 | 22 | const AnotherWidget({required this.onSubmit}) : super(null); 23 | } 24 | -------------------------------------------------------------------------------- /test/resources/unnecessary_nullable_analyzer/suppressed_file.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unnecessary-nullable, avoid-unused-parameters, no-empty-block 2 | 3 | class IgnoredClassWithMethods { 4 | void someMethod(String? value) {} 5 | 6 | void alwaysNonNullable(String? anotherValue) {} 7 | 8 | void multipleParametersUsed( 9 | String value, 10 | int anotherValue, { 11 | required String? name, 12 | }) {} 13 | 14 | void multipleParametersWithNamed( 15 | String? value, 16 | int anotherValue, { 17 | required String? name, 18 | String? secondName, 19 | }) {} 20 | } 21 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/conditional_file.dart: -------------------------------------------------------------------------------- 1 | // ignore: prefer_expression_function_bodies 2 | String calculateResults() { 3 | return 'conditional results'; 4 | } 5 | 6 | bool hello() => false; // LINT 7 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/conditional_prefixed_file.dart: -------------------------------------------------------------------------------- 1 | int calculate() => 1; 2 | 3 | bool helloWorld() => false; // LINT 4 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/export.dart: -------------------------------------------------------------------------------- 1 | export 'exported_members.dart'; 2 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/exported_members.dart: -------------------------------------------------------------------------------- 1 | class SomeClass {} 2 | 3 | const int variable = 1; 4 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/generated/some_file.freezed.dart: -------------------------------------------------------------------------------- 1 | void freeze() { 2 | print('brr'); 3 | } 4 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/library/entry_point.dart: -------------------------------------------------------------------------------- 1 | export 'src/usage.dart'; 2 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/library/resources/app_icons.dart: -------------------------------------------------------------------------------- 1 | part of 'resources.dart'; 2 | 3 | class AppIcons { 4 | AppIcons._(); 5 | 6 | static const String authError = 'assets/icons/auth_error.svg'; 7 | } 8 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/library/resources/app_strings.dart: -------------------------------------------------------------------------------- 1 | part of 'resources.dart'; 2 | 3 | class AppStrings { 4 | AppStrings._(); 5 | 6 | static const String title = 'Application title'; 7 | } 8 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/library/resources/resources.dart: -------------------------------------------------------------------------------- 1 | part 'app_icons.dart'; 2 | part 'app_strings.dart'; 3 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/library/src/usage.dart: -------------------------------------------------------------------------------- 1 | import '../resources/resources.dart'; 2 | 3 | /// Checks if you are awesome. Spoiler: you are. 4 | class Awesome { 5 | bool get isAwesome => AppStrings.title.isNotEmpty; 6 | } 7 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/not_used.dart: -------------------------------------------------------------------------------- 1 | class NotUsed {} // LINT 2 | 3 | const int value = 15; // LINT 4 | 5 | // ignore: no-empty-block 6 | void someFunction() {} // LINT 7 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/suppressed_file.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unused-code 2 | 3 | class SomeClass {} 4 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/unconditional_file.dart: -------------------------------------------------------------------------------- 1 | // ignore: prefer_expression_function_bodies 2 | String calculateResults() { 3 | return 'unconditional results'; 4 | } 5 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/unconditional_prefixed_file.dart: -------------------------------------------------------------------------------- 1 | int calculate() => 2; 2 | -------------------------------------------------------------------------------- /test/resources/unused_code_analyzer/unused_code_example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unnecessary_statements, cascade_invocations, prefer_const_declarations, omit_local_variable_types 2 | 3 | import 'public_members.dart'; 4 | import 'unconditional_file.dart' 5 | if (dart.library.html) 'conditional_file.dart' 6 | if (dart.library.io) 'conditional_file.dart'; 7 | import 'unconditional_prefixed_file.dart' 8 | if (dart.library.html) 'conditional_prefixed_file.dart' 9 | if (dart.library.io) 'conditional_prefixed_file.dart' as config; 10 | 11 | void main() { 12 | final widget = MyWidget('hello'); 13 | 14 | if (someOtherVariable == widget.prop) { 15 | widget.createState(); 16 | } 17 | 18 | printBool(false); 19 | 20 | ClassWithStaticFiled.field; 21 | ClassWithStaticMethod.printHello(); 22 | 23 | final Hello str = 'world'; 24 | 25 | str.doNothing(); 26 | 27 | SomeEnum.hello; 28 | 29 | calculateResults(); 30 | 31 | config.calculate(); 32 | 33 | setPadding(); 34 | } 35 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/annotation_file.dart: -------------------------------------------------------------------------------- 1 | @pragma('vm:entry-point') 2 | void customEntryPoint() {} 3 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/conditional_file.dart: -------------------------------------------------------------------------------- 1 | class ConditionalClass {} 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/enrtypoint_file.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/exported_file.dart: -------------------------------------------------------------------------------- 1 | class ExportedClass {} 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/generated/intl/messages_all.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that looks up messages for specific locales by 3 | // delegating to the appropriate library. 4 | 5 | import 'dart:async'; 6 | 7 | import 'messages_en.dart' as messages_en; 8 | import 'messages_ru.dart' as messages_ru; 9 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/generated/intl/messages_en.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a en locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/generated/intl/messages_ru.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a en locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/imported_file.dart: -------------------------------------------------------------------------------- 1 | class ImportedClass {} 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/part_file.dart: -------------------------------------------------------------------------------- 1 | part of 'unused_files_example.dart'; 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/suppressed_file.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unused-files 2 | 3 | class SomeClass {} 4 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/unconditional_file.dart: -------------------------------------------------------------------------------- 1 | class UnconditionalClass {} 2 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/unused_file.dart: -------------------------------------------------------------------------------- 1 | import 'exported_file.dart'; 2 | 3 | @immutable 4 | class SomeClass {} 5 | 6 | const instance = ExportedClass(); 7 | -------------------------------------------------------------------------------- /test/resources/unused_files_analyzer/unused_files_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_code_linter/config.dart'; 2 | 3 | import 'unconditional_file.dart' if (dart.library.html) 'conditional_file.dart' 4 | as file; 5 | 6 | import 'imported_file.dart'; 7 | 8 | import 'generated/intl/messages_all.dart'; 9 | 10 | export 'exported_file.dart'; 11 | 12 | part 'part_file.dart'; 13 | -------------------------------------------------------------------------------- /test/resources/unused_l10n_analyzer/base_localization.dart: -------------------------------------------------------------------------------- 1 | class BaseLocalization { 2 | String get baseGetter => 'getter'; 3 | 4 | String get anotherBaseGetter => 'getter'; // LINT 5 | } 6 | -------------------------------------------------------------------------------- /test/resources/unused_l10n_analyzer/unused_l10n_analyzer_example.dart: -------------------------------------------------------------------------------- 1 | import 'test_i18n.dart'; 2 | 3 | void main() { 4 | final _ = TestI18n.method('value'); 5 | 6 | S.getter; 7 | 8 | TestI18n.of('').regularMethod('some-string'); 9 | 10 | TestI18n.of('').regularField.trim(); 11 | 12 | TestI18n.of('').anotherRegularGetter; 13 | 14 | TestI18n.of('').baseGetter; 15 | 16 | final wrapper = L10nWrapper(); 17 | 18 | wrapper.l10n.regularField.trim(); 19 | 20 | wrapper.l10n.regularGetter; 21 | 22 | wrapper.l10n.method('value'); 23 | } 24 | 25 | class SomeClass { 26 | final field = TestI18n.field; 27 | 28 | void method() { 29 | S.of('').regularMethod(''); 30 | S.of('').anotherRegularGetter; 31 | S.current.regularGetter; 32 | S.current.anotherRegularMethod(''); 33 | 34 | final instance = S(); 35 | instance.proxyGetter; 36 | instance.proxyMethod('hello'); 37 | 38 | final wrapper = SofS(S()); 39 | wrapper.l10n.proxyField; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/anti_patterns/anti_patterns_list/long_parameter_list/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | 3 | void func(int a, int b, int c, int e) {} 4 | 5 | void func2(int a, int b, int c, int e, String f) {} 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/models/severity_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_code_linter/src/analyzers/lint_analyzer/models/severity.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | test('Severity fromString converts string to Severity object', () { 6 | expect( 7 | ['nOne', 'StyLe', 'wArnInG', 'erROr', '', null].map(Severity.fromString), 8 | equals([ 9 | Severity.none, 10 | Severity.style, 11 | Severity.warning, 12 | Severity.error, 13 | Severity.none, 14 | null, 15 | ]), 16 | ); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/examples/class_example.dart: -------------------------------------------------------------------------------- 1 | class Person { 2 | Person({ 3 | required this.name, 4 | required this.age, 5 | this.surname, 6 | }); 7 | 8 | final String name; 9 | final int age; 10 | final String? surname; 11 | } 12 | 13 | final goodPerson1 = Person(name: '', age: 42, surname: ''); 14 | final goodPerson2 = Person(name: '', age: 42); 15 | 16 | final badPerson1 = Person(name: 42, surname: '', age: ''); // LINT 17 | final badPerson2 = Person(surname: '', name: '', age: 42); // LINT 18 | final badPerson3 = Person(surname: '', age: 42, name: ''); // LINT 19 | final badPerson4 = Person(age: 42, surname: '', name: ''); // LINT 20 | final badPerson5 = Person(age: 42, name: '', surname: ''); // LINT 21 | final badPerson6 = Person(age: 42, name: ''); // LINT 22 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/examples/function_example.dart: -------------------------------------------------------------------------------- 1 | Person? createPerson( 2 | {required String name, required int age, String? surname}) => 3 | null; 4 | 5 | final goodPerson1 = createPerson(name: '', age: 42, surname: ''); 6 | final goodPerson2 = createPerson(name: '', age: 42); 7 | 8 | final badPerson1 = createPerson(name: 42, surname: '', age: ''); // LINT 9 | final badPerson2 = createPerson(surname: '', name: '', age: 42); // LINT 10 | final badPerson3 = createPerson(surname: '', age: 42, name: ''); // LINT 11 | final badPerson4 = createPerson(age: 42, surname: '', name: ''); // LINT 12 | final badPerson5 = createPerson(age: 42, name: '', surname: ''); // LINT 13 | final badPerson6 = createPerson(age: 42, name: ''); // LINT 14 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/examples/mixed_example.dart: -------------------------------------------------------------------------------- 1 | A? create(String a, String b, {required String c, String? d}) => null; 2 | 3 | final good1 = create('a', 'b', c: 'c', d: 'd'); 4 | final good2 = create('a', 'b', c: 'c'); 5 | 6 | final bad1 = create('a', c: 'c', 'b', d: 'd'); // LINT 7 | final bad2 = create('a', d: 'd', 'b', c: 'c'); // LINT 8 | final bad3 = create('a', 'b', d: 'd', c: 'c'); // LINT 9 | final bad4 = create('a', c: 'c', 'b'); // LINT 10 | final bad5 = create(c: 'c', 'a', 'b'); // LINT 11 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/examples/widget_example.dart: -------------------------------------------------------------------------------- 1 | class PersonWidget extends StatelessWidget { 2 | PersonWidget({ 3 | required this.name, 4 | required this.child, 5 | required this.age, 6 | }); 7 | 8 | final String name; 9 | final Widget child; 10 | final int age; 11 | 12 | Widget build(BuildContext context) => Container(); 13 | } 14 | 15 | final goodPerson = PersonWidget(name: '', child: Container(), age: 42); 16 | 17 | final badPerson1 = PersonWidget(name: '', age: 42, child: Container()); // LINT 18 | final badPerson2 = PersonWidget(child: Container(), name: '', age: 42); // LINT 19 | final badPerson3 = PersonWidget(child: Container(), age: 42, name: ''); // LINT 20 | final badPerson4 = PersonWidget(age: 42, child: Container(), name: ''); // LINT 21 | final badPerson5 = PersonWidget(age: 42, name: '', child: Container()); // LINT 22 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/arguments_ordering/examples/widget_example_child_last.dart: -------------------------------------------------------------------------------- 1 | class PersonWidget extends StatelessWidget { 2 | PersonWidget({ 3 | required this.child, 4 | required this.children, 5 | required this.name, 6 | }); 7 | 8 | final Widget child; 9 | final List children; 10 | final String name; 11 | 12 | Widget build(BuildContext context) => Container(); 13 | } 14 | 15 | final goodPerson = PersonWidget(name: '', child: Container(), children: []); 16 | 17 | final badPerson1 = 18 | PersonWidget(name: '', child: Container(), children: []); // LINT 19 | final badPerson2 = 20 | PersonWidget(child: Container(), children: [], name: ''); // LINT 21 | final badPerson3 = 22 | PersonWidget(child: Container(), name: '', children: []); // LINT 23 | final badPerson4 = 24 | PersonWidget(children: [], child: Container(), name: ''); // LINT 25 | final badPerson5 = 26 | PersonWidget(children: [], name: '', child: Container()); // LINT 27 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_banned_imports/examples/example.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/material.dart'; // LINT 2 | import 'package:mocktail/good_file.dart'; 3 | 4 | import 'package:intl/ban_folder/something.dart'; // LINT 5 | import 'package:intl/good_folder/something.dart'; 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_cascade_after_if_null/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Cow { 2 | void moo() {} 3 | } 4 | 5 | class Ranch { 6 | final Cow? _cow; 7 | 8 | Ranch([Cow? cow]) 9 | : _cow = cow ?? Cow() 10 | ..moo(); // LINT 11 | } 12 | 13 | void main() { 14 | final Cow? nullableCow; 15 | 16 | final cow = nullableCow ?? Cow() 17 | ..moo(); // LINT 18 | final cow = (nullableCow ?? Cow())..moo(); 19 | final cow = nullableCow ?? (Cow()..moo()); 20 | } 21 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/examples/dynamic_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | { 3 | dynamic key = 1; 4 | 5 | final regularMap = Map(); 6 | regularMap[key] = "value"; // LINT 7 | } 8 | 9 | { 10 | Object? key = 1; 11 | 12 | final regularMap = Map(); 13 | regularMap[key] = "value"; // LINT 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/examples/nullable_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | { 3 | final regularMap = Map(); 4 | regularMap[null] = "value"; // LINT 5 | 6 | final nullableMap = Map(); 7 | nullableMap[42] = "value"; 8 | nullableMap[null] = "value"; 9 | final value = nullableMap[null]; 10 | nullableMap["str"] = "value"; // LINT 11 | } 12 | 13 | { 14 | final regularList = [10, 20, 30]; 15 | regularList.remove(null); // LINT 16 | 17 | final nullableList = [10, 20, 30, null]; 18 | nullableList.remove(null); 19 | nullableList.remove(20); 20 | nullableList.remove("str"); // LINT 21 | } 22 | 23 | { 24 | final regularSet = {10, 20, 30}; 25 | regularSet.contains(null); // LINT 26 | 27 | final nullableSet = {10, 20, 30, null}; 28 | nullableSet.contains(null); 29 | nullableSet.contains(42); 30 | nullableSet.contains("str"); // LINT 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_double_slash_imports/examples/example.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/material.dart'; 2 | import 'package:mocktail/good_file.dart'; 3 | import '../../..//rule_utils_test.dart'; // LINT 4 | 5 | part '..//empty.dart'; // LINT 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_duplicate_exports/examples/example.dart: -------------------------------------------------------------------------------- 1 | export 'package:test/material.dart'; 2 | export 'package:mocktail/good_file.dart'; 3 | 4 | export 'package:intl/ban_folder/something.dart'; 5 | export 'package:intl/good_folder/something.dart'; 6 | export 'package:intl/good_folder/something.dart'; // LINT 7 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_dynamic/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | dynamic s = 1; // LINT 3 | 4 | final result = someFunction('1', '2'); 5 | 6 | (s as dynamic).toString(); // LINT 7 | } 8 | 9 | // LINT 10 | dynamic someFunction(dynamic a, dynamic b) { 11 | // LINT 12 | if (a is dynamic) { 13 | return b; 14 | } 15 | 16 | return a + b; 17 | } 18 | 19 | typedef Json = Map; 20 | 21 | class SomeClass { 22 | // LINT 23 | final dynamic value; 24 | 25 | SomeClass(this.value); 26 | 27 | // LINT 28 | dynamic get state => value; 29 | 30 | // LINT 31 | dynamic calculate() { 32 | return value; 33 | } 34 | } 35 | 36 | abstract class BaseClass {} 37 | 38 | // LINT 39 | class Generic extends BaseClass { 40 | final Map myMap = {}; 41 | 42 | final myMap = {}; 43 | } 44 | 45 | extension type Asset(String path) { } 46 | 47 | class TestClass { 48 | const TestClass({required this.asset}); 49 | 50 | final Asset asset; 51 | } -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_global_state/examples/example.dart: -------------------------------------------------------------------------------- 1 | var answer = 42; // LINT 2 | var evenNumbers = [1, 2, 3].where((element) => element.isEven); // LINT 3 | const a = 1; 4 | final b = 1; 5 | const noted2 = ''; 6 | 7 | void function() {} 8 | 9 | class Foo { 10 | static int? a; // LINT 11 | static dynamic c; // LINT 12 | final int? b; 13 | dynamic c2; 14 | const d = 1; 15 | static const noted = ''; 16 | static final finalField = 1; 17 | static var _c3 = ''; 18 | void function() {} 19 | } 20 | 21 | class Mixin { 22 | static int? a; // LINT 23 | static dynamic c; // LINT 24 | final int? b; 25 | dynamic c2; 26 | const d = 1; 27 | static const noted = ''; 28 | static final finalField = 1; 29 | static var _c3 = ''; 30 | void function() {} 31 | } 32 | 33 | extension Extension on String { 34 | static int? a; // LINT 35 | static dynamic c; // LINT 36 | static const noted = ''; 37 | static final finalField = 1; 38 | static var _c3 = ''; 39 | void function() {} 40 | } 41 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_initializing_in_on_mount/examples/example.dart: -------------------------------------------------------------------------------- 1 | class MyComponent extends Component { 2 | late final int x; 3 | 4 | int y; 5 | 6 | @override 7 | void onMount() { 8 | x = 1; // LINT 9 | y = 2; 10 | } 11 | } 12 | 13 | class Component { 14 | void onMount() {} 15 | } 16 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_late_keyword/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | late final field = 'string'; // LINT 3 | 4 | final String anotherField = ''; 5 | 6 | String? nullableField; 7 | 8 | late int uninitializedField; // LINT 9 | 10 | void method() { 11 | late final variable = 'string'; // LINT 12 | 13 | final anotherVariable = ''; 14 | 15 | String? nullableVariable; 16 | 17 | late String uninitializedVariable; // LINT 18 | } 19 | } 20 | 21 | late final topLevelVariable = 'string'; // LINT 22 | 23 | late String topLevelUninitializedVariable; // LINT 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_missing_enum_constant_in_map/examples/example.dart: -------------------------------------------------------------------------------- 1 | enum CountyCode { 2 | russia, 3 | kazachstan, 4 | another, 5 | } 6 | 7 | extension CountyTypeX on CountyCode { 8 | // LINT 9 | static const _code = { 10 | CountyCode.russia: 'RUS', 11 | CountyCode.another: 'XXX', 12 | }; 13 | 14 | // LINT 15 | static const _title = { 16 | CountyCode.russia: 'Россия', 17 | }; 18 | 19 | static CountyCode? fromCode(String? code) => enumDecodeNullable(_code, code); 20 | 21 | String get title => _title[this]!; 22 | 23 | String get code => _code[this]!; 24 | } 25 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_nested_conditional_expressions/examples/example.dart: -------------------------------------------------------------------------------- 1 | void func() { 2 | final str = ''; 3 | 4 | final oneLevel = str.isEmpty ? 'hello' : 'world'; 5 | 6 | final twoLevels = str.isEmpty 7 | ? str.isEmpty // LINT 8 | ? 'hello' 9 | : 'world' 10 | : 'here'; 11 | 12 | final threeLevels = str.isEmpty 13 | ? str.isEmpty // LINT 14 | ? str.isEmpty // LINT 15 | ? 'hi' 16 | : 'hello' 17 | : 'here' 18 | : 'deep'; 19 | 20 | final fourLevels = str.isEmpty 21 | ? str.isEmpty // LINT 22 | ? str.isEmpty // LINT 23 | ? str.isEmpty // LINT 24 | ? 'hi' 25 | : 'hello' 26 | : 'here' 27 | : 'deep' 28 | : 'four'; 29 | } 30 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_ascii_symbols/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | final english = 'hello'; 3 | final chinese = 'hello 汉字'; // LINT 4 | final russian = 'hello привет'; // LINT 5 | final someGenericSymbols = '!@#${english}%^'; 6 | final nonAsciiSymbols = '#!$_&- éè ;∞¥₤€'; // LINT 7 | final misspelling = 'inform@tiv€'; // LINT 8 | } 9 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_returning_widgets/examples/nullable_example.dart: -------------------------------------------------------------------------------- 1 | class AnotherWidget extends StatelessWidget { 2 | Widget? get widgetGetter => Container(); 3 | 4 | List? _getWidgetsList() => [Container()].toList(); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | Widget? _localBuildMyWidget() { 9 | return Container(); 10 | } 11 | 12 | _localBuildMyWidget(); 13 | 14 | _getWidgetsList(); 15 | 16 | return Container(); 17 | } 18 | } 19 | 20 | Widget? _globalBuildMyWidget() { 21 | return Container(); 22 | } 23 | 24 | class Widget {} 25 | 26 | class Container extends Widget { 27 | final Widget? child; 28 | 29 | const Container({this.child}); 30 | } 31 | 32 | class StatelessWidget extends Widget {} 33 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_returning_widgets/examples/provider_example.dart: -------------------------------------------------------------------------------- 1 | class MyWidget extends StatelessWidget { 2 | List _getProvidersList() => [Provider()]; 3 | 4 | MultiProvider _getMultiProvider() => MultiProvider(providers: []); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | _getProvidersList(); 9 | 10 | _getMultiProvider(); 11 | 12 | return Container(); 13 | } 14 | } 15 | 16 | class StatelessWidget extends Widget {} 17 | 18 | class Widget {} 19 | 20 | class Container extends Widget { 21 | final Widget? child; 22 | 23 | const Container({this.child}); 24 | } 25 | 26 | class MultiProvider { 27 | final List providers; 28 | 29 | const MultiProvider({required this.providers}); 30 | } 31 | 32 | class Provider extends InheritedProvider { 33 | final Widget? child; 34 | 35 | const Provider(this.child); 36 | } 37 | 38 | class InheritedProvider extends Widget {} 39 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_substring/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | final s = "It's a smiley 😀 smile"; 3 | s.substring(14, 15); // LINT 4 | 5 | "It's a smiley 😀 smile".substring(14, 15); // LINT 6 | } 7 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_throw_in_catch_block/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | try { 3 | repository(); 4 | } on Object catch (error, stackTrace) { 5 | logError(error, stackTrace); 6 | } 7 | } 8 | 9 | /// Where did the original error occur based on the log? 10 | void logError(Object error, StackTrace stackTrace) => 11 | print('$error\n$stackTrace'); 12 | 13 | void repository() { 14 | try { 15 | networkDataProvider(); 16 | } on Object { 17 | throw RepositoryException(); // LINT 18 | } 19 | } 20 | 21 | void networkDataProvider() { 22 | try { 23 | networkClient(); 24 | } on Object { 25 | throw DataProviderException(); // LINT 26 | } 27 | } 28 | 29 | void networkClient() { 30 | throw 'Some serious problem'; 31 | } 32 | 33 | class RepositoryException {} 34 | 35 | class DataProviderException {} 36 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_top_level_members_in_tests/examples/example.dart: -------------------------------------------------------------------------------- 1 | final public = 1; // LINT 2 | final _private = 2; 3 | 4 | void main() {} 5 | 6 | void function() {} // LINT 7 | 8 | void _function() {} 9 | 10 | class Class {} // LINT 11 | 12 | class _Class {} 13 | 14 | mixin Mixin {} // LINT 15 | 16 | mixin _Mixin {} 17 | 18 | extension Extension on String {} // LINT 19 | 20 | extension _Extension on String {} 21 | 22 | enum Enum { first, second } // LINT 23 | 24 | enum _Enum { first, second } 25 | 26 | typedef Public = String; // LINT 27 | 28 | typedef _Private = String; 29 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_unnecessary_conditionals/examples/example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | const str = ''; 3 | 4 | final assignment = str.isEmpty ? otherFunction() : bar(); 5 | final boolean = str.isEmpty ? bar() : baz(); 6 | 7 | final another = str.isEmpty ? true : false; // LINT 8 | } 9 | 10 | bool foo() { 11 | const str = ''; 12 | 13 | return str.isEmpty ? false : true; // LINT 14 | } 15 | 16 | bool bar() => foo ? false : true; // LINT 17 | 18 | bool baz() => foo ? true : false; // LINT 19 | 20 | String otherFunction() => 'str'; 21 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_unnecessary_type_assertions/examples/example_with_not_is.dart: -------------------------------------------------------------------------------- 1 | class Animal {} 2 | 3 | class NotAnimal {} 4 | 5 | class HomeAnimal extends Animal {} 6 | 7 | class Dog extends HomeAnimal {} 8 | 9 | class Cat extends HomeAnimal {} 10 | 11 | void checkSameOrInheritor() { 12 | final cat = Cat(); 13 | 14 | final check = cat is! Cat; // LINT 15 | final check = cat is Dog; 16 | final check = cat is! Dog; // LINT 17 | final check = cat is! NotAnimal; // LINT 18 | 19 | final Cat? nullableCat = null; 20 | 21 | final check = nullableCat is! Cat; 22 | 23 | final dynamic a; 24 | final check = a is! int; 25 | 26 | final Object b; 27 | final check = b is! int; 28 | } 29 | 30 | void check() { 31 | final T b; 32 | final check = b is! int; 33 | } 34 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_unused_parameters/examples/tear_off_example.dart: -------------------------------------------------------------------------------- 1 | class TestClass { 2 | String value; 3 | 4 | void _someMethod(Function(String, int) callback) { 5 | callback(); 6 | } 7 | 8 | void _otherMethod(String string, int value) { 9 | print(string); 10 | } 11 | 12 | // LINT 13 | void _anotherMethod(String firstString, String secondString) { 14 | someMethod(_otherMethod); 15 | _someOtherMethod(value); 16 | 17 | final replacement = value.isNotEmpty ? _someAnotherMethod(1, '1') : null; 18 | } 19 | 20 | // LINT 21 | void _someOtherMethod(String value) {} 22 | 23 | // LINT 24 | String _someAnotherMethod( 25 | int value, 26 | String name, 27 | ) { 28 | return ''; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/avoid_wrapping_in_padding/examples/example.dart: -------------------------------------------------------------------------------- 1 | class CoolWidget { 2 | Widget build() { 3 | // LINT 4 | return Padding( 5 | child: Container(), 6 | ); 7 | } 8 | } 9 | 10 | class AnotherWidget { 11 | Widget build() { 12 | return Padding( 13 | child: Icon(), 14 | ); 15 | } 16 | } 17 | 18 | class Container extends Widget { 19 | final EdgeInsetsGeometry? padding; 20 | final Widget child; 21 | 22 | const Container(this.padding); 23 | } 24 | 25 | class Padding extends Widget { 26 | final EdgeInsetsGeometry? padding; 27 | final Widget child; 28 | 29 | const Padding(this.padding); 30 | } 31 | 32 | class Icon extends Widget {} 33 | 34 | class Widget {} 35 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/examples/classes.dart: -------------------------------------------------------------------------------- 1 | class StrangeClass { 2 | void someMethod(); 3 | } 4 | 5 | class NonStrangeClass { 6 | void someMethod(); 7 | } 8 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/examples/dialogs.dart: -------------------------------------------------------------------------------- 1 | void myShowDialog(String arg1, String arg2) {} 2 | 3 | void showDialog(String arg1, String arg2) {} 4 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/examples/example.dart: -------------------------------------------------------------------------------- 1 | import 'dialog.dart'; 2 | import 'dialog.dart' as material; 3 | import 'classes.dart'; 4 | 5 | void func() { 6 | myShowDialog('some_arguments', 'another_argument'); 7 | showDialog('some_arguments', 'another_argument'); // LINT 8 | material.showDialog('some_arguments', 'another_argument'); // LINT 9 | 10 | var strangeName = 42; // LINT 11 | } 12 | 13 | void strangeName() {} // LINT 14 | 15 | // LINT 16 | class AnotherStrangeName { 17 | late var strangeName; // LINT 18 | } 19 | 20 | void main() { 21 | StrangeClass.someMethod(); // LINT 22 | NonStrangeClass.someMethod(); 23 | 24 | DateTime.now(); // LINT 25 | DateTime.now().day; // LINT 26 | DateTime.now().day.isFinite; // LINT 27 | 28 | DateTime now = DateTime(2022); 29 | } 30 | 31 | class DateTimeTest { 32 | final currentTimestamp = DateTime.now(); // LINT 33 | } 34 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/binary_expression_operand_order/examples/example.dart: -------------------------------------------------------------------------------- 1 | const c = 42; 2 | 3 | const bad1 = 1 + c; // LINT 4 | const bad2 = c + (1 + c); // LINT 5 | const bad3 = c + (12.44 * c); // LINT 6 | const bad4 = 1 & c; // LINT 7 | const bad5 = 2 | c; // LINT 8 | const bad6 = 4 ^ c; // LINT 9 | 10 | const good1 = c + 1; 11 | const good2 = c + (c + 1); 12 | const good3 = c + (c * 12.44); 13 | const good4 = c & 1; 14 | const good5 = c | 2; 15 | const good6 = c ^ 4; 16 | 17 | const skip1 = 100 - c; 18 | const skip2 = 168 / c; 19 | const skip3 = 168 / (84 - c); 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/double_literal_format/examples/example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: double-literal-format, unused_local_variable 2 | void main() { 3 | const a = [ 4 | 05.23, // LINT 5 | 5.23, 6 | 003.6e+5, // LINT 7 | 3.6e+5, 8 | -012.2, // LINT 9 | -12.2, 10 | -001.1e-1, // LINT 11 | -1.1e-1, 12 | ]; 13 | 14 | const b = [ 15 | .257, // LINT 16 | 0.257, 17 | .16e+5, // LINT 18 | 0.16e+5, 19 | -.259, // LINT 20 | -0.259, 21 | -.14e-5, // LINT 22 | -0.14e-5, 23 | ]; 24 | 25 | const c = [ 26 | 0.2100, // LINT 27 | 0.21, 28 | 0.100e+5, // LINT 29 | 0.1e+5, 30 | -0.2500, // LINT 31 | -0.25, 32 | -0.400e-5, // LINT 33 | -0.4e-5, 34 | ]; 35 | 36 | const d = [ 37 | 0.0, 38 | -0.0, 39 | 12.0e+1, 40 | 150, 41 | 0x015, 42 | 0x020, 43 | ]; 44 | } 45 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/examples/example.dart: -------------------------------------------------------------------------------- 1 | // With start space without dot 2 | class Test { 3 | //Without start space without dot 4 | Test() { 5 | // with start space with dot. 6 | } 7 | 8 | /// With start space without dot 9 | function() { 10 | //Any other comment 11 | } 12 | // ignore: 13 | } 14 | 15 | // ignore_for_file: 16 | var a; 17 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/examples/example_documentation.dart: -------------------------------------------------------------------------------- 1 | class Box { 2 | /// The value this wraps 3 | Object? _value; 4 | 5 | /// true if this box contains a value. 6 | bool get hasValue => _value != null; 7 | } 8 | 9 | //not if there is nothing before it 10 | test() => false; 11 | 12 | void greet(String name) { 13 | // assume we have a valid name. 14 | print('Hi, $name!'); 15 | } 16 | 17 | /// deletes the file at [path] from the file system. 18 | void delete(String path) {} 19 | 20 | /// {@template template_name} 21 | void f1() {} 22 | 23 | /// {@endtemplate} 24 | void f2() {} 25 | 26 | /// {@macro template_name} 27 | void f3() {} 28 | 29 | /// {@template my_project.my_class.my_method} 30 | void f4() {} 31 | 32 | /// {@nodoc} 33 | void f5() {} 34 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/examples/example_without_issue.dart: -------------------------------------------------------------------------------- 1 | // With start space without dot. 2 | var a; 3 | 4 | /// With start space without dot. 5 | var a; 6 | /* With start space without dot.*/ 7 | var a; 8 | // TODO: Asdasd:asd:Asdasdasd. 9 | var a; 10 | // TODO(vlad): Asdasd:asd:Asdasdasd. 11 | var a; 12 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/alphabetical_correct_example.dart: -------------------------------------------------------------------------------- 1 | class OrderExample { 2 | String publicField; 3 | 4 | String get string => publicField.toString(); 5 | 6 | set string(String newString) => publicField = newString; 7 | 8 | String _privateField = '42'; 9 | 10 | String get _field => _privateField; 11 | 12 | set _field(String newString) => _privateField = '42'; 13 | } 14 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/alphabetical_example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | final value = 1; 3 | 4 | final data = 2; // LINT 5 | 6 | final algorithm = 3; // LINT 7 | 8 | void work() {} // LINT 9 | 10 | void create() {} // LINT 11 | 12 | void init() {} // LINT 13 | } 14 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | String _value; 3 | 4 | static const staticConstField = ''; // LINT 5 | 6 | late final staticLateFinalField; // LINT 7 | 8 | String? nullableField; // LINT 9 | 10 | late String? lateNullableField; // LINT 11 | 12 | void doWork() {} 13 | 14 | void doAnotherWork() {} 15 | 16 | final data = 1; // LINT 17 | 18 | Test(); 19 | 20 | factory Test.empty() => Test(); 21 | 22 | Test.create(); 23 | 24 | String _doWork() => 'test'; 25 | 26 | void _doAnotherWork() {} 27 | 28 | String get value => _value; // LINT 29 | 30 | set value(String str) => _value = str; 31 | } 32 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/flutter_widget_example.dart: -------------------------------------------------------------------------------- 1 | class _MyStatelessWidget extends StatelessWidget { 2 | const _MyStatelessWidget(); 3 | 4 | void doNothing() {} 5 | 6 | // LINT 7 | @override 8 | Widget build(BuildContext context) { 9 | return Widget(); 10 | } 11 | 12 | @override 13 | void initState() {} // LINT 14 | 15 | @override 16 | void didChangeDependencies() {} // LINT 17 | 18 | @override 19 | void didUpdateWidget() {} // LINT 20 | 21 | @override 22 | void dispose() {} // LINT 23 | 24 | @override 25 | void someOtherMethod() {} // LINT 26 | } 27 | 28 | class Widget {} 29 | 30 | class StatelessWidget extends Widget { 31 | Widget build(BuildContext context); 32 | 33 | void initState(); // LINT 34 | 35 | void didChangeDependencies(); // LINT 36 | 37 | void didUpdateWidget(); // LINT 38 | 39 | void dispose(); // LINT 40 | 41 | void someOtherMethod(); 42 | } 43 | 44 | class BuildContext {} 45 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/multiple_classes_example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | final _data = 1; 3 | 4 | int get data => _data; 5 | 6 | void doWork() {} 7 | } 8 | 9 | class AnotherTest { 10 | final _anotherData = 1; 11 | 12 | int get anotherData => _anotherData; 13 | 14 | void anotherDoWork() {} 15 | } 16 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/not_widget_example.dart: -------------------------------------------------------------------------------- 1 | class MyNotWidget { 2 | const MyNotWidget(); 3 | 4 | void doNothing() {} 5 | 6 | @override 7 | void build(Object context) {} 8 | 9 | @override 10 | void initState() {} 11 | 12 | @override 13 | void didChangeDependencies() {} 14 | 15 | @override 16 | void didUpdateWidget() {} 17 | 18 | @override 19 | void dispose() {} 20 | 21 | @override 22 | void someOtherMethod() {} 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/member_ordering/examples/type_alphabetical_example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | final value = 1; 3 | 4 | String a; 5 | 6 | String z; 7 | 8 | double f; // LINT 9 | 10 | double e; 11 | 12 | int x; 13 | 14 | // LINT 15 | String work() { 16 | return ''; 17 | } 18 | 19 | bool create() => false; // LINT 20 | 21 | void init() {} // LINT 22 | } 23 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/missing_test_assertion/examples/custom_assertions_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Hello'); 3 | 4 | test(null, () => verify(1, 1)); 5 | } 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/missing_test_assertion/examples/custom_methods_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Hello'); 3 | 4 | customTest(null, () => 1 == 1); // LINT 5 | 6 | otherTestMethod(null, () => 1 == 1); // LINT 7 | 8 | excludedTestMethod(null, () => 1 == 1); 9 | } 10 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/missing_test_assertion/examples/incorrect_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Hello'); 3 | 4 | test('bad unit test', () { 5 | final a = 1; 6 | final b = 2; 7 | final c = a + 1; 8 | }); // LINT 9 | 10 | testWidgets('bad widget test', (WidgetTester tester) async { 11 | await tester.pumpWidget(MyApp()); 12 | await tester.pumpAndSettle(); 13 | }); // LINT 14 | 15 | test(null, () => 1 == 1); // LINT 16 | } 17 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_empty_block/examples/example.dart: -------------------------------------------------------------------------------- 1 | int simpleFunction() { 2 | try {} catch (_) {} // LINT 3 | 4 | var a = 4; 5 | 6 | // LINT 7 | if (a > 70) { 8 | } else if (a > 65) { 9 | // TODO(developerName): message. 10 | } else if (a > 60) { 11 | return a + 2; 12 | } 13 | 14 | // LINT 15 | [1, 2, 3, 4].forEach((val) {}); 16 | 17 | [1, 2, 3, 4].forEach((val) { 18 | // TODO(developerName): need to implement. 19 | }); 20 | 21 | return a; 22 | } 23 | 24 | // LINT 25 | void emptyFunction() {} 26 | 27 | void emptyFunction2() { 28 | // TODO(developerName): need to implement. 29 | } 30 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_equal_arguments/examples/named_parameters_example.dart: -------------------------------------------------------------------------------- 1 | String getUserImage({String firstName, String lastName}) { 2 | return '/test_url/' + firstName ?? '' + lastName ?? ''; 3 | } 4 | 5 | const firstName = 'name'; 6 | 7 | final image = getUserImage( 8 | firstName: firstName, 9 | lastName: firstName, // LINT 10 | ); 11 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/examples/array_example.dart: -------------------------------------------------------------------------------- 1 | class ContainerWidget { 2 | int height; 3 | List? children; 4 | ContainerWidget({required this.height, this.children}); 5 | 6 | ContainerWidget build() { 7 | return ContainerWidget( 8 | height: 83, // LINT 9 | children: [ 10 | ContainerWidget( 11 | height: 83, // LINT 12 | ), 13 | ], 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/examples/enum_example.dart: -------------------------------------------------------------------------------- 1 | enum ExampleMagicNumbers { 2 | second(2), 3 | third(3); 4 | 5 | final int value; 6 | 7 | const ExampleMagicNumbers(this.value); 8 | } 9 | 10 | enum ExampleNamedMagicNumbers { 11 | second(value: 2), 12 | third(value: 3); 13 | 14 | final int value; 15 | 16 | const ExampleNamedMagicNumbers({required this.value}); 17 | } 18 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/examples/example.dart: -------------------------------------------------------------------------------- 1 | const pi = 3.14; 2 | const pi2 = pi * 2; 3 | const str = 'Hello'; 4 | 5 | void fun1(int x) => a * pi; 6 | void fun2() => fun1(pi2); 7 | void fun3() => const { 8 | 'Key.a': 0.1, 9 | 'Key.b': 0.1, 10 | 'Key.c': 0.1, 11 | }; 12 | void fun4() { 13 | return const {1, 2}; 14 | } 15 | 16 | void fun5() => const {1, 2}; 17 | 18 | void fun6() => const Map(); 19 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/examples/exceptions_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | int good_f1(int x) => x + 1; 3 | bool good_f2(int x) => x != 0; 4 | bool good_f3(String x) => x.indexOf(str) != -1; 5 | final someDay = DateTime(2006, 12, 1); 6 | final anotherDay = DateTime.utc(2006, 12, 1); 7 | final f = Intl.message(example: const {'Assigned': 3}); 8 | final f = foo(const [32, 12]); 9 | final f = Future.delayed(const Duration(seconds: 5)); 10 | final f = foo(const Bar(5)); 11 | final number = 500; 12 | var number = 500; 13 | var numbers = [100, 200, 300]; 14 | numbers[0]; 15 | 16 | Map m = { 17 | 1: '', 18 | 2: '', 19 | 3: '', 20 | }; 21 | String? mv = m[2]; 22 | final mf = m[2]; 23 | print(m[2]); 24 | } 25 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_magic_number/examples/incorrect_example.dart: -------------------------------------------------------------------------------- 1 | int bad_f1(int x) => x + 42; // LINT 2 | bool bad_f2(int x) => x != 12; // LINT 3 | void bad_f4(int x) => a * 3.14; // LINT 4 | void bad_f5() => bad_f4(12); // LINT 5 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/no_object_declaration/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Test { 2 | Object data = 1; // LINT 3 | 4 | Object get getter => 1; // LINT 5 | 6 | // LINT 7 | Object doWork() { 8 | return null; 9 | } 10 | } 11 | 12 | class AnotherTest { 13 | int data = 1; 14 | 15 | int get getter => 1; 16 | 17 | void doWork() { 18 | return; 19 | } 20 | 21 | void doAnotherWork(Object param) { 22 | return; 23 | } 24 | } 25 | 26 | Object a = 1; 27 | 28 | Object function(Object param) { 29 | return null; 30 | } 31 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_async_await/examples/example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | void function() async { 4 | final future = Future.delayed(Duration(microseconds: 100), () => 6); 5 | 6 | future.then((value) => print(value)); // LINT 7 | 8 | future..then((value) => print(value)); // LINT 9 | 10 | final value = await future; 11 | 12 | final anotherFuture = getFuture().then((value) => value + 5); // LINT 13 | 14 | final anotherValue = await anotherFuture; 15 | } 16 | 17 | Future getFuture() { 18 | return Future.delayed(Duration(microseconds: 100), () => 5) 19 | .then((value) => value + 1); // LINT 20 | } 21 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_commenting_analyzer_ignores/examples/example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: some_rule 2 | void main() { 3 | // ignore: deprecated_member_use 4 | final map = Map(); // LINT 5 | 6 | // ignore: deprecated_member_use, long-method 7 | final set = Set(); // LINT 8 | 9 | // Ignored for some reasons 10 | // ignore: deprecated_member_use 11 | final list = List(); 12 | 13 | // ignore: deprecated_member_use same line ignore 14 | final queue = Queue(); 15 | 16 | // ignore: deprecated_member_use, long-method multiple same line ignore 17 | final linkedList = LinkedList(); 18 | 19 | // ignore: avoid-non-null-assertion, checked for non-null 20 | final hashMap = HashMap(); 21 | 22 | /// documentation comment 23 | // ignore: avoid-non-null-assertion 24 | final value = 1; // LINT 25 | } 26 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_conditional_expressions/examples/nested_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | String? value = 'value'; 3 | 4 | final condition = true; 5 | if (condition) { 6 | value = !condition ? 'new' : 'old'; 7 | } else { 8 | value = null; 9 | } 10 | 11 | Widget traceColor; 12 | Widget? image; 13 | 14 | if (condition != null) { 15 | traceColor = condition ? Widget() : Widget(); 16 | } else { 17 | traceColor = image == null ? Widget() : Widget(); 18 | } 19 | } 20 | 21 | class Widget {} 22 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/class_example.dart: -------------------------------------------------------------------------------- 1 | class Example { 2 | final x = 0; // LINT 3 | final y = 0; // LINT 4 | final z = 0; 5 | final zyt = 0; 6 | final property = 0; 7 | final multiplatformConfig = 0; // LINT 8 | final multiplatformConfigurationPoint = 0; // LINT 9 | 10 | Example.todo() { 11 | final u = 1; // LINT 12 | const i = 1; // LINT 13 | } 14 | 15 | Example._() { 16 | final u = 1; // LINT 17 | const i = 1; // LINT 18 | } 19 | 20 | bool get o => false; // LINT 21 | 22 | bool set p() => true; // LINT 23 | 24 | void test() { 25 | final u = 1; // LINT 26 | const i = 1; // LINT 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/common_example.dart: -------------------------------------------------------------------------------- 1 | void test() { 2 | final zy = 0; // LINT 3 | final _ze = 1; // LINT 4 | } 5 | 6 | final u = 1; // LINT 7 | const i = 1; // LINT 8 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/enum_example.dart: -------------------------------------------------------------------------------- 1 | enum Enum { 2 | u, // LINT 3 | i, // LINT 4 | } 5 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/extension_example.dart: -------------------------------------------------------------------------------- 1 | extension Extension on String { 2 | onExtension() { 3 | final u = 1; // LINT 4 | const i = 1; // LINT 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/mixin_example.dart: -------------------------------------------------------------------------------- 1 | mixin Mixin { 2 | final u = 1; // LINT 3 | const i = 1; // LINT 4 | } 5 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_identifier_length/examples/without_error_example.dart: -------------------------------------------------------------------------------- 1 | class WithoutErrorExample { 2 | final abc; 3 | const bcd; 4 | 5 | WithoutErrorExample.todo() { 6 | final abc = 1; 7 | const bcd = 1; 8 | } 9 | 10 | WithoutErrorExample._() { 11 | final abc = 1; 12 | const bcd = 1; 13 | } 14 | 15 | bool get abcd => false; 16 | 17 | bool set bcde() => true; 18 | 19 | void test() { 20 | final bcd = 1; 21 | const abc = 1; 22 | } 23 | } 24 | 25 | void test() { 26 | final abc = 0; 27 | final bcd = 1; 28 | } 29 | 30 | final abc = 1; 31 | const bcd = 1; 32 | 33 | enum Enum { 34 | abc, 35 | bcd, 36 | } 37 | 38 | extension Extension on String { 39 | onExtension() { 40 | final abc = 1; 41 | const bcd = 1; 42 | } 43 | } 44 | 45 | mixin Mixin { 46 | final abc = 1; 47 | const bcd = 1; 48 | } 49 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_test_file_name/examples/correct_example.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_test_file_name/examples/example.dart: -------------------------------------------------------------------------------- 1 | // LINT 2 | void main() { 3 | print('Hello'); 4 | } 5 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_type_name/examples/class_example.dart: -------------------------------------------------------------------------------- 1 | // LINT Check regular class without uppercase 2 | class example { 3 | example(); 4 | } 5 | 6 | // LINT Private class without uppercase 7 | class _example { 8 | _example(); 9 | } 10 | 11 | // LINT Private class with short name 12 | class _ex { 13 | _ex(); 14 | } 15 | 16 | // LINT Class with short name 17 | class ex { 18 | ex(); 19 | } 20 | 21 | // LINT Private class with long name 22 | class _ExampleWithLongName { 23 | _ExampleWithLongName(); 24 | } 25 | 26 | // LINT Class with long name 27 | class ExampleWithLongName { 28 | ExampleWithLongName(); 29 | } 30 | 31 | // Check private class with name contained in exclude config 32 | class _exampleExclude { 33 | _exampleExclude(); 34 | } 35 | 36 | // Check regular class without error 37 | class Example {} 38 | 39 | // Check private class without error 40 | class _Example {} 41 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_type_name/examples/enum_example.dart: -------------------------------------------------------------------------------- 1 | // LINT Check regular enum without uppercase 2 | enum example { 3 | param1, 4 | param2, 5 | } 6 | 7 | // LINT Private enum without uppercase 8 | enum _example { 9 | param1, 10 | param2, 11 | } 12 | 13 | // LINT Private enum with short name 14 | enum _ex { 15 | param1, 16 | param2, 17 | } 18 | 19 | // LINT Enum with short name 20 | enum ex { 21 | param1, 22 | param2, 23 | } 24 | 25 | // LINT Private enum with long name 26 | enum _ExampleWithLongName { 27 | param1, 28 | param2, 29 | } 30 | 31 | // LINT Enum with long name 32 | enum ExampleWithLongName { 33 | param1, 34 | param2, 35 | } 36 | 37 | // Check private enum with name contained in exclude config 38 | enum _exampleExclude { 39 | param1, 40 | param2, 41 | } 42 | 43 | // Check regular enum without error 44 | enum Example { 45 | param1, 46 | param2, 47 | } 48 | 49 | // Check private enum without error 50 | enum _Example { 51 | param1, 52 | param2, 53 | } 54 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_type_name/examples/extension_example.dart: -------------------------------------------------------------------------------- 1 | // LINT Check regular class without uppercase 2 | extension example on String {} 3 | 4 | // LINT Private extension without uppercase 5 | extension _example on String {} 6 | 7 | // LINT Private extension with short name 8 | extension _ex on String {} 9 | 10 | // LINT Extension with short name 11 | extension ex on String {} 12 | 13 | // LINT Private extension with long name 14 | extension _ExampleWithLongName on String {} 15 | 16 | // LINT extension with long name 17 | extension ExampleWithLongName on String {} 18 | 19 | // Check private extension with name contained in exclude config 20 | extension _exampleExclude on String {} 21 | 22 | // Check regular extension without error 23 | extension Example on String {} 24 | 25 | // Check private enum without error 26 | extension _Example on String {} 27 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_correct_type_name/examples/mixin_example.dart: -------------------------------------------------------------------------------- 1 | // LINT Check regular mixin without uppercase 2 | mixin example {} 3 | 4 | // LINT Private mixin without uppercase 5 | mixin _example {} 6 | 7 | // LINT Private mixin with short name 8 | mixin _ex {} 9 | 10 | // LINT mixin with short name 11 | mixin ex {} 12 | 13 | // LINT Private mixin with long name 14 | mixin _ExampleWithLongName {} 15 | 16 | // LINT Mixin with long name 17 | mixin ExampleWithLongName {} 18 | 19 | // Check private mixin with name contained in exclude config 20 | mixin _exampleExclude {} 21 | 22 | // Check regular mixin without error 23 | mixin Example {} 24 | 25 | // Check private mixin without error 26 | mixin _Example {} 27 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_enums_by_name/examples/example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | void main() async { 4 | SomeEnums.values.byName('first'); 5 | // LINT 6 | SomeEnums.values.firstWhere((element) => element.name == 'first'); 7 | // LINT 8 | SomeEnums.values 9 | .firstWhere((element) => element.name == 'second', orElse: () => null); 10 | } 11 | 12 | enum SomeEnums { first, second } 13 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/double_linked_queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const queue = DoubleLinkedQueue.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = DoubleLinkedQueue.from(queue); // LINT 7 | final numQueue = DoubleLinkedQueue.from(queue); // LINT 8 | 9 | final intQueue = DoubleLinkedQueue.from(numQueue); 10 | 11 | final unspecifedQueue = DoubleLinkedQueue.from(queue); // LINT 12 | 13 | final dynamicQueue = DoubleLinkedQueue.from([1, 2, 3]); 14 | final copy = DoubleLinkedQueue.from(dynamicQueue); 15 | final dynamicCopy = DoubleLinkedQueue.from(dynamicQueue); 16 | 17 | final objectQueue = DoubleLinkedQueue.from([1, 2, 3]); 18 | final copy = DoubleLinkedQueue.from(objectQueue); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/hash_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const hashSet = HashSet.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = HashSet.from(hashSet); // LINT 7 | final numSet = HashSet.from(hashSet); // LINT 8 | 9 | final intSet = HashSet.from(numSet); 10 | 11 | final unspecifedSet = HashSet.from(hashSet); // LINT 12 | 13 | final dynamicSet = HashSet.from([1, 2, 3]); 14 | final copy = HashSet.from(dynamicSet); 15 | final dynamicCopy = HashSet.from(dynamicSet); 16 | 17 | final objectSet = HashSet.from([1, 2, 3]); 18 | final copy = HashSet.from(objectSet); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/linked_hash_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const hashSet = LinkedHashSet.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = LinkedHashSet.from(hashSet); // LINT 7 | final numSet = LinkedHashSet.from(hashSet); // LINT 8 | 9 | final intSet = LinkedHashSet.from(numSet); 10 | 11 | final unspecifedSet = LinkedHashSet.from(hashSet); // LINT 12 | 13 | final dynamicSet = LinkedHashSet.from([1, 2, 3]); 14 | final copy = LinkedHashSet.from(dynamicSet); 15 | final dynamicCopy = LinkedHashSet.from(dynamicSet); 16 | 17 | final objectSet = LinkedHashSet.from([1, 2, 3]); 18 | final copy = LinkedHashSet.from(objectSet); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/list_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 3 | 4 | final copy = List.from(array); // LINT 5 | final numList = List.from(array); // LINT 6 | 7 | final intList = List.from(numList); 8 | 9 | final unspecifedList = List.from(array); // LINT 10 | 11 | final dynamicArray = [1, 2, 3]; 12 | final copy = List.from(dynamicArray); 13 | final dynamicCopy = List.from(dynamicArray); 14 | 15 | final objectArray = [1, 2, 3]; 16 | final copy = List.from(objectArray); 17 | } 18 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/list_queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const queue = ListQueue.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = ListQueue.from(queue); // LINT 7 | final numQueue = ListQueue.from(queue); // LINT 8 | 9 | final intQueue = ListQueue.from(numQueue); 10 | 11 | final unspecifedQueue = ListQueue.from(queue); // LINT 12 | 13 | final dynamicQueue = ListQueue.from([1, 2, 3]); 14 | final copy = ListQueue.from(dynamicQueue); 15 | final dynamicCopy = ListQueue.from(dynamicQueue); 16 | 17 | final objectQueue = ListQueue.from([1, 2, 3]); 18 | final copy = ListQueue.from(objectQueue); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const queue = Queue.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = Queue.from(queue); // LINT 7 | final numQueue = Queue.from(queue); // LINT 8 | 9 | final intQueue = Queue.from(numQueue); 10 | 11 | final unspecifedQueue = Queue.from(queue); // LINT 12 | 13 | final dynamicQueue = Queue.from([1, 2, 3]); 14 | final copy = Queue.from(dynamicQueue); 15 | final dynamicCopy = Queue.from(dynamicQueue); 16 | 17 | final objectQueue = Queue.from([1, 2, 3]); 18 | final copy = Queue.from(objectQueue); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/queue_list_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:collection/collection.dart'; 2 | 3 | void main() { 4 | const queue = QueueList.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = QueueList.from(queue); 7 | final numQueue = QueueList.from(queue); 8 | 9 | final intQueue = QueueList.from(numQueue); 10 | 11 | final unspecifedQueue = QueueList.from(queue); 12 | 13 | final dynamicQueue = QueueList.from([1, 2, 3]); 14 | final copy = QueueList.from(dynamicQueue); 15 | final dynamicCopy = QueueList.from(dynamicQueue); 16 | 17 | final objectQueue = QueueList.from([1, 2, 3]); 18 | final copy = QueueList.from(objectQueue); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/set_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | const set = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 3 | 4 | final copy = Set.from(set); // LINT 5 | final numSet = Set.from(set); // LINT 6 | 7 | final intSet = Set.from(numSet); 8 | 9 | final unspecifedSet = Set.from(set); // LINT 10 | 11 | final dynamicSet = {1, 2, 3}; 12 | final copy = Set.from(dynamicSet); 13 | final dynamicCopy = Set.from(dynamicSet); 14 | 15 | final objectSet = {1, 2, 3}; 16 | final copy = Set.from(objectSet); 17 | } 18 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_iterable_of/examples/splay_tree_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | void main() { 4 | const hashSet = SplayTreeSet.of([1, 2, 3, 4, 5, 6, 7, 8, 9]); 5 | 6 | final copy = SplayTreeSet.from(hashSet); // LINT 7 | final numSet = SplayTreeSet.from(hashSet); // LINT 8 | 9 | final intSet = SplayTreeSet.from(numSet); 10 | 11 | final unspecifedSet = SplayTreeSet.from(hashSet); // LINT 12 | 13 | final dynamicSet = SplayTreeSet.from([1, 2, 3]); 14 | final copy = SplayTreeSet.from(dynamicSet); 15 | final dynamicCopy = SplayTreeSet.from(dynamicSet); 16 | 17 | final objectSet = SplayTreeSet.from([1, 2, 3]); 18 | final copy = SplayTreeSet.from(objectSet); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/double_linked_queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final doubleLinkedQueue = DoubleLinkedQueue.of(_array); 7 | final doubleLinkedQueueLength = doubleLinkedQueue.length; 8 | final doubleLinkedQueueLastIndex = doubleLinkedQueue.length - 1; 9 | 10 | doubleLinkedQueue.last; 11 | doubleLinkedQueue.elementAt(doubleLinkedQueue.length - 1); // LINT 12 | doubleLinkedQueue.elementAt(doubleLinkedQueue.length - 2); 13 | doubleLinkedQueue.elementAt(doubleLinkedQueueLength - 1); 14 | doubleLinkedQueue.elementAt(doubleLinkedQueueLastIndex); 15 | doubleLinkedQueue.elementAt(8); 16 | 17 | doubleLinkedQueue 18 | ..elementAt(doubleLinkedQueue.length - 1) // LINT 19 | ..elementAt(doubleLinkedQueue.length - 2) 20 | ..elementAt(doubleLinkedQueueLength - 1) 21 | ..elementAt(doubleLinkedQueueLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/hash_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final hashSet = HashSet.of(_array); 7 | final hashSetLength = hashSet.length; 8 | final hashSetLastIndex = hashSet.length - 1; 9 | 10 | hashSet.last; 11 | hashSet.elementAt(hashSet.length - 1); // LINT 12 | hashSet.elementAt(hashSet.length - 2); 13 | hashSet.elementAt(hashSetLength - 1); 14 | hashSet.elementAt(hashSetLastIndex); 15 | hashSet.elementAt(8); 16 | 17 | hashSet 18 | ..elementAt(hashSet.length - 1) // LINT 19 | ..elementAt(hashSet.length - 2) 20 | ..elementAt(hashSetLength - 1) 21 | ..elementAt(hashSetLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/iterable_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | const iterable = _array as Iterable; 7 | final iterableLength = iterable.length; 8 | final iterableLastIndex = iterable.length - 1; 9 | 10 | iterable.last; 11 | iterable.elementAt(iterable.length - 1); // LINT 12 | iterable.elementAt(iterable.length - 2); 13 | iterable.elementAt(iterableLength - 1); 14 | iterable.elementAt(iterableLastIndex); 15 | iterable.elementAt(8); 16 | 17 | iterable 18 | ..elementAt(iterable.length - 1) // LINT 19 | ..elementAt(iterable.length - 2) 20 | ..elementAt(iterableLength - 1) 21 | ..elementAt(iterableLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/linked_hash_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final linkedHashSet = LinkedHashSet.of(_array); 7 | final linkedHashSetLength = linkedHashSet.length; 8 | final linkedHashSetLastIndex = linkedHashSet.length - 1; 9 | 10 | linkedHashSet.last; 11 | linkedHashSet.elementAt(linkedHashSet.length - 1); // LINT 12 | linkedHashSet.elementAt(linkedHashSet.length - 2); 13 | linkedHashSet.elementAt(linkedHashSetLength - 1); 14 | linkedHashSet.elementAt(linkedHashSetLastIndex); 15 | linkedHashSet.elementAt(8); 16 | 17 | linkedHashSet 18 | ..elementAt(linkedHashSet.length - 1) // LINT 19 | ..elementAt(linkedHashSet.length - 2) 20 | ..elementAt(linkedHashSetLength - 1) 21 | ..elementAt(linkedHashSetLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/list_example.dart: -------------------------------------------------------------------------------- 1 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 2 | 3 | void func() { 4 | const list = _array; 5 | final listLength = list.length; 6 | final listLastIndex = list.length - 1; 7 | 8 | list.last; 9 | list.elementAt(list.length - 1); // LINT 10 | list.elementAt(list.length - 2); 11 | list.elementAt(listLength - 1); 12 | list.elementAt(listLastIndex); 13 | list.elementAt(8); 14 | list[list.length - 1]; // LINT 15 | list[list.length - 2]; 16 | 17 | list 18 | ..elementAt(list.length - 1) // LINT 19 | ..elementAt(list.length - 2) 20 | ..elementAt(listLength - 1) 21 | ..elementAt(listLastIndex) 22 | ..elementAt(8) 23 | ..[list.length - 1] // LINT 24 | ..[list.length - 2]; 25 | 26 | (list 27 | ..[list.length - 2] 28 | ..[list.length - 1]) // LINT 29 | .length; 30 | 31 | list 32 | ..[list.length - 2].toDouble() 33 | ..[list.length - 1].toDouble(); // LINT 34 | } 35 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/list_queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final listQueue = ListQueue.of(_array); 7 | final listQueueLength = listQueue.length; 8 | final listQueueLastIndex = listQueue.length - 1; 9 | 10 | listQueue.last; 11 | listQueue.elementAt(listQueue.length - 1); // LINT 12 | listQueue.elementAt(listQueue.length - 2); 13 | listQueue.elementAt(listQueueLength - 1); 14 | listQueue.elementAt(listQueueLastIndex); 15 | listQueue.elementAt(8); 16 | 17 | listQueue 18 | ..elementAt(listQueue.length - 1) // LINT 19 | ..elementAt(listQueue.length - 2) 20 | ..elementAt(listQueueLength - 1) 21 | ..elementAt(listQueueLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/queue_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final queue = Queue.of(_array); 7 | final queueLength = queue.length; 8 | final queueLastIndex = queue.length - 1; 9 | 10 | queue.last; 11 | queue.elementAt(queue.length - 1); // LINT 12 | queue.elementAt(queue.length - 2); 13 | queue.elementAt(queueLength - 1); 14 | queue.elementAt(queueLastIndex); 15 | queue.elementAt(8); 16 | 17 | queue 18 | ..elementAt(queue.length - 1) // LINT 19 | ..elementAt(queue.length - 2) 20 | ..elementAt(queueLength - 1) 21 | ..elementAt(queueLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/set_example.dart: -------------------------------------------------------------------------------- 1 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 2 | 3 | void func() { 4 | final set = _array.toSet(); 5 | final setLength = set.length; 6 | final setLastIndex = set.length - 1; 7 | 8 | set.last; 9 | set.elementAt(set.length - 1); // LINT 10 | set.elementAt(set.length - 2); 11 | set.elementAt(setLength - 1); 12 | set.elementAt(setLastIndex); 13 | set.elementAt(8); 14 | 15 | set 16 | ..elementAt(set.length - 1) // LINT 17 | ..elementAt(set.length - 2) 18 | ..elementAt(setLength - 1) 19 | ..elementAt(setLastIndex) 20 | ..elementAt(8); 21 | } 22 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/splay_tree_set_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final splayTreeSet = SplayTreeSet.of(_array); 7 | final splayTreeSetLength = splayTreeSet.length; 8 | final splayTreeSetLastIndex = splayTreeSet.length - 1; 9 | 10 | splayTreeSet.last; 11 | splayTreeSet.elementAt(splayTreeSet.length - 1); // LINT 12 | splayTreeSet.elementAt(splayTreeSet.length - 2); 13 | splayTreeSet.elementAt(splayTreeSetLength - 1); 14 | splayTreeSet.elementAt(splayTreeSetLastIndex); 15 | splayTreeSet.elementAt(8); 16 | 17 | splayTreeSet 18 | ..elementAt(splayTreeSet.length - 1) // LINT 19 | ..elementAt(splayTreeSet.length - 2) 20 | ..elementAt(splayTreeSetLength - 1) 21 | ..elementAt(splayTreeSetLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_last/examples/unmodifiable_set_view_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 4 | 5 | void func() { 6 | final unmodifiableSetView = UnmodifiableSetView(_array.toSet()); 7 | final unmodifiableSetViewLength = unmodifiableSetView.length; 8 | final unmodifiableSetViewLastIndex = unmodifiableSetView.length - 1; 9 | 10 | unmodifiableSetView.last; 11 | unmodifiableSetView.elementAt(unmodifiableSetView.length - 1); // LINT 12 | unmodifiableSetView.elementAt(unmodifiableSetView.length - 2); 13 | unmodifiableSetView.elementAt(unmodifiableSetViewLength - 1); 14 | unmodifiableSetView.elementAt(unmodifiableSetViewLastIndex); 15 | unmodifiableSetView.elementAt(8); 16 | 17 | unmodifiableSetView 18 | ..elementAt(unmodifiableSetView.length - 1) // LINT 19 | ..elementAt(unmodifiableSetView.length - 2) 20 | ..elementAt(unmodifiableSetViewLength - 1) 21 | ..elementAt(unmodifiableSetViewLastIndex) 22 | ..elementAt(8); 23 | } 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/empty_file.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Example extends StatelessWidget { 2 | const Example({Key? key}) : super(key: key); 3 | 4 | @override 5 | Widget build(BuildContext context) { 6 | return Container(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/example_with_issue.dart: -------------------------------------------------------------------------------- 1 | class Example extends StatelessWidget { 2 | const Example({Key? key}) : super(key: key); 3 | 4 | @override 5 | Widget build(BuildContext context) { 6 | return Container(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/example_with_state.dart: -------------------------------------------------------------------------------- 1 | class ExampleWithState extends StatefulWidget { 2 | const ExampleWithState({Key? key}) : super(key: key); 3 | 4 | @override 5 | _ExampleWithStateState createState() => _ExampleWithStateState(); 6 | } 7 | 8 | class _ExampleWithStateState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/multiple_classes_example.dart: -------------------------------------------------------------------------------- 1 | class _Multiclass {} 2 | 3 | class MultipleClassesExample {} 4 | 5 | class Test {} 6 | 7 | class Absolut {} 8 | 9 | class Best {} 10 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/multiple_enums.dart: -------------------------------------------------------------------------------- 1 | enum _MultiEnum { a, b, c } 2 | 3 | enum MultipleEnumExample { a, b, c } 4 | 5 | enum Test { a, b, c } 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/multiple_extensions.dart: -------------------------------------------------------------------------------- 1 | extension _MultiExtension on String {} 2 | 3 | extension MultipleExtensionExample on String {} 4 | 5 | extension Test on String {} 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/multiple_mixins.dart: -------------------------------------------------------------------------------- 1 | mixin _MultiMixin {} 2 | 3 | mixin MultipleMixinExample {} 4 | 5 | mixin Test {} 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/private_class.dart: -------------------------------------------------------------------------------- 1 | class _PrivateClass {} 2 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_match_file_name/examples/some_widget.codegen.dart: -------------------------------------------------------------------------------- 1 | class SomeWidget extends StatelessWidget { 2 | @override 3 | Widget build(BuildContext context) { 4 | //... 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/assignment_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | final var1 = someFunction(); 3 | final var2 = someFunction(); 4 | } 5 | 6 | String someFunction() { 7 | return 'qwe'; 8 | } 9 | 10 | class SomeClass { 11 | final SomeClass inner; 12 | 13 | String _value = '123'; 14 | 15 | String get value => _value; 16 | set(String value) { 17 | _value = value; 18 | } 19 | 20 | void method() { 21 | final first = inner.inner.value; 22 | inner.inner.value = 'hello'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/generics_example.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | final a = GetIt.instance(); 3 | final b = GetIt.instance(); 4 | } 5 | 6 | class GetIt { 7 | static final _instance = GetIt(); 8 | 9 | static GetIt get instance => _instance; 10 | 11 | T get() => 'str' as T; 12 | 13 | T call() => get; 14 | } 15 | 16 | enum AnotherEnum { 17 | firstValue, 18 | anotherValue, 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/prefix_example.dart: -------------------------------------------------------------------------------- 1 | import 'example.dart' as prefix; 2 | import 'generics_example.dart'; 3 | 4 | void main() { 5 | AnotherEnum.anotherValue; 6 | AnotherEnum.anotherValue; 7 | AnotherEnum.firstValue; 8 | 9 | prefix.SomeValue.firstValue; 10 | prefix.SomeValue.firstValue; 11 | prefix.SomeValue.secondValue; 12 | 13 | prefix.SomeClass.value; 14 | prefix.SomeClass.value; 15 | prefix.instance.field; 16 | 17 | print(prefix.SomeValue.entry1); 18 | print(prefix.SomeValue.entry2); 19 | } 20 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/provider_example.dart: -------------------------------------------------------------------------------- 1 | class MyApp extends StatefulWidget { 2 | const MyApp(); 3 | } 4 | 5 | class _MyAppState extends State { 6 | late final A a; 7 | late final B b; 8 | late final C c; 9 | 10 | @override 11 | void initState() { 12 | super.initState(); 13 | 14 | a = context.read(); 15 | b = context.read(); 16 | c = context.read(); 17 | } 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Container(); 22 | } 23 | } 24 | 25 | class A {} 26 | 27 | class B {} 28 | 29 | class C {} 30 | 31 | class Widget {} 32 | 33 | class StatefulWidget extends Widget {} 34 | 35 | class BuildContext {} 36 | 37 | extension ReadContext on BuildContext { 38 | T read() { 39 | return 'value' as T; 40 | } 41 | } 42 | 43 | abstract class State { 44 | void initState(); 45 | 46 | void setState(VoidCallback callback) => callback(); 47 | 48 | BuildContext get context => BuildContext(); 49 | } 50 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/while_example.dart: -------------------------------------------------------------------------------- 1 | class SomeClass { 2 | final _addedComments = {}; 3 | 4 | Token? _latestCommentToken(Token token) { 5 | Token? latestCommentToken = token.precedingComments; 6 | while (latestCommentToken?.next != null) { 7 | latestCommentToken = latestCommentToken?.next; 8 | } 9 | 10 | return latestCommentToken; 11 | } 12 | 13 | void method(Token token) { 14 | Token? commentToken = token.precedingComments; 15 | 16 | if (commentToken != null && !_addedComments.contains(commentToken)) { 17 | if (!fromEnd) { 18 | sink.write('\n'); 19 | } 20 | } 21 | 22 | while (commentToken != null) { 23 | if (_addedComments.contains(commentToken)) { 24 | commentToken = commentToken.next; 25 | continue; 26 | } 27 | _addedComments.add(commentToken); 28 | } 29 | } 30 | } 31 | 32 | class Token { 33 | final Token precedingComments; 34 | 35 | const Token(this.precedingComments); 36 | } 37 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_quotes/examples/example.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: unnecessary_cast, unused_local_variable 2 | 3 | import 'dart:collection'; 4 | 5 | void func() { 6 | final String value1 = "some value"; // Lint 7 | final String value2 = 'some value'; 8 | 9 | final String value3 = "some value \"another text\""; // Lint 10 | final String value4 = 'some value \"another text\"'; 11 | 12 | final String value5 = """ 13 | multi line text 14 | """; 15 | final String value6 = ''' 16 | multi line text 17 | '''; 18 | } 19 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/examples/correct_statefull_widget_example.dart: -------------------------------------------------------------------------------- 1 | import 'flutter_defines.dart'; 2 | 3 | class SomeStatefulWidget extends StatefulWidget { 4 | @override 5 | _someStatefulWidgetState createState() => _someStatefulWidgetState(); 6 | } 7 | 8 | class _SomeStatefulWidgetState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | // ... 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/examples/correct_stateless_widget_example.dart: -------------------------------------------------------------------------------- 1 | import 'flutter_defines.dart'; 2 | 3 | class SomeWidget extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | // ... 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/examples/flutter_defines.dart: -------------------------------------------------------------------------------- 1 | class Widget {} 2 | 3 | class StatefulWidget extends Widget {} 4 | 5 | class StatelessWidget extends Widget {} 6 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/examples/incorrect_example.dart: -------------------------------------------------------------------------------- 1 | import 'flutter_defines.dart'; 2 | 3 | class SomeWidget extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | // ... 7 | } 8 | } 9 | 10 | // LINT 11 | class SomeOtherWidget extends StatelessWidget { 12 | @override 13 | Widget build(BuildContext context) { 14 | // ... 15 | } 16 | } 17 | 18 | // LINT 19 | class _SomeOtherWidget extends StatelessWidget { 20 | @override 21 | Widget build(BuildContext context) { 22 | // ... 23 | } 24 | } 25 | 26 | // LINT 27 | class SomeStatefulWidget extends StatefulWidget { 28 | @override 29 | _someStatefulWidgetState createState() => _someStatefulWidgetState(); 30 | } 31 | 32 | class _SomeStatefulWidgetState extends State { 33 | @override 34 | Widget build(BuildContext context) { 35 | // ... 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_single_widget_per_file/examples/multi_widgets_example.dart: -------------------------------------------------------------------------------- 1 | import 'flutter_defines.dart'; 2 | 3 | class ExampleWidget extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | // ... 7 | } 8 | } 9 | 10 | class _PrivateWidget extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | // ... 14 | } 15 | } 16 | 17 | class _AnotherPrivateWidget extends StatefulWidget { 18 | @override 19 | _SomeStatefulWidgetState createState() => _SomeStatefulWidgetState(); 20 | } 21 | 22 | class _SomeStatefulWidgetState extends State { 23 | @override 24 | Widget build(BuildContext context) { 25 | // ... 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_static_class/examples/correct_example.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | 3 | Future main() {} 4 | 5 | class Example { 6 | void classMethod() {} 7 | static void staticClassMethod() {} 8 | var classVariable = 42; 9 | static var staticClassVariable = 42; 10 | static final staticClassFinalVariable = 42; 11 | static const classConstant = 42; 12 | 13 | void _privateClassMethod() {} 14 | static void _privateStaticClassMethod() {} 15 | var _privateClassVariable = 42; 16 | static var _privateStaticClassVariable = 42; 17 | static final _privateStaticClassFinalVariable = 42; 18 | static const _privateClassConstant = 42; 19 | } 20 | 21 | @FunctionalWidget 22 | Widget functionalWidget() {} 23 | 24 | @swidget 25 | Widget statelessWidget() {} 26 | 27 | @hwidget 28 | Widget hookWidget() {} 29 | 30 | @hcwidget 31 | Widget hookConsumerWidget() {} 32 | 33 | @riverpod 34 | int riverpodFunction(riverpodFunction ref) => 0; 35 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_static_class/examples/correct_ignore_annotation_example.dart: -------------------------------------------------------------------------------- 1 | @ignoredAnnotation 2 | void globalFunction() {} 3 | 4 | @ignoredAnnotation 5 | var globalVariable = 42; 6 | 7 | @ignoredAnnotation 8 | final globalFinalVariable = 42; 9 | 10 | @ignoredAnnotation 11 | const globalConstant = 42; 12 | 13 | @ignoredAnnotation 14 | void _privateGlobalFunction() {} 15 | 16 | @ignoredAnnotation 17 | var _privateGlobalVariable = 42; 18 | 19 | @ignoredAnnotation 20 | final _privateGlobalFinalVariable = 42; 21 | 22 | @ignoredAnnotation 23 | const _privateGlobalConstant = 42; 24 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_static_class/examples/correct_ignore_names_example.dart: -------------------------------------------------------------------------------- 1 | final someRiverpodProvider = 42; 2 | 3 | final useSomeRiverpodHook = 42; 4 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_static_class/examples/correct_ignore_private_example.dart: -------------------------------------------------------------------------------- 1 | void _privateGlobalFunction() {} 2 | 3 | var _privateGlobalVariable = 42; 4 | 5 | final _privateGlobalFinalVariable = 42; 6 | 7 | const _privateGlobalConstant = 42; 8 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/prefer_static_class/examples/incorrect_example.dart: -------------------------------------------------------------------------------- 1 | void globalFunction() {} // LINT 2 | var globalVariable = 42; // LINT 3 | final globalFinalVariable = 42; // LINT 4 | const globalConstant = 42; // LINT 5 | 6 | void _privateGlobalFunction() {} // LINT 7 | var _privateGlobalVariable = 42; // LINT 8 | final _privateGlobalFinalVariable = 42; // LINT 9 | const _privateGlobalConstant = 42; // LINT 10 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/tag_name/examples/example.dart: -------------------------------------------------------------------------------- 1 | class Fruit { 2 | static const _kTag = 'Fruit'; 3 | } 4 | 5 | class Apple extends Fruit { 6 | static const _kTag = 'Orange'; // LINT 7 | } 8 | 9 | class Orange extends Fruit { 10 | static const TAG = 'Or' + 'an' + 'ge'; 11 | } 12 | 13 | class _PlantState { 14 | static const _kTag = 'Plant'; // should not lint 15 | } 16 | 17 | const TAG = 'FileLevelTagIsIgnored'; 18 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/use_setstate_synchronously/examples/assert_example.dart: -------------------------------------------------------------------------------- 1 | class _FooState extends State { 2 | Widget build(context) { 3 | return FooWidget( 4 | onChange: (value) async { 5 | setState(() {}); 6 | await fetchData(); 7 | setState(() {}); // LINT 8 | 9 | assert(mounted); 10 | setState(() {}); 11 | }, 12 | ); 13 | } 14 | 15 | void pathologicalCases() async { 16 | setState(() {}); 17 | 18 | await fetch(); 19 | this.setState(() {}); // LINT 20 | 21 | if (1 == 1) { 22 | setState(() {}); // LINT 23 | } else { 24 | assert(mounted); 25 | setState(() {}); 26 | return; 27 | } 28 | setState(() {}); // LINT 29 | 30 | await fetch(); 31 | if (mounted && foo) { 32 | assert(mounted); 33 | } else { 34 | return; 35 | } 36 | setState(() {}); // LINT 37 | 38 | assert(mounted); 39 | setState(() {}); 40 | } 41 | } 42 | 43 | class State {} 44 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/use_setstate_synchronously/examples/context_mounted.dart: -------------------------------------------------------------------------------- 1 | class _FooState extends State { 2 | Widget build(BuildContext context) { 3 | return FooWidget( 4 | onChange: (value) async { 5 | setState(() {}); 6 | await fetchData(); 7 | 8 | if (context.mounted) setState(() {}); 9 | }, 10 | ); 11 | } 12 | } 13 | 14 | typedef VoidCallback = void Function(); 15 | 16 | class State { 17 | void setState(VoidCallback callback) {} 18 | } 19 | 20 | class BuildContext { 21 | bool get mounted => true; 22 | } 23 | 24 | Future fetchData() => Future.value('123'); 25 | -------------------------------------------------------------------------------- /test/src/analyzers/lint_analyzer/rules/rules_list/use_setstate_synchronously/examples/known_errors.dart: -------------------------------------------------------------------------------- 1 | class _MyState extends State { 2 | void awaitEmptyFuture() async { 3 | await Future.value(); 4 | setState(() {}); // LINT 5 | } 6 | 7 | void syncRegression() { 8 | doStuff(); 9 | setState(() {}); 10 | } 11 | 12 | void controlFlow() { 13 | await doStuff(); 14 | for (;;) { 15 | if (!mounted) break; 16 | setState(() {}); 17 | 18 | await doStuff(); 19 | if (!mounted) continue; 20 | setState(() {}); 21 | } 22 | 23 | await doStuff(); 24 | while (true) { 25 | if (!mounted) break; 26 | 27 | setState(() {}); 28 | } 29 | } 30 | } 31 | 32 | class State {} 33 | -------------------------------------------------------------------------------- /test/src/analyzers/unused_code_analyzer/reporters/reporter_factory_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dart_code_linter/src/analyzers/unused_code_analyzer/reporters/reporter_factory.dart'; 4 | import 'package:dart_code_linter/src/analyzers/unused_code_analyzer/reporters/reporters_list/console/unused_code_console_reporter.dart'; 5 | import 'package:dart_code_linter/src/analyzers/unused_code_analyzer/reporters/reporters_list/json/unused_code_json_reporter.dart'; 6 | import 'package:test/test.dart'; 7 | 8 | void main() { 9 | test('Unused code reporter returns only required reporter', () { 10 | expect( 11 | reporter(name: '', output: stdout), 12 | isNull, 13 | ); 14 | 15 | expect( 16 | reporter( 17 | name: 'console', 18 | output: stdout, 19 | ), 20 | isA(), 21 | ); 22 | 23 | expect( 24 | reporter( 25 | name: 'json', 26 | output: stdout, 27 | ), 28 | isA(), 29 | ); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/src/analyzers/unused_files_analyzer/reporters/reporter_factory_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dart_code_linter/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart'; 4 | import 'package:dart_code_linter/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart'; 5 | import 'package:dart_code_linter/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart'; 6 | import 'package:test/test.dart'; 7 | 8 | void main() { 9 | test('Unused files reporter returns only required reporter', () { 10 | expect( 11 | reporter(name: '', output: stdout), 12 | isNull, 13 | ); 14 | 15 | expect( 16 | reporter( 17 | name: 'console', 18 | output: stdout, 19 | ), 20 | isA(), 21 | ); 22 | 23 | expect( 24 | reporter( 25 | name: 'json', 26 | output: stdout, 27 | ), 28 | isA(), 29 | ); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart'; 4 | import 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart'; 5 | import 'package:dart_code_linter/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart'; 6 | import 'package:test/test.dart'; 7 | 8 | void main() { 9 | test('Unused l10n reporter returns only required reporter', () { 10 | expect( 11 | reporter(name: '', output: stdout), 12 | isNull, 13 | ); 14 | 15 | expect( 16 | reporter( 17 | name: 'console', 18 | output: stdout, 19 | ), 20 | isA(), 21 | ); 22 | 23 | expect( 24 | reporter( 25 | name: 'json', 26 | output: stdout, 27 | ), 28 | isA(), 29 | ); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /tools/analyzer_plugin/analysis_options.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/dart-code-linter/976665473056877f5bb2bf088542a6d5258e90ee/tools/analyzer_plugin/analysis_options.yaml -------------------------------------------------------------------------------- /tools/analyzer_plugin/bin/plugin.dart: -------------------------------------------------------------------------------- 1 | import 'dart:isolate'; 2 | 3 | import 'package:dart_code_linter/analyzer_plugin.dart'; 4 | 5 | void main(List args, SendPort sendPort) { 6 | start(args, sendPort); 7 | } 8 | -------------------------------------------------------------------------------- /tools/analyzer_plugin/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_code_linter_plugin_loader 2 | description: This pubspec determines the version of the analyzer plugin to load. 3 | version: 2.0.0 4 | 5 | environment: 6 | sdk: ">=2.14.0 <3.0.0" 7 | 8 | dependencies: 9 | dart_code_linter: 2.0.0 10 | 11 | dev_dependencies: 12 | lints: ^1.0.1 13 | --------------------------------------------------------------------------------