@sun-asterisk/sunlint 1.3.43 → 1.3.45

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.
Files changed (158) hide show
  1. package/core/cli-action-handler.js +4 -4
  2. package/core/output-service.js +2 -2
  3. package/core/output-service.js.debug.js +1 -0
  4. package/dart_analyzer/README.md +226 -0
  5. package/dart_analyzer/analysis_options.yaml +66 -0
  6. package/dart_analyzer/bin/sunlint-dart-macos +0 -0
  7. package/dart_analyzer/bin/sunlint_dart_analyzer.dart +124 -0
  8. package/dart_analyzer/lib/analyzer_service.dart +625 -0
  9. package/dart_analyzer/lib/json_rpc_server.dart +275 -0
  10. package/dart_analyzer/lib/models/rule.dart +67 -0
  11. package/dart_analyzer/lib/models/symbol_table.dart +607 -0
  12. package/dart_analyzer/lib/models/violation.dart +69 -0
  13. package/dart_analyzer/lib/rules/base_analyzer.dart +52 -0
  14. package/dart_analyzer/lib/rules/common/C002_no_duplicate_code.dart +344 -0
  15. package/dart_analyzer/lib/rules/common/C003_no_vague_abbreviations.dart +318 -0
  16. package/dart_analyzer/lib/rules/common/C006_function_naming.dart +219 -0
  17. package/dart_analyzer/lib/rules/common/C008_variable_declaration_locality.dart +205 -0
  18. package/dart_analyzer/lib/rules/common/C010_limit_block_nesting.dart +162 -0
  19. package/dart_analyzer/lib/rules/common/C012_command_query_separation.dart +214 -0
  20. package/dart_analyzer/lib/rules/common/C013_no_dead_code.dart +225 -0
  21. package/dart_analyzer/lib/rules/common/C014_dependency_injection.dart +249 -0
  22. package/dart_analyzer/lib/rules/common/C017_constructor_logic.dart +158 -0
  23. package/dart_analyzer/lib/rules/common/C018_no_throw_generic_error.dart +141 -0
  24. package/dart_analyzer/lib/rules/common/C019_log_level_usage.dart +165 -0
  25. package/dart_analyzer/lib/rules/common/C020_unused_imports.dart +128 -0
  26. package/dart_analyzer/lib/rules/common/C021_import_organization.dart +86 -0
  27. package/dart_analyzer/lib/rules/common/C023_no_duplicate_variable.dart +112 -0
  28. package/dart_analyzer/lib/rules/common/C024_no_scatter_hardcoded_constants.dart +79 -0
  29. package/dart_analyzer/lib/rules/common/C029_catch_block_logging.dart +81 -0
  30. package/dart_analyzer/lib/rules/common/C030_use_custom_error_classes.dart +77 -0
  31. package/dart_analyzer/lib/rules/common/C031_validation_separation.dart +90 -0
  32. package/dart_analyzer/lib/rules/common/C033_separate_service_repository.dart +80 -0
  33. package/dart_analyzer/lib/rules/common/C035_error_logging_context.dart +148 -0
  34. package/dart_analyzer/lib/rules/common/C040_centralized_validation.dart +84 -0
  35. package/dart_analyzer/lib/rules/common/C041_no_sensitive_hardcode.dart +103 -0
  36. package/dart_analyzer/lib/rules/common/C042_boolean_name_prefix.dart +105 -0
  37. package/dart_analyzer/lib/rules/common/C043_no_console_or_print.dart +101 -0
  38. package/dart_analyzer/lib/rules/common/C047_no_duplicate_retry_logic.dart +94 -0
  39. package/dart_analyzer/lib/rules/common/C048_no_bypass_architectural_layers.dart +132 -0
  40. package/dart_analyzer/lib/rules/common/C052_parsing_or_data_transformation.dart +95 -0
  41. package/dart_analyzer/lib/rules/common/C060_no_override_superclass.dart +81 -0
  42. package/dart_analyzer/lib/rules/common/C065_one_behavior_per_test.dart +83 -0
  43. package/dart_analyzer/lib/rules/common/C067_no_hardcoded_config.dart +89 -0
  44. package/dart_analyzer/lib/rules/common/C070_no_real_time_tests.dart +99 -0
  45. package/dart_analyzer/lib/rules/common/C072_single_test_behavior.dart +78 -0
  46. package/dart_analyzer/lib/rules/common/C073_validate_required_config_on_startup.dart +82 -0
  47. package/dart_analyzer/lib/rules/common/C075_explicit_return_types.dart +85 -0
  48. package/dart_analyzer/lib/rules/common/C076_explicit_function_types.dart +104 -0
  49. package/dart_analyzer/lib/rules/dart/D001_recommended_lint_rules.dart +309 -0
  50. package/dart_analyzer/lib/rules/dart/D002_dispose_resources.dart +338 -0
  51. package/dart_analyzer/lib/rules/dart/D003_prefer_widgets_over_methods.dart +273 -0
  52. package/dart_analyzer/lib/rules/dart/D004_avoid_shrinkwrap_listview.dart +154 -0
  53. package/dart_analyzer/lib/rules/dart/D005_limit_widget_nesting.dart +265 -0
  54. package/dart_analyzer/lib/rules/dart/D006_prefer_extracting_large_callbacks.dart +135 -0
  55. package/dart_analyzer/lib/rules/dart/D007_prefer_init_first_dispose_last.dart +150 -0
  56. package/dart_analyzer/lib/rules/dart/D008_avoid_long_functions.dart +394 -0
  57. package/dart_analyzer/lib/rules/dart/D009_limit_function_parameters.dart +179 -0
  58. package/dart_analyzer/lib/rules/dart/D010_limit_cyclomatic_complexity.dart +257 -0
  59. package/dart_analyzer/lib/rules/dart/D011_prefer_named_parameters.dart +152 -0
  60. package/dart_analyzer/lib/rules/dart/D012_prefer_named_boolean_parameters.dart +156 -0
  61. package/dart_analyzer/lib/rules/dart/D013_single_public_class.dart +246 -0
  62. package/dart_analyzer/lib/rules/dart/D014_unsafe_collection_access.dart +202 -0
  63. package/dart_analyzer/lib/rules/dart/D015_copywith_all_parameters.dart +125 -0
  64. package/dart_analyzer/lib/rules/dart/D016_project_should_have_tests.dart +134 -0
  65. package/dart_analyzer/lib/rules/dart/D017_pubspec_dependencies_review.dart +187 -0
  66. package/dart_analyzer/lib/rules/dart/D018_remove_commented_code.dart +196 -0
  67. package/dart_analyzer/lib/rules/dart/D019_avoid_single_child_multi_child_widget.dart +161 -0
  68. package/dart_analyzer/lib/rules/dart/D020_limit_if_else_branches.dart +125 -0
  69. package/dart_analyzer/lib/rules/dart/D021_avoid_negated_boolean_checks.dart +227 -0
  70. package/dart_analyzer/lib/rules/dart/D022_use_setstate_correctly.dart +269 -0
  71. package/dart_analyzer/lib/rules/dart/D023_avoid_unnecessary_method_overrides.dart +191 -0
  72. package/dart_analyzer/lib/rules/dart/D024_avoid_unnecessary_stateful_widget.dart +194 -0
  73. package/dart_analyzer/lib/rules/dart/D025_avoid_nested_conditional_expressions.dart +90 -0
  74. package/dart_analyzer/lib/rules/security/S001_backend_auth_communications.dart +155 -0
  75. package/dart_analyzer/lib/rules/security/S002_os_command_injection.dart +159 -0
  76. package/dart_analyzer/lib/rules/security/S003_open_redirect_protection.dart +208 -0
  77. package/dart_analyzer/lib/rules/security/S004_sensitive_data_logging.dart +391 -0
  78. package/dart_analyzer/lib/rules/security/S005_trusted_service_authorization.dart +182 -0
  79. package/dart_analyzer/lib/rules/security/S006_no_default_credentials.dart +208 -0
  80. package/dart_analyzer/lib/rules/security/S007_output_encoding.dart +224 -0
  81. package/dart_analyzer/lib/rules/security/S008_svg_content_sanitization.dart +211 -0
  82. package/dart_analyzer/lib/rules/security/S009_no_insecure_encryption.dart +160 -0
  83. package/dart_analyzer/lib/rules/security/S010_use_csprng.dart +184 -0
  84. package/dart_analyzer/lib/rules/security/S011_ech_tls_config.dart +175 -0
  85. package/dart_analyzer/lib/rules/security/S012_hardcoded_secrets.dart +255 -0
  86. package/dart_analyzer/lib/rules/security/S013_tls_enforcement.dart +148 -0
  87. package/dart_analyzer/lib/rules/security/S014_tls_version_enforcement.dart +117 -0
  88. package/dart_analyzer/lib/rules/security/S015_insecure_tls_certificate.dart +315 -0
  89. package/dart_analyzer/lib/rules/security/S016_no_sensitive_querystring.dart +244 -0
  90. package/dart_analyzer/lib/rules/security/S017_use_parameterized_queries.dart +191 -0
  91. package/dart_analyzer/lib/rules/security/S018_no_sensitive_browser_storage.dart +175 -0
  92. package/dart_analyzer/lib/rules/security/S019_smtp_injection_protection.dart +166 -0
  93. package/dart_analyzer/lib/rules/security/S020_no_eval_dynamic_code.dart +149 -0
  94. package/dart_analyzer/lib/rules/security/S021_referrer_policy.dart +146 -0
  95. package/dart_analyzer/lib/rules/security/S022_escape_output_context.dart +111 -0
  96. package/dart_analyzer/lib/rules/security/S023_no_json_injection.dart +550 -0
  97. package/dart_analyzer/lib/rules/security/S024_xpath_xxe_protection.dart +299 -0
  98. package/dart_analyzer/lib/rules/security/S025_server_side_validation.dart +140 -0
  99. package/dart_analyzer/lib/rules/security/S026_tls_all_connections.dart +196 -0
  100. package/dart_analyzer/lib/rules/security/S027_mtls_certificate_validation.dart +195 -0
  101. package/dart_analyzer/lib/rules/security/S028_file_upload_size_limits.dart +186 -0
  102. package/dart_analyzer/lib/rules/security/S029_csrf_protection.dart +171 -0
  103. package/dart_analyzer/lib/rules/security/S030_directory_browsing_protection.dart +144 -0
  104. package/dart_analyzer/lib/rules/security/S031_secure_session_cookies.dart +118 -0
  105. package/dart_analyzer/lib/rules/security/S032_httponly_session_cookies.dart +114 -0
  106. package/dart_analyzer/lib/rules/security/S033_samesite_session_cookies.dart +120 -0
  107. package/dart_analyzer/lib/rules/security/S034_host_prefix_session_cookies.dart +160 -0
  108. package/dart_analyzer/lib/rules/security/S035_separate_app_hostnames.dart +117 -0
  109. package/dart_analyzer/lib/rules/security/S036_lfi_rfi_protection.dart +188 -0
  110. package/dart_analyzer/lib/rules/security/S037_cache_headers.dart +113 -0
  111. package/dart_analyzer/lib/rules/security/S038_no_version_headers.dart +114 -0
  112. package/dart_analyzer/lib/rules/security/S039_tls_certificate_validation.dart +131 -0
  113. package/dart_analyzer/lib/rules/security/S040_session_fixation_protection.dart +155 -0
  114. package/dart_analyzer/lib/rules/security/S041_session_token_invalidation.dart +201 -0
  115. package/dart_analyzer/lib/rules/security/S042_require_re_authentication_for_long_lived.dart +158 -0
  116. package/dart_analyzer/lib/rules/security/S043_password_changes_invalidate_all_sessions.dart +88 -0
  117. package/dart_analyzer/lib/rules/security/S044_re_authentication_required.dart +119 -0
  118. package/dart_analyzer/lib/rules/security/S045_brute_force_protection.dart +253 -0
  119. package/dart_analyzer/lib/rules/security/S046_jwt_algorithm_allowlist.dart +113 -0
  120. package/dart_analyzer/lib/rules/security/S047_oauth_pkce_protection.dart +124 -0
  121. package/dart_analyzer/lib/rules/security/S048_oauth_redirect_uri_validation.dart +134 -0
  122. package/dart_analyzer/lib/rules/security/S049_short_validity_tokens.dart +145 -0
  123. package/dart_analyzer/lib/rules/security/S050_reference_tokens_entropy.dart +234 -0
  124. package/dart_analyzer/lib/rules/security/S051_password_length_policy.dart +171 -0
  125. package/dart_analyzer/lib/rules/security/S052_weak_otp_entropy.dart +107 -0
  126. package/dart_analyzer/lib/rules/security/S053_generic_error_messages.dart +159 -0
  127. package/dart_analyzer/lib/rules/security/S054_no_default_accounts.dart +141 -0
  128. package/dart_analyzer/lib/rules/security/S055_content_type_validation.dart +324 -0
  129. package/dart_analyzer/lib/rules/security/S056_log_injection_protection.dart +119 -0
  130. package/dart_analyzer/lib/rules/security/S057_utc_logging.dart +114 -0
  131. package/dart_analyzer/lib/rules/security/S058_no_ssrf.dart +175 -0
  132. package/dart_analyzer/lib/rules/security/S059_disable_debug_mode.dart +172 -0
  133. package/dart_analyzer/lib/rules/security/S060_password_minimum_length.dart +170 -0
  134. package/dart_analyzer/lib/symbol_table_extractor.dart +510 -0
  135. package/dart_analyzer/lib/utils/common_utils.dart +26 -0
  136. package/dart_analyzer/pubspec.lock +557 -0
  137. package/dart_analyzer/pubspec.yaml +39 -0
  138. package/dart_analyzer/test/fixtures/complex_code.dart +95 -0
  139. package/docs/GENERATED_FILE_HANDLING_SUMMARY.md +2 -2
  140. package/package.json +3 -2
  141. package/rules/common/C006_function_naming/typescript/analyzer.js +1 -2
  142. package/rules/common/C017_constructor_logic/typescript/symbol-based-analyzer.js +1 -1
  143. package/rules/common/C019_log_level_usage/typescript/system-log-analyzer.js +2 -2
  144. package/rules/common/C021_import_organization/typescript/ts-morph-analyzer.js +3 -3
  145. package/rules/common/C024_no_scatter_hardcoded_constants/typescript/symbol-based-analyzer.js +1 -1
  146. package/rules/common/C029_catch_block_logging/typescript/analyzer.js +1 -1
  147. package/rules/common/C040_centralized_validation/typescript/regex-based-analyzer.js +1 -1
  148. package/rules/common/C073_validate_required_config_on_startup/typescript/analyzer.js +1 -1
  149. package/rules/security/S042_require_re_authentication_for_long_lived/typescript/symbol-based-analyzer.js +9 -9
  150. package/rules/security/S043_password_changes_invalidate_all_sessions/typescript/symbol-based-analyzer.js +1 -1
  151. package/rules/security/S046_jwt_algorithm_allowlist/dart/analyzer.js +1 -1
  152. package/rules/security/S047_oauth_pkce_protection/dart/analyzer.js +1 -1
  153. package/rules/security/S050_reference_tokens_entropy/dart/analyzer.js +1 -1
  154. package/rules/security/S053_generic_error_messages/dart/analyzer.js +1 -1
  155. package/rules/security/S055_content_type_validation/typescript/symbol-based-analyzer.js +1 -1
  156. package/rules/security/S059_disable_debug_mode/dart/analyzer.js +1 -1
  157. package/rules/security/S060_password_minimum_length/dart/analyzer.js +1 -1
  158. package/rules/utils/severity-constants.js +0 -1
