diff --git a/.changeset/sharp-geckos-see.md b/.changeset/sharp-geckos-see.md new file mode 100644 index 000000000000..b6018e3decac --- /dev/null +++ b/.changeset/sharp-geckos-see.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#9314](https://github.com/biomejs/biome/issues/9314). Now Biome doesn't panic when `useAriaPropsForRole` is configured using an object. diff --git a/crates/biome_configuration/Cargo.toml b/crates/biome_configuration/Cargo.toml index 409663afec55..53348bbd96b6 100644 --- a/crates/biome_configuration/Cargo.toml +++ b/crates/biome_configuration/Cargo.toml @@ -60,9 +60,9 @@ tikv-jemallocator = { workspace = true } mimalloc = { workspace = true } [features] -default = [] -markdown = [] -schema = [ +default = [] +markdown = [] +schema = [ "biome_analyze/schema", "biome_formatter/schema", "biome_html_formatter/schema", @@ -74,6 +74,7 @@ schema = [ "biome_rule_options/schema", "dep:schemars", ] +test-utils = [] [lints] workspace = true diff --git a/crates/biome_configuration/src/generated.rs b/crates/biome_configuration/src/generated.rs index d1e538e1788f..2c5d5c758e94 100644 --- a/crates/biome_configuration/src/generated.rs +++ b/crates/biome_configuration/src/generated.rs @@ -1,6 +1,8 @@ mod assist; mod domain_selector; mod linter; +#[cfg(any(test, feature = "test-utils"))] +pub mod linter_options_check; pub use assist::push_to_analyzer_assist; pub use linter::push_to_analyzer_rules; diff --git a/crates/biome_configuration/src/generated/linter_options_check.rs b/crates/biome_configuration/src/generated/linter_options_check.rs new file mode 100644 index 000000000000..a8ed4a8de2a5 --- /dev/null +++ b/crates/biome_configuration/src/generated/linter_options_check.rs @@ -0,0 +1,2190 @@ +//! Generated file, do not edit by hand, see `xtask/codegen` + +#![expect(clippy::vec_init_then_push)] +use std::any::TypeId; + +/// Returns a list of `(group, rule, config_side_type_id)` for every lint rule. +/// +/// The `TypeId` is derived from the rule name convention: +/// `biome_rule_options::{snake_case_name}::{PascalCaseName}Options` +/// +/// This is the type that the configuration layer uses when constructing +/// [`RuleOptions`](biome_analyze::options::RuleOptions). If the rule's +/// `type Options` doesn't match, the `debug_assert_eq!` inside +/// `RuleOptions::value()` will fire at runtime. +pub fn config_side_rule_options_types() -> Vec<(&'static str, &'static str, TypeId)> { + let mut result = Vec::new(); + result.push(( + "a11y", + "noAccessKey", + TypeId::of::(), + )); + result.push(( + "performance", + "noAccumulatingSpread", + TypeId::of::(), + )); + result.push(("complexity", "noAdjacentSpacesInRegex", TypeId::of::())); + result.push(( + "suspicious", + "noAlert", + TypeId::of::(), + )); + result.push(( + "nursery", + "noAmbiguousAnchorText", + TypeId::of::(), + )); + result.push(("suspicious", "noApproximativeNumericConstant", TypeId::of::())); + result.push(( + "complexity", + "noArguments", + TypeId::of::(), + )); + result.push(("a11y", "noAriaHiddenOnFocusable", TypeId::of::())); + result.push(( + "a11y", + "noAriaUnsupportedElements", + TypeId::of::< + biome_rule_options::no_aria_unsupported_elements::NoAriaUnsupportedElementsOptions, + >(), + )); + result.push(( + "suspicious", + "noArrayIndexKey", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noAssignInExpressions", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noAsyncPromiseExecutor", + TypeId::of::( + ), + )); + result.push(( + "a11y", + "noAutofocus", + TypeId::of::(), + )); + result.push(( + "performance", + "noAwaitInLoops", + TypeId::of::(), + )); + result.push(( + "complexity", + "noBannedTypes", + TypeId::of::(), + )); + result.push(( + "performance", + "noBarrelFile", + TypeId::of::(), + )); + result.push(("nursery", "noBeforeInteractiveScriptOutsideDocument", TypeId::of::())); + result.push(( + "suspicious", + "noBiomeFirstException", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noBitwiseOperators", + TypeId::of::(), + )); + result.push(( + "security", + "noBlankTarget", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noCatchAssign", + TypeId::of::(), + )); + result.push(( + "correctness", + "noChildrenProp", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noClassAssign", + TypeId::of::(), + )); + result.push(( + "complexity", + "noCommaOperator", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noCommentText", + TypeId::of::(), + )); + result.push(( + "style", + "noCommonJs", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noCompareNegZero", + TypeId::of::(), + )); + result.push(( + "nursery", + "noConditionalExpect", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noConfusingLabels", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noConfusingVoidType", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noConsole", + TypeId::of::(), + )); + result.push(( + "correctness", + "noConstAssign", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noConstEnum", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noConstantBinaryExpressions", + TypeId::of::< + biome_rule_options::no_constant_binary_expressions::NoConstantBinaryExpressionsOptions, + >(), + )); + result.push(( + "correctness", + "noConstantCondition", + TypeId::of::(), + )); + result.push(( + "correctness", + "noConstantMathMinMaxClamp", + TypeId::of::< + biome_rule_options::no_constant_math_min_max_clamp::NoConstantMathMinMaxClampOptions, + >(), + )); + result.push(( + "correctness", + "noConstructorReturn", + TypeId::of::(), + )); + result.push(( + "nursery", + "noContinue", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noControlCharactersInRegex", + TypeId::of::< + biome_rule_options::no_control_characters_in_regex::NoControlCharactersInRegexOptions, + >(), + )); + result.push(( + "security", + "noDangerouslySetInnerHtml", + TypeId::of::< + biome_rule_options::no_dangerously_set_inner_html::NoDangerouslySetInnerHtmlOptions, + >(), + )); + result.push(("security", "noDangerouslySetInnerHtmlWithChildren", TypeId::of::())); + result.push(( + "suspicious", + "noDebugger", + TypeId::of::(), + )); + result.push(( + "style", + "noDefaultExport", + TypeId::of::(), + )); + result.push(( + "performance", + "noDelete", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDeprecatedImports", + TypeId::of::(), + )); + result.push(( + "nursery", + "noDeprecatedMediaType", + TypeId::of::(), + )); + result.push(( + "style", + "noDescendingSpecificity", + TypeId::of::( + ), + )); + result.push(( + "a11y", + "noDistractingElements", + TypeId::of::(), + )); + result.push(( + "nursery", + "noDivRegex", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDocumentCookie", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDocumentImportInPage", + TypeId::of::( + ), + )); + result.push(( + "style", + "noDoneCallback", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDoubleEquals", + TypeId::of::(), + )); + result.push(( + "nursery", + "noDuplicateArgumentNames", + TypeId::of::< + biome_rule_options::no_duplicate_argument_names::NoDuplicateArgumentNamesOptions, + >(), + )); + result.push(( + "suspicious", + "noDuplicateAtImportRules", + TypeId::of::< + biome_rule_options::no_duplicate_at_import_rules::NoDuplicateAtImportRulesOptions, + >(), + )); + result.push(( + "nursery", + "noDuplicateAttributes", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDuplicateCase", + TypeId::of::(), + )); + result.push(("suspicious", "noDuplicateClassMembers", TypeId::of::())); + result.push(( + "suspicious", + "noDuplicateCustomProperties", + TypeId::of::< + biome_rule_options::no_duplicate_custom_properties::NoDuplicateCustomPropertiesOptions, + >(), + )); + result.push(( + "suspicious", + "noDuplicateDependencies", + TypeId::of::( + ), + )); + result.push(( + "suspicious", + "noDuplicateElseIf", + TypeId::of::(), + )); + result.push(( + "nursery", + "noDuplicateEnumValueNames", + TypeId::of::< + biome_rule_options::no_duplicate_enum_value_names::NoDuplicateEnumValueNamesOptions, + >(), + )); + result.push(( + "nursery", + "noDuplicateEnumValues", + TypeId::of::(), + )); + result.push(("nursery", "noDuplicateFieldDefinitionNames", TypeId::of::())); + result.push(( + "suspicious", + "noDuplicateFields", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDuplicateFontNames", + TypeId::of::(), + )); + result.push(("nursery", "noDuplicateGraphqlOperationName", TypeId::of::())); + result.push(( + "nursery", + "noDuplicateInputFieldNames", + TypeId::of::< + biome_rule_options::no_duplicate_input_field_names::NoDuplicateInputFieldNamesOptions, + >(), + )); + result.push(( + "suspicious", + "noDuplicateJsxProps", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDuplicateObjectKeys", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDuplicateParameters", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noDuplicateProperties", + TypeId::of::(), + )); + result.push(("suspicious", "noDuplicateSelectorsKeyframeBlock", TypeId::of::())); + result.push(( + "suspicious", + "noDuplicateTestHooks", + TypeId::of::(), + )); + result.push(( + "nursery", + "noDuplicateVariableNames", + TypeId::of::< + biome_rule_options::no_duplicate_variable_names::NoDuplicateVariableNamesOptions, + >(), + )); + result.push(("nursery", "noDuplicatedSpreadProps", TypeId::of::())); + result.push(("performance", "noDynamicNamespaceImportAccess", TypeId::of::())); + result.push(( + "suspicious", + "noEmptyBlock", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noEmptyBlockStatements", + TypeId::of::( + ), + )); + result.push(("correctness", "noEmptyCharacterClassInRegex", TypeId::of::())); + result.push(( + "suspicious", + "noEmptyInterface", + TypeId::of::(), + )); + result.push(( + "nursery", + "noEmptyObjectKeys", + TypeId::of::(), + )); + result.push(( + "correctness", + "noEmptyPattern", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noEmptySource", + TypeId::of::(), + )); + result.push(( + "complexity", + "noEmptyTypeParameters", + TypeId::of::(), + )); + result.push(( + "style", + "noEnum", + TypeId::of::(), + )); + result.push(( + "nursery", + "noEqualsToNull", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noEvolvingTypes", + TypeId::of::(), + )); + result.push(( + "nursery", + "noExcessiveClassesPerFile", + TypeId::of::< + biome_rule_options::no_excessive_classes_per_file::NoExcessiveClassesPerFileOptions, + >(), + )); + result.push(("complexity", "noExcessiveCognitiveComplexity", TypeId::of::())); + result.push(("nursery", "noExcessiveLinesPerFile", TypeId::of::())); + result.push(( + "complexity", + "noExcessiveLinesPerFunction", + TypeId::of::< + biome_rule_options::no_excessive_lines_per_function::NoExcessiveLinesPerFunctionOptions, + >(), + )); + result.push(( + "complexity", + "noExcessiveNestedTestSuites", + TypeId::of::< + biome_rule_options::no_excessive_nested_test_suites::NoExcessiveNestedTestSuitesOptions, + >(), + )); + result.push(( + "suspicious", + "noExplicitAny", + TypeId::of::(), + )); + result.push(( + "style", + "noExportedImports", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noExportsInTest", + TypeId::of::(), + )); + result.push(( + "complexity", + "noExtraBooleanCast", + TypeId::of::(), + )); + result.push(("suspicious", "noExtraNonNullAssertion", TypeId::of::())); + result.push(( + "suspicious", + "noFallthroughSwitchClause", + TypeId::of::< + biome_rule_options::no_fallthrough_switch_clause::NoFallthroughSwitchClauseOptions, + >(), + )); + result.push(( + "complexity", + "noFlatMapIdentity", + TypeId::of::(), + )); + result.push(( + "nursery", + "noFloatingClasses", + TypeId::of::(), + )); + result.push(( + "nursery", + "noFloatingPromises", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noFocusedTests", + TypeId::of::(), + )); + result.push(( + "complexity", + "noForEach", + TypeId::of::(), + )); + result.push(( + "nursery", + "noForIn", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noFunctionAssign", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noGlobalAssign", + TypeId::of::(), + )); + result.push(("correctness", "noGlobalDirnameFilename", TypeId::of::())); + result.push(( + "security", + "noGlobalEval", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noGlobalIsFinite", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noGlobalIsNan", + TypeId::of::(), + )); + result.push(( + "correctness", + "noGlobalObjectCalls", + TypeId::of::(), + )); + result.push(( + "style", + "noHeadElement", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noHeadImportInDocument", + TypeId::of::( + ), + )); + result.push(( + "a11y", + "noHeaderScope", + TypeId::of::(), + )); + result.push(( + "nursery", + "noHexColors", + TypeId::of::(), + )); + result.push(( + "performance", + "noImgElement", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noImplicitAnyLet", + TypeId::of::(), + )); + result.push(( + "style", + "noImplicitBoolean", + TypeId::of::(), + )); + result.push(( + "complexity", + "noImplicitCoercions", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noImportAssign", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noImportCycles", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noImportantInKeyframe", + TypeId::of::(), + )); + result.push(( + "complexity", + "noImportantStyles", + TypeId::of::(), + )); + result.push(( + "nursery", + "noIncrementDecrement", + TypeId::of::(), + )); + result.push(( + "style", + "noInferrableTypes", + TypeId::of::(), + )); + result.push(( + "correctness", + "noInnerDeclarations", + TypeId::of::(), + )); + result.push(("a11y", "noInteractiveElementToNoninteractiveRole", TypeId::of::())); + result.push(("correctness", "noInvalidBuiltinInstantiation", TypeId::of::())); + result.push(( + "correctness", + "noInvalidConstructorSuper", + TypeId::of::< + biome_rule_options::no_invalid_constructor_super::NoInvalidConstructorSuperOptions, + >(), + )); + result.push(("correctness", "noInvalidDirectionInLinearGradient", TypeId::of::())); + result.push(( + "correctness", + "noInvalidGridAreas", + TypeId::of::(), + )); + result.push(("correctness", "noInvalidPositionAtImportRule", TypeId::of::())); + result.push(("correctness", "noInvalidUseBeforeDeclaration", TypeId::of::())); + result.push(( + "suspicious", + "noIrregularWhitespace", + TypeId::of::(), + )); + result.push(( + "style", + "noJsxLiterals", + TypeId::of::(), + )); + result.push(( + "nursery", + "noJsxPropsBind", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noLabelVar", + TypeId::of::(), + )); + result.push(( + "a11y", + "noLabelWithoutControl", + TypeId::of::(), + )); + result.push(( + "nursery", + "noLeakedRender", + TypeId::of::(), + )); + result.push(( + "style", + "noMagicNumbers", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noMisleadingCharacterClass", + TypeId::of::< + biome_rule_options::no_misleading_character_class::NoMisleadingCharacterClassOptions, + >(), + )); + result.push(("suspicious", "noMisleadingInstantiator", TypeId::of::())); + result.push(( + "suspicious", + "noMisplacedAssertion", + TypeId::of::(), + )); + result.push(("suspicious", "noMisrefactoredShorthandAssign", TypeId::of::())); + result.push(( + "correctness", + "noMissingVarFunction", + TypeId::of::(), + )); + result.push(( + "nursery", + "noMisusedPromises", + TypeId::of::(), + )); + result.push(( + "nursery", + "noMultiAssign", + TypeId::of::(), + )); + result.push(( + "nursery", + "noMultiStr", + TypeId::of::(), + )); + result.push(( + "style", + "noNamespace", + TypeId::of::(), + )); + result.push(( + "performance", + "noNamespaceImport", + TypeId::of::(), + )); + result.push(( + "style", + "noNegationElse", + TypeId::of::(), + )); + result.push(("correctness", "noNestedComponentDefinitions", TypeId::of::())); + result.push(( + "nursery", + "noNestedPromises", + TypeId::of::(), + )); + result.push(( + "style", + "noNestedTernary", + TypeId::of::(), + )); + result.push(( + "correctness", + "noNextAsyncClientComponent", + TypeId::of::< + biome_rule_options::no_next_async_client_component::NoNextAsyncClientComponentOptions, + >(), + )); + result.push(( + "correctness", + "noNodejsModules", + TypeId::of::(), + )); + result.push(("suspicious", "noNonNullAssertedOptionalChain", TypeId::of::())); + result.push(( + "style", + "noNonNullAssertion", + TypeId::of::(), + )); + result.push(("a11y", "noNoninteractiveElementInteractions", TypeId::of::())); + result.push(("a11y", "noNoninteractiveElementToInteractiveRole", TypeId::of::())); + result.push(("a11y", "noNoninteractiveTabindex", TypeId::of::())); + result.push(("correctness", "noNonoctalDecimalEscape", TypeId::of::())); + result.push(( + "suspicious", + "noOctalEscape", + TypeId::of::(), + )); + result.push(( + "style", + "noParameterAssign", + TypeId::of::(), + )); + result.push(( + "style", + "noParameterProperties", + TypeId::of::(), + )); + result.push(("nursery", "noParametersOnlyUsedInRecursion", TypeId::of::())); + result.push(( + "nursery", + "noPlaywrightElementHandle", + TypeId::of::< + biome_rule_options::no_playwright_element_handle::NoPlaywrightElementHandleOptions, + >(), + )); + result.push(( + "nursery", + "noPlaywrightEval", + TypeId::of::(), + )); + result.push(("nursery", "noPlaywrightForceOption", TypeId::of::())); + result.push(( + "nursery", + "noPlaywrightMissingAwait", + TypeId::of::< + biome_rule_options::no_playwright_missing_await::NoPlaywrightMissingAwaitOptions, + >(), + )); + result.push(( + "nursery", + "noPlaywrightNetworkidle", + TypeId::of::( + ), + )); + result.push(( + "nursery", + "noPlaywrightPagePause", + TypeId::of::(), + )); + result.push(( + "nursery", + "noPlaywrightUselessAwait", + TypeId::of::< + biome_rule_options::no_playwright_useless_await::NoPlaywrightUselessAwaitOptions, + >(), + )); + result.push(("nursery", "noPlaywrightWaitForNavigation", TypeId::of::())); + result.push(( + "nursery", + "noPlaywrightWaitForSelector", + TypeId::of::< + biome_rule_options::no_playwright_wait_for_selector::NoPlaywrightWaitForSelectorOptions, + >(), + )); + result.push(( + "nursery", + "noPlaywrightWaitForTimeout", + TypeId::of::< + biome_rule_options::no_playwright_wait_for_timeout::NoPlaywrightWaitForTimeoutOptions, + >(), + )); + result.push(( + "a11y", + "noPositiveTabindex", + TypeId::of::(), + )); + result.push(( + "correctness", + "noPrecisionLoss", + TypeId::of::(), + )); + result.push(( + "correctness", + "noPrivateImports", + TypeId::of::(), + )); + result.push(( + "style", + "noProcessEnv", + TypeId::of::(), + )); + result.push(( + "correctness", + "noProcessGlobal", + TypeId::of::(), + )); + result.push(( + "nursery", + "noProto", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noPrototypeBuiltins", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noQuickfixBiome", + TypeId::of::(), + )); + result.push(( + "correctness", + "noQwikUseVisibleTask", + TypeId::of::(), + )); + result.push(( + "performance", + "noReExportAll", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noReactForwardRef", + TypeId::of::(), + )); + result.push(( + "correctness", + "noReactPropAssignments", + TypeId::of::( + ), + )); + result.push(( + "suspicious", + "noReactSpecificProps", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noRedeclare", + TypeId::of::(), + )); + result.push(( + "a11y", + "noRedundantAlt", + TypeId::of::(), + )); + result.push(( + "nursery", + "noRedundantDefaultExport", + TypeId::of::< + biome_rule_options::no_redundant_default_export::NoRedundantDefaultExportOptions, + >(), + )); + result.push(( + "a11y", + "noRedundantRoles", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noRedundantUseStrict", + TypeId::of::(), + )); + result.push(( + "correctness", + "noRenderReturnValue", + TypeId::of::(), + )); + result.push(( + "correctness", + "noRestrictedElements", + TypeId::of::(), + )); + result.push(( + "style", + "noRestrictedGlobals", + TypeId::of::(), + )); + result.push(( + "style", + "noRestrictedImports", + TypeId::of::(), + )); + result.push(( + "style", + "noRestrictedTypes", + TypeId::of::(), + )); + result.push(( + "nursery", + "noReturnAssign", + TypeId::of::(), + )); + result.push(( + "nursery", + "noRootType", + TypeId::of::(), + )); + result.push(( + "nursery", + "noScriptUrl", + TypeId::of::(), + )); + result.push(( + "security", + "noSecrets", + TypeId::of::(), + )); + result.push(( + "correctness", + "noSelfAssign", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noSelfCompare", + TypeId::of::(), + )); + result.push(( + "correctness", + "noSetterReturn", + TypeId::of::(), + )); + result.push(( + "nursery", + "noShadow", + TypeId::of::(), + )); + result.push(("suspicious", "noShadowRestrictedNames", TypeId::of::())); + result.push(("suspicious", "noShorthandPropertyOverrides", TypeId::of::())); + result.push(( + "style", + "noShoutyConstants", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noSkippedTests", + TypeId::of::(), + )); + result.push(( + "correctness", + "noSolidDestructuredProps", + TypeId::of::< + biome_rule_options::no_solid_destructured_props::NoSolidDestructuredPropsOptions, + >(), + )); + result.push(( + "suspicious", + "noSparseArray", + TypeId::of::(), + )); + result.push(( + "a11y", + "noStaticElementInteractions", + TypeId::of::< + biome_rule_options::no_static_element_interactions::NoStaticElementInteractionsOptions, + >(), + )); + result.push(( + "complexity", + "noStaticOnlyClass", + TypeId::of::(), + )); + result.push(( + "correctness", + "noStringCaseMismatch", + TypeId::of::(), + )); + result.push(( + "style", + "noSubstr", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noSuspiciousSemicolonInJsx", + TypeId::of::< + biome_rule_options::no_suspicious_semicolon_in_jsx::NoSuspiciousSemicolonInJsxOptions, + >(), + )); + result.push(( + "a11y", + "noSvgWithoutTitle", + TypeId::of::(), + )); + result.push(( + "correctness", + "noSwitchDeclarations", + TypeId::of::(), + )); + result.push(( + "nursery", + "noSyncScripts", + TypeId::of::(), + )); + result.push(("suspicious", "noTemplateCurlyInString", TypeId::of::())); + result.push(( + "nursery", + "noTernary", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noThenProperty", + TypeId::of::(), + )); + result.push(( + "complexity", + "noThisInStatic", + TypeId::of::(), + )); + result.push(( + "nursery", + "noTopLevelLiterals", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noTsIgnore", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noUnassignedVariables", + TypeId::of::(), + )); + result.push(("correctness", "noUndeclaredDependencies", TypeId::of::())); + result.push(( + "nursery", + "noUndeclaredEnvVars", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUndeclaredVariables", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noUnknownAtRules", + TypeId::of::(), + )); + result.push(( + "nursery", + "noUnknownAttribute", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnknownFunction", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnknownMediaFeatureName", + TypeId::of::< + biome_rule_options::no_unknown_media_feature_name::NoUnknownMediaFeatureNameOptions, + >(), + )); + result.push(( + "correctness", + "noUnknownProperty", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnknownPseudoClass", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnknownPseudoElement", + TypeId::of::( + ), + )); + result.push(( + "correctness", + "noUnknownTypeSelector", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnknownUnit", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnmatchableAnbSelector", + TypeId::of::< + biome_rule_options::no_unmatchable_anb_selector::NoUnmatchableAnbSelectorOptions, + >(), + )); + result.push(( + "nursery", + "noUnnecessaryConditions", + TypeId::of::( + ), + )); + result.push(( + "correctness", + "noUnreachable", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnreachableSuper", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnresolvedImports", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noUnsafeDeclarationMerging", + TypeId::of::< + biome_rule_options::no_unsafe_declaration_merging::NoUnsafeDeclarationMergingOptions, + >(), + )); + result.push(( + "correctness", + "noUnsafeFinally", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noUnsafeNegation", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnsafeOptionalChaining", + TypeId::of::< + biome_rule_options::no_unsafe_optional_chaining::NoUnsafeOptionalChainingOptions, + >(), + )); + result.push(( + "suspicious", + "noUnusedExpressions", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnusedFunctionParameters", + TypeId::of::< + biome_rule_options::no_unused_function_parameters::NoUnusedFunctionParametersOptions, + >(), + )); + result.push(( + "correctness", + "noUnusedImports", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnusedLabels", + TypeId::of::(), + )); + result.push(( + "correctness", + "noUnusedPrivateClassMembers", + TypeId::of::< + biome_rule_options::no_unused_private_class_members::NoUnusedPrivateClassMembersOptions, + >(), + )); + result.push(("style", "noUnusedTemplateLiteral", TypeId::of::())); + result.push(( + "correctness", + "noUnusedVariables", + TypeId::of::(), + )); + result.push(( + "performance", + "noUnwantedPolyfillio", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessCatch", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessCatchBinding", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessConstructor", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessContinue", + TypeId::of::(), + )); + result.push(( + "style", + "noUselessElse", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessEmptyExport", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessEscapeInRegex", + TypeId::of::( + ), + )); + result.push(("suspicious", "noUselessEscapeInString", TypeId::of::())); + result.push(( + "complexity", + "noUselessFragments", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessLabel", + TypeId::of::(), + )); + result.push(("complexity", "noUselessLoneBlockStatements", TypeId::of::())); + result.push(( + "suspicious", + "noUselessRegexBackrefs", + TypeId::of::( + ), + )); + result.push(( + "complexity", + "noUselessRename", + TypeId::of::(), + )); + result.push(( + "nursery", + "noUselessReturn", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessStringConcat", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessStringRaw", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessSwitchCase", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessTernary", + TypeId::of::(), + )); + result.push(( + "complexity", + "noUselessThisAlias", + TypeId::of::(), + )); + result.push(("complexity", "noUselessTypeConstraint", TypeId::of::())); + result.push(( + "complexity", + "noUselessUndefined", + TypeId::of::(), + )); + result.push(("complexity", "noUselessUndefinedInitialization", TypeId::of::())); + result.push(( + "style", + "noValueAtRule", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noVar", + TypeId::of::(), + )); + result.push(( + "complexity", + "noVoid", + TypeId::of::(), + )); + result.push(( + "correctness", + "noVoidElementsWithChildren", + TypeId::of::< + biome_rule_options::no_void_elements_with_children::NoVoidElementsWithChildrenOptions, + >(), + )); + result.push(( + "correctness", + "noVoidTypeReturn", + TypeId::of::(), + )); + result.push(( + "nursery", + "noVueArrowFuncInWatch", + TypeId::of::( + ), + )); + result.push(( + "correctness", + "noVueDataObjectDeclaration", + TypeId::of::< + biome_rule_options::no_vue_data_object_declaration::NoVueDataObjectDeclarationOptions, + >(), + )); + result.push(( + "correctness", + "noVueDuplicateKeys", + TypeId::of::(), + )); + result.push(( + "nursery", + "noVueOptionsApi", + TypeId::of::(), + )); + result.push(( + "nursery", + "noVueRefAsOperand", + TypeId::of::(), + )); + result.push(( + "correctness", + "noVueReservedKeys", + TypeId::of::(), + )); + result.push(( + "correctness", + "noVueReservedProps", + TypeId::of::(), + )); + result.push(("correctness", "noVueSetupPropsReactivityLoss", TypeId::of::())); + result.push(( + "nursery", + "noVueVIfWithVFor", + TypeId::of::(), + )); + result.push(( + "suspicious", + "noWith", + TypeId::of::(), + )); + result.push(( + "style", + "noYodaExpression", + TypeId::of::(), + )); + result.push(("suspicious", "useAdjacentOverloadSignatures", TypeId::of::())); + result.push(( + "a11y", + "useAltText", + TypeId::of::(), + )); + result.push(( + "a11y", + "useAnchorContent", + TypeId::of::(), + )); + result.push(("a11y", "useAriaActivedescendantWithTabindex", TypeId::of::())); + result.push(( + "a11y", + "useAriaPropsForRole", + TypeId::of::(), + )); + result.push(("a11y", "useAriaPropsSupportedByRole", TypeId::of::())); + result.push(( + "style", + "useArrayLiterals", + TypeId::of::(), + )); + result.push(( + "nursery", + "useArraySome", + TypeId::of::(), + )); + result.push(( + "nursery", + "useArraySortCompare", + TypeId::of::(), + )); + result.push(( + "complexity", + "useArrowFunction", + TypeId::of::(), + )); + result.push(( + "style", + "useAsConstAssertion", + TypeId::of::(), + )); + result.push(( + "style", + "useAtIndex", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useAwait", + TypeId::of::(), + )); + result.push(( + "nursery", + "useAwaitThenable", + TypeId::of::(), + )); + result.push(( + "nursery", + "useBaseline", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useBiomeIgnoreFolder", + TypeId::of::(), + )); + result.push(( + "style", + "useBlockStatements", + TypeId::of::(), + )); + result.push(( + "a11y", + "useButtonType", + TypeId::of::(), + )); + result.push(( + "style", + "useCollapsedElseIf", + TypeId::of::(), + )); + result.push(( + "style", + "useCollapsedIf", + TypeId::of::(), + )); + result.push(("style", "useComponentExportOnlyModules", TypeId::of::())); + result.push(( + "style", + "useConsistentArrayType", + TypeId::of::( + ), + )); + result.push(( + "style", + "useConsistentArrowReturn", + TypeId::of::< + biome_rule_options::use_consistent_arrow_return::UseConsistentArrowReturnOptions, + >(), + )); + result.push(("style", "useConsistentBuiltinInstantiation", TypeId::of::())); + result.push(( + "style", + "useConsistentCurlyBraces", + TypeId::of::< + biome_rule_options::use_consistent_curly_braces::UseConsistentCurlyBracesOptions, + >(), + )); + result.push(( + "nursery", + "useConsistentEnumValueType", + TypeId::of::< + biome_rule_options::use_consistent_enum_value_type::UseConsistentEnumValueTypeOptions, + >(), + )); + result.push(("nursery", "useConsistentGraphqlDescriptions", TypeId::of::())); + result.push(("style", "useConsistentMemberAccessibility", TypeId::of::())); + result.push(("nursery", "useConsistentMethodSignatures", TypeId::of::())); + result.push(("style", "useConsistentObjectDefinitions", TypeId::of::())); + result.push(("style", "useConsistentTypeDefinitions", TypeId::of::())); + result.push(( + "style", + "useConst", + TypeId::of::(), + )); + result.push(( + "complexity", + "useDateNow", + TypeId::of::(), + )); + result.push(("style", "useDefaultParameterLast", TypeId::of::())); + result.push(( + "style", + "useDefaultSwitchClause", + TypeId::of::( + ), + )); + result.push(( + "suspicious", + "useDefaultSwitchClauseLast", + TypeId::of::< + biome_rule_options::use_default_switch_clause_last::UseDefaultSwitchClauseLastOptions, + >(), + )); + result.push(( + "suspicious", + "useDeprecatedDate", + TypeId::of::(), + )); + result.push(( + "style", + "useDeprecatedReason", + TypeId::of::(), + )); + result.push(( + "nursery", + "useDestructuring", + TypeId::of::(), + )); + result.push(( + "style", + "useEnumInitializers", + TypeId::of::(), + )); + result.push(( + "nursery", + "useErrorCause", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useErrorMessage", + TypeId::of::(), + )); + result.push(( + "correctness", + "useExhaustiveDependencies", + TypeId::of::< + biome_rule_options::use_exhaustive_dependencies::UseExhaustiveDependenciesOptions, + >(), + )); + result.push(( + "nursery", + "useExhaustiveSwitchCases", + TypeId::of::< + biome_rule_options::use_exhaustive_switch_cases::UseExhaustiveSwitchCasesOptions, + >(), + )); + result.push(( + "nursery", + "useExpect", + TypeId::of::(), + )); + result.push(( + "style", + "useExplicitLengthCheck", + TypeId::of::( + ), + )); + result.push(( + "nursery", + "useExplicitType", + TypeId::of::(), + )); + result.push(( + "style", + "useExponentiationOperator", + TypeId::of::< + biome_rule_options::use_exponentiation_operator::UseExponentiationOperatorOptions, + >(), + )); + result.push(( + "style", + "useExportType", + TypeId::of::(), + )); + result.push(( + "style", + "useExportsLast", + TypeId::of::(), + )); + result.push(( + "style", + "useFilenamingConvention", + TypeId::of::( + ), + )); + result.push(( + "nursery", + "useFind", + TypeId::of::(), + )); + result.push(( + "complexity", + "useFlatMap", + TypeId::of::(), + )); + result.push(( + "a11y", + "useFocusableInteractive", + TypeId::of::( + ), + )); + result.push(( + "style", + "useForOf", + TypeId::of::(), + )); + result.push(( + "style", + "useFragmentSyntax", + TypeId::of::(), + )); + result.push(( + "a11y", + "useGenericFontNames", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useGetterReturn", + TypeId::of::(), + )); + result.push(( + "nursery", + "useGlobalThis", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useGoogleFontDisplay", + TypeId::of::(), + )); + result.push(("performance", "useGoogleFontPreconnect", TypeId::of::())); + result.push(( + "correctness", + "useGraphqlNamedOperations", + TypeId::of::< + biome_rule_options::use_graphql_named_operations::UseGraphqlNamedOperationsOptions, + >(), + )); + result.push(( + "style", + "useGraphqlNamingConvention", + TypeId::of::< + biome_rule_options::use_graphql_naming_convention::UseGraphqlNamingConventionOptions, + >(), + )); + result.push(("style", "useGroupedAccessorPairs", TypeId::of::())); + result.push(( + "suspicious", + "useGuardForIn", + TypeId::of::(), + )); + result.push(( + "a11y", + "useHeadingContent", + TypeId::of::(), + )); + result.push(( + "correctness", + "useHookAtTopLevel", + TypeId::of::(), + )); + result.push(( + "a11y", + "useHtmlLang", + TypeId::of::(), + )); + result.push(( + "a11y", + "useIframeTitle", + TypeId::of::(), + )); + result.push(( + "correctness", + "useImageSize", + TypeId::of::(), + )); + result.push(( + "correctness", + "useImportExtensions", + TypeId::of::(), + )); + result.push(( + "style", + "useImportType", + TypeId::of::(), + )); + result.push(( + "nursery", + "useImportsFirst", + TypeId::of::(), + )); + result.push(( + "complexity", + "useIndexOf", + TypeId::of::(), + )); + result.push(( + "nursery", + "useInlineScriptId", + TypeId::of::(), + )); + result.push(( + "nursery", + "useInputName", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useIsArray", + TypeId::of::(), + )); + result.push(( + "correctness", + "useIsNan", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useIterableCallbackReturn", + TypeId::of::< + biome_rule_options::use_iterable_callback_return::UseIterableCallbackReturnOptions, + >(), + )); + result.push(("correctness", "useJsonImportAttributes", TypeId::of::())); + result.push(( + "correctness", + "useJsxKeyInIterable", + TypeId::of::(), + )); + result.push(( + "a11y", + "useKeyWithClickEvents", + TypeId::of::(), + )); + result.push(( + "a11y", + "useKeyWithMouseEvents", + TypeId::of::(), + )); + result.push(( + "style", + "useLiteralEnumMembers", + TypeId::of::(), + )); + result.push(( + "complexity", + "useLiteralKeys", + TypeId::of::(), + )); + result.push(( + "nursery", + "useLoneAnonymousOperation", + TypeId::of::< + biome_rule_options::use_lone_anonymous_operation::UseLoneAnonymousOperationOptions, + >(), + )); + result.push(( + "nursery", + "useLoneExecutableDefinition", + TypeId::of::< + biome_rule_options::use_lone_executable_definition::UseLoneExecutableDefinitionOptions, + >(), + )); + result.push(( + "complexity", + "useMaxParams", + TypeId::of::(), + )); + result.push(( + "a11y", + "useMediaCaption", + TypeId::of::(), + )); + result.push(( + "nursery", + "useNamedCaptureGroup", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useNamespaceKeyword", + TypeId::of::(), + )); + result.push(( + "style", + "useNamingConvention", + TypeId::of::(), + )); + result.push(( + "style", + "useNodeAssertStrict", + TypeId::of::(), + )); + result.push(("style", "useNodejsImportProtocol", TypeId::of::())); + result.push(( + "nursery", + "useNullishCoalescing", + TypeId::of::(), + )); + result.push(( + "style", + "useNumberNamespace", + TypeId::of::(), + )); + result.push(("suspicious", "useNumberToFixedDigitsArgument", TypeId::of::())); + result.push(( + "complexity", + "useNumericLiterals", + TypeId::of::(), + )); + result.push(( + "style", + "useNumericSeparators", + TypeId::of::(), + )); + result.push(( + "style", + "useObjectSpread", + TypeId::of::(), + )); + result.push(( + "complexity", + "useOptionalChain", + TypeId::of::(), + )); + result.push(( + "correctness", + "useParseIntRadix", + TypeId::of::(), + )); + result.push(("nursery", "usePlaywrightValidDescribeCallback", TypeId::of::())); + result.push(( + "correctness", + "useQwikClasslist", + TypeId::of::(), + )); + result.push(( + "correctness", + "useQwikMethodUsage", + TypeId::of::(), + )); + result.push(( + "correctness", + "useQwikValidLexicalScope", + TypeId::of::< + biome_rule_options::use_qwik_valid_lexical_scope::UseQwikValidLexicalScopeOptions, + >(), + )); + result.push(( + "style", + "useReactFunctionComponents", + TypeId::of::< + biome_rule_options::use_react_function_components::UseReactFunctionComponentsOptions, + >(), + )); + result.push(( + "style", + "useReadonlyClassProperties", + TypeId::of::< + biome_rule_options::use_readonly_class_properties::UseReadonlyClassPropertiesOptions, + >(), + )); + result.push(( + "complexity", + "useRegexLiterals", + TypeId::of::(), + )); + result.push(( + "nursery", + "useRegexpExec", + TypeId::of::(), + )); + result.push(( + "nursery", + "useRequiredScripts", + TypeId::of::(), + )); + result.push(( + "nursery", + "useScopedStyles", + TypeId::of::(), + )); + result.push(( + "style", + "useSelfClosingElements", + TypeId::of::( + ), + )); + result.push(( + "a11y", + "useSemanticElements", + TypeId::of::(), + )); + result.push(( + "style", + "useShorthandAssign", + TypeId::of::(), + )); + result.push(( + "style", + "useShorthandFunctionType", + TypeId::of::< + biome_rule_options::use_shorthand_function_type::UseShorthandFunctionTypeOptions, + >(), + )); + result.push(( + "complexity", + "useSimpleNumberKeys", + TypeId::of::(), + )); + result.push(("complexity", "useSimplifiedLogicExpression", TypeId::of::())); + result.push(( + "correctness", + "useSingleJsDocAsterisk", + TypeId::of::( + ), + )); + result.push(( + "style", + "useSingleVarDeclarator", + TypeId::of::( + ), + )); + result.push(( + "performance", + "useSolidForComponent", + TypeId::of::(), + )); + result.push(( + "nursery", + "useSortedClasses", + TypeId::of::(), + )); + result.push(( + "nursery", + "useSpread", + TypeId::of::(), + )); + result.push(( + "suspicious", + "useStaticResponseMethods", + TypeId::of::< + biome_rule_options::use_static_response_methods::UseStaticResponseMethodsOptions, + >(), + )); + result.push(( + "suspicious", + "useStrictMode", + TypeId::of::(), + )); + result.push(( + "style", + "useSymbolDescription", + TypeId::of::(), + )); + result.push(( + "style", + "useTemplate", + TypeId::of::(), + )); + result.push(( + "style", + "useThrowNewError", + TypeId::of::(), + )); + result.push(( + "style", + "useThrowOnlyError", + TypeId::of::(), + )); + result.push(( + "performance", + "useTopLevelRegex", + TypeId::of::(), + )); + result.push(( + "style", + "useTrimStartEnd", + TypeId::of::(), + )); + result.push(( + "nursery", + "useUnicodeRegex", + TypeId::of::(), + )); + result.push(( + "style", + "useUnifiedTypeSignatures", + TypeId::of::< + biome_rule_options::use_unified_type_signatures::UseUnifiedTypeSignaturesOptions, + >(), + )); + result.push(( + "correctness", + "useUniqueElementIds", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidAnchor", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidAriaProps", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidAriaRole", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidAriaValues", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidAutocomplete", + TypeId::of::(), + )); + result.push(( + "correctness", + "useValidForDirection", + TypeId::of::(), + )); + result.push(( + "a11y", + "useValidLang", + TypeId::of::(), + )); + result.push(( + "correctness", + "useValidTypeof", + TypeId::of::(), + )); + result.push(("nursery", "useVueConsistentDefinePropsDeclaration", TypeId::of::())); + result.push(( + "nursery", + "useVueConsistentVBindStyle", + TypeId::of::< + biome_rule_options::use_vue_consistent_v_bind_style::UseVueConsistentVBindStyleOptions, + >(), + )); + result.push(( + "nursery", + "useVueConsistentVOnStyle", + TypeId::of::< + biome_rule_options::use_vue_consistent_v_on_style::UseVueConsistentVOnStyleOptions, + >(), + )); + result.push(("nursery", "useVueDefineMacrosOrder", TypeId::of::())); + result.push(( + "nursery", + "useVueHyphenatedAttributes", + TypeId::of::< + biome_rule_options::use_vue_hyphenated_attributes::UseVueHyphenatedAttributesOptions, + >(), + )); + result.push(("nursery", "useVueMultiWordComponentNames", TypeId::of::())); + result.push(( + "nursery", + "useVueVForKey", + TypeId::of::(), + )); + result.push(("nursery", "useVueValidTemplateRoot", TypeId::of::())); + result.push(( + "nursery", + "useVueValidVBind", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVCloak", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVElse", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVElseIf", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVHtml", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVIf", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVOn", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVOnce", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVPre", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueValidVText", + TypeId::of::(), + )); + result.push(( + "nursery", + "useVueVapor", + TypeId::of::(), + )); + result.push(( + "complexity", + "useWhile", + TypeId::of::(), + )); + result.push(( + "correctness", + "useYield", + TypeId::of::(), + )); + result +} diff --git a/crates/biome_html_analyze/src/lint/a11y/use_aria_props_for_role.rs b/crates/biome_html_analyze/src/lint/a11y/use_aria_props_for_role.rs index ead9b61d881a..54c6cfc4362b 100644 --- a/crates/biome_html_analyze/src/lint/a11y/use_aria_props_for_role.rs +++ b/crates/biome_html_analyze/src/lint/a11y/use_aria_props_for_role.rs @@ -6,7 +6,7 @@ use biome_console::markup; use biome_diagnostics::Severity; use biome_html_syntax::{AnyHtmlElement, HtmlAttribute}; use biome_rowan::{AstNode, Text}; -use biome_rule_options::use_aria_props_supported_by_role::UseAriaPropsSupportedByRoleOptions; +use biome_rule_options::use_aria_props_for_role::UseAriaPropsForRoleOptions; declare_lint_rule! { /// Enforce that elements with ARIA roles must have all required ARIA attributes for that role. @@ -64,7 +64,7 @@ impl Rule for UseAriaPropsForRole { type Query = Ast; type State = UseAriaPropsForRoleState; type Signals = Option; - type Options = UseAriaPropsSupportedByRoleOptions; + type Options = UseAriaPropsForRoleOptions; fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); diff --git a/crates/biome_service/Cargo.toml b/crates/biome_service/Cargo.toml index f8d823184694..da6d7e644097 100644 --- a/crates/biome_service/Cargo.toml +++ b/crates/biome_service/Cargo.toml @@ -86,7 +86,8 @@ tracing = { workspace = true, features = ["attributes", "log"] web-time = { workspace = true } [dev-dependencies] -insta = { workspace = true } +biome_configuration = { workspace = true, features = ["test-utils"] } +insta = { workspace = true } [features] js_plugin = ["biome_plugin_loader/js_plugin"] diff --git a/crates/biome_service/src/configuration.rs b/crates/biome_service/src/configuration.rs index cccad909cfc6..da44d3af6076 100644 --- a/crates/biome_service/src/configuration.rs +++ b/crates/biome_service/src/configuration.rs @@ -1148,3 +1148,138 @@ mod tests { ); } } + +#[cfg(test)] +mod configuration_harness { + use biome_analyze::{GroupCategory, Queryable, RegistryVisitor, Rule, RuleCategory, RuleGroup}; + use biome_configuration::generated::linter_options_check::config_side_rule_options_types; + use biome_css_syntax::CssLanguage; + use biome_graphql_syntax::GraphqlLanguage; + use biome_html_syntax::HtmlLanguage; + use biome_js_syntax::JsLanguage; + use biome_json_syntax::JsonLanguage; + use std::any::TypeId; + use std::collections::HashMap; + + /// Collects `TypeId::of::()` for every rule via the registry visitor. + /// This is the "rule side" type — what the rule declares as `type Options`. + struct RuleSideOptionsVisitor { + types: HashMap<(&'static str, &'static str), TypeId>, + } + + impl RuleSideOptionsVisitor { + fn collect_rule(&mut self) + where + R: Rule> + 'static, + { + let category = ::Category::CATEGORY; + if !matches!(category, RuleCategory::Lint) { + return; + } + self.types.insert( + (::NAME, R::METADATA.name), + TypeId::of::(), + ); + } + } + + impl RegistryVisitor for RuleSideOptionsVisitor { + fn record_rule(&mut self) + where + R: Rule> + + 'static, + { + self.collect_rule::(); + } + } + + impl RegistryVisitor for RuleSideOptionsVisitor { + fn record_rule(&mut self) + where + R: Rule> + + 'static, + { + self.collect_rule::(); + } + } + + impl RegistryVisitor for RuleSideOptionsVisitor { + fn record_rule(&mut self) + where + R: Rule> + + 'static, + { + self.collect_rule::(); + } + } + + impl RegistryVisitor for RuleSideOptionsVisitor { + fn record_rule(&mut self) + where + R: Rule> + + 'static, + { + self.collect_rule::(); + } + } + + impl RegistryVisitor for RuleSideOptionsVisitor { + fn record_rule(&mut self) + where + R: Rule> + + 'static, + { + self.collect_rule::(); + } + } + + /// Verifies that every lint rule's `type Options` matches the canonical options + /// type derived from the rule name (`biome_rule_options::{snake_name}::{Name}Options`). + /// + /// This catches copy-paste bugs where a rule accidentally uses another rule's + /// options type (e.g. `type Options = SomeOtherRuleOptions`). The configuration + /// layer always constructs `RuleOptions` using the canonical type, so a mismatch + /// causes a `TypeId` divergence that triggers a panic at runtime. + #[test] + fn rule_options_match_config_types() { + let config_side = config_side_rule_options_types(); + + let mut visitor = RuleSideOptionsVisitor { + types: HashMap::new(), + }; + biome_js_analyze::visit_registry(&mut visitor); + biome_json_analyze::visit_registry(&mut visitor); + biome_css_analyze::visit_registry(&mut visitor); + biome_graphql_analyze::visit_registry(&mut visitor); + biome_html_analyze::visit_registry(&mut visitor); + + let mut mismatches = Vec::new(); + for (group, rule, config_type_id) in &config_side { + if let Some(rule_type_id) = visitor.types.get(&(*group, *rule)) + && config_type_id != rule_type_id + { + mismatches.push(format!( + " {group}/{rule}: rule declares a different Options type than \ + biome_rule_options::{module}::{name}Options", + module = biome_string_case::Case::Snake.convert(rule), + name = { + let mut c = rule.chars(); + match c.next() { + None => String::new(), + Some(f) => f.to_uppercase().collect::() + c.as_str(), + } + }, + )); + } + } + + if !mismatches.is_empty() { + panic!( + "Rule options type mismatches detected:\n{}\n\n\ + Each rule's `type Options` must match the canonical options type \ + generated from its name. Check for copy-paste errors.", + mismatches.join("\n") + ); + } + } +} diff --git a/xtask/codegen/src/generate_configuration.rs b/xtask/codegen/src/generate_configuration.rs index 114f491a004e..46aa324b120f 100644 --- a/xtask/codegen/src/generate_configuration.rs +++ b/xtask/codegen/src/generate_configuration.rs @@ -11,8 +11,8 @@ use proc_macro2::{Ident, Literal, Span}; use quote::{format_ident, quote}; use std::collections::{BTreeMap, BTreeSet}; use std::path::Path; -use xtask_codegen::update; use xtask_codegen::{generate_analyzer_rule_options, get_analyzer_rule_options_path}; +use xtask_codegen::{to_capitalized, update}; use xtask_glue::*; // ======= LINT ====== @@ -847,6 +847,50 @@ fn generate_for_groups( update(path, &xtask_glue::reformat(configuration)?, mode)?; update(file_name, &xtask_glue::reformat(push_rules)?, mode)?; + // Generate the options type-check test file for lint rules + if kind == RuleCategory::Lint { + let mut push_statements = String::new(); + for rg in &rule_group_names { + let snake_name = Case::Snake.convert(rg.rule_name); + let options_type_name = format!("{}Options", to_capitalized(rg.rule_name)); + push_statements.push_str(&format!( + "result.push((\"{group}\", \"{rule}\", TypeId::of::()));\n", + group = rg.group_name, + rule = rg.rule_name, + module = snake_name, + options = options_type_name, + )); + } + + let options_check = format!( + "\ +#![expect(clippy::vec_init_then_push)] +use std::any::TypeId; + +/// Returns a list of `(group, rule, config_side_type_id)` for every lint rule. +/// +/// The `TypeId` is derived from the rule name convention: +/// `biome_rule_options::{{snake_case_name}}::{{PascalCaseName}}Options` +/// +/// This is the type that the configuration layer uses when constructing +/// [`RuleOptions`](biome_analyze::options::RuleOptions). If the rule's +/// `type Options` doesn't match, the `debug_assert_eq!` inside +/// `RuleOptions::value()` will fire at runtime. +pub fn config_side_rule_options_types() -> Vec<(&'static str, &'static str, TypeId)> {{ + let mut result = Vec::new(); +{push_statements} result +}} +" + ); + + let options_check_file = push_directory.join("linter_options_check.rs"); + update( + &options_check_file, + &xtask_glue::reformat(options_check)?, + mode, + )?; + } + Ok(()) }