refactor(rust)!: clippy avoid-breaking-exported-api = false (#11088)

This commit is contained in:
Boshen committed 2025-05-17 02:21:26 +00:00
1 parent c294447aca
commit 5d9344fbfa
48 files changed
+204 -254

No files matched your search

+2
View File
@@ -1,3 +1,5 @@
avoid-breaking-exported-api = false
ignore-interior-mutability = ["oxc_linter::rules::RuleEnum"]
disallowed-methods = [
+2 -4
View File
@@ -51,7 +51,5 @@ jobs:
- name: Test with Miri
run: |
cargo miri test -p oxc_ast --all-features
cargo miri test -p oxc_data_structures --all-features
cargo miri test -p oxc_parser
cargo miri test -p oxc_transformer
cargo miri test --doc --all-features -p oxc_ast -p oxc_data_structures
cargo miri test -p oxc_parser -p oxc_transformer
+3 -28
View File
@@ -248,20 +248,7 @@ impl Runner for LintRunner {
let mut options =
LintServiceOptions::new(self.cwd, paths).with_cross_module(use_cross_module);
let lint_config = match config_builder.build() {
Ok(config) => config,
Err(diagnostic) => {
print_and_flush_stdout(
stdout,
&format!(
"Failed to parse configuration file.\n{}\n",
render_report(&handler, &diagnostic)
),
);
return CliRunResult::InvalidOptionConfig;
}
};
let lint_config = config_builder.build();
let report_unused_directives = match inline_config_options.report_unused_directives {
ReportUnusedDirectives::WithoutSeverity(true) => Some(AllowWarnDeny::Warn),
@@ -439,20 +426,8 @@ impl LintRunner {
}
.with_filters(filters);
match builder.build() {
Ok(config) => nested_configs.insert(dir.to_path_buf(), config),
Err(diagnostic) => {
print_and_flush_stdout(
stdout,
&format!(
"Failed to parse configuration file.\n{}\n",
render_report(handler, &diagnostic)
),
);
return Err(CliRunResult::InvalidOptionConfig);
}
};
let config = builder.build();
nested_configs.insert(dir.to_path_buf(), config);
}
Ok(nested_configs)
+5 -1
View File
@@ -1,4 +1,8 @@
#![expect(missing_docs)] // FIXME
#![expect(
missing_docs, // FIXME
clippy::enum_variant_names,
clippy::struct_field_names,
)]
// NB: `#[span]`, `#[scope(...)]`,`#[visit(...)]` and `#[generate_derive(...)]` do NOT do anything to the code.
// They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates.
+4 -1
View File
@@ -2,7 +2,10 @@
//!
//! - [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/v8.9.0/packages/ast-spec)
//! - [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md)
#![expect(missing_docs)] // FIXME
#![expect(
missing_docs, // FIXME
clippy::enum_variant_names,
)]
// NB: `#[span]`, `#[scope(...)]`,`#[visit(...)]` and `#[generate_derive(...)]` do NOT do anything to the code.
// They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates.
+1
View File
@@ -10,6 +10,7 @@ use crate::{AstBuilder, ast::*};
/// Type that can be used in any AST builder method call which requires an `IntoIn<'a, Anything<'a>>`.
/// Pass `NONE` instead of `None::<Anything<'a>>`.
#[expect(clippy::upper_case_acronyms)]
pub struct NONE;
impl<'a, T> FromIn<'a, NONE> for Option<Box<'a, T>> {
+1 -1
View File
@@ -1328,7 +1328,7 @@ impl<'a> Function<'a> {
impl FunctionType {
/// Returns `true` if it is a [`FunctionType::TSDeclareFunction`] or [`FunctionType::TSEmptyBodyFunctionExpression`].
pub fn is_typescript_syntax(&self) -> bool {
pub fn is_typescript_syntax(self) -> bool {
matches!(self, Self::TSDeclareFunction | Self::TSEmptyBodyFunctionExpression)
}
}
+1 -1
View File
@@ -207,7 +207,7 @@ impl RegExpFlags {
/// Convert [`RegExpFlags`] to an [`InlineString`].
///
/// This performs the same role as `RegExpFlags::to_string`, but does not allocate.
pub fn to_inline_string(&self) -> InlineString<8, usize> {
pub fn to_inline_string(self) -> InlineString<8, usize> {
let mut str = InlineString::new();
// In alphabetical order.
+3 -3
View File
@@ -184,7 +184,7 @@ impl TSModuleDeclarationKind {
/// Declaration keyword as a string, identical to how it would appear in the
/// source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Global => "global",
Self::Module => "module",
@@ -295,12 +295,12 @@ impl<'a> Decorator<'a> {
impl ImportOrExportKind {
/// Returns `true` for "regular" imports and exports.
pub fn is_value(&self) -> bool {
pub fn is_value(self) -> bool {
matches!(self, Self::Value)
}
/// Returns `true` if this is an `import type` or `export type` statement.
pub fn is_type(&self) -> bool {
pub fn is_type(self) -> bool {
matches!(self, Self::Type)
}
}
+5 -1
View File
@@ -3,7 +3,11 @@
//! AST node factories
#![expect(clippy::default_trait_access, clippy::inconsistent_struct_constructor)]
#![expect(
clippy::default_trait_access,
clippy::inconsistent_struct_constructor,
clippy::unused_self
)]
use std::cell::Cell;
+2 -1
View File
@@ -7,7 +7,8 @@
//! * [visitor pattern](https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html)
//! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs)
#![expect(unused_variables, clippy::semicolon_if_nothing_returned, clippy::match_same_arms)]
#![expect(unused_variables, clippy::match_same_arms, clippy::semicolon_if_nothing_returned)]
#![allow(clippy::needless_pass_by_ref_mut, clippy::trivially_copy_pass_by_ref)]
use std::cell::Cell;
@@ -7,7 +7,8 @@
//! * [visitor pattern](https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html)
//! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs)
#![expect(unused_variables, clippy::semicolon_if_nothing_returned, clippy::match_same_arms)]
#![expect(unused_variables, clippy::match_same_arms, clippy::semicolon_if_nothing_returned)]
#![allow(clippy::needless_pass_by_ref_mut, clippy::trivially_copy_pass_by_ref)]
use std::cell::Cell;
@@ -354,6 +354,7 @@ impl<T> NonEmptyStack<T> {
}
/// Get if stack is empty. Always returns `false`.
#[expect(clippy::unused_self)]
#[inline]
pub fn is_empty(&self) -> bool {
// This method is pointless, as the stack is never empty. But provide it to override
@@ -7,20 +7,20 @@ pub enum Quote {
}
impl Quote {
pub fn as_char(&self) -> char {
pub fn as_char(self) -> char {
match self {
Quote::Double => '"',
Quote::Single => '\'',
}
}
pub fn as_byte(&self) -> u8 {
pub fn as_byte(self) -> u8 {
self.as_char() as u8
}
/// Given the current quote, it returns the other one
#[must_use]
pub fn other(&self) -> Self {
pub fn other(self) -> Self {
match self {
Quote::Double => Quote::Single,
Quote::Single => Quote::Double,
+22 -22
View File
@@ -115,12 +115,12 @@ impl IndentStyle {
pub const DEFAULT_SPACES: u8 = 2;
/// Returns `true` if this is an [IndentStyle::Tab].
pub const fn is_tab(&self) -> bool {
pub const fn is_tab(self) -> bool {
matches!(self, IndentStyle::Tab)
}
/// Returns `true` if this is an [IndentStyle::Space].
pub const fn is_space(&self) -> bool {
pub const fn is_space(self) -> bool {
matches!(self, IndentStyle::Space)
}
}
@@ -163,7 +163,7 @@ pub enum LineEnding {
impl LineEnding {
#[inline]
pub const fn as_str(&self) -> &'static str {
pub const fn as_str(self) -> &'static str {
match self {
LineEnding::Lf => "\n",
LineEnding::Crlf => "\r\n",
@@ -172,17 +172,17 @@ impl LineEnding {
}
/// Returns `true` if this is a [LineEnding::Lf].
pub const fn is_line_feed(&self) -> bool {
pub const fn is_line_feed(self) -> bool {
matches!(self, LineEnding::Lf)
}
/// Returns `true` if this is a [LineEnding::Crlf].
pub const fn is_carriage_return_line_feed(&self) -> bool {
pub const fn is_carriage_return_line_feed(self) -> bool {
matches!(self, LineEnding::Crlf)
}
/// Returns `true` if this is a [LineEnding::Cr].
pub const fn is_carriage_return(&self) -> bool {
pub const fn is_carriage_return(self) -> bool {
matches!(self, LineEnding::Cr)
}
}
@@ -219,7 +219,7 @@ impl IndentWidth {
pub const MIN: u8 = 0;
/// Return the numeric value for this [IndentWidth]
pub fn value(&self) -> u8 {
pub fn value(self) -> u8 {
self.0
}
}
@@ -278,7 +278,7 @@ impl LineWidth {
pub const MIN: u16 = 1;
/// Return the numeric value for this [LineWidth]
pub fn value(&self) -> u16 {
pub fn value(self) -> u16 {
self.0
}
}
@@ -410,14 +410,14 @@ impl QuoteStyle {
}
}
pub fn as_char(&self) -> char {
pub fn as_char(self) -> char {
match self {
QuoteStyle::Double => '"',
QuoteStyle::Single => '\'',
}
}
pub fn as_byte(&self) -> u8 {
pub fn as_byte(self) -> u8 {
self.as_char() as u8
}
@@ -431,14 +431,14 @@ impl QuoteStyle {
/// Given the current quote, it returns the other one
#[must_use]
pub fn other(&self) -> Self {
pub fn other(self) -> Self {
match self {
QuoteStyle::Double => QuoteStyle::Single,
QuoteStyle::Single => QuoteStyle::Double,
}
}
pub const fn is_double(&self) -> bool {
pub const fn is_double(self) -> bool {
matches!(self, Self::Double)
}
}
@@ -527,11 +527,11 @@ pub enum Semicolons {
}
impl Semicolons {
pub const fn is_as_needed(&self) -> bool {
pub const fn is_as_needed(self) -> bool {
matches!(self, Self::AsNeeded)
}
pub const fn is_always(&self) -> bool {
pub const fn is_always(self) -> bool {
matches!(self, Self::Always)
}
}
@@ -568,11 +568,11 @@ pub enum ArrowParentheses {
}
impl ArrowParentheses {
pub const fn is_as_needed(&self) -> bool {
pub const fn is_as_needed(self) -> bool {
matches!(self, Self::AsNeeded)
}
pub const fn is_always(&self) -> bool {
pub const fn is_always(self) -> bool {
matches!(self, Self::Always)
}
}
@@ -629,7 +629,7 @@ pub enum TrailingSeparator {
impl FormatTrailingCommas {
/// This function returns corresponding [TrailingSeparator] for `format_separated` function.
pub fn trailing_separator(&self, options: &FormatOptions) -> TrailingSeparator {
pub fn trailing_separator(self, options: &FormatOptions) -> TrailingSeparator {
if options.trailing_commas.is_none() {
return TrailingSeparator::Omit;
}
@@ -674,15 +674,15 @@ pub enum TrailingCommas {
}
impl TrailingCommas {
pub const fn is_es5(&self) -> bool {
pub const fn is_es5(self) -> bool {
matches!(self, TrailingCommas::Es5)
}
pub const fn is_all(&self) -> bool {
pub const fn is_all(self) -> bool {
matches!(self, TrailingCommas::All)
}
pub const fn is_none(&self) -> bool {
pub const fn is_none(self) -> bool {
matches!(self, TrailingCommas::None)
}
}
@@ -748,7 +748,7 @@ pub struct BracketSpacing(bool);
impl BracketSpacing {
/// Return the boolean value for this [BracketSpacing]
pub fn value(&self) -> bool {
pub fn value(self) -> bool {
self.0
}
}
@@ -792,7 +792,7 @@ pub struct BracketSameLine(bool);
impl BracketSameLine {
/// Return the boolean value for this [BracketSameLine]
pub fn value(&self) -> bool {
pub fn value(self) -> bool {
self.0
}
}
@@ -192,7 +192,7 @@ impl<'a> IsolatedDeclarations<'a> {
}
Declaration::TSEnumDeclaration(enum_decl) => {
if !check_binding || self.scope.has_reference(&enum_decl.id.name) {
self.transform_ts_enum_declaration(enum_decl)
Some(self.transform_ts_enum_declaration(enum_decl))
} else {
None
}
+3 -6
View File
@@ -18,10 +18,7 @@ enum ConstantValue {
}
impl<'a> IsolatedDeclarations<'a> {
pub fn transform_ts_enum_declaration(
&mut self,
decl: &TSEnumDeclaration<'a>,
) -> Option<Declaration<'a>> {
pub fn transform_ts_enum_declaration(&self, decl: &TSEnumDeclaration<'a>) -> Declaration<'a> {
let mut members = self.ast.vec();
let mut prev_initializer_value = Some(ConstantValue::Number(-1.0));
let mut prev_members = FxHashMap::default();
@@ -83,13 +80,13 @@ impl<'a> IsolatedDeclarations<'a> {
members.push(member);
}
Some(self.ast.declaration_ts_enum(
self.ast.declaration_ts_enum(
decl.span,
decl.id.clone_in(self.ast.allocator),
self.ast.ts_enum_body(decl.body.span, members),
decl.r#const,
self.is_declare(),
))
)
}
/// Evaluate the expression to a constant value.
@@ -11,7 +11,7 @@ impl<'a> IsolatedDeclarations<'a> {
///
/// Infer get accessor return type from set accessor's param type
/// Infer set accessor parameter type from get accessor return type
pub fn transform_ts_signatures(&mut self, signatures: &mut ArenaVec<'a, TSSignature<'a>>) {
pub fn transform_ts_signatures(&self, signatures: &mut ArenaVec<'a, TSSignature<'a>>) {
// <name, (requires_inference, first_param_annotation, return_type)>
let mut method_annotations: FxHashMap<_, (bool, _, _)> = FxHashMap::default();
@@ -61,7 +61,7 @@ impl ServerLinter {
config_builder.plugins().has_import()
};
let base_config = config_builder.build().expect("Failed to build config store");
let base_config = config_builder.build();
let lint_options = LintOptions { fix: options.fix_kind(), ..Default::default() };
@@ -123,10 +123,7 @@ impl ServerLinter {
warn!("Skipping config (builder failed): {}", file_path.display());
continue;
};
let Ok(config_store) = config_store_builder.build() else {
warn!("Skipping config (builder failed): {}", file_path.display());
continue;
};
let config_store = config_store_builder.build();
nested_configs.pin().insert(dir_path.to_path_buf(), config_store);
}
+4 -11
View File
@@ -6,7 +6,6 @@ use std::{
use itertools::Itertools;
use rustc_hash::FxHashMap;
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{CompactStr, format_compact_str};
use crate::{
@@ -293,8 +292,7 @@ impl ConfigStoreBuilder {
}
}
/// # Errors
pub fn build(self) -> Result<Config, OxcDiagnostic> {
pub fn build(self) -> Config {
// When a plugin gets disabled before build(), rules for that plugin aren't removed until
// with_filters() gets called. If the user never calls it, those now-undesired rules need
// to be taken out.
@@ -308,8 +306,7 @@ impl ConfigStoreBuilder {
self.rules.into_iter().collect::<Vec<_>>()
};
rules.sort_unstable_by_key(|(r, _)| r.id());
Ok(Config::new(rules, self.config, self.overrides))
Config::new(rules, self.config, self.overrides)
}
/// Warn for all correctness rules in the given set of plugins.
@@ -652,7 +649,7 @@ mod test {
let mut desired_plugins = LintPlugins::default();
desired_plugins.set(LintPlugins::TYPESCRIPT, false);
let linter = ConfigStoreBuilder::default().with_plugins(desired_plugins).build().unwrap();
let linter = ConfigStoreBuilder::default().with_plugins(desired_plugins).build();
for (rule, _) in linter.base.rules.iter() {
let name = rule.name();
let plugin = rule.plugin_name();
@@ -1029,13 +1026,9 @@ mod test {
ConfigStoreBuilder::from_oxlintrc(true, Oxlintrc::from_file(&PathBuf::from(path)).unwrap())
.unwrap()
.build()
.unwrap()
}
fn config_store_from_str(s: &str) -> Config {
ConfigStoreBuilder::from_oxlintrc(true, serde_json::from_str(s).unwrap())
.unwrap()
.build()
.unwrap()
ConfigStoreBuilder::from_oxlintrc(true, serde_json::from_str(s).unwrap()).unwrap().build()
}
}
-33
View File
@@ -21,33 +21,6 @@ impl Loader {
.and_then(std::ffi::OsStr::to_str)
.is_some_and(|ext| LINT_PARTIAL_LOADER_EXTENSIONS.contains(&ext))
}
/// # Errors
/// - If the file is too large (> 4GB, or u32::MAX)
/// - If the file has no extension
/// - If the file extension is not supported
pub fn load_str<'a, P: AsRef<Path>>(
&self,
path: P,
source_text: &'a str,
) -> Result<Vec<JavaScriptSource<'a>>, LoadError> {
if source_text.len() > u32::MAX as usize {
return Err(LoadError::TooLarge);
}
let path = path.as_ref();
let ext = path.extension().ok_or(LoadError::NoExtension)?;
// file extension is not unicode, we definitely don't support it.
let ext = ext.to_str().ok_or_else(|| LoadError::unsupported(ext))?;
// let source_type = SourceType::from_path(path);
if let Ok(source_type) = SourceType::from_path(path) {
Ok(vec![JavaScriptSource::new(source_text, source_type)])
} else {
let partial = PartialLoader::parse(ext, source_text);
partial.ok_or_else(|| LoadError::UnsupportedFileType(ext.to_string()))
}
}
}
#[derive(Debug, Clone)]
@@ -57,12 +30,6 @@ pub enum LoadError {
UnsupportedFileType(String),
}
impl LoadError {
pub(super) fn unsupported(ext: &std::ffi::OsStr) -> Self {
Self::UnsupportedFileType(ext.to_string_lossy().to_string())
}
}
impl fmt::Display for LoadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@@ -155,7 +155,7 @@ impl Rule for NoLargeSnapshots {
let allowed_snapshots = config
.and_then(|c| c.get("allowedSnapshots"))
.and_then(serde_json::Value::as_object)
.and_then(Self::compile_allowed_snapshots)
.map(Self::compile_allowed_snapshots)
.unwrap_or_default();
Self(Box::new(NoLargeSnapshotsConfig { max_size, inline_max_size, allowed_snapshots }))
@@ -286,22 +286,20 @@ impl NoLargeSnapshots {
pub fn compile_allowed_snapshots(
matchers: &serde_json::Map<String, serde_json::Value>,
) -> Option<FxHashMap<CompactStr, Vec<CompactStr>>> {
Some(
matchers
.iter()
.map(|(key, value)| {
let serde_json::Value::Array(configs) = value else {
return (CompactStr::from(key.as_str()), vec![]);
};
) -> FxHashMap<CompactStr, Vec<CompactStr>> {
matchers
.iter()
.map(|(key, value)| {
let serde_json::Value::Array(configs) = value else {
return (CompactStr::from(key.as_str()), vec![]);
};
let configs =
configs.iter().filter_map(|c| c.as_str().map(CompactStr::from)).collect();
let configs =
configs.iter().filter_map(|c| c.as_str().map(CompactStr::from)).collect();
(CompactStr::from(key.as_str()), configs)
})
.collect(),
)
(CompactStr::from(key.as_str()), configs)
})
.collect()
}
}
@@ -66,7 +66,7 @@ impl Rule for NoRestrictedJestMethods {
let restricted_jest_methods = &value
.get(0)
.and_then(serde_json::Value::as_object)
.and_then(Self::compile_restricted_jest_methods)
.map(Self::compile_restricted_jest_methods)
.unwrap_or_default();
Self(Box::new(NoRestrictedJestMethodsConfig {
@@ -138,15 +138,13 @@ impl NoRestrictedJestMethods {
pub fn compile_restricted_jest_methods(
matchers: &serde_json::Map<String, serde_json::Value>,
) -> Option<FxHashMap<String, String>> {
Some(
matchers
.iter()
.map(|(key, value)| {
(String::from(key), String::from(value.as_str().unwrap_or_default()))
})
.collect(),
)
) -> FxHashMap<String, String> {
matchers
.iter()
.map(|(key, value)| {
(String::from(key), String::from(value.as_str().unwrap_or_default()))
})
.collect()
}
}
@@ -82,7 +82,7 @@ impl Rule for NoRestrictedMatchers {
let restricted_matchers = &value
.get(0)
.and_then(serde_json::Value::as_object)
.and_then(Self::compile_restricted_matchers)
.map(Self::compile_restricted_matchers)
.unwrap_or_default();
Self(Box::new(NoRestrictedMatchersConfig {
@@ -152,15 +152,13 @@ impl NoRestrictedMatchers {
pub fn compile_restricted_matchers(
matchers: &serde_json::Map<String, serde_json::Value>,
) -> Option<FxHashMap<String, String>> {
Some(
matchers
.iter()
.map(|(key, value)| {
(String::from(key), String::from(value.as_str().unwrap_or_default()))
})
.collect(),
)
) -> FxHashMap<String, String> {
matchers
.iter()
.map(|(key, value)| {
(String::from(key), String::from(value.as_str().unwrap_or_default()))
})
.collect()
}
}
+1 -2
View File
@@ -493,8 +493,7 @@ impl Tester {
})
.with_plugins(self.plugins)
.with_rule(rule, AllowWarnDeny::Warn)
.build()
.unwrap(),
.build(),
FxHashMap::default(),
),
)
@@ -1,6 +1,6 @@
#![expect(clippy::trivially_copy_pass_by_ref)]
// NOTE: For now, this file is implemented by hand for convenience.
// But like `oxc_ast`, this should be generated by `tasks/ast_tools` in the future.
use oxc_span::{GetSpan, Span};
use crate::ast::{
+1
View File
@@ -451,6 +451,7 @@ impl Scoping {
/// Get the root [`Program`] scope id.
///
/// [`Program`]: oxc_ast::ast::Program
#[expect(clippy::unused_self)]
#[inline]
pub const fn root_scope_id(&self) -> ScopeId {
Self::ROOT_SCOPE_ID
@@ -6,7 +6,7 @@ use crate::util::{Expect, SemanticTester};
#[test]
fn test_only_program() {
let tester = SemanticTester::js("let x = 1;");
tester.has_root_symbol("x").is_in_scope(ScopeFlags::Top).test();
tester.has_root_symbol("x").in_scope(ScopeFlags::Top).test();
let semantic = tester.build();
let scopes = semantic.scoping();
@@ -38,7 +38,7 @@ fn test_top_level_strict() {
"#,
)
.has_root_symbol("foo")
.is_in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
.in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
// .expect(expect_strict)
.test();
@@ -51,7 +51,7 @@ fn test_top_level_strict() {
",
)
.has_root_symbol("foo")
.is_in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
.in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
.test();
// Script with top-level "use strict"
@@ -65,7 +65,7 @@ fn test_top_level_strict() {
)
.with_module(false)
.has_root_symbol("foo")
.is_in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
.in_scope(ScopeFlags::Top | ScopeFlags::StrictMode)
.test();
// Script without top-level "use strict"
@@ -78,8 +78,8 @@ fn test_top_level_strict() {
)
.with_module(false)
.has_root_symbol("foo")
.is_in_scope(ScopeFlags::Top)
.is_not_in_scope(ScopeFlags::StrictMode)
.in_scope(ScopeFlags::Top)
.not_in_scope(ScopeFlags::StrictMode)
.test();
}
@@ -98,7 +98,7 @@ fn test_function_level_strict() {
tester
.has_some_symbol("x")
.is_in_scope(ScopeFlags::StrictMode | ScopeFlags::Function)
.in_scope(ScopeFlags::StrictMode | ScopeFlags::Function)
.expect(|(semantic, symbol_id)| -> Result<(), &'static str> {
let scope_id = semantic.symbol_scope(symbol_id);
let Some(parent_scope_id) = semantic.scoping().scope_parent_id(scope_id) else {
@@ -112,7 +112,7 @@ fn test_function_level_strict() {
}
})
.test();
tester.has_some_symbol("foo").is_not_in_scope(ScopeFlags::StrictMode).test();
tester.has_some_symbol("foo").not_in_scope(ScopeFlags::StrictMode).test();
}
#[test]
@@ -219,7 +219,7 @@ fn var_hoisting() {
)
.has_root_symbol("e")
// `e` was hoisted to the top scope so the symbol's scope is also the top scope
.is_in_scope(ScopeFlags::Top)
.in_scope(ScopeFlags::Top)
.test();
}
@@ -218,7 +218,7 @@ impl<'a> SymbolTester<'a> {
self
}
pub fn is_in_scope(mut self, expected_flags: ScopeFlags) -> Self {
pub fn in_scope(mut self, expected_flags: ScopeFlags) -> Self {
let target_name: &str = self.target_symbol_name.as_ref();
self.test_result = match self.test_result {
Ok(symbol_id) => {
@@ -237,7 +237,7 @@ impl<'a> SymbolTester<'a> {
self
}
pub fn is_not_in_scope(mut self, excluded_flags: ScopeFlags) -> Self {
pub fn not_in_scope(mut self, excluded_flags: ScopeFlags) -> Self {
let target_name: &str = self.target_symbol_name.as_ref();
self.test_result = match self.test_result {
Ok(symbol_id) => {
+1 -1
View File
@@ -58,7 +58,7 @@ impl<'a> Atom<'a> {
/// Convert this [`Atom`] into a [`CompactStr`] without consuming `self`.
#[inline]
pub fn to_compact_str(&self) -> CompactStr {
pub fn to_compact_str(self) -> CompactStr {
CompactStr::new(self.as_str())
}
}
+4 -4
View File
@@ -74,25 +74,25 @@ bitflags! {
impl NodeFlags {
/// Returns `true` if this node has a JSDoc comment attached to it.
#[inline]
pub fn has_jsdoc(&self) -> bool {
pub fn has_jsdoc(self) -> bool {
self.contains(Self::JSDoc)
}
/// Returns `true` if this node is inside a class.
#[inline]
pub fn has_class(&self) -> bool {
pub fn has_class(self) -> bool {
self.contains(Self::Class)
}
/// Returns `true` if this function has a yield statement.
#[inline]
pub fn has_yield(&self) -> bool {
pub fn has_yield(self) -> bool {
self.contains(Self::HasYield)
}
/// Returns `true` if this function has an export specifier.
#[inline]
pub fn has_export_specifier(&self) -> bool {
pub fn has_export_specifier(self) -> bool {
self.contains(Self::ExportSpecifier)
}
}
+3 -3
View File
@@ -16,7 +16,7 @@ pub enum NumberBase {
}
impl NumberBase {
pub fn is_base_10(&self) -> bool {
pub fn is_base_10(self) -> bool {
matches!(self, Self::Float | Self::Decimal)
}
}
@@ -32,8 +32,8 @@ pub enum BigintBase {
}
impl BigintBase {
pub fn is_base_10(&self) -> bool {
self == &Self::Decimal
pub fn is_base_10(self) -> bool {
self == Self::Decimal
}
}
+7 -7
View File
@@ -130,7 +130,7 @@ impl AssignmentOperator {
/// Get the string representation of this operator.
///
/// This is the same as how the operator appears in source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Assign => "=",
Self::Addition => "+=",
@@ -338,7 +338,7 @@ impl BinaryOperator {
}
/// The string representation of this operator as it appears in source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Equality => "==",
Self::Inequality => "!=",
@@ -368,7 +368,7 @@ impl BinaryOperator {
/// Get the operator that has a lower precedence than this operator by a
/// single level. Use [`BinaryOperator::precedence`] to get the operator
/// with a higher precedence.
pub fn lower_precedence(&self) -> Precedence {
pub fn lower_precedence(self) -> Precedence {
match self {
Self::BitwiseOR => Precedence::LogicalAnd,
Self::BitwiseXOR => Precedence::BitwiseOr,
@@ -449,7 +449,7 @@ impl LogicalOperator {
}
/// Get the string representation of this operator as it appears in source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Or => "||",
Self::And => "&&",
@@ -460,7 +460,7 @@ impl LogicalOperator {
/// Get the operator that has a lower precedence than this operator by a
/// single level. Use [`BinaryOperator::precedence`] to get the operator
/// with a higher precedence.
pub fn lower_precedence(&self) -> Precedence {
pub fn lower_precedence(self) -> Precedence {
match self {
Self::Or => Precedence::NullishCoalescing,
Self::And => Precedence::LogicalOr,
@@ -560,7 +560,7 @@ impl UnaryOperator {
}
/// Get the string representation of this operator as it appears in source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::UnaryPlus => "+",
Self::UnaryNegation => "-",
@@ -588,7 +588,7 @@ pub enum UpdateOperator {
impl UpdateOperator {
/// Get the string representation of this operator as it appears in source code.
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Increment => "++",
Self::Decrement => "--",
+2 -2
View File
@@ -43,11 +43,11 @@ pub enum Precedence {
}
impl Precedence {
pub fn is_right_associative(&self) -> bool {
pub fn is_right_associative(self) -> bool {
matches!(self, Self::Exponentiation | Self::Conditional | Self::Assign)
}
pub fn is_left_associative(&self) -> bool {
pub fn is_left_associative(self) -> bool {
matches!(
self,
Self::Lowest
+8 -8
View File
@@ -159,43 +159,43 @@ impl ReferenceFlags {
/// The identifier is read from. It may also be written to.
#[inline]
pub const fn is_read(&self) -> bool {
pub const fn is_read(self) -> bool {
self.intersects(Self::Read)
}
/// The identifier is only read from.
#[inline]
pub const fn is_read_only(&self) -> bool {
pub const fn is_read_only(self) -> bool {
!self.contains(Self::Write)
}
/// The identifier is written to. It may also be read from.
#[inline]
pub const fn is_write(&self) -> bool {
pub const fn is_write(self) -> bool {
self.intersects(Self::Write)
}
/// The identifier is only written to. It is not read from in this reference.
#[inline]
pub const fn is_write_only(&self) -> bool {
pub const fn is_write_only(self) -> bool {
!self.contains(Self::Read)
}
/// The identifier is both read from and written to, e.g `a += 1`.
#[inline]
pub fn is_read_write(&self) -> bool {
pub fn is_read_write(self) -> bool {
self.contains(Self::Read | Self::Write)
}
/// Checks if the reference is a value being used in a type context.
#[inline]
pub fn is_value_as_type(&self) -> bool {
pub fn is_value_as_type(self) -> bool {
self.contains(Self::ValueAsType)
}
/// The identifier is used in a type definition.
#[inline]
pub const fn is_type(&self) -> bool {
pub const fn is_type(self) -> bool {
self.contains(Self::Type)
}
@@ -205,7 +205,7 @@ impl ReferenceFlags {
}
#[inline]
pub const fn is_value(&self) -> bool {
pub const fn is_value(self) -> bool {
self.intersects(Self::Value)
}
}
+15 -15
View File
@@ -100,71 +100,71 @@ impl ScopeFlags {
}
#[inline]
pub fn is_strict_mode(&self) -> bool {
pub fn is_strict_mode(self) -> bool {
self.contains(Self::StrictMode)
}
#[inline]
pub fn is_block(&self) -> bool {
self.is_empty() || *self == Self::StrictMode
pub fn is_block(self) -> bool {
self.is_empty() || self == Self::StrictMode
}
#[inline]
pub fn is_top(&self) -> bool {
pub fn is_top(self) -> bool {
self.contains(Self::Top)
}
#[inline]
pub fn is_function(&self) -> bool {
pub fn is_function(self) -> bool {
self.contains(Self::Function)
}
#[inline]
pub fn is_arrow(&self) -> bool {
pub fn is_arrow(self) -> bool {
self.contains(Self::Arrow)
}
#[inline]
pub fn is_constructor(&self) -> bool {
pub fn is_constructor(self) -> bool {
self.contains(Self::Constructor)
}
#[inline]
pub fn is_class_static_block(&self) -> bool {
pub fn is_class_static_block(self) -> bool {
self.contains(Self::ClassStaticBlock)
}
#[inline]
pub fn is_ts_module_block(&self) -> bool {
pub fn is_ts_module_block(self) -> bool {
self.contains(Self::TsModuleBlock)
}
#[inline]
pub fn is_var(&self) -> bool {
pub fn is_var(self) -> bool {
self.intersects(Self::Var)
}
#[inline]
pub fn is_set_accessor(&self) -> bool {
pub fn is_set_accessor(self) -> bool {
self.contains(Self::SetAccessor)
}
#[inline]
pub fn is_set_or_get_accessor(&self) -> bool {
pub fn is_set_or_get_accessor(self) -> bool {
self.intersects(Self::SetAccessor | Self::GetAccessor)
}
#[inline]
pub fn is_catch_clause(&self) -> bool {
pub fn is_catch_clause(self) -> bool {
self.contains(Self::CatchClause)
}
pub fn is_ts_conditional(&self) -> bool {
pub fn is_ts_conditional(self) -> bool {
self.contains(Self::TsConditional)
}
#[inline]
pub fn contains_direct_eval(&self) -> bool {
pub fn contains_direct_eval(self) -> bool {
self.contains(Self::DirectEval)
}
}
+22 -22
View File
@@ -172,118 +172,118 @@ bitflags! {
impl SymbolFlags {
#[inline]
pub fn is_variable(&self) -> bool {
pub fn is_variable(self) -> bool {
self.intersects(Self::Variable)
}
#[inline]
pub fn is_type_parameter(&self) -> bool {
pub fn is_type_parameter(self) -> bool {
self.contains(Self::TypeParameter)
}
/// If true, then the symbol is a type, such as a TypeAlias, Interface, or Enum
#[inline]
pub fn is_type(&self) -> bool {
pub fn is_type(self) -> bool {
self.intersects((Self::TypeImport | Self::Type) - Self::Value)
}
/// If true, then the symbol is a value, such as a Variable, Function, or Class
#[inline]
pub fn is_value(&self) -> bool {
pub fn is_value(self) -> bool {
self.intersects(Self::Value | Self::Import)
}
#[inline]
pub fn is_const_variable(&self) -> bool {
pub fn is_const_variable(self) -> bool {
self.contains(Self::ConstVariable)
}
/// Returns `true` if this symbol is a function declaration or expression.
#[inline]
pub fn is_function(&self) -> bool {
pub fn is_function(self) -> bool {
self.contains(Self::Function)
}
#[inline]
pub fn is_class(&self) -> bool {
pub fn is_class(self) -> bool {
self.contains(Self::Class)
}
#[inline]
pub fn is_interface(&self) -> bool {
pub fn is_interface(self) -> bool {
self.contains(Self::Interface)
}
#[inline]
pub fn is_type_alias(&self) -> bool {
pub fn is_type_alias(self) -> bool {
self.contains(Self::TypeAlias)
}
#[inline]
pub fn is_enum(&self) -> bool {
pub fn is_enum(self) -> bool {
self.intersects(Self::Enum)
}
#[inline]
pub fn is_const_enum(&self) -> bool {
pub fn is_const_enum(self) -> bool {
self.intersects(Self::ConstEnum)
}
#[inline]
pub fn is_enum_member(&self) -> bool {
pub fn is_enum_member(self) -> bool {
self.contains(Self::EnumMember)
}
#[inline]
pub fn is_catch_variable(&self) -> bool {
pub fn is_catch_variable(self) -> bool {
self.contains(Self::CatchVariable)
}
#[inline]
pub fn is_function_scoped_declaration(&self) -> bool {
pub fn is_function_scoped_declaration(self) -> bool {
self.contains(Self::FunctionScopedVariable)
}
#[inline]
pub fn is_import(&self) -> bool {
pub fn is_import(self) -> bool {
self.intersects(Self::Import | Self::TypeImport)
}
#[inline]
pub fn is_type_import(&self) -> bool {
pub fn is_type_import(self) -> bool {
self.contains(Self::TypeImport)
}
#[inline]
pub fn is_ambient(&self) -> bool {
pub fn is_ambient(self) -> bool {
self.contains(Self::Ambient)
}
#[inline]
pub fn is_namespace_module(&self) -> bool {
pub fn is_namespace_module(self) -> bool {
self.contains(Self::NamespaceModule)
}
#[inline]
pub fn is_value_module(&self) -> bool {
pub fn is_value_module(self) -> bool {
self.contains(Self::ValueModule)
}
/// If true, then the symbol can be referenced by a type reference
#[inline]
pub fn can_be_referenced_by_type(&self) -> bool {
pub fn can_be_referenced_by_type(self) -> bool {
self.intersects(Self::Type | Self::TypeImport | Self::Import | Self::Namespace)
}
/// If true, then the symbol can be referenced by a value reference
#[inline]
pub fn can_be_referenced_by_value(&self) -> bool {
pub fn can_be_referenced_by_value(self) -> bool {
self.is_value()
}
/// If true, then the symbol can be referenced by a value_as_type reference
#[inline]
pub fn can_be_referenced_by_value_as_type(&self) -> bool {
pub fn can_be_referenced_by_value_as_type(self) -> bool {
self.intersects(Self::Value | Self::Import | Self::Function | Self::TypeImport)
}
}
+4 -4
View File
@@ -16,18 +16,18 @@ use crate::options::babel::BabelModule;
pub enum Module {
#[default]
Preserve,
ESM,
Esm,
CommonJS,
}
impl Module {
/// Check if the module is ECMAScript Module(ESM).
pub fn is_esm(&self) -> bool {
matches!(self, Self::ESM)
pub fn is_esm(self) -> bool {
matches!(self, Self::Esm)
}
/// Check if the module is CommonJS.
pub fn is_commonjs(&self) -> bool {
pub fn is_commonjs(self) -> bool {
matches!(self, Self::CommonJS)
}
}
@@ -123,7 +123,7 @@ pub enum RewriteExtensionsMode {
}
impl RewriteExtensionsMode {
pub fn is_remove(&self) -> bool {
pub fn is_remove(self) -> bool {
matches!(self, Self::Remove)
}
}
@@ -251,7 +251,7 @@ impl<'a> InjectGlobalVariables<'a> {
}
}
fn replace_dot_defines(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
fn replace_dot_defines(&mut self, expr: &mut Expression<'a>, ctx: &TraverseCtx<'a>) {
if let Expression::StaticMemberExpression(member) = expr {
for DotDefineState { dot_define, value_atom } in &mut self.dot_defines {
if ReplaceGlobalDefines::is_dot_define(
@@ -344,7 +344,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
fn replace_define_with_assignment_expr(
&self,
node: &mut AssignmentExpression<'a>,
ctx: &mut TraverseCtx<'a>,
ctx: &TraverseCtx<'a>,
) -> bool {
let new_left = node
.left
@@ -369,7 +369,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
false
}
fn replace_dot_defines(&self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) -> bool {
fn replace_dot_defines(&self, expr: &mut Expression<'a>, ctx: &TraverseCtx<'a>) -> bool {
match expr {
Expression::ChainExpression(chain) => {
let Some(new_expr) =
@@ -417,7 +417,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
fn replace_dot_computed_member_expr(
&self,
ctx: &mut TraverseCtx<'a>,
ctx: &TraverseCtx<'a>,
member: &ComputedMemberExpression<'a>,
) -> Option<Expression<'a>> {
for dot_define in &self.config.0.dot {
@@ -436,7 +436,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
fn replace_dot_static_member_expr(
&self,
ctx: &mut TraverseCtx<'a>,
ctx: &TraverseCtx<'a>,
member: &StaticMemberExpression<'a>,
) -> Option<Expression<'a>> {
for dot_define in &self.config.0.dot {
@@ -536,7 +536,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
}
pub fn is_dot_define<'b>(
ctx: &mut TraverseCtx<'a>,
ctx: &TraverseCtx<'a>,
dot_define: &DotDefine,
member: DotDefineMemberExpression<'b, 'a>,
) -> bool {
@@ -116,6 +116,7 @@ export default function generateAncestorsCode(types) {
clippy::cast_ptr_alignment,
clippy::elidable_lifetime_names,
clippy::ptr_as_ptr,
clippy::ref_option,
clippy::undocumented_unsafe_blocks,
)]
@@ -6,6 +6,7 @@
clippy::cast_ptr_alignment,
clippy::elidable_lifetime_names,
clippy::ptr_as_ptr,
clippy::ref_option,
clippy::undocumented_unsafe_blocks
)]
+1 -2
View File
@@ -285,8 +285,7 @@ impl Oxc {
if run_options.lint.unwrap_or_default() && self.diagnostics.is_empty() {
let semantic_ret = SemanticBuilder::new().with_cfg(true).build(program);
let semantic = Rc::new(semantic_ret.semantic);
let lint_config =
ConfigStoreBuilder::default().build().expect("Failed to build config store");
let lint_config = ConfigStoreBuilder::default().build();
let linter_ret = Linter::new(
LintOptions::default(),
ConfigStore::new(lint_config, FxHashMap::default()),
@@ -69,7 +69,11 @@ impl Generator for AstBuilderGenerator {
//! AST node factories
//!@@line_break
#![expect(clippy::default_trait_access, clippy::inconsistent_struct_constructor)]
#![expect(
clippy::default_trait_access,
clippy::inconsistent_struct_constructor,
clippy::unused_self,
)]
///@@line_break
use std::cell::Cell;
+9 -1
View File
@@ -240,7 +240,15 @@ fn generate_output(
//! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs)
//!@@line_break
#![expect(unused_variables, clippy::semicolon_if_nothing_returned, clippy::match_same_arms)]
#![expect(
unused_variables,
clippy::match_same_arms,
clippy::semicolon_if_nothing_returned,
)]
#![allow(
clippy::needless_pass_by_ref_mut,
clippy::trivially_copy_pass_by_ref,
)]
///@@line_break
use std::cell::Cell;
+1 -2
View File
@@ -41,8 +41,7 @@ fn bench_linter(criterion: &mut Criterion) {
let semantic = semantic_ret.semantic;
let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record, &semantic));
let semantic = Rc::new(semantic);
let lint_config =
ConfigStoreBuilder::all().build().expect("Failed to build config store");
let lint_config = ConfigStoreBuilder::all().build();
let linter = Linter::new(
LintOptions::default(),
ConfigStore::new(lint_config, FxHashMap::default()),
+2 -2
View File
@@ -15,7 +15,7 @@ pub enum TestLanguage {
}
impl TestLanguage {
pub fn as_str(&self) -> &'static str {
pub fn as_str(self) -> &'static str {
match self {
Self::Js => "js",
Self::Ts => "ts",
@@ -23,7 +23,7 @@ impl TestLanguage {
}
/// Prettier's test fixtures roots for different languages.
pub fn fixtures_roots(&self, base: &Path) -> Vec<PathBuf> {
pub fn fixtures_roots(self, base: &Path) -> Vec<PathBuf> {
match self {
Self::Js => ["js", "jsx"],
// There is no `tsx` directory, just check it works with TS