Skip to content

Commit

Permalink
refactor: add nursery rule migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Sep 12, 2024
1 parent 0afae5a commit 2725f67
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 87 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ Linter:
complexity/useSimpleNumberKeys
suspicious/noCommentText
complexity/noExcessiveNestedTestSuites
complexity/useDateNow
complexity/noUselessLabel
complexity/noUselessCatch
complexity/noUselessFragments
Expand Down
117 changes: 71 additions & 46 deletions crates/biome_migrate/src/analyzers/nursery_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,57 +70,66 @@ fn find_group_by_name(root: &JsonRoot, group_name: &str) -> Option<JsonMember> {
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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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!['}']),
)),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 │ }
```
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"rules": {
"nursery": {
"noExcessiveNestedTestSuites": "error",
"oldName": "error"
"useConsistentGridAreas": "error"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ expression: renamedRuleAndNewRule.json
"rules": {
"nursery": {
"noExcessiveNestedTestSuites": "error",
"oldName": "error"
"useConsistentGridAreas": "error"
}
}
}
Expand All @@ -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.
Expand All @@ -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 │ }
Expand All @@ -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 │ }
Expand All @@ -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 │ }
Expand Down

0 comments on commit 2725f67

Please sign in to comment.