@@ -505,12 +505,12 @@ class CliActionHandler {
505
505
  handleExit(results) {
506
506
  if (this.options.noExit) return;
507
507
 
508
- // Check if any violations were found
509
- const hasViolations = results.results?.some(result =>
510
- result.violations && result.violations.length > 0
508
+ // Only fail on errors, not warnings (ESLint-compatible behavior)
509
+ const hasErrors = results.results?.some(result =>
510
+ result.violations?.some(v => v.severity === 'error')
511
511
  );
512
512
 
513
- if (hasViolations && this.options.failOnViolations !== false) {
513
+ if (hasErrors && this.options.failOnViolations !== false) {
514
514
  process.exit(1);
515
515
  } else {
516
516
  process.exit(0);
@@ -273,10 +273,10 @@ class OutputService {
273
273
  if (result.ruleId) {
274
274
  result.violations.forEach(violation => {
275
275
  if (isValidViolation(violation)) {
276
- allViolations.push(violation); // violation already has file path
276
+ allViolations.push(violation);
277
277
  }
278
278
  });
279
- }
279
+ }
280
280
  // Handle file-based format (legacy)
281
281
  else {
282
282
  result.violations.forEach(violation => {
@@ -0,0 +1 @@
1
+ // temp debug
@@ -0,0 +1,226 @@
1
+ # SunLint Dart Analyzer
2
+
3
+ Dart language analyzer for SunLint. Provides AST-based code analysis and rule checking via JSON-RPC communication.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────────┐
9
+ │ SunLint (Node.js) │
10
+ │ └── DartAnalyzer adapter │
11
+ └────────┬───────────────────────────────────────────────────────┘
12
+ │ JSON-RPC over STDIO
13
+
14
+ ┌─────────────────────────────────────────────────────────────────┐
15
+ │ SunLint Dart Analyzer (This package) │
16
+ │ ├── JsonRpcServer - Handles communication │
17
+ │ ├── AnalyzerService - Orchestrates analysis │
18
+ │ ├── SymbolTableExtractor - Extracts symbols from AST │
19
+ │ └── Analyzers/ - Rule implementations │
20
+ │ ├── C001 - Code Complexity │
21
+ │ ├── C008 - Deep Nesting │
22
+ │ ├── N001 - Naming Conventions │
23
+ │ ├── E001 - Error Handling │
24
+ │ └── S003 - Security (Sensitive Data) │
25
+ └─────────────────────────────────────────────────────────────────┘
26
+ ```
27
+
28
+ ## Development
29
+
30
+ ### Prerequisites
31
+
32
+ - Dart SDK >= 3.0.0
33
+
34
+ ### Setup
35
+
36
+ ```bash
37
+ cd dart_analyzer
38
+ dart pub get
39
+ ```
40
+
41
+ ### Run in standalone mode (for testing)
42
+
43
+ ```bash
44
+ # Analyze a single file
45
+ dart run bin/sunlint_dart_analyzer.dart --standalone --file test/fixtures/sample.dart
46
+
47
+ # Analyze with specific rules
48
+ dart run bin/sunlint_dart_analyzer.dart --standalone --file lib/main.dart --rules C001,N001
49
+ ```
50
+
51
+ ### Run as JSON-RPC server
52
+
53
+ ```bash
54
+ dart run bin/sunlint_dart_analyzer.dart
55
+ ```
56
+
57
+ ### Build executable
58
+
59
+ ```bash
60
+ # Compile to native executable
61
+ dart compile exe bin/sunlint_dart_analyzer.dart -o bin/sunlint-dart-macos
62
+
63
+ # For different platforms (requires cross-compilation):
64
+ # Linux: dart compile exe bin/sunlint_dart_analyzer.dart -o bin/sunlint-dart-linux
65
+ # Windows: dart compile exe bin/sunlint_dart_analyzer.dart -o bin/sunlint-dart-windows.exe
66
+ ```
67
+
68
+ ## JSON-RPC Protocol
69
+
70
+ ### Methods
71
+
72
+ #### `initialize`
73
+
74
+ Initialize the analyzer with a project.
75
+
76
+ **Request:**
77
+ ```json
78
+ {
79
+ "jsonrpc": "2.0",
80
+ "id": 1,
81
+ "method": "initialize",
82
+ "params": {
83
+ "projectPath": "/path/to/project",
84
+ "targetFiles": ["lib/main.dart"]
85
+ }
86
+ }
87
+ ```
88
+
89
+ **Response:**
90
+ ```json
91
+ {
92
+ "jsonrpc": "2.0",
93
+ "id": 1,
94
+ "result": {
95
+ "success": true,
96
+ "version": "1.0.0",
97
+ "capabilities": {
98
+ "analyze": true,
99
+ "getSymbolTable": true,
100
+ "rules": ["C001", "C008", "N001", "E001", "S003"]
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ #### `analyze`
107
+
108
+ Analyze a file with specified rules.
109
+
110
+ **Request:**
111
+ ```json
112
+ {
113
+ "jsonrpc": "2.0",
114
+ "id": 2,
115
+ "method": "analyze",
116
+ "params": {
117
+ "filePath": "lib/main.dart",
118
+ "rules": [
119
+ {"id": "C001", "config": {"threshold": 10}},
120
+ {"id": "N001"}
121
+ ]
122
+ }
123
+ }
124
+ ```
125
+
126
+ **Response:**
127
+ ```json
128
+ {
129
+ "jsonrpc": "2.0",
130
+ "id": 2,
131
+ "result": {
132
+ "violations": [
133
+ {
134
+ "ruleId": "C001",
135
+ "filePath": "/path/to/lib/main.dart",
136
+ "line": 15,
137
+ "column": 3,
138
+ "message": "Method \"processData\" has cyclomatic complexity of 12 (threshold: 10)",
139
+ "severity": "warning",
140
+ "analysisMethod": "ast"
141
+ }
142
+ ],
143
+ "fileAnalyzed": "lib/main.dart"
144
+ }
145
+ }
146
+ ```
147
+
148
+ #### `getSymbolTable`
149
+
150
+ Get symbol table for a file.
151
+
152
+ **Request:**
153
+ ```json
154
+ {
155
+ "jsonrpc": "2.0",
156
+ "id": 3,
157
+ "method": "getSymbolTable",
158
+ "params": {
159
+ "filePath": "lib/main.dart"
160
+ }
161
+ }
162
+ ```
163
+
164
+ **Response:**
165
+ ```json
166
+ {
167
+ "jsonrpc": "2.0",
168
+ "id": 3,
169
+ "result": {
170
+ "filePath": "/path/to/lib/main.dart",
171
+ "fileName": "main.dart",
172
+ "imports": [...],
173
+ "classes": [...],
174
+ "functions": [...],
175
+ "variables": [...]
176
+ }
177
+ }
178
+ ```
179
+
180
+ #### `shutdown`
181
+
182
+ Gracefully shut down the analyzer.
183
+
184
+ **Request:**
185
+ ```json
186
+ {
187
+ "jsonrpc": "2.0",
188
+ "id": 4,
189
+ "method": "shutdown",
190
+ "params": {}
191
+ }
192
+ ```
193
+
194
+ #### `ping`
195
+
196
+ Health check.
197
+
198
+ **Request:**
199
+ ```json
200
+ {
201
+ "jsonrpc": "2.0",
202
+ "id": 5,
203
+ "method": "ping",
204
+ "params": {}
205
+ }
206
+ ```
207
+
208
+ ## Supported Rules
209
+
210
+ | Rule ID | Name | Description |
211
+ |---------|------|-------------|
212
+ | C001 | Code Complexity | Detects functions with high cyclomatic complexity |
213
+ | C008 | Deep Nesting | Detects code with excessive nesting depth |
214
+ | N001 | Naming Conventions | Enforces Dart naming conventions |
215
+ | E001 | Error Handling | Detects empty catch blocks and ignored exceptions |
216
+ | S003 | Security | Detects logging of sensitive data |
217
+
218
+ ## Testing
219
+
220
+ ```bash
221
+ dart test
222
+ ```
223
+
224
+ ## License
225
+
226
+ MIT
@@ -0,0 +1,66 @@
1
+ include: package:lints/recommended.yaml
2
+
3
+ analyzer:
4
+ exclude:
5
+ - build/**
6
+ - .dart_tool/**
7
+
8
+ linter:
9
+ rules:
10
+ - always_declare_return_types
11
+ - annotate_overrides
12
+ - avoid_empty_else
13
+ - avoid_print
14
+ - avoid_relative_lib_imports
15
+ - avoid_returning_null_for_void
16
+ - avoid_types_as_parameter_names
17
+ - await_only_futures
18
+ - camel_case_extensions
19
+ - camel_case_types
20
+ - cancel_subscriptions
21
+ - close_sinks
22
+ - constant_identifier_names
23
+ - control_flow_in_finally
24
+ - curly_braces_in_flow_control_structures
25
+ - empty_catches
26
+ - empty_constructor_bodies
27
+ - empty_statements
28
+ - hash_and_equals
29
+ - implementation_imports
30
+ - library_names
31
+ - library_prefixes
32
+ - no_duplicate_case_values
33
+ - non_constant_identifier_names
34
+ - null_closures
35
+ - overridden_fields
36
+ - package_names
37
+ - package_prefixed_library_names
38
+ - prefer_adjacent_string_concatenation
39
+ - prefer_collection_literals
40
+ - prefer_conditional_assignment
41
+ - prefer_contains
42
+ - prefer_final_fields
43
+ - prefer_for_elements_to_map_fromIterable
44
+ - prefer_generic_function_type_aliases
45
+ - prefer_if_null_operators
46
+ - prefer_is_empty
47
+ - prefer_is_not_empty
48
+ - prefer_iterable_whereType
49
+ - prefer_single_quotes
50
+ - prefer_spread_collections
51
+ - prefer_typing_uninitialized_variables
52
+ - recursive_getters
53
+ - slash_for_doc_comments
54
+ - type_init_formals
55
+ - unawaited_futures
56
+ - unnecessary_brace_in_string_interps
57
+ - unnecessary_const
58
+ - unnecessary_getters_setters
59
+ - unnecessary_new
60
+ - unnecessary_null_in_if_null_operators
61
+ - unnecessary_statements
62
+ - unnecessary_this
63
+ - unrelated_type_equality_checks
64
+ - use_function_type_syntax_for_parameters
65
+ - use_rethrow_when_possible
66
+ - valid_regexps
@@ -0,0 +1,124 @@
1
+ import 'dart:io';
2
+
3
+ import 'package:sunlint_dart_analyzer/json_rpc_server.dart';
4
+ import 'package:sunlint_dart_analyzer/analyzer_service.dart';
5
+
6
+ /// Entry point for SunLint Dart Analyzer
7
+ /// This is the executable that communicates with SunLint's Node.js process
8
+ /// via JSON-RPC over STDIO
9
+ void main(List<String> arguments) async {
10
+ // Parse arguments
11
+ if (arguments.contains('--help') || arguments.contains('-h')) {
12
+ _printHelp();
13
+ return;
14
+ }
15
+
16
+ if (arguments.contains('--version') || arguments.contains('-v')) {
17
+ print('SunLint Dart Analyzer v1.0.0');
18
+ return;
19
+ }
20
+
21
+ // Check for standalone mode (for testing)
22
+ if (arguments.contains('--standalone')) {
23
+ await _runStandalone(arguments);
24
+ return;
25
+ }
26
+
27
+ // Normal mode: JSON-RPC server
28
+ final server = JsonRpcServer();
29
+ await server.start();
30
+
31
+ // Keep the process running until interrupted
32
+ await ProcessSignal.sigint.watch().first;
33
+ await server.stop();
34
+ }
35
+
36
+ /// Print help message
37
+ void _printHelp() {
38
+ print('''
39
+ SunLint Dart Analyzer
40
+
41
+ Usage:
42
+ sunlint_dart_analyzer [options]
43
+
44
+ Options:
45
+ --help, -h Show this help message
46
+ --version, -v Show version
47
+ --standalone Run in standalone mode (for testing)
48
+
49
+ Standalone mode options:
50
+ --file <path> Analyze a single file
51
+ --rules <ids> Comma-separated rule IDs (default: all)
52
+
53
+ Examples:
54
+ # Normal mode (JSON-RPC server)
55
+ sunlint_dart_analyzer
56
+
57
+ # Standalone mode (for testing)
58
+ sunlint_dart_analyzer --standalone --file lib/main.dart
59
+ sunlint_dart_analyzer --standalone --file lib/main.dart --rules C001,N001
60
+ ''');
61
+ }
62
+
63
+ /// Run in standalone mode for testing
64
+ Future<void> _runStandalone(List<String> arguments) async {
65
+ stderr.writeln('Running in standalone mode...');
66
+
67
+ // Parse arguments
68
+ String? filePath;
69
+ List<String>? ruleIds;
70
+
71
+ for (var i = 0; i < arguments.length; i++) {
72
+ if (arguments[i] == '--file' && i + 1 < arguments.length) {
73
+ filePath = arguments[i + 1];
74
+ i++;
75
+ } else if (arguments[i] == '--rules' && i + 1 < arguments.length) {
76
+ ruleIds = arguments[i + 1].split(',');
77
+ i++;
78
+ }
79
+ }
80
+
81
+ if (filePath == null) {
82
+ stderr.writeln('Error: --file is required in standalone mode');
83
+ exit(1);
84
+ }
85
+
86
+ // Create analyzer service
87
+ final analyzerService = AnalyzerService();
88
+
89
+ // Initialize with project path
90
+ final projectPath = Directory.current.path;
91
+ await analyzerService.initialize(
92
+ projectPath: projectPath,
93
+ targetFiles: [filePath],
94
+ );
95
+
96
+ stderr.writeln('Analyzing: $filePath');
97
+ stderr.writeln('Rules: ${ruleIds?.join(', ') ?? 'all'}');
98
+
99
+ // Analyze file
100
+ final violations = await analyzerService.analyzeFile(
101
+ filePath: filePath,
102
+ rulesData: ruleIds?.map((id) => {'id': id}).toList(),
103
+ );
104
+
105
+ // Print results
106
+ if (violations.isEmpty) {
107
+ print('No violations found!');
108
+ } else {
109
+ print('Found ${violations.length} violation(s):');
110
+ for (final v in violations) {
111
+ print(' ${v.ruleId} at line ${v.line}: ${v.message}');
112
+ }
113
+ }
114
+
115
+ // Get symbol table
116
+ stderr.writeln('\nSymbol Table:');
117
+ final symbolTable = await analyzerService.getSymbolTable(filePath);
118
+ if (symbolTable != null) {
119
+ stderr.writeln(' Imports: ${symbolTable.imports.length}');
120
+ stderr.writeln(' Classes: ${symbolTable.classes.length}');
121
+ stderr.writeln(' Functions: ${symbolTable.functions.length}');
122
+ stderr.writeln(' Variables: ${symbolTable.variables.length}');
123
+ }
124
+ }