@sun-asterisk/sunlint 1.1.7 → 1.2.0
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/.sunlint.json +1 -1
- package/CHANGELOG.md +83 -0
- package/README.md +66 -4
- package/config/presets/all.json +125 -0
- package/config/presets/beginner.json +16 -8
- package/config/presets/ci.json +12 -4
- package/config/presets/maintainability.json +38 -0
- package/config/presets/performance.json +32 -0
- package/config/presets/quality.json +103 -0
- package/config/presets/recommended.json +36 -12
- package/config/presets/security.json +88 -0
- package/config/presets/strict.json +15 -5
- package/config/rules/rules-registry-generated.json +6312 -0
- package/config/rules-summary.json +1941 -0
- package/core/adapters/sunlint-rule-adapter.js +452 -0
- package/core/analysis-orchestrator.js +4 -4
- package/core/config-manager.js +28 -5
- package/core/rule-selection-service.js +52 -55
- package/docs/CONFIGURATION.md +111 -3
- package/docs/LANGUAGE-SPECIFIC-RULES.md +308 -0
- package/docs/README.md +3 -0
- package/docs/STANDARDIZED-CATEGORY-FILTERING.md +156 -0
- package/engines/eslint-engine.js +92 -2
- package/engines/heuristic-engine.js +8 -31
- package/origin-rules/common-en.md +1320 -0
- package/origin-rules/dart-en.md +289 -0
- package/origin-rules/java-en.md +60 -0
- package/origin-rules/kotlin-mobile-en.md +453 -0
- package/origin-rules/reactjs-en.md +102 -0
- package/origin-rules/security-en.md +1055 -0
- package/origin-rules/swift-en.md +449 -0
- package/origin-rules/typescript-en.md +136 -0
- package/package.json +6 -5
- package/scripts/copy-rules.js +86 -0
- package/rules/README.md +0 -252
- package/rules/common/C002_no_duplicate_code/analyzer.js +0 -65
- package/rules/common/C002_no_duplicate_code/config.json +0 -23
- package/rules/common/C003_no_vague_abbreviations/analyzer.js +0 -418
- package/rules/common/C003_no_vague_abbreviations/config.json +0 -35
- package/rules/common/C006_function_naming/analyzer.js +0 -349
- package/rules/common/C006_function_naming/config.json +0 -86
- package/rules/common/C010_limit_block_nesting/analyzer.js +0 -389
- package/rules/common/C013_no_dead_code/analyzer.js +0 -206
- package/rules/common/C014_dependency_injection/analyzer.js +0 -338
- package/rules/common/C017_constructor_logic/analyzer.js +0 -314
- package/rules/common/C019_log_level_usage/analyzer.js +0 -362
- package/rules/common/C019_log_level_usage/config.json +0 -121
- package/rules/common/C029_catch_block_logging/analyzer.js +0 -373
- package/rules/common/C029_catch_block_logging/config.json +0 -59
- package/rules/common/C031_validation_separation/analyzer.js +0 -186
- package/rules/common/C041_no_sensitive_hardcode/analyzer.js +0 -292
- package/rules/common/C042_boolean_name_prefix/analyzer.js +0 -300
- package/rules/common/C043_no_console_or_print/analyzer.js +0 -304
- package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +0 -351
- package/rules/common/C075_explicit_return_types/analyzer.js +0 -103
- package/rules/common/C076_single_test_behavior/analyzer.js +0 -121
- package/rules/docs/C002_no_duplicate_code.md +0 -57
- package/rules/docs/C031_validation_separation.md +0 -72
- package/rules/index.js +0 -149
- package/rules/migration/converter.js +0 -385
- package/rules/migration/mapping.json +0 -164
- package/rules/security/S026_json_schema_validation/analyzer.js +0 -251
- package/rules/security/S026_json_schema_validation/config.json +0 -27
- package/rules/security/S027_no_hardcoded_secrets/analyzer.js +0 -263
- package/rules/security/S027_no_hardcoded_secrets/config.json +0 -29
- package/rules/security/S029_csrf_protection/analyzer.js +0 -264
- package/rules/tests/C002_no_duplicate_code.test.js +0 -50
- package/rules/universal/C010/generic.js +0 -0
- package/rules/universal/C010/tree-sitter-analyzer.js +0 -0
- package/rules/utils/ast-utils.js +0 -191
- package/rules/utils/base-analyzer.js +0 -98
- package/rules/utils/pattern-matchers.js +0 -239
- package/rules/utils/rule-helpers.js +0 -264
- package/rules/utils/severity-constants.js +0 -93
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
### 📘 Rule SW001 – Use Swift's observe property instead of legacy KVO
|
|
2
|
+
|
|
3
|
+
- **Objective**: Avoid using outdated KVO mechanisms.
|
|
4
|
+
- **Details**:
|
|
5
|
+
- Prefer block-based KVO API with `keypaths` when using Swift 3.2 or later.
|
|
6
|
+
- Eliminate the need to override the traditional `observeValue`, which is complex and error-prone.
|
|
7
|
+
- **Applies to**: Swift/iOS
|
|
8
|
+
- **Tools**: SwiftLint (`block_based_kvo`)
|
|
9
|
+
- **Principles**: CODE_QUALITY
|
|
10
|
+
- **Version**: 1.0
|
|
11
|
+
- **Status**: activated
|
|
12
|
+
- **Severity**: major
|
|
13
|
+
|
|
14
|
+
### 📘 Rule SW002 – Delegate Protocols must be class-only
|
|
15
|
+
|
|
16
|
+
- **Objective**: Allow the use of `weak` to avoid retain cycles (memory leaks).
|
|
17
|
+
- **Details**:
|
|
18
|
+
- `weak` is only supported for class types, so delegate protocols must be declared as `class`-based (`AnyObject`).
|
|
19
|
+
- **Applies to**: Swift/iOS
|
|
20
|
+
- **Tools**: SwiftLint (`class_delegate_protocol`)
|
|
21
|
+
- **Principles**: CODE_QUALITY
|
|
22
|
+
- **Version**: 1.0
|
|
23
|
+
- **Status**: activated
|
|
24
|
+
- **Severity**: major
|
|
25
|
+
|
|
26
|
+
### 📘 Rule SW003 – Do not directly instantiate system protocols
|
|
27
|
+
|
|
28
|
+
- **Objective**: Avoid misusing protocols like `ExpressibleByArrayLiteral`.
|
|
29
|
+
- **Details**:
|
|
30
|
+
- Compiler protocols (such as `ExpressibleByArrayLiteral`) should not be directly initialized.
|
|
31
|
+
- Use concise syntax for initialization.
|
|
32
|
+
- **Applies to**: Swift/iOS
|
|
33
|
+
- **Tools**: SwiftLint (`compiler_protocol_init`)
|
|
34
|
+
- **Principles**: CODE_QUALITY
|
|
35
|
+
- **Version**: 1.0
|
|
36
|
+
- **Status**: activated
|
|
37
|
+
- **Severity**: major
|
|
38
|
+
|
|
39
|
+
### 📘 Rule SW004 – Prefer `.contains` for certain filtering operations
|
|
40
|
+
|
|
41
|
+
- **Objective**: Improve performance and clarity.
|
|
42
|
+
- **Details**:
|
|
43
|
+
- Instead of `.filter { ... }.count > 0` or `.first != nil`, use `.contains`.
|
|
44
|
+
- `.contains` is usually shorter, clearer, and more efficient.
|
|
45
|
+
- **Applies to**: Swift/iOS
|
|
46
|
+
- **Tools**: SwiftLint (`contains_over_*`)
|
|
47
|
+
- **Principles**: CODE_QUALITY, PERFORMANCE
|
|
48
|
+
- **Version**: 1.0
|
|
49
|
+
- **Status**: activated
|
|
50
|
+
- **Severity**: major
|
|
51
|
+
|
|
52
|
+
### 📘 Rule SW005 – Use `enum` for types with only static members
|
|
53
|
+
|
|
54
|
+
- **Objective**: Prevent unnecessary instantiation.
|
|
55
|
+
- **Details**:
|
|
56
|
+
- If a type only contains static members, use `enum` to disallow instantiation.
|
|
57
|
+
- `enum` cannot be directly instantiated, helping to avoid misuse.
|
|
58
|
+
- **Applies to**: Swift/iOS
|
|
59
|
+
- **Tools**: SwiftLint (`convenience_type`)
|
|
60
|
+
- **Principles**: CODE_QUALITY
|
|
61
|
+
- **Version**: 1.0
|
|
62
|
+
- **Status**: activated
|
|
63
|
+
- **Severity**: major
|
|
64
|
+
|
|
65
|
+
### 📘 Rule SW006 – Always dispose NotificationCenter observers
|
|
66
|
+
|
|
67
|
+
- **Objective**: Prevent memory leaks due to retain cycles.
|
|
68
|
+
- **Details**:
|
|
69
|
+
- Always store the token when using `addObserver` with NotificationCenter.
|
|
70
|
+
- Call `removeObserver()` when the observer is no longer needed or in `deinit`.
|
|
71
|
+
- **Applies to**: Swift/iOS
|
|
72
|
+
- **Tools**: SwiftLint (`discarded_notification_center_observer`)
|
|
73
|
+
- **Principles**: PERFORMANCE
|
|
74
|
+
- **Version**: 1.0
|
|
75
|
+
- **Status**: activated
|
|
76
|
+
- **Severity**: major
|
|
77
|
+
|
|
78
|
+
### 📘 Rule SW007 – Avoid direct instantiation of system types
|
|
79
|
+
|
|
80
|
+
- **Objective**: Prevent creating types that may cause errors or are unnecessary.
|
|
81
|
+
- **Details**:
|
|
82
|
+
- Avoid directly instantiating types like `Bundle`, `NSError`, `UIDevice`.
|
|
83
|
+
- Use factory methods or existing properties instead of direct `init`.
|
|
84
|
+
- **Applies to**: Swift/iOS
|
|
85
|
+
- **Tools**: SwiftLint (`discouraged_direct_init`)
|
|
86
|
+
- **Principles**: CODE_QUALITY
|
|
87
|
+
- **Version**: 1.0
|
|
88
|
+
- **Status**: activated
|
|
89
|
+
- **Severity**: major
|
|
90
|
+
|
|
91
|
+
### 📘 Rule SW008 – Do not use optionals for Boolean values
|
|
92
|
+
|
|
93
|
+
- **Objective**: Avoid ambiguous logic and hard-to-control conditions.
|
|
94
|
+
- **Details**:
|
|
95
|
+
- Do not declare `Bool?` if it can be avoided.
|
|
96
|
+
- Use `Bool` with a clear default value to avoid three states (`true`, `false`, `nil`).
|
|
97
|
+
- **Applies to**: Swift/iOS
|
|
98
|
+
- **Tools**: SwiftLint (`discouraged_optional_boolean`)
|
|
99
|
+
- **Principles**: CODE_QUALITY
|
|
100
|
+
- **Version**: 1.0
|
|
101
|
+
- **Status**: activated
|
|
102
|
+
- **Severity**: critical
|
|
103
|
+
|
|
104
|
+
### 📘 Rule SW009 – Prefer `.isEmpty` over `.count == 0`
|
|
105
|
+
|
|
106
|
+
- **Objective**: Make code clearer and more efficient.
|
|
107
|
+
- **Details**:
|
|
108
|
+
- Use `.isEmpty` for better readability and clarity.
|
|
109
|
+
- `.count == 0` is slower and more verbose than `.isEmpty`.
|
|
110
|
+
- **Applies to**: Swift/iOS
|
|
111
|
+
- **Tools**: SwiftLint (`empty_count`)
|
|
112
|
+
- **Principles**: CODE_QUALITY
|
|
113
|
+
- **Version**: 1.0
|
|
114
|
+
- **Status**: activated
|
|
115
|
+
- **Severity**: major
|
|
116
|
+
|
|
117
|
+
### 📘 Rule SW010 – Prefer `isEmpty` over comparing to `""`
|
|
118
|
+
|
|
119
|
+
- **Objective**: Increase clarity and avoid potential errors with empty strings.
|
|
120
|
+
- **Details**:
|
|
121
|
+
- Use `.isEmpty` instead of comparing to an empty string.
|
|
122
|
+
- Avoid mistakes or semantic errors when handling strings.
|
|
123
|
+
- **Applies to**: Swift/iOS
|
|
124
|
+
- **Tools**: SwiftLint (`empty_string`)
|
|
125
|
+
- **Principles**: CODE_QUALITY
|
|
126
|
+
- **Version**: 1.0
|
|
127
|
+
- **Status**: activated
|
|
128
|
+
- **Severity**: major
|
|
129
|
+
|
|
130
|
+
### 📘 Rule SW011 – Do not use `.init()` unnecessarily
|
|
131
|
+
|
|
132
|
+
- **Objective**: Increase code clarity.
|
|
133
|
+
- **Details**:
|
|
134
|
+
- Avoid explicitly calling `.init()` unless required.
|
|
135
|
+
- Prefer concise and readable object initialization.
|
|
136
|
+
- **Applies to**: Swift/iOS
|
|
137
|
+
- **Tools**: SwiftLint (`explicit_init`)
|
|
138
|
+
- **Principles**: CODE_QUALITY
|
|
139
|
+
- **Version**: 1.0
|
|
140
|
+
- **Status**: activated
|
|
141
|
+
- **Severity**: major
|
|
142
|
+
|
|
143
|
+
### 📘 Rule SW012 – Always provide a clear message when using `fatalError`
|
|
144
|
+
|
|
145
|
+
- **Objective**: Make it easier to trace application crashes.
|
|
146
|
+
- **Details**:
|
|
147
|
+
- Always add a description when calling `fatalError(...)`.
|
|
148
|
+
- The message helps identify the cause during debugging or logging.
|
|
149
|
+
- **Applies to**: Swift/iOS
|
|
150
|
+
- **Tools**: SwiftLint (`fatal_error_message`)
|
|
151
|
+
- **Principles**: CODE_QUALITY
|
|
152
|
+
- **Version**: 1.0
|
|
153
|
+
- **Status**: activated
|
|
154
|
+
- **Severity**: major
|
|
155
|
+
|
|
156
|
+
### 📘 Rule SW013 – Prefer `for-where` over `if` inside loops
|
|
157
|
+
|
|
158
|
+
- **Objective**: Make code clearer and express intent.
|
|
159
|
+
- **Details**:
|
|
160
|
+
- If there is only one condition in a loop, use `for ... where` instead of `if` inside the loop.
|
|
161
|
+
- Simplifies conditional flow and clarifies filtering intent.
|
|
162
|
+
- **Applies to**: Swift/iOS
|
|
163
|
+
- **Tools**: SwiftLint (`for_where`)
|
|
164
|
+
- **Principles**: CODE_QUALITY
|
|
165
|
+
- **Version**: 1.0
|
|
166
|
+
- **Status**: activated
|
|
167
|
+
- **Severity**: major
|
|
168
|
+
|
|
169
|
+
### 📘 Rule SW014 – Avoid `as!` (force cast)
|
|
170
|
+
|
|
171
|
+
- **Objective**: Prevent crashes due to incorrect type casting.
|
|
172
|
+
- **Details**:
|
|
173
|
+
- Do not use forced casting `as!`; use `as?` with null checks instead.
|
|
174
|
+
- Force-casting can cause crashes if the object is not of the expected type.
|
|
175
|
+
- **Applies to**: Swift/iOS
|
|
176
|
+
- **Tools**: SwiftLint (`force_cast`)
|
|
177
|
+
- **Principles**: CODE_QUALITY, SECURITY
|
|
178
|
+
- **Version**: 1.0
|
|
179
|
+
- **Status**: activated
|
|
180
|
+
- **Severity**: critical
|
|
181
|
+
|
|
182
|
+
### 📘 Rule SW015 – Avoid `try!` (force try)
|
|
183
|
+
|
|
184
|
+
- **Objective**: Prevent crashes when errors occur.
|
|
185
|
+
- **Details**:
|
|
186
|
+
- Avoid using `try!`; use `try?` or `do-catch` instead.
|
|
187
|
+
- Force-try ignores error handling and causes crashes if an exception occurs.
|
|
188
|
+
- **Applies to**: Swift/iOS
|
|
189
|
+
- **Tools**: SwiftLint (`force_try`)
|
|
190
|
+
- **Principles**: CODE_QUALITY, SECURITY
|
|
191
|
+
- **Version**: 1.0
|
|
192
|
+
- **Status**: activated
|
|
193
|
+
- **Severity**: critical
|
|
194
|
+
|
|
195
|
+
### 📘 Rule SW016 – Avoid using `!` (force unwrap)
|
|
196
|
+
|
|
197
|
+
- **Objective**: Prevent crashes caused by `nil` values.
|
|
198
|
+
- **Details**:
|
|
199
|
+
- Do not use `value!` to force unwrap optionals.
|
|
200
|
+
- Prefer optional binding (`if let`, `guard let`) for safe handling.
|
|
201
|
+
- **Applies to**: Swift/iOS
|
|
202
|
+
- **Tools**: SwiftLint (`force_unwrapping`)
|
|
203
|
+
- **Principles**: SECURITY
|
|
204
|
+
- **Version**: 1.0
|
|
205
|
+
- **Status**: activated
|
|
206
|
+
- **Severity**: critical
|
|
207
|
+
|
|
208
|
+
### 📘 Rule SW017 – Limit function parameters to less than 6
|
|
209
|
+
|
|
210
|
+
- **Objective**: Improve readability and reduce complexity.
|
|
211
|
+
- **Details**:
|
|
212
|
+
- Avoid declaring functions with too many parameters (should be < 6).
|
|
213
|
+
- If more data is needed, consider grouping into a `struct` or `object`.
|
|
214
|
+
- **Applies to**: Swift/iOS
|
|
215
|
+
- **Tools**: SwiftLint (`function_parameter_count`)
|
|
216
|
+
- **Principles**: CODE_QUALITY
|
|
217
|
+
- **Version**: 1.0
|
|
218
|
+
- **Status**: activated
|
|
219
|
+
- **Severity**: major
|
|
220
|
+
|
|
221
|
+
### 📘 Rule SW018 – Do not use tuples with too many elements
|
|
222
|
+
|
|
223
|
+
- **Objective**: Reduce complexity, improve readability and maintainability.
|
|
224
|
+
- **Details**:
|
|
225
|
+
- Tuples should only be used for small groups of data (≤ 2 elements).
|
|
226
|
+
- If a tuple has more than 2–3 elements, replace it with a `struct`.
|
|
227
|
+
- **Applies to**: Swift/iOS
|
|
228
|
+
- **Tools**: SwiftLint (`large_tuple`)
|
|
229
|
+
- **Principles**: CODE_QUALITY
|
|
230
|
+
- **Version**: 1.0
|
|
231
|
+
- **Status**: activated
|
|
232
|
+
- **Severity**: major
|
|
233
|
+
|
|
234
|
+
### 📘 Rule SW019 – Use Swift initializers instead of Objective-C style
|
|
235
|
+
|
|
236
|
+
- **Objective**: Keep Swift code pure, clear, and maintainable.
|
|
237
|
+
- **Details**:
|
|
238
|
+
- Do not use old-style initializers like `CGPointMake`, `CGRectMake`, etc.
|
|
239
|
+
- Use Swift initializers such as `CGPoint(x:y:)`, `CGRect(x:y:width:height:)`, etc.
|
|
240
|
+
- **Applies to**: Swift/iOS
|
|
241
|
+
- **Tools**: SwiftLint (`legacy_constructor`)
|
|
242
|
+
- **Principles**: CODE_QUALITY
|
|
243
|
+
- **Version**: 1.0
|
|
244
|
+
- **Status**: activated
|
|
245
|
+
- **Severity**: major
|
|
246
|
+
|
|
247
|
+
### 📘 Rule SW020 – Data types should be nested at most 1 level
|
|
248
|
+
|
|
249
|
+
- **Objective**: Avoid unreadable and hard-to-debug code due to deep nesting.
|
|
250
|
+
- **Details**:
|
|
251
|
+
- Do not nest more than 1 level in type definitions like `class`, `struct`, `actor`.
|
|
252
|
+
- Deep nesting makes maintenance difficult and violates Single Responsibility.
|
|
253
|
+
- **Applies to**: Swift/iOS
|
|
254
|
+
- **Tools**: SwiftLint (`nesting`)
|
|
255
|
+
- **Principles**: CODE_QUALITY
|
|
256
|
+
- **Version**: 1.0
|
|
257
|
+
- **Status**: activated
|
|
258
|
+
- **Severity**: major
|
|
259
|
+
|
|
260
|
+
### 📘 Rule SW021 – Do not use access modifiers with extensions
|
|
261
|
+
|
|
262
|
+
- **Objective**: Keep extensions clear and consistent.
|
|
263
|
+
- **Details**:
|
|
264
|
+
- Do not declare `public`, `private`, `internal`, or `fileprivate` on the extension itself.
|
|
265
|
+
- Access control should be defined at the member level inside the extension.
|
|
266
|
+
- **Applies to**: Swift/iOS
|
|
267
|
+
- **Tools**: SwiftLint (`no_extension_access_modifier`)
|
|
268
|
+
- **Principles**: CODE_QUALITY, MAINTAINABILITY
|
|
269
|
+
- **Version**: 1.0
|
|
270
|
+
- **Status**: activated
|
|
271
|
+
- **Severity**: critical
|
|
272
|
+
|
|
273
|
+
### 📘 Rule SW022 – Call `super` in lifecycle methods
|
|
274
|
+
|
|
275
|
+
- **Objective**: Ensure default behaviors are executed correctly.
|
|
276
|
+
- **Details**:
|
|
277
|
+
- When overriding lifecycle methods (`viewDidLoad`, `viewWillAppear`, etc.), always call `super.methodName()`.
|
|
278
|
+
- Missing `super` may cause UI or logic to malfunction.
|
|
279
|
+
- **Applies to**: Swift/iOS
|
|
280
|
+
- **Tools**: SwiftLint (`overridden_super_call`)
|
|
281
|
+
- **Principles**: CODE_QUALITY
|
|
282
|
+
- **Version**: 1.0
|
|
283
|
+
- **Status**: activated
|
|
284
|
+
- **Severity**: major
|
|
285
|
+
|
|
286
|
+
### 📘 Rule SW023 – Do not use `override` in extensions
|
|
287
|
+
|
|
288
|
+
- **Objective**: Avoid changing original behavior and keep extensions for extension only.
|
|
289
|
+
- **Details**:
|
|
290
|
+
- Do not override properties/methods in extensions.
|
|
291
|
+
- If overriding is needed, do it in the main class or subclass.
|
|
292
|
+
- **Applies to**: Swift/iOS
|
|
293
|
+
- **Tools**: SwiftLint (`override_in_extension`)
|
|
294
|
+
- **Principles**: CODE_QUALITY
|
|
295
|
+
- **Version**: 1.0
|
|
296
|
+
- **Status**: activated
|
|
297
|
+
- **Severity**: critical
|
|
298
|
+
|
|
299
|
+
### 📘 Rule SW024 – Prefer `private` over `fileprivate`
|
|
300
|
+
|
|
301
|
+
- **Objective**: Restrict access scope more tightly.
|
|
302
|
+
- **Details**:
|
|
303
|
+
- Use `private` to limit access within the same class/struct.
|
|
304
|
+
- Use `fileprivate` only if sharing between multiple classes in the same file is necessary.
|
|
305
|
+
- **Applies to**: Swift/iOS
|
|
306
|
+
- **Tools**: SwiftLint (`private_over_fileprivate`)
|
|
307
|
+
- **Principles**: CODE_QUALITY
|
|
308
|
+
- **Version**: 1.0
|
|
309
|
+
- **Status**: activated
|
|
310
|
+
- **Severity**: major
|
|
311
|
+
|
|
312
|
+
### 📘 Rule SW025 – Do not declare Unit Test functions as `private`
|
|
313
|
+
|
|
314
|
+
- **Objective**: Ensure tests are executed from the test target.
|
|
315
|
+
- **Details**:
|
|
316
|
+
- Do not use `private` for classes/functions in `XCTestCase`.
|
|
317
|
+
- Use `internal` or `public` so the Swift test runner can call them.
|
|
318
|
+
- **Applies to**: Swift/iOS
|
|
319
|
+
- **Tools**: SwiftLint (`private_unit_test`)
|
|
320
|
+
- **Principles**: TESTABILITY
|
|
321
|
+
- **Version**: 1.0
|
|
322
|
+
- **Status**: activated
|
|
323
|
+
- **Severity**: critical
|
|
324
|
+
|
|
325
|
+
### 📘 Rule SW026 – Do not call `super` in specific methods
|
|
326
|
+
|
|
327
|
+
- **Objective**: Avoid errors from unnecessary `super` calls.
|
|
328
|
+
- **Details**:
|
|
329
|
+
- Do not call `super` if the method is not defined in the parent class or Apple recommends not to (e.g., `loadView()`).
|
|
330
|
+
- **Applies to**: Swift/iOS
|
|
331
|
+
- **Tools**: SwiftLint (`prohibited_super_call`)
|
|
332
|
+
- **Principles**: CODE_QUALITY
|
|
333
|
+
- **Version**: 1.0
|
|
334
|
+
- **Status**: activated
|
|
335
|
+
- **Severity**: major
|
|
336
|
+
|
|
337
|
+
### 📘 Rule SW027 – Prefer `.min()` or `.max()` over `sorted().first/last`
|
|
338
|
+
|
|
339
|
+
- **Objective**: Improve performance and clarity.
|
|
340
|
+
- **Details**:
|
|
341
|
+
- `.sorted().first` is slower than `.min()` because it sorts the entire collection.
|
|
342
|
+
- `.min()` and `.max()` only require a single pass.
|
|
343
|
+
- **Applies to**: Swift/iOS
|
|
344
|
+
- **Tools**: SwiftLint (`sorted_first_last`)
|
|
345
|
+
- **Principles**: PERFORMANCE
|
|
346
|
+
- **Version**: 1.0
|
|
347
|
+
- **Status**: activated
|
|
348
|
+
- **Severity**: critical
|
|
349
|
+
|
|
350
|
+
### 📘 Rule SW028 – Prefer shorthand syntax `[T]` over `Array<T>`
|
|
351
|
+
|
|
352
|
+
- **Objective**: Make code more idiomatic and concise.
|
|
353
|
+
- **Details**:
|
|
354
|
+
- Swift supports sugar syntax `[Int]` instead of `Array<Int>`.
|
|
355
|
+
- Shorter, clearer, and more common in modern Swift code.
|
|
356
|
+
- **Applies to**: Swift/iOS
|
|
357
|
+
- **Tools**: SwiftLint (`syntactic_sugar`)
|
|
358
|
+
- **Principles**: CODE_QUALITY
|
|
359
|
+
- **Version**: 1.0
|
|
360
|
+
- **Status**: activated
|
|
361
|
+
- **Severity**: critical
|
|
362
|
+
|
|
363
|
+
### 📘 Rule SW029 – Warn for unused closure parameters
|
|
364
|
+
|
|
365
|
+
- **Objective**: Avoid compile warnings and improve readability.
|
|
366
|
+
- **Details**:
|
|
367
|
+
- If a closure receives parameters that are not used, use `_`.
|
|
368
|
+
- Avoid declaring unnecessary variables in closures.
|
|
369
|
+
- **Applies to**: Swift/iOS
|
|
370
|
+
- **Tools**: SwiftLint (`unused_closure_parameter`)
|
|
371
|
+
- **Principles**: CODE_QUALITY
|
|
372
|
+
- **Version**: 1.0
|
|
373
|
+
- **Status**: activated
|
|
374
|
+
- **Severity**: major
|
|
375
|
+
|
|
376
|
+
### 📘 Rule SW030 – Avoid using `enumerated()` when index is not needed
|
|
377
|
+
|
|
378
|
+
- **Objective**: Remove redundant code and avoid performance risks.
|
|
379
|
+
- **Details**:
|
|
380
|
+
- Only use `.enumerated()` if both `index` and `value` are needed.
|
|
381
|
+
- If only `value` is needed, iterate directly.
|
|
382
|
+
- **Applies to**: Swift/iOS
|
|
383
|
+
- **Tools**: SwiftLint (`unused_enumerated`)
|
|
384
|
+
- **Principles**: CODE_QUALITY
|
|
385
|
+
- **Version**: 1.0
|
|
386
|
+
- **Status**: activated
|
|
387
|
+
- **Severity**: major
|
|
388
|
+
|
|
389
|
+
### 📘 Rule SW031 – Do not use optional binding just to call a function or property
|
|
390
|
+
|
|
391
|
+
- **Objective**: Increase clarity and avoid deep nesting.
|
|
392
|
+
- **Details**:
|
|
393
|
+
- Avoid using `if let` or `guard let` solely to call a function or access a property.
|
|
394
|
+
- Use optional chaining instead for simpler code.
|
|
395
|
+
- **Applies to**: Swift/iOS
|
|
396
|
+
- **Tools**: SwiftLint (`unused_optional_binding`)
|
|
397
|
+
- **Principles**: CODE_QUALITY
|
|
398
|
+
- **Version**: 1.0
|
|
399
|
+
- **Status**: activated
|
|
400
|
+
- **Severity**: critical
|
|
401
|
+
|
|
402
|
+
### 📘 Rule SW032 – Do not use `@IBInspectable` with unsupported types and constants
|
|
403
|
+
|
|
404
|
+
- **Objective**: Prevent crashes or compile-time errors.
|
|
405
|
+
- **Details**:
|
|
406
|
+
- `@IBInspectable` should only be used with supported types (Int, CGFloat, String, etc.).
|
|
407
|
+
- Do not use with `let` properties; it must be a mutable property (`var`).
|
|
408
|
+
- **Applies to**: Swift/iOS
|
|
409
|
+
- **Tools**: SwiftLint (`valid_ibinspectable`)
|
|
410
|
+
- **Principles**: CODE_QUALITY
|
|
411
|
+
- **Version**: 1.0
|
|
412
|
+
- **Status**: activated
|
|
413
|
+
- **Severity**: major
|
|
414
|
+
|
|
415
|
+
### 📘 Rule SW033 – Parameters must be vertically aligned when calling functions
|
|
416
|
+
|
|
417
|
+
- **Objective**: Improve readability and maintain consistent code style.
|
|
418
|
+
- **Details**:
|
|
419
|
+
- If breaking into multiple lines, each parameter should be on its own line and aligned.
|
|
420
|
+
- **Applies to**: Swift/iOS
|
|
421
|
+
- **Tools**: SwiftLint (`vertical_parameter_alignment_on_call`, `vertical_parameter_alignment`)
|
|
422
|
+
- **Principles**: CODE_QUALITY
|
|
423
|
+
- **Version**: 1.0
|
|
424
|
+
- **Status**: activated
|
|
425
|
+
- **Severity**: major
|
|
426
|
+
|
|
427
|
+
### 📘 Rule SW034 – Use `-> Void` instead of `-> ()` for function types
|
|
428
|
+
|
|
429
|
+
- **Objective**: Increase consistency and readability.
|
|
430
|
+
- **Details**:
|
|
431
|
+
- Swift Coding Convention prefers `Void` over `()`.
|
|
432
|
+
- **Applies to**: Swift/iOS
|
|
433
|
+
- **Tools**: SwiftLint (`void_return`)
|
|
434
|
+
- **Principles**: CODE_QUALITY
|
|
435
|
+
- **Version**: 1.0
|
|
436
|
+
- **Status**: activated
|
|
437
|
+
- **Severity**: major
|
|
438
|
+
|
|
439
|
+
### 📘 Rule SW035 – Delegates must be marked as `weak`
|
|
440
|
+
|
|
441
|
+
- **Objective**: Prevent retain cycles and memory leaks.
|
|
442
|
+
- **Details**:
|
|
443
|
+
- If the delegate is a class-only protocol, always mark it as `weak`.
|
|
444
|
+
- **Applies to**: Swift/iOS
|
|
445
|
+
- **Tools**: SwiftLint (`weak_delegate`)
|
|
446
|
+
- **Principles**: CODE_QUALITY, PERFORMANCE
|
|
447
|
+
- **Version**: 1.0
|
|
448
|
+
- **Status**: activated
|
|
449
|
+
- **Severity**: major
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# 📘 TypeScript Specific Coding Rules
|
|
2
|
+
|
|
3
|
+
### 📘 Rule T002 – Interface names should start with 'I'
|
|
4
|
+
|
|
5
|
+
- **Objective**: Ensure interface names follow naming conventions with 'I' prefix.
|
|
6
|
+
- **Details**: Interface names must start with the letter 'I' followed by a capital letter. For example: `IUser`, `IProduct`, `IRepository`.
|
|
7
|
+
- **Applies to**: TypeScript/JavaScript
|
|
8
|
+
- **Tools**: ESLint custom rule (custom/t002)
|
|
9
|
+
- **Principles**: CODE_QUALITY
|
|
10
|
+
- **Version**: 1.0
|
|
11
|
+
- **Status**: activated
|
|
12
|
+
|
|
13
|
+
### 📘 Rule T003 – Avoid using @ts-ignore without a clear justification
|
|
14
|
+
|
|
15
|
+
- **Objective**: Avoid using @ts-ignore without a clear reason.
|
|
16
|
+
- **Details**: When using `@ts-ignore`, you must include a comment explaining the reason on the same line. For example: `// @ts-ignore: API has no types` instead of just `// @ts-ignore`.
|
|
17
|
+
- **Applies to**: TypeScript/JavaScript
|
|
18
|
+
- **Tools**: ESLint custom rule (custom/t003)
|
|
19
|
+
- **Principles**: CODE_QUALITY
|
|
20
|
+
- **Version**: 1.0
|
|
21
|
+
- **Status**: activated
|
|
22
|
+
|
|
23
|
+
### 📘 Rule T004 – Disallow declaring empty types like `type X = {}`
|
|
24
|
+
|
|
25
|
+
- **Objective**: Avoid declaring meaningless empty data types.
|
|
26
|
+
- **Details**: Do not declare empty type aliases like `type EmptyType = {}`. Instead, use `Record<string, never>` or define properties clearly.
|
|
27
|
+
- **Applies to**: TypeScript/JavaScript
|
|
28
|
+
- **Tools**: ESLint custom rule (custom/t004)
|
|
29
|
+
- **Principles**: CODE_QUALITY
|
|
30
|
+
- **Version**: 1.0
|
|
31
|
+
- **Status**: activated
|
|
32
|
+
|
|
33
|
+
### 📘 Rule T007 – Avoid declaring functions inside constructors or class bodies
|
|
34
|
+
|
|
35
|
+
- **Objective**: Avoid declaring functions inside constructors or class bodies.
|
|
36
|
+
- **Details**: Do not declare functions inside constructors or class methods. Instead, define them as private methods or extract them as utility functions.
|
|
37
|
+
- **Applies to**: TypeScript/JavaScript
|
|
38
|
+
- **Tools**: ESLint custom rule (custom/t007)
|
|
39
|
+
- **Principles**: CODE_QUALITY
|
|
40
|
+
- **Version**: 1.0
|
|
41
|
+
- **Status**: activated
|
|
42
|
+
|
|
43
|
+
### 📘 Rule T010 – Avoid deeply nested union or tuple types
|
|
44
|
+
|
|
45
|
+
- **Objective**: Avoid complex nested union or tuple types.
|
|
46
|
+
- **Details**: Avoid creating nested union types or tuple types like `A | (B | C)` or `[string, [number, boolean]]`. Break them into separate type aliases for better readability and maintainability.
|
|
47
|
+
- **Applies to**: TypeScript/JavaScript
|
|
48
|
+
- **Tools**: ESLint custom rule (custom/t010)
|
|
49
|
+
- **Principles**: CODE_QUALITY
|
|
50
|
+
- **Version**: 1.0
|
|
51
|
+
- **Status**: activated
|
|
52
|
+
|
|
53
|
+
### 📘 Rule T015 – Do not use `instanceof` to distinguish behavior when interfaces are available
|
|
54
|
+
|
|
55
|
+
- **Objective**: Use polymorphism instead of branching with type checks.
|
|
56
|
+
- **Details**: Instead of: `if (a instanceof A)`, design `a.doSomething()` through interfaces.
|
|
57
|
+
- **Applies to**: TypeScript/JavaScript
|
|
58
|
+
- **Tools**: AI review / static analyzer
|
|
59
|
+
- **Principles**: CODE_QUALITY
|
|
60
|
+
- **Version**:
|
|
61
|
+
- **Status**: draft
|
|
62
|
+
|
|
63
|
+
### 📘 Rule T016 – Use strict type checking
|
|
64
|
+
|
|
65
|
+
- **Objective**: Leverage TypeScript's type safety to reduce runtime errors.
|
|
66
|
+
- **Details**:
|
|
67
|
+
- Enable strict mode in tsconfig.json
|
|
68
|
+
- Avoid using `any` type
|
|
69
|
+
- Use union types instead of any
|
|
70
|
+
- Define interfaces for complex objects
|
|
71
|
+
- **Applies to**: TypeScript/JavaScript
|
|
72
|
+
- **Tools**: TypeScript compiler, ESLint
|
|
73
|
+
- **Principles**: CODE_QUALITY
|
|
74
|
+
- **Severity**: critical
|
|
75
|
+
- **Version**: 1.0
|
|
76
|
+
- **Status**: activated
|
|
77
|
+
|
|
78
|
+
### 📘 Rule T017 – Use async/await instead of Promises
|
|
79
|
+
|
|
80
|
+
- **Objective**: Improve code readability and ease debugging of async operations.
|
|
81
|
+
- **Details**:
|
|
82
|
+
- Prefer async/await for async operations
|
|
83
|
+
- Proper error handling with try-catch
|
|
84
|
+
- Avoid callback hell and promise chaining
|
|
85
|
+
- Use Promise.all for parallel operations
|
|
86
|
+
- **Applies to**: TypeScript/JavaScript
|
|
87
|
+
- **Tools**: ESLint, Prettier
|
|
88
|
+
- **Principles**: CODE_QUALITY
|
|
89
|
+
- **Severity**: major
|
|
90
|
+
- **Version**: 1.0
|
|
91
|
+
- **Status**: activated
|
|
92
|
+
|
|
93
|
+
### 📘 Rule T018 – Use proper error handling
|
|
94
|
+
|
|
95
|
+
- **Objective**: Ensure robust error handling and good user experience.
|
|
96
|
+
- **Details**:
|
|
97
|
+
- Define custom error types
|
|
98
|
+
- Use Result pattern for error handling
|
|
99
|
+
- Proper logging for production debugging
|
|
100
|
+
- Graceful error recovery when possible
|
|
101
|
+
- **Applies to**: TypeScript/JavaScript
|
|
102
|
+
- **Tools**: ESLint, Custom error libraries
|
|
103
|
+
- **Principles**: CODE_QUALITY
|
|
104
|
+
- **Severity**: major
|
|
105
|
+
- **Version**: 1.0
|
|
106
|
+
- **Status**: activated
|
|
107
|
+
|
|
108
|
+
### 📘 Rule T019 – Do not assign to this arbitrarily
|
|
109
|
+
|
|
110
|
+
- **Objective**: Maintain proper context and avoid this manipulation.
|
|
111
|
+
- **Details**: Do not reassign `this` or use patterns like `const that = this`. Use proper binding, arrow functions, or explicit parameter passing instead. This prevents confusion about execution context and maintains clean object-oriented code.
|
|
112
|
+
- **Applies to**: TypeScript/JavaScript
|
|
113
|
+
- **Tools**: ESLint custom rule (custom/t019)
|
|
114
|
+
- **Principles**: CODE_QUALITY
|
|
115
|
+
- **Version**: 1.0
|
|
116
|
+
- **Status**: activated
|
|
117
|
+
|
|
118
|
+
### 📘 Rule T020 – Avoid export default for multi-responsibility modules
|
|
119
|
+
|
|
120
|
+
- **Objective**: Improve tree-shaking and module clarity.
|
|
121
|
+
- **Details**: Use named exports when a module has multiple functions, classes, or constants. Reserve default export for single-purpose modules only. This improves bundler optimization and makes dependencies more explicit.
|
|
122
|
+
- **Applies to**: TypeScript/JavaScript
|
|
123
|
+
- **Tools**: ESLint custom rule (custom/t020)
|
|
124
|
+
- **Principles**: CODE_QUALITY
|
|
125
|
+
- **Version**: 1.0
|
|
126
|
+
- **Status**: activated
|
|
127
|
+
|
|
128
|
+
### 📘 Rule T021 – Limit deeply nested generics
|
|
129
|
+
|
|
130
|
+
- **Objective**: Improve code readability and TypeScript performance.
|
|
131
|
+
- **Details**: Avoid deeply nested generics beyond 3 levels like `Promise<Array<Map<string, Record<string, T>>>>`. Break complex types into intermediate type aliases for better readability and TypeScript compiler performance.
|
|
132
|
+
- **Applies to**: TypeScript/JavaScript
|
|
133
|
+
- **Tools**: ESLint custom rule (custom/t021)
|
|
134
|
+
- **Principles**: CODE_QUALITY
|
|
135
|
+
- **Version**: 1.0
|
|
136
|
+
- **Status**: activated
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sunlint",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
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": {
|
|
@@ -40,16 +40,17 @@
|
|
|
40
40
|
"demo:file-targeting": "./demo-file-targeting.sh",
|
|
41
41
|
"lint": "node cli.js --config=.sunlint.json --input=.",
|
|
42
42
|
"lint:eslint-integration": "node cli.js --all --eslint-integration --input=.",
|
|
43
|
-
"build": "echo '
|
|
43
|
+
"build": "npm run copy-rules && echo 'Build completed with rules copy'",
|
|
44
|
+
"copy-rules": "node scripts/copy-rules.js",
|
|
44
45
|
"clean": "rm -rf coverage/ *.log reports/ *.tgz",
|
|
45
46
|
"postpack": "echo '📦 Package created successfully! Size: ' && ls -lh *.tgz | awk '{print $5}'",
|
|
46
47
|
"start": "node cli.js --help",
|
|
47
48
|
"version": "node cli.js --version",
|
|
48
|
-
"pack": "npm pack",
|
|
49
|
+
"pack": "npm run copy-rules && npm pack",
|
|
49
50
|
"publish:github": "npm publish --registry=https://npm.pkg.github.com",
|
|
50
51
|
"publish:npmjs": "npm publish --registry=https://registry.npmjs.org",
|
|
51
52
|
"publish:test": "npm publish --dry-run --registry=https://registry.npmjs.org",
|
|
52
|
-
"prepublishOnly": "npm run clean"
|
|
53
|
+
"prepublishOnly": "npm run clean && npm run copy-rules"
|
|
53
54
|
},
|
|
54
55
|
"keywords": [
|
|
55
56
|
"linting",
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
"files": [
|
|
70
71
|
"cli.js",
|
|
71
72
|
"core/",
|
|
72
|
-
"rules/",
|
|
73
|
+
"origin-rules/",
|
|
73
74
|
"config/",
|
|
74
75
|
"engines/",
|
|
75
76
|
"integrations/",
|