Repository: astral-sh/ruff
File: crates/ruff_linter/src/rules/refurb/rules/metaclass_abcmeta.rs (Rust)

Code before:
            keyword.range.start(),
            checker.semantic(),
        )?;

        // Check the `abc.ABC` is in base classes.
        let is_has_abc = class_def.bases().iter().any(|base| {
            matches!(base, Expr::Name(_) | Expr::Attribute(_))
                && checker
                    .semantic()
                    .resolve_qualified_name(base)
                    .is_some_and(
                        |qualified_name| matches!(qualified_name.segments(), ["abc", "ABC"])
                    )
        });

        Ok(if position > 0 {
            // When the `abc.ABCMeta` is not the first keyword, put `abc.ABC` before the first
            // keyword.
            let rest = if is_has_abc {
                vec![]
            } else {
                vec![
                    Edit::insertion(format!("{binding}, "), class_def.keywords()[0].start()),
                    import_edit,
                ]
            };
            Fix::applicable_edits(
                // Delete from the previous argument, to the end of the `metaclass` argument.
                Edit::range_deletion(TextRange::new(
                    class_def.keywords()[position - 1].end(),
                    keyword.end(),
                )),
                // Insert `abc.ABC` before the first keyword.
                rest,
                applicability,
            )
        } else {

            // If class already inherits the `abc.ABC` we need to delete the entire
            // `metaclass` argument, otherwise, replace metaclass-keyword with `abc.ABC`.
            let edit_action = if is_has_abc {
                Edit::deletion(keyword.start(), keyword.end())
            } else {
                Edit::range_replacement(binding, keyword.range)
            };

            Fix::applicable_edits(
                edit_action,
                [import_edit],
                applicability,
            )

Review comment (suggestion):
I think we should be able to use a slice here to avoid allocating vecs:


```suggestion
            let rest = if is_has_abc {
                &[]
            } else {
                &[
                    Edit::insertion(format!("{binding}, "), class_def.keywords()[0].start()),
                    import_edit,
                ]
            };
```

You might have to annotate `rest` as `&[Edit]`, though.

Code after:
        // The class has base arguments (not just a `metaclass` keyword).
        // Applying the fix may change semantics, so it is considered unsafe.
        Applicability::Unsafe
    } else if checker.comment_ranges().intersects(arguments.range()) {
        // The `metaclass` keyword overlaps with a comment.
        // Applying the fix would remove or alter the comment, so it is unsafe.
        Applicability::Unsafe
    } else {
        // An empty class definition with no overlapping comments.
        // Applying the fix is considered safe.
        Applicability::Safe
    };
    let mut diagnostic = checker.report_diagnostic(MetaClassABCMeta, keyword.range);

    diagnostic.try_set_fix(|| {
        let (import_edit, binding) = checker.importer().get_or_import_symbol(
            &ImportRequest::import("abc", "ABC"),
            keyword.range.start(),
            checker.semantic(),
        )?;

        // Check the `abc.ABC` is in base classes.
        let has_abc = analyze::class::any_qualified_base_class(
            class_def,
            checker.semantic(),
            &|qualified_name| matches!(qualified_name.segments(), ["abc", "ABC"]),
        );

        let delete_metaclass_keyword = remove_argument(
            keyword,
            arguments,
            Parentheses::Remove,
            checker.source(),
            checker.tokens(),
        )?;

        Ok(if position > 0 {
            // When the `abc.ABCMeta` is not the first keyword and `abc.ABC` is not
            // in base classes put `abc.ABC` before the first keyword argument.
            if has_abc {
                Fix::applicable_edit(delete_metaclass_keyword, applicability)
            } else {
                Fix::applicable_edits(
                    delete_metaclass_keyword,
                    [
                        Edit::insertion(format!("{binding}, "), class_def.keywords()[0].start()),
                        import_edit,
                    ],
                    applicability,
                )
            }