@sun-asterisk/sunlint 1.3.43 → 1.3.44
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/dart_analyzer/README.md +226 -0
- package/dart_analyzer/analysis_options.yaml +66 -0
- package/dart_analyzer/bin/sunlint-dart-macos +0 -0
- package/dart_analyzer/bin/sunlint_dart_analyzer.dart +124 -0
- package/dart_analyzer/lib/analyzer_service.dart +625 -0
- package/dart_analyzer/lib/json_rpc_server.dart +275 -0
- package/dart_analyzer/lib/models/rule.dart +67 -0
- package/dart_analyzer/lib/models/symbol_table.dart +607 -0
- package/dart_analyzer/lib/models/violation.dart +69 -0
- package/dart_analyzer/lib/rules/base_analyzer.dart +52 -0
- package/dart_analyzer/lib/rules/common/C002_no_duplicate_code.dart +344 -0
- package/dart_analyzer/lib/rules/common/C003_no_vague_abbreviations.dart +318 -0
- package/dart_analyzer/lib/rules/common/C006_function_naming.dart +219 -0
- package/dart_analyzer/lib/rules/common/C008_variable_declaration_locality.dart +205 -0
- package/dart_analyzer/lib/rules/common/C010_limit_block_nesting.dart +162 -0
- package/dart_analyzer/lib/rules/common/C012_command_query_separation.dart +214 -0
- package/dart_analyzer/lib/rules/common/C013_no_dead_code.dart +225 -0
- package/dart_analyzer/lib/rules/common/C014_dependency_injection.dart +249 -0
- package/dart_analyzer/lib/rules/common/C017_constructor_logic.dart +158 -0
- package/dart_analyzer/lib/rules/common/C018_no_throw_generic_error.dart +141 -0
- package/dart_analyzer/lib/rules/common/C019_log_level_usage.dart +165 -0
- package/dart_analyzer/lib/rules/common/C020_unused_imports.dart +128 -0
- package/dart_analyzer/lib/rules/common/C021_import_organization.dart +86 -0
- package/dart_analyzer/lib/rules/common/C023_no_duplicate_variable.dart +112 -0
- package/dart_analyzer/lib/rules/common/C024_no_scatter_hardcoded_constants.dart +79 -0
- package/dart_analyzer/lib/rules/common/C029_catch_block_logging.dart +81 -0
- package/dart_analyzer/lib/rules/common/C030_use_custom_error_classes.dart +77 -0
- package/dart_analyzer/lib/rules/common/C031_validation_separation.dart +90 -0
- package/dart_analyzer/lib/rules/common/C033_separate_service_repository.dart +80 -0
- package/dart_analyzer/lib/rules/common/C035_error_logging_context.dart +148 -0
- package/dart_analyzer/lib/rules/common/C040_centralized_validation.dart +84 -0
- package/dart_analyzer/lib/rules/common/C041_no_sensitive_hardcode.dart +103 -0
- package/dart_analyzer/lib/rules/common/C042_boolean_name_prefix.dart +105 -0
- package/dart_analyzer/lib/rules/common/C043_no_console_or_print.dart +101 -0
- package/dart_analyzer/lib/rules/common/C047_no_duplicate_retry_logic.dart +94 -0
- package/dart_analyzer/lib/rules/common/C048_no_bypass_architectural_layers.dart +132 -0
- package/dart_analyzer/lib/rules/common/C052_parsing_or_data_transformation.dart +95 -0
- package/dart_analyzer/lib/rules/common/C060_no_override_superclass.dart +81 -0
- package/dart_analyzer/lib/rules/common/C065_one_behavior_per_test.dart +83 -0
- package/dart_analyzer/lib/rules/common/C067_no_hardcoded_config.dart +89 -0
- package/dart_analyzer/lib/rules/common/C070_no_real_time_tests.dart +99 -0
- package/dart_analyzer/lib/rules/common/C072_single_test_behavior.dart +78 -0
- package/dart_analyzer/lib/rules/common/C073_validate_required_config_on_startup.dart +82 -0
- package/dart_analyzer/lib/rules/common/C075_explicit_return_types.dart +85 -0
- package/dart_analyzer/lib/rules/common/C076_explicit_function_types.dart +104 -0
- package/dart_analyzer/lib/rules/dart/D001_recommended_lint_rules.dart +309 -0
- package/dart_analyzer/lib/rules/dart/D002_dispose_resources.dart +338 -0
- package/dart_analyzer/lib/rules/dart/D003_prefer_widgets_over_methods.dart +273 -0
- package/dart_analyzer/lib/rules/dart/D004_avoid_shrinkwrap_listview.dart +154 -0
- package/dart_analyzer/lib/rules/dart/D005_limit_widget_nesting.dart +265 -0
- package/dart_analyzer/lib/rules/dart/D006_prefer_extracting_large_callbacks.dart +135 -0
- package/dart_analyzer/lib/rules/dart/D007_prefer_init_first_dispose_last.dart +150 -0
- package/dart_analyzer/lib/rules/dart/D008_avoid_long_functions.dart +394 -0
- package/dart_analyzer/lib/rules/dart/D009_limit_function_parameters.dart +179 -0
- package/dart_analyzer/lib/rules/dart/D010_limit_cyclomatic_complexity.dart +257 -0
- package/dart_analyzer/lib/rules/dart/D011_prefer_named_parameters.dart +152 -0
- package/dart_analyzer/lib/rules/dart/D012_prefer_named_boolean_parameters.dart +156 -0
- package/dart_analyzer/lib/rules/dart/D013_single_public_class.dart +246 -0
- package/dart_analyzer/lib/rules/dart/D014_unsafe_collection_access.dart +202 -0
- package/dart_analyzer/lib/rules/dart/D015_copywith_all_parameters.dart +125 -0
- package/dart_analyzer/lib/rules/dart/D016_project_should_have_tests.dart +134 -0
- package/dart_analyzer/lib/rules/dart/D017_pubspec_dependencies_review.dart +187 -0
- package/dart_analyzer/lib/rules/dart/D018_remove_commented_code.dart +196 -0
- package/dart_analyzer/lib/rules/dart/D019_avoid_single_child_multi_child_widget.dart +161 -0
- package/dart_analyzer/lib/rules/dart/D020_limit_if_else_branches.dart +125 -0
- package/dart_analyzer/lib/rules/dart/D021_avoid_negated_boolean_checks.dart +227 -0
- package/dart_analyzer/lib/rules/dart/D022_use_setstate_correctly.dart +269 -0
- package/dart_analyzer/lib/rules/dart/D023_avoid_unnecessary_method_overrides.dart +191 -0
- package/dart_analyzer/lib/rules/dart/D024_avoid_unnecessary_stateful_widget.dart +194 -0
- package/dart_analyzer/lib/rules/dart/D025_avoid_nested_conditional_expressions.dart +90 -0
- package/dart_analyzer/lib/rules/security/S001_backend_auth_communications.dart +155 -0
- package/dart_analyzer/lib/rules/security/S002_os_command_injection.dart +159 -0
- package/dart_analyzer/lib/rules/security/S003_open_redirect_protection.dart +208 -0
- package/dart_analyzer/lib/rules/security/S004_sensitive_data_logging.dart +391 -0
- package/dart_analyzer/lib/rules/security/S005_trusted_service_authorization.dart +182 -0
- package/dart_analyzer/lib/rules/security/S006_no_default_credentials.dart +208 -0
- package/dart_analyzer/lib/rules/security/S007_output_encoding.dart +224 -0
- package/dart_analyzer/lib/rules/security/S008_svg_content_sanitization.dart +211 -0
- package/dart_analyzer/lib/rules/security/S009_no_insecure_encryption.dart +160 -0
- package/dart_analyzer/lib/rules/security/S010_use_csprng.dart +184 -0
- package/dart_analyzer/lib/rules/security/S011_ech_tls_config.dart +175 -0
- package/dart_analyzer/lib/rules/security/S012_hardcoded_secrets.dart +255 -0
- package/dart_analyzer/lib/rules/security/S013_tls_enforcement.dart +148 -0
- package/dart_analyzer/lib/rules/security/S014_tls_version_enforcement.dart +117 -0
- package/dart_analyzer/lib/rules/security/S015_insecure_tls_certificate.dart +315 -0
- package/dart_analyzer/lib/rules/security/S016_no_sensitive_querystring.dart +244 -0
- package/dart_analyzer/lib/rules/security/S017_use_parameterized_queries.dart +191 -0
- package/dart_analyzer/lib/rules/security/S018_no_sensitive_browser_storage.dart +175 -0
- package/dart_analyzer/lib/rules/security/S019_smtp_injection_protection.dart +166 -0
- package/dart_analyzer/lib/rules/security/S020_no_eval_dynamic_code.dart +149 -0
- package/dart_analyzer/lib/rules/security/S021_referrer_policy.dart +146 -0
- package/dart_analyzer/lib/rules/security/S022_escape_output_context.dart +111 -0
- package/dart_analyzer/lib/rules/security/S023_no_json_injection.dart +550 -0
- package/dart_analyzer/lib/rules/security/S024_xpath_xxe_protection.dart +299 -0
- package/dart_analyzer/lib/rules/security/S025_server_side_validation.dart +140 -0
- package/dart_analyzer/lib/rules/security/S026_tls_all_connections.dart +196 -0
- package/dart_analyzer/lib/rules/security/S027_mtls_certificate_validation.dart +195 -0
- package/dart_analyzer/lib/rules/security/S028_file_upload_size_limits.dart +186 -0
- package/dart_analyzer/lib/rules/security/S029_csrf_protection.dart +171 -0
- package/dart_analyzer/lib/rules/security/S030_directory_browsing_protection.dart +144 -0
- package/dart_analyzer/lib/rules/security/S031_secure_session_cookies.dart +118 -0
- package/dart_analyzer/lib/rules/security/S032_httponly_session_cookies.dart +114 -0
- package/dart_analyzer/lib/rules/security/S033_samesite_session_cookies.dart +120 -0
- package/dart_analyzer/lib/rules/security/S034_host_prefix_session_cookies.dart +160 -0
- package/dart_analyzer/lib/rules/security/S035_separate_app_hostnames.dart +117 -0
- package/dart_analyzer/lib/rules/security/S036_lfi_rfi_protection.dart +188 -0
- package/dart_analyzer/lib/rules/security/S037_cache_headers.dart +113 -0
- package/dart_analyzer/lib/rules/security/S038_no_version_headers.dart +114 -0
- package/dart_analyzer/lib/rules/security/S039_tls_certificate_validation.dart +131 -0
- package/dart_analyzer/lib/rules/security/S040_session_fixation_protection.dart +155 -0
- package/dart_analyzer/lib/rules/security/S041_session_token_invalidation.dart +201 -0
- package/dart_analyzer/lib/rules/security/S042_require_re_authentication_for_long_lived.dart +158 -0
- package/dart_analyzer/lib/rules/security/S043_password_changes_invalidate_all_sessions.dart +88 -0
- package/dart_analyzer/lib/rules/security/S044_re_authentication_required.dart +119 -0
- package/dart_analyzer/lib/rules/security/S045_brute_force_protection.dart +253 -0
- package/dart_analyzer/lib/rules/security/S046_jwt_algorithm_allowlist.dart +113 -0
- package/dart_analyzer/lib/rules/security/S047_oauth_pkce_protection.dart +124 -0
- package/dart_analyzer/lib/rules/security/S048_oauth_redirect_uri_validation.dart +134 -0
- package/dart_analyzer/lib/rules/security/S049_short_validity_tokens.dart +145 -0
- package/dart_analyzer/lib/rules/security/S050_reference_tokens_entropy.dart +234 -0
- package/dart_analyzer/lib/rules/security/S051_password_length_policy.dart +171 -0
- package/dart_analyzer/lib/rules/security/S052_weak_otp_entropy.dart +107 -0
- package/dart_analyzer/lib/rules/security/S053_generic_error_messages.dart +159 -0
- package/dart_analyzer/lib/rules/security/S054_no_default_accounts.dart +141 -0
- package/dart_analyzer/lib/rules/security/S055_content_type_validation.dart +324 -0
- package/dart_analyzer/lib/rules/security/S056_log_injection_protection.dart +119 -0
- package/dart_analyzer/lib/rules/security/S057_utc_logging.dart +114 -0
- package/dart_analyzer/lib/rules/security/S058_no_ssrf.dart +175 -0
- package/dart_analyzer/lib/rules/security/S059_disable_debug_mode.dart +172 -0
- package/dart_analyzer/lib/rules/security/S060_password_minimum_length.dart +170 -0
- package/dart_analyzer/lib/symbol_table_extractor.dart +510 -0
- package/dart_analyzer/lib/utils/common_utils.dart +26 -0
- package/dart_analyzer/pubspec.lock +557 -0
- package/dart_analyzer/pubspec.yaml +39 -0
- package/dart_analyzer/test/fixtures/complex_code.dart +95 -0
- package/docs/GENERATED_FILE_HANDLING_SUMMARY.md +2 -2
- package/package.json +3 -2
|
@@ -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
|
|
Binary file
|
|
@@ -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
|
+
}
|