@sun-asterisk/sunlint 1.3.32 → 1.3.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/config/released-rules.json +62 -0
- package/config/rules/enhanced-rules-registry.json +2315 -1354
- package/core/adapters/dart-analyzer.js +658 -0
- package/core/adapters/index.js +102 -0
- package/core/adapters/sunlint-rule-adapter.js +0 -2
- package/core/adapters/typescript-analyzer.js +277 -0
- package/core/analysis-orchestrator.js +168 -40
- package/core/architecture-integration.js +220 -0
- package/core/cli-action-handler.js +72 -24
- package/core/cli-program.js +13 -1
- package/core/config-merger.js +24 -14
- package/core/constants/defaults.js +1 -2
- package/core/github-annotate-service.js +141 -89
- package/core/github-step-summary-generator.js +8 -8
- package/core/interfaces/language-analyzer.interface.js +393 -0
- package/core/output-service.js +102 -38
- package/core/rule-selection-service.js +77 -27
- package/core/scoring-service.js +65 -20
- package/core/semantic-engine-manager.js +375 -0
- package/core/semantic-engine.js +4 -57
- package/core/unified-rule-registry.js +52 -11
- package/core/upload-service.js +43 -9
- package/docs/DART_RULE_EXECUTION_FLOW.md +745 -0
- package/docs/DART_SUPPORT_IMPLEMENTATION.md +245 -0
- package/docs/SUNLINT_ARCHITECTURE.md +692 -0
- package/docs/skills/CREATE_DART_RULE.md +909 -0
- package/engines/eslint-engine.js +2 -8
- package/engines/heuristic-engine.js +234 -38
- package/package.json +6 -5
- package/rules/common/C002_no_duplicate_code/config.json +12 -20
- package/rules/common/C002_no_duplicate_code/dart/analyzer.js +53 -0
- package/rules/common/C002_no_duplicate_code/index.js +93 -0
- package/rules/common/C003_no_vague_abbreviations/config.json +1 -1
- package/rules/common/C003_no_vague_abbreviations/dart/analyzer.js +54 -0
- package/rules/common/C003_no_vague_abbreviations/index.js +93 -0
- package/rules/common/C006_function_naming/dart/analyzer.js +40 -0
- package/rules/common/C006_function_naming/index.js +86 -0
- package/rules/common/C008_variable_declaration_locality/dart/analyzer.js +32 -0
- package/rules/common/C008_variable_declaration_locality/index.js +86 -0
- package/rules/common/C010_limit_block_nesting/dart/analyzer.js +32 -0
- package/rules/common/C010_limit_block_nesting/index.js +86 -0
- package/rules/common/C012_command_query_separation/config.json +61 -0
- package/rules/common/C012_command_query_separation/dart/analyzer.js +32 -0
- package/rules/common/C012_command_query_separation/index.js +86 -0
- package/rules/common/C013_no_dead_code/dart/analyzer.js +32 -0
- package/rules/common/C013_no_dead_code/index.js +86 -0
- package/rules/common/C014_dependency_injection/dart/analyzer.js +32 -0
- package/rules/common/C014_dependency_injection/index.js +86 -0
- package/rules/common/C017_constructor_logic/dart/analyzer.js +32 -0
- package/rules/common/C017_constructor_logic/index.js +86 -0
- package/rules/common/C018_no_throw_generic_error/dart/analyzer.js +32 -0
- package/rules/common/C018_no_throw_generic_error/index.js +86 -0
- package/rules/common/C019_log_level_usage/dart/analyzer.js +32 -0
- package/rules/common/C019_log_level_usage/index.js +86 -0
- package/rules/common/C019_log_level_usage/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C020_unused_imports/dart/analyzer.js +32 -0
- package/rules/common/C020_unused_imports/index.js +86 -0
- package/rules/common/C020_unused_imports/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C021_import_organization/config.json +29 -9
- package/rules/common/C021_import_organization/dart/analyzer.js +40 -0
- package/rules/common/C021_import_organization/index.js +83 -0
- package/rules/common/C021_import_organization/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C023_no_duplicate_variable/config.json +7 -2
- package/rules/common/C023_no_duplicate_variable/dart/analyzer.js +40 -0
- package/rules/common/C023_no_duplicate_variable/index.js +83 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/config.json +7 -2
- package/rules/common/C024_no_scatter_hardcoded_constants/dart/analyzer.js +40 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/index.js +83 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +19 -1
- package/rules/common/C029_catch_block_logging/config.json +15 -5
- package/rules/common/C029_catch_block_logging/dart/analyzer.js +40 -0
- package/rules/common/C029_catch_block_logging/index.js +83 -0
- package/rules/common/C030_use_custom_error_classes/config.json +28 -0
- package/rules/common/C030_use_custom_error_classes/dart/analyzer.js +40 -0
- package/rules/common/C030_use_custom_error_classes/index.js +83 -0
- package/rules/common/C031_validation_separation/config.json +28 -0
- package/rules/common/C031_validation_separation/dart/analyzer.js +40 -0
- package/rules/common/C031_validation_separation/index.js +83 -0
- package/rules/common/C033_separate_service_repository/config.json +8 -3
- package/rules/common/C033_separate_service_repository/dart/analyzer.js +40 -0
- package/rules/common/C033_separate_service_repository/index.js +83 -0
- package/rules/common/C035_error_logging_context/config.json +34 -12
- package/rules/common/C035_error_logging_context/dart/analyzer.js +40 -0
- package/rules/common/C035_error_logging_context/index.js +83 -0
- package/rules/common/C040_centralized_validation/config.json +37 -8
- package/rules/common/C040_centralized_validation/dart/analyzer.js +40 -0
- package/rules/common/C040_centralized_validation/index.js +83 -0
- package/rules/common/C041_no_sensitive_hardcode/config.json +7 -2
- package/rules/common/C041_no_sensitive_hardcode/dart/analyzer.js +40 -0
- package/rules/common/C041_no_sensitive_hardcode/index.js +83 -0
- package/rules/common/C042_boolean_name_prefix/config.json +28 -0
- package/rules/common/C042_boolean_name_prefix/dart/analyzer.js +40 -0
- package/rules/common/C042_boolean_name_prefix/index.js +83 -0
- package/rules/common/C043_no_console_or_print/config.json +28 -0
- package/rules/common/C043_no_console_or_print/dart/analyzer.js +40 -0
- package/rules/common/C043_no_console_or_print/index.js +83 -0
- package/rules/common/C047_no_duplicate_retry_logic/config.json +28 -0
- package/rules/common/C047_no_duplicate_retry_logic/dart/analyzer.js +40 -0
- package/rules/common/C047_no_duplicate_retry_logic/index.js +83 -0
- package/rules/common/C048_no_bypass_architectural_layers/config.json +7 -2
- package/rules/common/C048_no_bypass_architectural_layers/dart/analyzer.js +40 -0
- package/rules/common/C048_no_bypass_architectural_layers/index.js +83 -0
- package/rules/common/C052_parsing_or_data_transformation/config.json +7 -2
- package/rules/common/C052_parsing_or_data_transformation/dart/analyzer.js +40 -0
- package/rules/common/C052_parsing_or_data_transformation/index.js +83 -0
- package/rules/common/C060_no_override_superclass/config.json +7 -2
- package/rules/common/C060_no_override_superclass/dart/analyzer.js +40 -0
- package/rules/common/C060_no_override_superclass/index.js +83 -0
- package/rules/common/C065_one_behavior_per_test/config.json +187 -28
- package/rules/common/C065_one_behavior_per_test/dart/analyzer.js +40 -0
- package/rules/common/C065_one_behavior_per_test/index.js +83 -0
- package/rules/common/C067_no_hardcoded_config/config.json +18 -4
- package/rules/common/C067_no_hardcoded_config/dart/analyzer.js +40 -0
- package/rules/common/C067_no_hardcoded_config/index.js +83 -0
- package/rules/common/C070_no_real_time_tests/config.json +41 -12
- package/rules/common/C070_no_real_time_tests/dart/analyzer.js +40 -0
- package/rules/common/C070_no_real_time_tests/index.js +83 -0
- package/rules/common/C072_single_test_behavior/config.json +28 -0
- package/rules/common/C072_single_test_behavior/dart/analyzer.js +40 -0
- package/rules/common/C072_single_test_behavior/index.js +83 -0
- package/rules/common/C073_validate_required_config_on_startup/config.json +93 -18
- package/rules/common/C073_validate_required_config_on_startup/dart/analyzer.js +40 -0
- package/rules/common/C073_validate_required_config_on_startup/index.js +83 -0
- package/rules/common/C073_validate_required_config_on_startup/{analyzer.js → typescript/analyzer.js} +0 -1
- package/rules/common/C075_explicit_return_types/config.json +28 -0
- package/rules/common/C075_explicit_return_types/dart/analyzer.js +40 -0
- package/rules/common/C075_explicit_return_types/index.js +83 -0
- package/rules/common/C076_explicit_function_types/config.json +18 -4
- package/rules/common/C076_explicit_function_types/dart/analyzer.js +40 -0
- package/rules/common/C076_explicit_function_types/index.js +83 -0
- package/rules/index.js +26 -6
- package/rules/security/S003_open_redirect_protection/config.json +11 -53
- package/rules/security/S003_open_redirect_protection/dart/analyzer.js +43 -0
- package/rules/security/S003_open_redirect_protection/index.js +94 -0
- package/rules/security/S003_open_redirect_protection/typescript/analyzer.js +105 -0
- package/rules/security/S003_open_redirect_protection/{symbol-based-analyzer.js → typescript/semantic-analyzer.js} +1 -1
- package/rules/security/S004_sensitive_data_logging/config.json +1 -1
- package/rules/security/S004_sensitive_data_logging/dart/analyzer.js +58 -0
- package/rules/security/S004_sensitive_data_logging/index.js +93 -0
- package/rules/security/S005_no_origin_auth/dart/analyzer.js +30 -0
- package/rules/security/S005_no_origin_auth/index.js +83 -0
- package/rules/security/S005_no_origin_auth/{analyzer.js → typescript/analyzer.js} +1 -0
- package/rules/security/S006_no_plaintext_recovery_codes/dart/analyzer.js +30 -0
- package/rules/security/S006_no_plaintext_recovery_codes/index.js +83 -0
- package/rules/security/S007_no_plaintext_otp/dart/analyzer.js +30 -0
- package/rules/security/S007_no_plaintext_otp/index.js +83 -0
- package/rules/security/S009_no_insecure_encryption/dart/analyzer.js +30 -0
- package/rules/security/S009_no_insecure_encryption/index.js +83 -0
- package/rules/security/S010_no_insecure_encryption/dart/analyzer.js +30 -0
- package/rules/security/S010_no_insecure_encryption/index.js +83 -0
- package/rules/security/S011_secure_guid_generation/dart/analyzer.js +30 -0
- package/rules/security/S011_secure_guid_generation/index.js +83 -0
- package/rules/security/S012_hardcoded_secrets/dart/analyzer.js +30 -0
- package/rules/security/S012_hardcoded_secrets/index.js +83 -0
- package/rules/security/S012_hardcoded_secrets/typescript/config.json +75 -0
- package/rules/security/S013_tls_enforcement/dart/analyzer.js +30 -0
- package/rules/security/S013_tls_enforcement/index.js +83 -0
- package/rules/security/S014_tls_version_enforcement/dart/analyzer.js +30 -0
- package/rules/security/S014_tls_version_enforcement/index.js +83 -0
- package/rules/security/S015_insecure_tls_certificate/config.json +41 -0
- package/rules/security/S015_insecure_tls_certificate/dart/analyzer.js +19 -0
- package/rules/security/S015_insecure_tls_certificate/index.js +83 -0
- package/rules/security/S016_no_sensitive_querystring/dart/analyzer.js +30 -0
- package/rules/security/S016_no_sensitive_querystring/index.js +83 -0
- package/rules/security/S017_use_parameterized_queries/dart/analyzer.js +30 -0
- package/rules/security/S017_use_parameterized_queries/index.js +83 -0
- package/rules/security/S019_smtp_injection_protection/dart/analyzer.js +30 -0
- package/rules/security/S019_smtp_injection_protection/index.js +83 -0
- package/rules/security/S020_no_eval_dynamic_code/dart/analyzer.js +30 -0
- package/rules/security/S020_no_eval_dynamic_code/index.js +83 -0
- package/rules/security/S022_escape_output_context/dart/analyzer.js +30 -0
- package/rules/security/S022_escape_output_context/index.js +83 -0
- package/rules/security/S023_no_json_injection/dart/analyzer.js +30 -0
- package/rules/security/S023_no_json_injection/index.js +83 -0
- package/rules/security/S024_xpath_xxe_protection/dart/analyzer.js +30 -0
- package/rules/security/S024_xpath_xxe_protection/index.js +83 -0
- package/rules/security/S025_server_side_validation/dart/analyzer.js +30 -0
- package/rules/security/S025_server_side_validation/index.js +83 -0
- package/rules/security/S026_json_schema_validation/dart/analyzer.js +30 -0
- package/rules/security/S026_json_schema_validation/index.js +83 -0
- package/rules/security/S027_no_hardcoded_secrets/dart/analyzer.js +30 -0
- package/rules/security/S027_no_hardcoded_secrets/index.js +83 -0
- package/rules/security/S028_file_upload_size_limits/dart/analyzer.js +30 -0
- package/rules/security/S028_file_upload_size_limits/index.js +83 -0
- package/rules/security/S029_csrf_protection/dart/analyzer.js +30 -0
- package/rules/security/S029_csrf_protection/index.js +83 -0
- package/rules/security/S030_directory_browsing_protection/dart/analyzer.js +30 -0
- package/rules/security/S030_directory_browsing_protection/index.js +83 -0
- package/rules/security/S031_secure_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S031_secure_session_cookies/index.js +83 -0
- package/rules/security/S032_httponly_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S032_httponly_session_cookies/index.js +83 -0
- package/rules/security/S033_samesite_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S033_samesite_session_cookies/index.js +83 -0
- package/rules/security/S034_host_prefix_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S034_host_prefix_session_cookies/index.js +83 -0
- package/rules/security/S035_path_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S035_path_session_cookies/index.js +83 -0
- package/rules/security/S036_lfi_rfi_protection/dart/analyzer.js +30 -0
- package/rules/security/S036_lfi_rfi_protection/index.js +83 -0
- package/rules/security/S037_cache_headers/dart/analyzer.js +30 -0
- package/rules/security/S037_cache_headers/index.js +83 -0
- package/rules/security/S038_no_version_headers/dart/analyzer.js +30 -0
- package/rules/security/S038_no_version_headers/index.js +83 -0
- package/rules/security/S039_no_session_tokens_in_url/dart/analyzer.js +30 -0
- package/rules/security/S039_no_session_tokens_in_url/index.js +83 -0
- package/rules/security/S040_session_fixation_protection/dart/analyzer.js +30 -0
- package/rules/security/S040_session_fixation_protection/index.js +83 -0
- package/rules/security/S041_session_token_invalidation/dart/analyzer.js +30 -0
- package/rules/security/S041_session_token_invalidation/index.js +83 -0
- package/rules/security/S042_require_re_authentication_for_long_lived/dart/analyzer.js +30 -0
- package/rules/security/S042_require_re_authentication_for_long_lived/index.js +83 -0
- package/rules/security/S043_password_changes_invalidate_all_sessions/dart/analyzer.js +30 -0
- package/rules/security/S043_password_changes_invalidate_all_sessions/index.js +83 -0
- package/rules/security/S044_re_authentication_required/dart/analyzer.js +30 -0
- package/rules/security/S044_re_authentication_required/index.js +83 -0
- package/rules/security/S045_brute_force_protection/dart/analyzer.js +30 -0
- package/rules/security/S045_brute_force_protection/index.js +83 -0
- package/rules/security/S048_no_current_password_in_reset/dart/analyzer.js +30 -0
- package/rules/security/S048_no_current_password_in_reset/index.js +83 -0
- package/rules/security/S049_short_validity_tokens/dart/analyzer.js +30 -0
- package/rules/security/S049_short_validity_tokens/index.js +83 -0
- package/rules/security/S049_short_validity_tokens/typescript/config.json +124 -0
- package/rules/security/S051_password_length_policy/dart/analyzer.js +30 -0
- package/rules/security/S051_password_length_policy/index.js +83 -0
- package/rules/security/S051_password_length_policy/typescript/config.json +83 -0
- package/rules/security/S052_weak_otp_entropy/dart/analyzer.js +30 -0
- package/rules/security/S052_weak_otp_entropy/index.js +83 -0
- package/rules/security/S052_weak_otp_entropy/typescript/config.json +57 -0
- package/rules/security/S054_no_default_accounts/dart/analyzer.js +30 -0
- package/rules/security/S054_no_default_accounts/index.js +83 -0
- package/rules/security/S054_no_default_accounts/typescript/config.json +101 -0
- package/rules/security/S055_content_type_validation/dart/analyzer.js +30 -0
- package/rules/security/S055_content_type_validation/index.js +83 -0
- package/rules/security/S056_log_injection_protection/dart/analyzer.js +30 -0
- package/rules/security/S056_log_injection_protection/index.js +83 -0
- package/rules/security/S057_utc_logging/dart/analyzer.js +30 -0
- package/rules/security/S057_utc_logging/index.js +83 -0
- package/rules/security/S057_utc_logging/typescript/config.json +105 -0
- package/rules/security/S058_no_ssrf/dart/analyzer.js +30 -0
- package/rules/security/S058_no_ssrf/index.js +83 -0
- package/rules/security/S058_no_ssrf/{analyzer.js → typescript/analyzer.js} +0 -1
- package/rules/security/S058_no_ssrf/typescript/config.json +125 -0
- package/scripts/build-release.sh +12 -0
- package/scripts/copy-arch-detect.js +78 -0
- package/rules/common/C002_no_duplicate_code/test-cases/api-handlers.ts +0 -64
- package/rules/common/C002_no_duplicate_code/test-cases/data-processor.ts +0 -46
- package/rules/common/C002_no_duplicate_code/test-cases/good-example.tsx +0 -40
- package/rules/common/C002_no_duplicate_code/test-cases/product-service.ts +0 -57
- package/rules/common/C002_no_duplicate_code/test-cases/user-service.ts +0 -49
- package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js.backup +0 -3853
- package/rules/security/S003_open_redirect_protection/analyzer.js +0 -135
- /package/rules/common/C002_no_duplicate_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C003_no_vague_abbreviations/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C006_function_naming/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality}/config.json +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/analyzer.js +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/ts-morph-analyzer.js +0 -0
- /package/rules/common/C010_limit_block_nesting/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C010_limit_block_nesting/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C010_limit_block_nesting/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C012_command_query_separation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C012_command_query_separation/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C014_dependency_injection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C014_dependency_injection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C017_constructor_logic/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C017_constructor_logic/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{pattern-analyzer.js → typescript/pattern-analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{system-log-analyzer.js → typescript/system-log-analyzer.js} +0 -0
- /package/rules/common/C020_unused_imports/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C021_import_organization/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C023_no_duplicate_variable/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C023_no_duplicate_variable/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C024_no_scatter_hardcoded_constants/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C029_catch_block_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C030_use_custom_error_classes/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C031_validation_separation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C033_separate_service_repository/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{STRATEGY.md → typescript/STRATEGY.md} +0 -0
- /package/rules/common/C035_error_logging_context/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C041_no_sensitive_hardcode/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C041_no_sensitive_hardcode/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C042_boolean_name_prefix/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C043_no_console_or_print/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{c047-semantic-rule.js → typescript/c047-semantic-rule.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{symbol-analyzer-enhanced.js → typescript/symbol-analyzer-enhanced.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{symbol-config.json → typescript/symbol-config.json} +0 -0
- /package/rules/common/C048_no_bypass_architectural_layers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C048_no_bypass_architectural_layers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C052_parsing_or_data_transformation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C052_parsing_or_data_transformation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C060_no_override_superclass/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C060_no_override_superclass/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C065_one_behavior_per_test/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C067_no_hardcoded_config/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C067_no_hardcoded_config/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C070_no_real_time_tests/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C070_no_real_time_tests/{regex-analyzer.js → typescript/regex-analyzer.js} +0 -0
- /package/rules/common/C072_single_test_behavior/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C073_validate_required_config_on_startup/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C073_validate_required_config_on_startup/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C075_explicit_return_types/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C076_explicit_function_types/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C076_explicit_function_types/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C076_explicit_function_types/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
- /package/rules/security/S003_open_redirect_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S004_sensitive_data_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S004_sensitive_data_logging/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S005_no_origin_auth/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S005_no_origin_auth/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S005_no_origin_auth/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-config.json → typescript/semantic-config.json} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-wrapper.js → typescript/semantic-wrapper.js} +0 -0
- /package/rules/security/S009_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S009_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S010_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S010_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S011_secure_guid_generation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S011_secure_guid_generation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S011_secure_guid_generation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S012_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S012_hardcoded_secrets/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S013_tls_enforcement/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S013_tls_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S013_tls_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S015_insecure_tls_certificate/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S015_insecure_tls_certificate/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S019_smtp_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S019_smtp_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S022_escape_output_context/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S022_escape_output_context/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S023_no_json_injection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S023_no_json_injection/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S025_server_side_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S026_json_schema_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{categories.json → typescript/categories.json} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{categorized-analyzer.js → typescript/categorized-analyzer.js} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S029_csrf_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S031_secure_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S031_secure_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S031_secure_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{FRAMEWORK_SUPPORT.md → typescript/FRAMEWORK_SUPPORT.md} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S035_path_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S036_lfi_rfi_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S037_cache_headers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S038_no_version_headers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S040_session_fixation_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S041_session_token_invalidation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S044_re_authentication_required/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S045_brute_force_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S045_brute_force_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S045_brute_force_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S048_no_current_password_in_reset/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S048_no_current_password_in_reset/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S051_password_length_policy/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S052_weak_otp_entropy/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S054_no_default_accounts/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S054_no_default_accounts/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S055_content_type_validation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S055_content_type_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S055_content_type_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S057_utc_logging/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S057_utc_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S058_no_ssrf/{README.md → typescript/README.md} +0 -0
package/engines/eslint-engine.js
CHANGED
|
@@ -438,7 +438,6 @@ export default [
|
|
|
438
438
|
`;
|
|
439
439
|
|
|
440
440
|
fs.writeFileSync(tempConfigPath, configContent);
|
|
441
|
-
console.log(`🔧 [ESLintEngine] Created temporary flat config: ${tempConfigPath}`);
|
|
442
441
|
|
|
443
442
|
// Schedule cleanup
|
|
444
443
|
this.tempConfigPaths = this.tempConfigPaths || [];
|
|
@@ -545,7 +544,6 @@ export default [
|
|
|
545
544
|
}
|
|
546
545
|
}
|
|
547
546
|
|
|
548
|
-
console.log(`🔄 [ESLintEngine] Converted legacy config to flat config`);
|
|
549
547
|
return flatConfig;
|
|
550
548
|
|
|
551
549
|
} catch (error) {
|
|
@@ -1081,7 +1079,7 @@ export default [
|
|
|
1081
1079
|
}
|
|
1082
1080
|
}
|
|
1083
1081
|
|
|
1084
|
-
|
|
1082
|
+
// Custom rules loaded silently
|
|
1085
1083
|
return plugin;
|
|
1086
1084
|
} catch (error) {
|
|
1087
1085
|
console.warn('⚠️ Failed to load custom plugin:', error.message);
|
|
@@ -1148,7 +1146,7 @@ export default [
|
|
|
1148
1146
|
projectPath = process.cwd();
|
|
1149
1147
|
}
|
|
1150
1148
|
|
|
1151
|
-
|
|
1149
|
+
// Project path detected silently
|
|
1152
1150
|
|
|
1153
1151
|
// Get config detection for reuse
|
|
1154
1152
|
const configDetection = this.detectESLintConfig(projectPath);
|
|
@@ -1189,7 +1187,6 @@ export default [
|
|
|
1189
1187
|
overrideConfigFile: tempFlatConfigPath,
|
|
1190
1188
|
cwd: projectPath
|
|
1191
1189
|
};
|
|
1192
|
-
console.log(`✅ [ESLintEngine] Created temporary flat config for plugin compatibility`);
|
|
1193
1190
|
} else if (configDetection.hasLegacyConfig || configDetection.hasPackageConfig) {
|
|
1194
1191
|
// For legacy config, create a temporary flat config file
|
|
1195
1192
|
const tempFlatConfigPath = await this.createTemporaryFlatConfig(projectPath, configDetection, eslintConfig);
|
|
@@ -1197,20 +1194,17 @@ export default [
|
|
|
1197
1194
|
overrideConfigFile: tempFlatConfigPath,
|
|
1198
1195
|
cwd: projectPath
|
|
1199
1196
|
};
|
|
1200
|
-
console.log(`✅ [ESLintEngine] Created temporary flat config for legacy compatibility`);
|
|
1201
1197
|
} else {
|
|
1202
1198
|
// No config found - use analysis config only
|
|
1203
1199
|
finalESLintOptions = {
|
|
1204
1200
|
overrideConfig: eslintConfig,
|
|
1205
1201
|
cwd: projectPath
|
|
1206
1202
|
};
|
|
1207
|
-
console.log(`⚠️ [ESLintEngine] Using analysis config only`);
|
|
1208
1203
|
}
|
|
1209
1204
|
|
|
1210
1205
|
const finalESLintInstance = new ESLint(finalESLintOptions);
|
|
1211
1206
|
|
|
1212
1207
|
// Run ESLint analysis - let ESLint handle parsing errors gracefully
|
|
1213
|
-
console.log(`🔍 [ESLintEngine] Analyzing ${jstsFiles.length} JavaScript/TypeScript files...`);
|
|
1214
1208
|
let eslintResults;
|
|
1215
1209
|
|
|
1216
1210
|
try {
|
|
@@ -13,9 +13,43 @@ const SemanticEngine = require('../core/semantic-engine');
|
|
|
13
13
|
const SemanticRuleBase = require('../core/semantic-rule-base');
|
|
14
14
|
const { getInstance: getUnifiedRegistry } = require('../core/unified-rule-registry');
|
|
15
15
|
const AutoPerformanceManager = require('../core/auto-performance-manager');
|
|
16
|
+
// Multi-language support
|
|
17
|
+
const { getManager: getSemanticEngineManager } = require('../core/semantic-engine-manager');
|
|
18
|
+
const { registerBuiltInAnalyzers } = require('../core/adapters/index');
|
|
16
19
|
const fs = require('fs');
|
|
17
20
|
const path = require('path');
|
|
18
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Check if a rule supports Dart by detecting dart/ folder in rule structure
|
|
24
|
+
* @param {string} ruleId - Rule ID (e.g., 'C002', 'S003')
|
|
25
|
+
* @returns {boolean} True if rule has dart/ subfolder
|
|
26
|
+
*/
|
|
27
|
+
function detectDartSupport(ruleId) {
|
|
28
|
+
const rulesBasePath = path.join(__dirname, '../rules');
|
|
29
|
+
const categories = ['common', 'security', 'typescript'];
|
|
30
|
+
|
|
31
|
+
for (const category of categories) {
|
|
32
|
+
const categoryPath = path.join(rulesBasePath, category);
|
|
33
|
+
if (!fs.existsSync(categoryPath)) continue;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const ruleFolders = fs.readdirSync(categoryPath);
|
|
37
|
+
for (const folder of ruleFolders) {
|
|
38
|
+
// Match rule folder by ID prefix (e.g., C002_no_duplicate_code matches C002)
|
|
39
|
+
if (folder.startsWith(ruleId + '_') || folder === ruleId) {
|
|
40
|
+
const dartPath = path.join(categoryPath, folder, 'dart');
|
|
41
|
+
if (fs.existsSync(dartPath) && fs.statSync(dartPath).isDirectory()) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Ignore errors when scanning directories
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
19
53
|
class HeuristicEngine extends AnalysisEngineInterface {
|
|
20
54
|
constructor() {
|
|
21
55
|
super('heuristic', '4.0', ['typescript', 'javascript', 'dart', 'swift', 'kotlin', 'java', 'python', 'go', 'rust', 'all']);
|
|
@@ -30,6 +64,9 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
30
64
|
this.semanticEngine = null;
|
|
31
65
|
this.semanticRules = new Map();
|
|
32
66
|
this.symbolTableEnabled = false;
|
|
67
|
+
|
|
68
|
+
// Multi-language support via SemanticEngineManager
|
|
69
|
+
this.semanticEngineManager = null;
|
|
33
70
|
|
|
34
71
|
// Unified rule registry
|
|
35
72
|
this.unifiedRegistry = getUnifiedRegistry();
|
|
@@ -101,12 +138,13 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
101
138
|
}
|
|
102
139
|
|
|
103
140
|
/**
|
|
104
|
-
* Initialize
|
|
141
|
+
* Initialize Symbol Table with multi-language support
|
|
142
|
+
* ENHANCED: Uses SemanticEngineManager to support TypeScript, Dart, and other languages
|
|
105
143
|
* OPTIMIZED: Use targeted files instead of entire project for better performance
|
|
106
144
|
*/
|
|
107
145
|
async initializeSymbolTable(config) {
|
|
108
146
|
const projectPath = config?.projectPath || process.cwd();
|
|
109
|
-
|
|
147
|
+
|
|
110
148
|
try {
|
|
111
149
|
// Initialize semantic engine with config options including maxSemanticFiles
|
|
112
150
|
const semanticOptions = {
|
|
@@ -114,14 +152,49 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
114
152
|
verbose: this.verbose,
|
|
115
153
|
...config?.semanticOptions
|
|
116
154
|
};
|
|
117
|
-
|
|
155
|
+
|
|
156
|
+
// =========================================
|
|
157
|
+
// Multi-language support via SemanticEngineManager
|
|
158
|
+
// =========================================
|
|
159
|
+
|
|
160
|
+
// Register built-in language analyzers (TypeScript, Dart, etc.)
|
|
161
|
+
registerBuiltInAnalyzers({ verbose: this.verbose });
|
|
162
|
+
|
|
163
|
+
// Get the SemanticEngineManager singleton
|
|
164
|
+
this.semanticEngineManager = getSemanticEngineManager({
|
|
165
|
+
verbose: this.verbose,
|
|
166
|
+
maxSemanticFiles: config?.maxSemanticFiles
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Initialize all registered analyzers with the project
|
|
170
|
+
const managerSuccess = await this.semanticEngineManager.initialize(
|
|
171
|
+
projectPath,
|
|
172
|
+
config?.targetFiles
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
if (managerSuccess && this.verbose) {
|
|
176
|
+
console.log(`🌍 Multi-language support enabled:`);
|
|
177
|
+
const names = this.semanticEngineManager.getAnalyzerNames();
|
|
178
|
+
for (const name of names) {
|
|
179
|
+
const analyzer = this.semanticEngineManager.getAnalyzer(name);
|
|
180
|
+
if (analyzer?.isReady()) {
|
|
181
|
+
console.log(` ✅ ${name}: ${analyzer.extensions.join(', ')}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// =========================================
|
|
187
|
+
// Legacy SemanticEngine for backward compatibility
|
|
188
|
+
// =========================================
|
|
189
|
+
|
|
190
|
+
// Also initialize the legacy SemanticEngine directly for TypeScript
|
|
191
|
+
// This ensures backward compatibility with existing semantic rules
|
|
118
192
|
this.semanticEngine = new SemanticEngine(semanticOptions);
|
|
119
|
-
// Pass verbose option to semantic engine
|
|
120
193
|
this.semanticEngine.verbose = this.verbose;
|
|
121
|
-
|
|
194
|
+
|
|
122
195
|
// ts-morph is now a core dependency - but optimized for targeted files
|
|
123
196
|
const success = await this.semanticEngine.initialize(projectPath, config?.targetFiles);
|
|
124
|
-
|
|
197
|
+
|
|
125
198
|
if (success) {
|
|
126
199
|
this.semanticEnabled = true;
|
|
127
200
|
this.symbolTableInitialized = true;
|
|
@@ -133,7 +206,7 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
133
206
|
console.warn('⚠️ Symbol Table initialization failed, using fallback mode');
|
|
134
207
|
}
|
|
135
208
|
}
|
|
136
|
-
|
|
209
|
+
|
|
137
210
|
} catch (error) {
|
|
138
211
|
if (this.verbose) {
|
|
139
212
|
console.warn('⚠️ ts-morph Symbol Table unavailable:', error.message);
|
|
@@ -602,14 +675,25 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
602
675
|
if (ruleId === 'C047') {
|
|
603
676
|
return true;
|
|
604
677
|
}
|
|
605
|
-
|
|
678
|
+
|
|
679
|
+
// Check if rule supports Dart by detecting dart/ folder in rule structure
|
|
680
|
+
if (detectDartSupport(ruleId)) {
|
|
681
|
+
// Check if DartAnalyzer is available
|
|
682
|
+
if (this.semanticEngineManager) {
|
|
683
|
+
const dartAnalyzer = this.semanticEngineManager.getAnalyzer('dart');
|
|
684
|
+
if (dartAnalyzer && dartAnalyzer.isReady()) {
|
|
685
|
+
return true;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
606
690
|
// Use unified registry for primary lookup
|
|
607
691
|
if (this.unifiedRegistry && this.unifiedRegistry.initialized) {
|
|
608
692
|
return this.unifiedRegistry.isRuleSupported(ruleId, 'heuristic');
|
|
609
693
|
}
|
|
610
|
-
|
|
694
|
+
|
|
611
695
|
// Fallback to original logic for backward compatibility
|
|
612
|
-
return this.supportedRulesList.includes(ruleId) ||
|
|
696
|
+
return this.supportedRulesList.includes(ruleId) ||
|
|
613
697
|
this.semanticRules.has(ruleId) ||
|
|
614
698
|
this.ruleAnalyzers.has(ruleId) ||
|
|
615
699
|
this.checkShortRuleIdMatch(ruleId);
|
|
@@ -827,6 +911,11 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
827
911
|
processedRules++;
|
|
828
912
|
const ruleProgress = Math.floor((processedRules / totalRules) * 100);
|
|
829
913
|
|
|
914
|
+
// Notify progress callback
|
|
915
|
+
if (options.onRuleStart) {
|
|
916
|
+
options.onRuleStart(rule.id);
|
|
917
|
+
}
|
|
918
|
+
|
|
830
919
|
// Special case: Load C047 semantic rule on-demand
|
|
831
920
|
if (rule.id === 'C047' && !this.semanticRules.has('C047')) {
|
|
832
921
|
if (options.verbose) {
|
|
@@ -835,15 +924,22 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
835
924
|
await this.manuallyLoadC047();
|
|
836
925
|
}
|
|
837
926
|
|
|
838
|
-
//
|
|
839
|
-
|
|
927
|
+
// Check if this rule is handled by DartAnalyzer for Dart files
|
|
928
|
+
// Detect Dart support by checking for dart/ folder in rule structure
|
|
929
|
+
const isDartRule = detectDartSupport(rule.id);
|
|
930
|
+
const hasDartFiles = filesByLanguage['dart'] && filesByLanguage['dart'].length > 0;
|
|
931
|
+
const dartAnalyzer = this.semanticEngineManager?.getAnalyzer('dart');
|
|
932
|
+
const useDartAnalyzer = isDartRule && hasDartFiles && dartAnalyzer && dartAnalyzer.isReady();
|
|
933
|
+
|
|
934
|
+
// Lazy load rule if not already loaded (skip for Dart-only rules)
|
|
935
|
+
if (!useDartAnalyzer && !this.isRuleSupported(rule.id)) {
|
|
840
936
|
if (options.verbose) {
|
|
841
937
|
console.log(`🔄 [HeuristicEngine] Lazy loading rule ${rule.id}...`);
|
|
842
938
|
}
|
|
843
939
|
await this.lazyLoadRule(rule.id, options);
|
|
844
940
|
}
|
|
845
941
|
|
|
846
|
-
if (!this.isRuleSupported(rule.id)) {
|
|
942
|
+
if (!useDartAnalyzer && !this.isRuleSupported(rule.id)) {
|
|
847
943
|
if (options.verbose) {
|
|
848
944
|
console.warn(`⚠️ Rule ${rule.id} not supported by Heuristic engine, skipping...`);
|
|
849
945
|
}
|
|
@@ -853,24 +949,35 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
853
949
|
try {
|
|
854
950
|
let ruleViolations = [];
|
|
855
951
|
|
|
952
|
+
// Handle Dart files with DartAnalyzer
|
|
953
|
+
if (useDartAnalyzer) {
|
|
954
|
+
const dartFiles = filesByLanguage['dart'];
|
|
955
|
+
|
|
956
|
+
// Use DartAnalyzer directly
|
|
957
|
+
const rules = [{ id: rule.id, config: rule.config || {} }];
|
|
958
|
+
for (const filePath of dartFiles) {
|
|
959
|
+
try {
|
|
960
|
+
const violations = await dartAnalyzer.analyzeFile(filePath, rules, options);
|
|
961
|
+
if (violations && violations.length > 0) {
|
|
962
|
+
ruleViolations.push(...violations.map(v => ({
|
|
963
|
+
...v,
|
|
964
|
+
ruleId: v.ruleId || rule.id,
|
|
965
|
+
analysisMethod: v.analysisMethod || 'ast'
|
|
966
|
+
})));
|
|
967
|
+
}
|
|
968
|
+
} catch (error) {
|
|
969
|
+
// Silent error handling
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
856
973
|
// Check if this is a semantic rule first (higher priority)
|
|
857
|
-
if (this.semanticRules.has(rule.id)) {
|
|
858
|
-
const progressInfo = options.batchInfo?.overallProgress !== undefined
|
|
859
|
-
? `[${options.batchInfo.overallProgress}% overall] `
|
|
860
|
-
: '';
|
|
861
|
-
console.log(`🧠 ${progressInfo}Rule ${processedRules}/${totalRules} (${ruleProgress}%): ${rule.id} - Analyzing ${files.length} files...`);
|
|
862
|
-
|
|
974
|
+
else if (this.semanticRules.has(rule.id)) {
|
|
863
975
|
ruleViolations = await this.analyzeSemanticRule(rule, files, options);
|
|
864
976
|
} else {
|
|
865
977
|
// Fallback to traditional analysis
|
|
866
|
-
const progressInfo = options.batchInfo?.overallProgress !== undefined
|
|
867
|
-
? `[${options.batchInfo.overallProgress}% overall] `
|
|
868
|
-
: '';
|
|
869
|
-
console.log(`🔧 ${progressInfo}Rule ${processedRules}/${totalRules} (${ruleProgress}%): ${rule.id} - Analyzing ${files.length} files...`);
|
|
870
|
-
|
|
871
978
|
ruleViolations = await this.analyzeRule(rule, filesByLanguage, options);
|
|
872
979
|
}
|
|
873
|
-
|
|
980
|
+
|
|
874
981
|
if (ruleViolations.length > 0) {
|
|
875
982
|
// Group violations by file
|
|
876
983
|
const violationsByFile = this.groupViolationsByFile(ruleViolations);
|
|
@@ -886,11 +993,10 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
886
993
|
}
|
|
887
994
|
}
|
|
888
995
|
|
|
889
|
-
//
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
console.log(`✅ ${progressInfo}${rule.id}: Found ${ruleViolations.length} violations`);
|
|
996
|
+
// Only log in verbose mode
|
|
997
|
+
if (options.verbose) {
|
|
998
|
+
console.log(` ${rule.id}: ${ruleViolations.length} violations`);
|
|
999
|
+
}
|
|
894
1000
|
|
|
895
1001
|
results.metadata.analyzersUsed.push(rule.id);
|
|
896
1002
|
|
|
@@ -1208,6 +1314,48 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1208
1314
|
return this.supportedRulesList;
|
|
1209
1315
|
}
|
|
1210
1316
|
|
|
1317
|
+
/**
|
|
1318
|
+
* Get the SemanticEngineManager for multi-language support
|
|
1319
|
+
* @returns {SemanticEngineManager|null}
|
|
1320
|
+
*/
|
|
1321
|
+
getSemanticEngineManager() {
|
|
1322
|
+
return this.semanticEngineManager;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Get a language-specific analyzer
|
|
1327
|
+
* @param {string} language - Language name (e.g., 'dart', 'typescript')
|
|
1328
|
+
* @returns {ILanguageAnalyzer|null}
|
|
1329
|
+
*/
|
|
1330
|
+
getLanguageAnalyzer(language) {
|
|
1331
|
+
if (!this.semanticEngineManager) {
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
return this.semanticEngineManager.getAnalyzer(language);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Get Symbol Table for a file using the appropriate language analyzer
|
|
1339
|
+
* @param {string} filePath - Path to the file
|
|
1340
|
+
* @returns {Promise<Object|null>}
|
|
1341
|
+
*/
|
|
1342
|
+
async getSymbolTableForFile(filePath) {
|
|
1343
|
+
// Try multi-language manager first
|
|
1344
|
+
if (this.semanticEngineManager && this.semanticEngineManager.isReady()) {
|
|
1345
|
+
const symbolTable = await this.semanticEngineManager.getSymbolTable(filePath);
|
|
1346
|
+
if (symbolTable) {
|
|
1347
|
+
return symbolTable;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// Fallback to legacy TypeScript-only semantic engine
|
|
1352
|
+
if (this.semanticEngine && this.semanticEngine.isSymbolEngineReady()) {
|
|
1353
|
+
return await this.semanticEngine.getSymbolTable(filePath);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
return null;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1211
1359
|
/**
|
|
1212
1360
|
* Run enhanced analysis with multiple strategies
|
|
1213
1361
|
* Automatically selects optimal analysis method per rule
|
|
@@ -1349,22 +1497,58 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1349
1497
|
*/
|
|
1350
1498
|
async runASTPrimaryAnalysis(analyzer, ruleId, files, language, options, strategy, debugConfig) {
|
|
1351
1499
|
const violations = [];
|
|
1352
|
-
|
|
1500
|
+
|
|
1353
1501
|
if (debugConfig.enabled) {
|
|
1354
1502
|
debugConfig.logger(this.constructor.name, `Starting AST-primary analysis for ${ruleId}, AST available: ${strategy.astAvailable}`);
|
|
1355
1503
|
}
|
|
1356
|
-
|
|
1504
|
+
|
|
1505
|
+
// Check if Dart analyzer is available for Dart files
|
|
1506
|
+
const dartAnalyzer = language === 'dart' && this.semanticEngineManager
|
|
1507
|
+
? this.semanticEngineManager.getAnalyzer('dart')
|
|
1508
|
+
: null;
|
|
1509
|
+
|
|
1510
|
+
if (dartAnalyzer && dartAnalyzer.isReady()) {
|
|
1511
|
+
if (debugConfig.enabled) {
|
|
1512
|
+
debugConfig.logger(this.constructor.name, `Using DartAnalyzer for ${files.length} Dart files`);
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
// Use DartAnalyzer for all Dart files
|
|
1516
|
+
try {
|
|
1517
|
+
const rules = [{ id: ruleId, config: {} }];
|
|
1518
|
+
for (const filePath of files) {
|
|
1519
|
+
const dartViolations = await dartAnalyzer.analyzeFile(filePath, rules, options);
|
|
1520
|
+
if (dartViolations && dartViolations.length > 0) {
|
|
1521
|
+
violations.push(...dartViolations.map(v => ({
|
|
1522
|
+
...v,
|
|
1523
|
+
analysisMethod: v.analysisMethod || 'ast',
|
|
1524
|
+
confidence: 90
|
|
1525
|
+
})));
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
if (debugConfig.enabled) {
|
|
1530
|
+
debugConfig.logger(this.constructor.name, `DartAnalyzer found ${violations.length} violations`);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
return violations;
|
|
1534
|
+
} catch (error) {
|
|
1535
|
+
if (debugConfig.enabled) {
|
|
1536
|
+
debugConfig.logger(this.constructor.name, `DartAnalyzer failed: ${error.message}, falling back to regex`);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1357
1541
|
for (const filePath of files) {
|
|
1358
1542
|
try {
|
|
1359
1543
|
const code = fs.readFileSync(filePath, 'utf8');
|
|
1360
1544
|
let analysisResult = null;
|
|
1361
|
-
|
|
1545
|
+
|
|
1362
1546
|
// Try AST analysis first if available
|
|
1363
1547
|
if (strategy.astAvailable) {
|
|
1364
1548
|
if (debugConfig.enabled) {
|
|
1365
1549
|
debugConfig.logger(this.constructor.name, `Attempting AST for file: ${filePath}`);
|
|
1366
1550
|
}
|
|
1367
|
-
|
|
1551
|
+
|
|
1368
1552
|
try {
|
|
1369
1553
|
const astResult = await this.astRegistry.analyzeRule(ruleId, code, language, filePath);
|
|
1370
1554
|
if (astResult && astResult.length > 0) {
|
|
@@ -1374,7 +1558,7 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1374
1558
|
analysisMethod: 'ast',
|
|
1375
1559
|
confidence: strategy.config?.accuracy?.ast || 90
|
|
1376
1560
|
}));
|
|
1377
|
-
|
|
1561
|
+
|
|
1378
1562
|
if (debugConfig.enabled) {
|
|
1379
1563
|
debugConfig.logger(this.constructor.name, `AST found ${astResult.length} violations in ${filePath}`);
|
|
1380
1564
|
}
|
|
@@ -1383,7 +1567,7 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1383
1567
|
if (debugConfig.enabled) {
|
|
1384
1568
|
debugConfig.logger(this.constructor.name, `AST failed for ${filePath}: ${astError.message}`);
|
|
1385
1569
|
}
|
|
1386
|
-
|
|
1570
|
+
|
|
1387
1571
|
if (options.verbose) {
|
|
1388
1572
|
console.warn(`⚠️ AST analysis failed for ${filePath}, falling back to regex`);
|
|
1389
1573
|
}
|
|
@@ -1412,7 +1596,7 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1412
1596
|
if (analysisResult) {
|
|
1413
1597
|
violations.push(...analysisResult);
|
|
1414
1598
|
}
|
|
1415
|
-
|
|
1599
|
+
|
|
1416
1600
|
} catch (error) {
|
|
1417
1601
|
if (options.verbose) {
|
|
1418
1602
|
console.error(`❌ Analysis failed for ${filePath}:`, error.message);
|
|
@@ -1625,7 +1809,19 @@ class HeuristicEngine extends AnalysisEngineInterface {
|
|
|
1625
1809
|
// Clear analyzer cache
|
|
1626
1810
|
this.ruleAnalyzers.clear();
|
|
1627
1811
|
this.supportedRulesList = [];
|
|
1628
|
-
|
|
1812
|
+
|
|
1813
|
+
// Cleanup SemanticEngineManager (multi-language support)
|
|
1814
|
+
if (this.semanticEngineManager) {
|
|
1815
|
+
await this.semanticEngineManager.cleanup();
|
|
1816
|
+
this.semanticEngineManager = null;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
// Cleanup legacy semantic engine
|
|
1820
|
+
if (this.semanticEngine) {
|
|
1821
|
+
await this.semanticEngine.cleanup();
|
|
1822
|
+
this.semanticEngine = null;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1629
1825
|
await super.cleanup();
|
|
1630
1826
|
if (this.verbose) {
|
|
1631
1827
|
console.log('🔍 Heuristic engine cleanup completed');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sunlint",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.34",
|
|
4
4
|
"description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -41,18 +41,19 @@
|
|
|
41
41
|
"demo:file-targeting": "./demo-file-targeting.sh",
|
|
42
42
|
"lint": "node cli.js --config=.sunlint.json --input=.",
|
|
43
43
|
"lint:eslint-integration": "node cli.js --all --eslint-integration --input=.",
|
|
44
|
-
"build": "npm run copy-rules && npm run generate-registry &&
|
|
44
|
+
"build": "npm run copy-rules && npm run generate-registry && npm run copy-arch-detect && echo 'Build completed'",
|
|
45
45
|
"copy-rules": "node scripts/copy-rules.js",
|
|
46
46
|
"generate-registry": "node scripts/generate-rules-registry.js",
|
|
47
|
-
"
|
|
47
|
+
"copy-arch-detect": "node scripts/copy-arch-detect.js",
|
|
48
|
+
"clean": "rm -rf coverage/ *.log reports/ *.tgz engines/arch-detect",
|
|
48
49
|
"postpack": "echo '📦 Package created successfully! Size: ' && ls -lh *.tgz | awk '{print $5}'",
|
|
49
50
|
"start": "node cli.js --help",
|
|
50
51
|
"version": "node cli.js --version",
|
|
51
|
-
"pack": "npm run
|
|
52
|
+
"pack": "npm run build && npm pack",
|
|
52
53
|
"publish:github": "npm publish --registry=https://npm.pkg.github.com",
|
|
53
54
|
"publish:npmjs": "npm publish --registry=https://registry.npmjs.org",
|
|
54
55
|
"publish:test": "npm publish --dry-run --registry=https://registry.npmjs.org",
|
|
55
|
-
"prepublishOnly": "npm run clean && npm run
|
|
56
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
56
57
|
},
|
|
57
58
|
"keywords": [
|
|
58
59
|
"linting",
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "
|
|
3
|
-
"name": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"severity": "
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"status": "pending"
|
|
2
|
+
"id": "C002",
|
|
3
|
+
"name": "No Duplicate Code",
|
|
4
|
+
"description": "Không để trùng lặp code > 10 dòng - Tránh code rối, khó refactor và áp dụng DRY principle",
|
|
5
|
+
"category": "complexity",
|
|
6
|
+
"severity": "warning",
|
|
7
|
+
"languages": ["typescript", "javascript", "dart"],
|
|
8
|
+
"config": {
|
|
9
|
+
"minLines": 10,
|
|
10
|
+
"similarityThreshold": 0.95
|
|
12
11
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"**/*.ts"
|
|
17
|
-
],
|
|
18
|
-
"exclude": [
|
|
19
|
-
"**/*.test.*",
|
|
20
|
-
"**/*.spec.*"
|
|
21
|
-
]
|
|
22
|
-
}
|
|
12
|
+
"references": [
|
|
13
|
+
"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"
|
|
14
|
+
]
|
|
23
15
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C002 Dart Analyzer - No Duplicate Code (> 10 lines)
|
|
3
|
+
*
|
|
4
|
+
* This is a JS wrapper that delegates to DartAnalyzer binary.
|
|
5
|
+
* Actual implementation: dart_analyzer/lib/rules/duplicate_code_analyzer.dart
|
|
6
|
+
*
|
|
7
|
+
* Rule: Không để trùng lặp code > 10 dòng
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
class DartC002Analyzer {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.ruleId = 'C002';
|
|
13
|
+
this.language = 'dart';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get rule metadata
|
|
18
|
+
*/
|
|
19
|
+
getMetadata() {
|
|
20
|
+
return {
|
|
21
|
+
ruleId: 'C002',
|
|
22
|
+
name: 'No Duplicate Code',
|
|
23
|
+
language: 'dart',
|
|
24
|
+
delegateTo: 'dart_analyzer',
|
|
25
|
+
description: 'Detect duplicate code blocks > 10 lines'
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get default configuration
|
|
31
|
+
*/
|
|
32
|
+
getConfig() {
|
|
33
|
+
return {
|
|
34
|
+
minLines: 10,
|
|
35
|
+
similarityThreshold: 0.95,
|
|
36
|
+
severity: 'warning'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Analysis is delegated to DartAnalyzer via heuristic-engine.js
|
|
42
|
+
*/
|
|
43
|
+
async analyze(files, language, options) {
|
|
44
|
+
// Delegated to DartAnalyzer binary via heuristic-engine.js
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
supportsLanguage(language) {
|
|
49
|
+
return language === 'dart';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = DartC002Analyzer;
|