| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 94f99b3 commit 8694167
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1268,7 +1268,7 @@ export interface DummyRuleMap { | |||
| 1268 | 1268 | "prefer-destructuring"?: | |
| 1269 | 1269 | | RuleNoConfig | |
| 1270 | 1270 | | [AllowWarnDeny, PreferDestructuringOption] | |
| 1271 | - | [AllowWarnDeny, PreferDestructuringOption, PreferDestructuringRenamedPropertiesConfig]; | ||
| 1271 | + | [AllowWarnDeny, PreferDestructuringOption, PreferDestructuringEnforcementConfig]; | ||
| 1272 | 1272 | "prefer-exponentiation-operator"?: RuleNoConfig; | |
| 1273 | 1273 | "prefer-named-capture-group"?: RuleNoConfig; | |
| 1274 | 1274 | "prefer-numeric-literals"?: RuleNoConfig; | |
@@ -4148,7 +4148,8 @@ export interface PreferDestructuringAssignmentConfig { | |||
| 4148 | 4148 | AssignmentExpression?: PreferDestructuringTargetOption; | |
| 4149 | 4149 | VariableDeclarator?: PreferDestructuringTargetOption; | |
| 4150 | 4150 | } | |
| 4151 | - export interface PreferDestructuringRenamedPropertiesConfig { | ||
| 4151 | + export interface PreferDestructuringEnforcementConfig { | ||
| 4152 | + enforceForDeclarationWithTypeAnnotation?: boolean; | ||
| 4152 | 4153 | enforceForRenamedProperties?: boolean; | |
| 4153 | 4154 | } | |
| 4154 | 4155 | export interface PreferPromiseRejectErrors { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,16 +116,14 @@ impl PreferDestructuringOption { | |||
| 116 | 116 | ||
| 117 | 117 | #[derive(Debug, Default, Clone, JsonSchema, Deserialize, Serialize)] | |
| 118 | 118 | #[serde(rename_all = "camelCase", default, deny_unknown_fields)] | |
| 119 | - struct PreferDestructuringRenamedPropertiesConfig { | ||
| 119 | + struct PreferDestructuringEnforcementConfig { | ||
| 120 | 120 | enforce_for_renamed_properties: bool, | |
| 121 | + enforce_for_declaration_with_type_annotation: bool, | ||
| 121 | 122 | } | |
| 122 | 123 | ||
| 123 | 124 | #[derive(Debug, Default, Clone, JsonSchema, Deserialize, Serialize)] | |
| 124 | 125 | #[serde(default)] | |
| 125 | - struct PreferDestructuringConfig( | ||
| 126 | - PreferDestructuringOption, | ||
| 127 | - PreferDestructuringRenamedPropertiesConfig, | ||
| 128 | - ); | ||
| 126 | + struct PreferDestructuringConfig(PreferDestructuringOption, PreferDestructuringEnforcementConfig); | ||
| 129 | 127 | ||
| 130 | 128 | impl PreferDestructuringConfig { | |
| 131 | 129 | fn into_rule(self) -> PreferDestructuring { | |
@@ -135,6 +133,9 @@ impl PreferDestructuringConfig { | |||
| 135 | 133 | variable_declarator, | |
| 136 | 134 | assignment_expression, | |
| 137 | 135 | enforce_for_renamed_properties: self.1.enforce_for_renamed_properties, | |
| 136 | + enforce_for_declaration_with_type_annotation: self | ||
| 137 | + .1 | ||
| 138 | + .enforce_for_declaration_with_type_annotation, | ||
| 138 | 139 | } | |
| 139 | 140 | } | |
| 140 | 141 | } | |
@@ -150,6 +151,8 @@ pub struct PreferDestructuring { | |||
| 150 | 151 | assignment_expression: PreferDestructuringTargetConfig, | |
| 151 | 152 | /// Determines whether the object destructuring rule applies to renamed variables. | |
| 152 | 153 | enforce_for_renamed_properties: bool, | |
| 154 | + /// Determines whether the rule applies to variable declarations with type annotations. | ||
| 155 | + enforce_for_declaration_with_type_annotation: bool, | ||
| 153 | 156 | } | |
| 154 | 157 | ||
| 155 | 158 | declare_oxc_lint!( | |
@@ -245,6 +248,11 @@ impl Rule for PreferDestructuring { | |||
| 245 | 248 | } | |
| 246 | 249 | } | |
| 247 | 250 | AstKind::VariableDeclarator(declarator) => { | |
| 251 | + let has_type_annotation = declarator.type_annotation.is_some(); | ||
| 252 | + if has_type_annotation && !self.enforce_for_declaration_with_type_annotation { | ||
| 253 | + return; | ||
| 254 | + } | ||
| 255 | + | ||
| 248 | 256 | // Skip `using` and `await using` declarations - destructuring doesn't apply to them | |
| 249 | 257 | if matches!( | |
| 250 | 258 | declarator.kind, | |
@@ -272,54 +280,57 @@ impl Rule for PreferDestructuring { | |||
| 272 | 280 | if self.variable_declarator.array { | |
| 273 | 281 | ctx.diagnostic(prefer_array_destructuring(init.span())); | |
| 274 | 282 | } | |
| 275 | - } else { | ||
| 276 | - if self.enforce_for_renamed_properties | ||
| 277 | - && self.variable_declarator.object | ||
| 278 | - { | ||
| 279 | - ctx.diagnostic(prefer_object_destructuring(right.span())); | ||
| 280 | - } | ||
| 283 | + } else if self.variable_declarator.object { | ||
| 281 | 284 | if let Expression::StringLiteral(string_literal) = | |
| 282 | 285 | &comp_expr.expression | |
| 283 | - && self.variable_declarator.object | ||
| 284 | 286 | && name.is_some_and(|v| v == string_literal.value) | |
| 285 | 287 | { | |
| 288 | + if has_type_annotation { | ||
| 289 | + ctx.diagnostic(prefer_object_destructuring(init.span())); | ||
| 290 | + } else { | ||
| 291 | + ctx.diagnostic_with_fix( | ||
| 292 | + prefer_object_destructuring(init.span()), | ||
| 293 | + |fixer| { | ||
| 294 | + generate_fix( | ||
| 295 | + &fixer, | ||
| 296 | + string_literal.span.shrink(1), | ||
| 297 | + get_object_span_without_redundant_parentheses( | ||
| 298 | + &comp_expr.object, | ||
| 299 | + ), | ||
| 300 | + declarator.span(), | ||
| 301 | + ) | ||
| 302 | + }, | ||
| 303 | + ); | ||
| 304 | + } | ||
| 305 | + } else if self.enforce_for_renamed_properties { | ||
| 306 | + ctx.diagnostic(prefer_object_destructuring(right.span())); | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + } | ||
| 310 | + MemberExpression::StaticMemberExpression(static_expr) | ||
| 311 | + if self.variable_declarator.object => | ||
| 312 | + { | ||
| 313 | + if name.is_some_and(|name| name == static_expr.property.name.as_str()) { | ||
| 314 | + if has_type_annotation { | ||
| 315 | + ctx.diagnostic(prefer_object_destructuring(init.span())); | ||
| 316 | + } else { | ||
| 286 | 317 | ctx.diagnostic_with_fix( | |
| 287 | 318 | prefer_object_destructuring(init.span()), | |
| 288 | 319 | |fixer| { | |
| 289 | 320 | generate_fix( | |
| 290 | 321 | &fixer, | |
| 291 | - string_literal.span.shrink(1), | ||
| 322 | + static_expr.property.span, | ||
| 292 | 323 | get_object_span_without_redundant_parentheses( | |
| 293 | - &comp_expr.object, | ||
| 324 | + &static_expr.object, | ||
| 294 | 325 | ), | |
| 295 | 326 | declarator.span(), | |
| 296 | 327 | ) | |
| 297 | 328 | }, | |
| 298 | 329 | ); | |
| 299 | 330 | } | |
| 300 | - } | ||
| 301 | - } | ||
| 302 | - MemberExpression::StaticMemberExpression(static_expr) | ||
| 303 | - if self.variable_declarator.object => | ||
| 304 | - { | ||
| 305 | - if self.enforce_for_renamed_properties { | ||
| 331 | + } else if self.enforce_for_renamed_properties { | ||
| 306 | 332 | ctx.diagnostic(prefer_object_destructuring(right.span())); | |
| 307 | 333 | } | |
| 308 | - if name.is_some_and(|name| name == static_expr.property.name.as_str()) { | ||
| 309 | - ctx.diagnostic_with_fix( | ||
| 310 | - prefer_object_destructuring(init.span()), | ||
| 311 | - |fixer| { | ||
| 312 | - generate_fix( | ||
| 313 | - &fixer, | ||
| 314 | - static_expr.property.span, | ||
| 315 | - get_object_span_without_redundant_parentheses( | ||
| 316 | - &static_expr.object, | ||
| 317 | - ), | ||
| 318 | - declarator.span(), | ||
| 319 | - ) | ||
| 320 | - }, | ||
| 321 | - ); | ||
| 322 | - } | ||
| 323 | 334 | } | |
| 324 | 335 | _ => {} | |
| 325 | 336 | } | |
@@ -382,6 +393,26 @@ fn test() { | |||
| 382 | 393 | let pass = vec![ | |
| 383 | 394 | ("var [foo] = array;", None), | |
| 384 | 395 | ("var { foo } = object;", None), | |
| 396 | + ("const foo: string = object.foo;", None), | ||
| 397 | + ("const foo: string = object['foo'];", None), | ||
| 398 | + ("const foo: string = array[0];", None), | ||
| 399 | + ( | ||
| 400 | + "const object = { foo: 'value' as const }; const foo: string = object.foo;", | ||
| 401 | + Some(serde_json::json!([ | ||
| 402 | + { | ||
| 403 | + "VariableDeclarator": { "array": false, "object": true }, | ||
| 404 | + "AssignmentExpression": { "array": false, "object": false } | ||
| 405 | + }, | ||
| 406 | + { | ||
| 407 | + "enforceForDeclarationWithTypeAnnotation": false, | ||
| 408 | + "enforceForRenamedProperties": false | ||
| 409 | + } | ||
| 410 | + ])), | ||
| 411 | + ), | ||
| 412 | + ( | ||
| 413 | + "const foo: string = object.foo;", | ||
| 414 | + Some(serde_json::json!([{ "object": true }, { "enforceForRenamedProperties": true }])), | ||
| 415 | + ), | ||
| 385 | 416 | ( | |
| 386 | 417 | "a = b.c", | |
| 387 | 418 | Some( | |
@@ -584,6 +615,44 @@ fn test() { | |||
| 584 | 615 | ("var foo = array[0];", None), | |
| 585 | 616 | ("foo = array[0];", None), | |
| 586 | 617 | ("var foo = object.foo;", None), | |
| 618 | + ( | ||
| 619 | + "var foo: string = object.foo;", | ||
| 620 | + Some( | ||
| 621 | + serde_json::json!([{ "object": true }, { "enforceForDeclarationWithTypeAnnotation": true }]), | ||
| 622 | + ), | ||
| 623 | + ), | ||
| 624 | + ( | ||
| 625 | + "var foo: string = object['foo'];", | ||
| 626 | + Some( | ||
| 627 | + serde_json::json!([{ "object": true }, { "enforceForDeclarationWithTypeAnnotation": true }]), | ||
| 628 | + ), | ||
| 629 | + ), | ||
| 630 | + ( | ||
| 631 | + "var foo: string = array[0];", | ||
| 632 | + Some( | ||
| 633 | + serde_json::json!([{ "array": true }, { "enforceForDeclarationWithTypeAnnotation": true }]), | ||
| 634 | + ), | ||
| 635 | + ), | ||
| 636 | + ( | ||
| 637 | + "var foo: string = object.foo;", | ||
| 638 | + Some(serde_json::json!([ | ||
| 639 | + { "object": true }, | ||
| 640 | + { | ||
| 641 | + "enforceForDeclarationWithTypeAnnotation": true, | ||
| 642 | + "enforceForRenamedProperties": true | ||
| 643 | + } | ||
| 644 | + ])), | ||
| 645 | + ), | ||
| 646 | + ( | ||
| 647 | + "var foo: string = object['foo'];", | ||
| 648 | + Some(serde_json::json!([ | ||
| 649 | + { "object": true }, | ||
| 650 | + { | ||
| 651 | + "enforceForDeclarationWithTypeAnnotation": true, | ||
| 652 | + "enforceForRenamedProperties": true | ||
| 653 | + } | ||
| 654 | + ])), | ||
| 655 | + ), | ||
| 587 | 656 | ("var foo = (a, b).foo;", None), | |
| 588 | 657 | ("var length = (() => {}).length;", None), | |
| 589 | 658 | ("var foo = (a = b).foo;", None), | |
@@ -739,6 +808,20 @@ fn test() { | |||
| 739 | 808 | ), | |
| 740 | 809 | ("var foo = object.foo, /* comment */ a;", "var {foo} = object, /* comment */ a;", None), | |
| 741 | 810 | ("var foo = object['foo'];", "var {foo} = object;", None), | |
| 811 | + ( | ||
| 812 | + "var foo: string = object.foo;", | ||
| 813 | + "var foo: string = object.foo;", | ||
| 814 | + Some( | ||
| 815 | + serde_json::json!([{ "object": true }, { "enforceForDeclarationWithTypeAnnotation": true }]), | ||
| 816 | + ), | ||
| 817 | + ), | ||
| 818 | + ( | ||
| 819 | + "var foo: string = object['foo'];", | ||
| 820 | + "var foo: string = object['foo'];", | ||
| 821 | + Some( | ||
| 822 | + serde_json::json!([{ "object": true }, { "enforceForDeclarationWithTypeAnnotation": true }]), | ||
| 823 | + ), | ||
| 824 | + ), | ||
| 742 | 825 | ("foo = object.foo;", "foo = object.foo;", None), | |
| 743 | 826 | ("foo = object['foo'];", "foo = object['foo'];", None), | |
| 744 | 827 | ]; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,41 @@ source: crates/oxc_linter/src/tester.rs | |||
| 23 | 23 | ╰──── | |
| 24 | 24 | help: Use object destructuring rather than direct member access. | |
| 25 | 25 | ||
| 26 | + ⚠ eslint(prefer-destructuring): Use Object destructuring. | ||
| 27 | + ╭─[prefer_destructuring.tsx:1:19] | ||
| 28 | + 1 │ var foo: string = object.foo; | ||
| 29 | + · ────────── | ||
| 30 | + ╰──── | ||
| 31 | + help: Use object destructuring rather than direct member access. | ||
| 32 | + | ||
| 33 | + ⚠ eslint(prefer-destructuring): Use Object destructuring. | ||
| 34 | + ╭─[prefer_destructuring.tsx:1:19] | ||
| 35 | + 1 │ var foo: string = object['foo']; | ||
| 36 | + · ───────────── | ||
| 37 | + ╰──── | ||
| 38 | + help: Use object destructuring rather than direct member access. | ||
| 39 | + | ||
| 40 | + ⚠ eslint(prefer-destructuring): Use Array destructuring. | ||
| 41 | + ╭─[prefer_destructuring.tsx:1:19] | ||
| 42 | + 1 │ var foo: string = array[0]; | ||
| 43 | + · ──────── | ||
| 44 | + ╰──── | ||
| 45 | + help: Use array destructuring rather than direct member access. | ||
| 46 | + | ||
| 47 | + ⚠ eslint(prefer-destructuring): Use Object destructuring. | ||
| 48 | + ╭─[prefer_destructuring.tsx:1:19] | ||
| 49 | + 1 │ var foo: string = object.foo; | ||
| 50 | + · ────────── | ||
| 51 | + ╰──── | ||
| 52 | + help: Use object destructuring rather than direct member access. | ||
| 53 | + | ||
| 54 | + ⚠ eslint(prefer-destructuring): Use Object destructuring. | ||
| 55 | + ╭─[prefer_destructuring.tsx:1:19] | ||
| 56 | + 1 │ var foo: string = object['foo']; | ||
| 57 | + · ───────────── | ||
| 58 | + ╰──── | ||
| 59 | + help: Use object destructuring rather than direct member access. | ||
| 60 | + | ||
| 26 | 61 | ⚠ eslint(prefer-destructuring): Use Object destructuring. | |
| 27 | 62 | ╭─[prefer_destructuring.tsx:1:11] | |
| 28 | 63 | 1 │ var foo = (a, b).foo; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5987,7 +5987,7 @@ | |||
| 5987 | 5987 | "$ref": "#/definitions/PreferDestructuringOption" | |
| 5988 | 5988 | }, | |
| 5989 | 5989 | { | |
| 5990 | - "$ref": "#/definitions/PreferDestructuringRenamedPropertiesConfig" | ||
| 5990 | + "$ref": "#/definitions/PreferDestructuringEnforcementConfig" | ||
| 5991 | 5991 | } | |
| 5992 | 5992 | ], | |
| 5993 | 5993 | "maxItems": 3, | |
@@ -17016,12 +17016,26 @@ | |||
| 17016 | 17016 | "$ref": "#/definitions/PreferDestructuringOption" | |
| 17017 | 17017 | }, | |
| 17018 | 17018 | { | |
| 17019 | - "$ref": "#/definitions/PreferDestructuringRenamedPropertiesConfig" | ||
| 17019 | + "$ref": "#/definitions/PreferDestructuringEnforcementConfig" | ||
| 17020 | 17020 | } | |
| 17021 | 17021 | ], | |
| 17022 | 17022 | "maxItems": 2, | |
| 17023 | 17023 | "minItems": 2 | |
| 17024 | 17024 | }, | |
| 17025 | + "PreferDestructuringEnforcementConfig": { | ||
| 17026 | + "type": "object", | ||
| 17027 | + "properties": { | ||
| 17028 | + "enforceForDeclarationWithTypeAnnotation": { | ||
| 17029 | + "default": false, | ||
| 17030 | + "type": "boolean" | ||
| 17031 | + }, | ||
| 17032 | + "enforceForRenamedProperties": { | ||
| 17033 | + "default": false, | ||
| 17034 | + "type": "boolean" | ||
| 17035 | + } | ||
| 17036 | + }, | ||
| 17037 | + "additionalProperties": false | ||
| 17038 | + }, | ||
| 17025 | 17039 | "PreferDestructuringOption": { | |
| 17026 | 17040 | "anyOf": [ | |
| 17027 | 17041 | { | |
@@ -17032,16 +17046,6 @@ | |||
| 17032 | 17046 | } | |
| 17033 | 17047 | ] | |
| 17034 | 17048 | }, | |
| 17035 | - "PreferDestructuringRenamedPropertiesConfig": { | ||
| 17036 | - "type": "object", | ||
| 17037 | - "properties": { | ||
| 17038 | - "enforceForRenamedProperties": { | ||
| 17039 | - "default": false, | ||
| 17040 | - "type": "boolean" | ||
| 17041 | - } | ||
| 17042 | - }, | ||
| 17043 | - "additionalProperties": false | ||
| 17044 | - }, | ||
| 17045 | 17049 | "PreferDestructuringTargetOption": { | |
| 17046 | 17050 | "type": "object", | |
| 17047 | 17051 | "properties": { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments