class RuboCop::Cop::Sorbet::EnforceSigilOrder

other comments or magic comments are left in the same place.
Only ‘(en)?coding`, `typed`, `warn_indent` and `frozen_string_literal` magic comments are considered,
“`
class Foo; end
# frozen_string_literal: true
# typed: true
“`ruby
Will be corrected as:
“`
class Foo; end
# typed: true
# frozen_string_literal: true
“`ruby
For example, the following bad ordering:
The ordering is for consistency only, except for the encoding comment which must be first, if present.
The expected order for magic comments is: (en)?coding, typed, warn_indent then frozen_string_literal.
Checks that the Sorbet sigil comes as the first magic comment in the file, after the encoding comment if any.

def autocorrect(corrector)

def autocorrect(corrector)
  tokens = extract_magic_comments(processed_source)
  # Get the magic comments tokens in their expected order
  expected = PREFERRED_ORDER.keys.map do |re|
    tokens.select { |token| re.match?(token.text) }
  end.flatten
  tokens.each_with_index do |token, index|
    corrector.replace(token.pos, expected[index].text)
  end
  # Remove blank lines between the magic comments
  lines = tokens.map(&:line).to_set
  (lines.min...lines.max).each do |line|
    next if lines.include?(line)
    next unless processed_source[line - 1].empty?
    corrector.remove(source_range(processed_source.buffer, line, 0))
  end
end

def check_magic_comments_order(tokens)

def check_magic_comments_order(tokens)
  # Get the current magic comments order
  order = tokens.map do |token|
    PREFERRED_ORDER.keys.find { |re| re.match?(token.text) }
  end.compact.uniq
  # Get the expected magic comments order based on the one used in the actual source
  expected = PREFERRED_ORDER.keys.select do |re|
    tokens.any? { |token| re.match?(token.text) }
  end.uniq
  if order != expected
    tokens.each do |token|
      add_offense(
        token.pos,
        message: "Magic comments should be in the following order: #{PREFERRED_ORDER.values.join(", ")}.",
      ) do |corrector|
        autocorrect(corrector)
      end
    end
  end
end

def extract_magic_comments(processed_source)

Get all the tokens in `processed_source` that match `MAGIC_REGEX`
def extract_magic_comments(processed_source)
  processed_source.tokens
    .take_while { |token| token.type == :tCOMMENT }
    .select { |token| MAGIC_REGEX.match?(token.text) }
end

def on_new_investigation

def on_new_investigation
  return if processed_source.tokens.empty?
  tokens = extract_magic_comments(processed_source)
  return if tokens.empty?
  check_magic_comments_order(tokens)
end