<commit_before>module Liquor
  class Diagnostic < StandardError
    attr_reader :location
    attr_reader :raw_message

    def initialize(message, location=nil)
      location_info = ""
      if location
        if location.include? :file
          location_info << "`#{location[:file]}'"
        end

        if location.include? :line
          location_info << ": line #{location[:line] + 1}"
          if location.include? :start
            location_info << ", column #{location[:start] + 1}"
          end
        end
      end

      @location    = location
      @raw_message = message

      if location_info.empty?
        super(message)
      else
        super("#{message} at #{location_info}")
      end
    end

    def error?
      false
    end

    def decorate(source)
      if @location && @location.has_key?(:line)
        line = source.lines.drop(@location[:line]).first.rstrip

        if @location.has_key? :start
          start_col = tabify_column line, @location[:start]
          pointer =  "~" * start_col

          if location.has_key? :end
            end_col = tabify_column line, @location[:end]

            pointer += "^" * (end_col - start_col + 1)
          else<commit_msg>Handle a weird edge case in Diagnostic#decorate.<commit_after>module Liquor
  class Diagnostic < StandardError
    attr_reader :location
    attr_reader :raw_message

    def initialize(message, location=nil)
      location_info = ""
      if location
        if location.include? :file
          location_info << "`#{location[:file]}'"
        end

        if location.include? :line
          location_info << ": line #{location[:line] + 1}"
          if location.include? :start
            location_info << ", column #{location[:start] + 1}"
          end
        end
      end

      @location    = location
      @raw_message = message

      if location_info.empty?
        super(message)
      else
        super("#{message} at #{location_info}")
      end
    end

    def error?
      false
    end

    def decorate(source)
      if @location && @location.has_key?(:line)
        line   = source.lines.drop(@location[:line]).first
        line ||= "(source spans only #{source.lines.count} lines)"
        line   = line.rstrip

        if @location.has_key? :start
          start_col = tabify_column line, @location[:start]
          pointer =  "~" * start_col

          if location.has_key? :end
            end_col = tabify_column line, @location[:end]

            pointer += "^" * (end_col - start_col + 1)
          else
{'fraction_non_alphanumeric': 0.11019607843137255, 'fraction_numerical': 0.002352941176470588, 'mean_word_length': 2.0296912114014254, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '890998', 'n_tokens_mistral': 739, 'n_tokens_neox': 710, 'n_words': 179}