diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f34be852bbb..8509c065cfed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -314,7 +314,7 @@ The following JavaScript rules are promoted: - [a11y/noLabelWithoutControl](https://biomejs.dev/linter/rules/no-label-without-control/) - [a11y/useFocusableInteractive](https://biomejs.dev/linter/rules/use-focusable-interactive/) -- [accessibility/useSemanticElements](https://biomejs.dev/linter/rules/use-semantic-elements/) +- [a11y/useSemanticElements](https://biomejs.dev/linter/rules/use-semantic-elements/) - [complexity/noUselessStringConcat](https://biomejs.dev/linter/rules/no-useless-string-concat/) - [complexity/noUselessUndefinedInitialization](https://biomejs.dev/linter/rules/no-useless-undefined-initialization/) - [complexity/useDateNow](https://biomejs.dev/linter/rules/use-date-now/) diff --git a/crates/biome_cli/tests/snapshots/main_commands_rage/with_linter_configuration.snap b/crates/biome_cli/tests/snapshots/main_commands_rage/with_linter_configuration.snap index d7625b4bc9ed..42deb46ad88f 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_rage/with_linter_configuration.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_rage/with_linter_configuration.snap @@ -85,7 +85,6 @@ Linter: complexity/useSimpleNumberKeys suspicious/noCommentText complexity/noExcessiveNestedTestSuites - complexity/useDateNow complexity/noUselessLabel complexity/noUselessCatch complexity/noUselessFragments diff --git a/crates/biome_migrate/src/analyzers/nursery_rules.rs b/crates/biome_migrate/src/analyzers/nursery_rules.rs index 0ddcb2eaaf14..d9063e983150 100644 --- a/crates/biome_migrate/src/analyzers/nursery_rules.rs +++ b/crates/biome_migrate/src/analyzers/nursery_rules.rs @@ -70,57 +70,66 @@ fn find_group_by_name(root: &JsonRoot, group_name: &str) -> Option { group } -// used for testing purposes /// - Left: name of the rule in the nursery group /// - Right: name of the target group and name of the target rule (sometimes we change name) -#[cfg(debug_assertions)] +#[rustfmt::skip] const RULES_TO_MIGRATE: &[(&str, (&str, &str))] = &[ - ( - "noExcessiveNestedTestSuites", - ("complexity", "noExcessiveNestedTestSuites"), - ), - ("noUselessTernary", ("complexity", "noUselessTernary")), - ( - "useJsxKeyInIterable", - ("correctness", "useJsxKeyInIterable"), - ), - ("oldName", ("suspicious", "noSuspiciousSemicolonInJsx")), -]; - -#[cfg(not(debug_assertions))] -// Used in production -const RULES_TO_MIGRATE: &[(&str, (&str, &str))] = &[ - ( - "noExcessiveNestedTestSuites", - ("complexity", "noExcessiveNestedTestSuites"), - ), - ("noUselessTernary", ("complexity", "noUselessTernary")), - ( - "useJsxKeyInIterable", - ("correctness", "useJsxKeyInIterable"), - ), + // CSS + ("noDuplicateAtImportRules", ("suspicious", "noDuplicateAtImportRules")), + ("noDuplicateFontNames", ("suspicious", "noDuplicateFontNames")), + ("noDuplicateSelectorsKeyframeBlock", ("suspicious", "noDuplicateSelectorsKeyframeBlock")), + ("noEmptyBlock", ("suspicious", "noEmptyBlock")), + ("noImportantInKeyframe", ("suspicious", "noImportantInKeyframe")), + ("noInvalidDirectionInLinearGradient", ("correctness", "noInvalidDirectionInLinearGradient")), + ("noInvalidPositionAtImportRule", ("correctness", "noInvalidPositionAtImportRule")), + ("noShorthandPropertyOverrides", ("suspicious", "noShorthandPropertyOverrides")), + ("noUnknownFunction", ("correctness", "noUnknownFunction")), + ("noUnknownMediaFeatureName", ("correctness", "noUnknownMediaFeatureName")), + ("noUnknownProperty", ("correctness", "noUnknownProperty")), + ("noUnknownUnit", ("correctness", "noUnknownUnit")), + ("noUnmatchableAnbSelector", ("correctness", "noUnmatchableAnbSelector")), + ("useConsistentGridAreas", ("correctness", "noInvalidGridAreas")), + ("useGenericFontNames", ("a11y", "useGenericFontNames")), + // JS ("noBarrelFile", ("performance", "noBarrelFile")), - ("noReExportAll", ("performance", "noReExportAll")), - ("noNamespaceImport", ("style", "noNamespaceImport")), - ("useNodeAssertStrict", ("style", "useNodeAssertStrict")), - ( - "noDuplicateTestHooks", - ("suspicious", "noDuplicateTestHooks"), - ), + ("noConsole", ("suspicious", "noConsole")), + ("noConstantMathMinMaxClamp", ("correctness", "noConstantMathMinMaxClamp")), + ("noDoneCallback", ("style", "noDoneCallback")), + ("noDuplicateTestHooks", ("suspicious", "noDuplicateTestHooks")), + ("noEvolvingTypes", ("suspicious", "noEvolvingTypes")), + ("noExcessiveNestedTestSuites", ("complexity", "noExcessiveNestedTestSuites")), ("noExportsInTest", ("suspicious", "noExportsInTest")), - ("noFocusedTests", ("suspicious", "noFocusedTests")), - ("noSkippedTests", ("suspicious", "noSkippedTests")), - ( - "noSuspiciousSemicolonInJsx", - ("suspicious", "noSuspiciousSemicolonInJsx"), - ), - ( - "noConstantMathMinMaxClamp", - ("correctness", "noConstantMathMinMaxClamp"), - ), ("noFlatMapIdentity", ("correctness", "noFlatMapIdentity")), + ("noFocusedTests", ("suspicious", "noFocusedTests")), + ("noLabelWithoutControl", ("a11y", "noLabelWithoutControl")), + ("noMisplacedAssertion", ("suspicious", "noMisplacedAssertion")), + ("noNamespaceImport", ("style", "noNamespaceImport")), ("noNodejsModules", ("correctness", "noNodejsModules")), + ("noReactSpecificProps", ("suspicious", "noReactSpecificProps")), + ("noReExportAll", ("performance", "noReExportAll")), + ("noSkippedTests", ("suspicious", "noSkippedTests")), + ("noSuspiciousSemicolonInJsx", ("suspicious", "noSuspiciousSemicolonInJsx")), + ("noUndeclaredDependencies", ("correctness", "noUndeclaredDependencies")), + ("noUnusedFunctionParameters", ("correctness", "noUnusedFunctionParameters")), + ("noUselessStringConcat", ("complexity", "noUselessStringConcat")), + ("noUselessTernary", ("complexity", "noUselessTernary")), + ("noUselessUndefinedInitialization", ("complexity", "noUselessUndefinedInitialization")), + ("noYodaExpression", ("style", "noYodaExpression")), ("useArrayLiterals", ("correctness", "useArrayLiterals")), + ("useConsistentBuiltinInstantiation", ("style", "useConsistentBuiltinInstantiation")), + ("useDateNow", ("complexity", "useDateNow")), + ("useDefaultSwitchClause", ("style", "useDefaultSwitchClause")), + ("useErrorMessage", ("suspicious", "useErrorMessage")), + ("useExplicitLengthCheck", ("style", "useExplicitLengthCheck")), + ("useFocusableInteractive", ("a11y", "useFocusableInteractive")), + ("useImportExtensions", ("correctness", "useImportExtensions")), + ("useJsxKeyInIterable", ("correctness", "useJsxKeyInIterable") ), + ("useNodeAssertStrict", ("style", "useNodeAssertStrict")), + ("useNumberToFixedDigitsArgument", ("suspicious", "useNumberToFixedDigitsArgument")), + ("useSemanticElements", ("a11y", "useSemanticElements")), + ("useThrowNewError", ("style", "useThrowNewError")), + ("useThrowOnlyError", ("style", "useThrowOnlyError")), + ("useTopLevelRegex", ("performance", "useTopLevelRegex")), ]; impl Rule for NurseryRules { @@ -222,6 +231,10 @@ impl Rule for NurseryRules { let target_group_value_object = target_group_value.as_json_object_value()?; let current_rules = target_group_value_object.json_member_list(); + let mut current_rule_separators = target_group_value_object + .json_member_list() + .separators() + .flatten(); let current_rules_count = current_rules.len(); let mut separators = Vec::with_capacity(current_rules_count + 1); @@ -238,7 +251,11 @@ impl Rule for NurseryRules { break; } new_rules.push(current_rule.clone()); - separators.push(token(T![,])); + if let Some(current_rule_separator) = current_rule_separators.next() { + separators.push(current_rule_separator); + } else { + separators.push(token(T![,])); + } } // We only add the rule if the rule doesn't already exist in the target group @@ -275,12 +292,20 @@ impl Rule for NurseryRules { let object = node.value().ok()?; let object = object.as_json_object_value()?; + let mut separators: Vec<_> = + object.json_member_list().separators().flatten().collect(); let new_nursery_group: Vec<_> = object .json_member_list() .iter() - .filter_map(|node| { + .enumerate() + .filter_map(|(i, node)| { let node = node.ok()?; if &node == nursery_rule { + if i < separators.len() { + separators.remove(i); + } else { + separators.pop(); + } None } else { Some(node) @@ -293,7 +318,7 @@ impl Rule for NurseryRules { token(T![:]), AnyJsonValue::JsonObjectValue(json_object_value( token(T!['{']), - json_member_list(new_nursery_group, vec![]), + json_member_list(new_nursery_group, separators), token(T!['}']), )), ); diff --git a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRule.json.snap b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRule.json.snap index b28c56caf707..e77283089ebb 100644 --- a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRule.json.snap +++ b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRule.json.snap @@ -15,31 +15,3 @@ expression: renamedRule.json } ``` - -# Diagnostics -``` -renamedRule.json:5:9 migrate FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! This rule has been promoted to suspicious/noSuspiciousSemicolonInJsx. - - 3 │ "rules": { - 4 │ "nursery": { - > 5 │ "oldName": "error" - │ ^^^^^^^^^^^^^^^^^^ - 6 │ } - 7 │ } - - i Unsafe fix: Move the rule to the new stable group. - - 2 2 │ "linter": { - 3 3 │ "rules": { - 4 │ - ······"nursery":·{ - 5 │ - ········"oldName":·"error" - 4 │ + ······"nursery":{}, - 5 │ + ······"suspicious":{ - 6 │ + ········"noSuspiciousSemicolonInJsx":·"error" - 6 7 │ } - 7 8 │ } - - -``` diff --git a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json index 575fc30d9ced..970fae7ecc61 100644 --- a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json +++ b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json @@ -3,7 +3,7 @@ "rules": { "nursery": { "noExcessiveNestedTestSuites": "error", - "oldName": "error" + "useConsistentGridAreas": "error" } } } diff --git a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json.snap b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json.snap index 7033afa7f05c..04767470e1b3 100644 --- a/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json.snap +++ b/crates/biome_migrate/tests/specs/migrations/nurseryRules/renamedRuleAndNewRule.json.snap @@ -9,7 +9,7 @@ expression: renamedRuleAndNewRule.json "rules": { "nursery": { "noExcessiveNestedTestSuites": "error", - "oldName": "error" + "useConsistentGridAreas": "error" } } } @@ -27,7 +27,7 @@ renamedRuleAndNewRule.json:5:9 migrate FIXABLE ━━━━━━━━━━ 4 │ "nursery": { > 5 │ "noExcessiveNestedTestSuites": "error", │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 6 │ "oldName": "error" + 6 │ "useConsistentGridAreas": "error" 7 │ } i Unsafe fix: Move the rule to the new stable group. @@ -36,9 +36,9 @@ renamedRuleAndNewRule.json:5:9 migrate FIXABLE ━━━━━━━━━━ 3 3 │ "rules": { 4 │ - ······"nursery":·{ 5 │ - ········"noExcessiveNestedTestSuites":·"error", - 6 │ - ········"oldName":·"error" + 6 │ - ········"useConsistentGridAreas":·"error" 4 │ + ······"nursery":{ - 5 │ + ········"oldName":·"error"}, + 5 │ + ········"useConsistentGridAreas":·"error"}, 6 │ + ······"complexity":{ 7 │ + ········"noExcessiveNestedTestSuites":·"error" 7 8 │ } @@ -50,12 +50,12 @@ renamedRuleAndNewRule.json:5:9 migrate FIXABLE ━━━━━━━━━━ ``` renamedRuleAndNewRule.json:6:9 migrate FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ! This rule has been promoted to suspicious/noSuspiciousSemicolonInJsx. + ! This rule has been promoted to correctness/noInvalidGridAreas. 4 │ "nursery": { 5 │ "noExcessiveNestedTestSuites": "error", - > 6 │ "oldName": "error" - │ ^^^^^^^^^^^^^^^^^^ + > 6 │ "useConsistentGridAreas": "error" + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 7 │ } 8 │ } @@ -65,11 +65,11 @@ renamedRuleAndNewRule.json:6:9 migrate FIXABLE ━━━━━━━━━━ 3 3 │ "rules": { 4 │ - ······"nursery":·{ 5 │ - ········"noExcessiveNestedTestSuites":·"error", - 6 │ - ········"oldName":·"error" + 6 │ - ········"useConsistentGridAreas":·"error" 4 │ + ······"nursery":{ 5 │ + ········"noExcessiveNestedTestSuites":·"error"}, - 6 │ + ······"suspicious":{ - 7 │ + ········"noSuspiciousSemicolonInJsx":·"error" + 6 │ + ······"correctness":{ + 7 │ + ········"noInvalidGridAreas":·"error" 7 8 │ } 8 9 │ }