Chris@909: module CodeRay Chris@909: module Encoders Chris@909: Chris@909: # Makes a statistic for the given tokens. Chris@909: # Chris@909: # Alias: +stats+ Chris@909: class Statistic < Encoder Chris@909: Chris@909: register_for :statistic Chris@909: Chris@909: attr_reader :type_stats, :real_token_count # :nodoc: Chris@909: Chris@909: TypeStats = Struct.new :count, :size # :nodoc: Chris@909: Chris@909: protected Chris@909: Chris@909: def setup options Chris@909: super Chris@909: Chris@909: @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 } Chris@909: @real_token_count = 0 Chris@909: end Chris@909: Chris@909: STATS = <<-STATS # :nodoc: Chris@909: Chris@909: Code Statistics Chris@909: Chris@909: Tokens %8d Chris@909: Non-Whitespace %8d Chris@909: Bytes Total %8d Chris@909: Chris@909: Token Types (%d): Chris@909: type count ratio size (average) Chris@909: ------------------------------------------------------------- Chris@909: %s Chris@909: STATS Chris@909: Chris@909: TOKEN_TYPES_ROW = <<-TKR # :nodoc: Chris@909: %-20s %8d %6.2f %% %5.1f Chris@909: TKR Chris@909: Chris@909: def finish options Chris@909: all = @type_stats['TOTAL'] Chris@909: all_count, all_size = all.count, all.size Chris@909: @type_stats.each do |type, stat| Chris@909: stat.size /= stat.count.to_f Chris@909: end Chris@909: types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v| Chris@909: TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size] Chris@909: end.join Chris@909: @out << STATS % [ Chris@909: all_count, @real_token_count, all_size, Chris@909: @type_stats.delete_if { |k, v| k.is_a? String }.size, Chris@909: types_stats Chris@909: ] Chris@909: Chris@909: super Chris@909: end Chris@909: Chris@909: public Chris@909: Chris@909: def text_token text, kind Chris@909: @real_token_count += 1 unless kind == :space Chris@909: @type_stats[kind].count += 1 Chris@909: @type_stats[kind].size += text.size Chris@909: @type_stats['TOTAL'].size += text.size Chris@909: @type_stats['TOTAL'].count += 1 Chris@909: end Chris@909: Chris@909: # TODO Hierarchy handling Chris@909: def begin_group kind Chris@909: block_token ':begin_group', kind Chris@909: end Chris@909: Chris@909: def end_group kind Chris@909: block_token ':end_group', kind Chris@909: end Chris@909: Chris@909: def begin_line kind Chris@909: block_token ':begin_line', kind Chris@909: end Chris@909: Chris@909: def end_line kind Chris@909: block_token ':end_line', kind Chris@909: end Chris@909: Chris@909: def block_token action, kind Chris@909: @type_stats['TOTAL'].count += 1 Chris@909: @type_stats[action].count += 1 Chris@909: @type_stats[kind].count += 1 Chris@909: end Chris@909: Chris@909: end Chris@909: Chris@909: end Chris@909: end