class ReVIEW::Preprocessor::Repository

Public Class Methods

new(param) click to toggle source
# File lib/review/preprocessor/repository.rb, line 18
def initialize(param)
  @repository = {}
  @config = param
  @leave_content = nil
  @logger = ReVIEW.logger
end

Public Instance Methods

fetch(file, type, name) click to toggle source
# File lib/review/preprocessor/repository.rb, line 33
def fetch(file, type, name)
  table = file_descripter(file)[type] or return nil
  table[name]
end
fetch_file(file) click to toggle source
# File lib/review/preprocessor/repository.rb, line 25
def fetch_file(file)
  file_descripter(file)['file']
end
fetch_range(file, name) click to toggle source
# File lib/review/preprocessor/repository.rb, line 29
def fetch_range(file, name)
  fetch(file, 'range', name)
end

Private Instance Methods

_parse_file(f) click to toggle source
# File lib/review/preprocessor/repository.rb, line 65
def _parse_file(f)
  whole = []
  repo = { 'file' => whole }
  curr = { 'WHOLE' => whole }
  lineno = 1
  yacchack = false # remove ';'-only lines.
  opened = [['(not opened)', '(not opened)']] * 3

  f.each do |line|
    begin
      case line
      when /(?:\A\#@|\#@@)([a-z]+)_(begin|end)\((.*)\)/
        type = check_type($1)
        direction = $2
        spec = check_spec($3)
        case direction
        when 'begin'
          key = "#{type}/#{spec}"
          if curr[key]
            app_error "begin x2: #{key}"
          end
          (repo[type] ||= {})[spec] = curr[key] = []
        when 'end'
          curr.delete("#{type}/#{spec}") or
            app_error "end before begin: #{type}/#{spec}"
        else
          app_error 'must not happen'
        end

      when %r{(?:\A\#@|\#@@)([a-z]+)/(\w+)\{}
        type = check_type($1)
        spec = check_spec($2)
        key = "#{type}/#{spec}"
        if curr[key]
          app_error "begin x2: #{key}"
        end
        (repo[type] ||= {})[spec] = curr[key] = []
        opened.push([type, spec])

      when %r{(?:\A\#@|\#@@)([a-z]+)/(\w+)\}}
        type = check_type($1)
        spec = check_spec($2)
        curr.delete("#{type}/#{spec}") or
          app_error "end before begin: #{type}/#{spec}"
        opened.delete("#{type}/#{spec}")

      when /(?:\A\#@|\#@@)\}/
        type, spec = opened.last
        curr.delete("#{type}/#{spec}") or
          app_error "closed before open: #{type}/#{spec}"
        opened.pop

      when /(?:\A\#@|\#@@)yacchack/
        yacchack = true

      when /\A\#@-/ # does not increment line number.
        line = canonical($')
        curr.each_value { |list| list.push(Line.new(nil, line)) }

      else
        next if yacchack && (line.strip == ';')

        line = canonical(line)
        curr.each_value { |list| list.push(Line.new(lineno, line)) }
        lineno += 1
      end
    rescue ApplicationError => e
      @has_errors = true
      error e.message, location: location
    end
  end
  if curr.size > 1
    curr.delete('WHOLE')
    curr.each { |range, lines| warn "#{@inf.path}: unclosed range: #{range} (begin @#{lines.first.number})" }
    @has_errors = true
  end

  if @has_errors
    error! 'repository failed.'
  end

  repo
end
canonical(line) click to toggle source
# File lib/review/preprocessor/repository.rb, line 149
def canonical(line)
  if @leave_content
    return line
  end

  tabwidth = @config['tabwidth'] || 8
  if tabwidth > 0
    detab(line, tabwidth).rstrip + "\n"
  else
    line
  end
end
check_spec(spec) click to toggle source
# File lib/review/preprocessor/repository.rb, line 167
def check_spec(spec)
  app_error "wrong spec: #{spec.inspect}" unless /\A\w+\z/ =~ spec
  spec
end
check_type(type) click to toggle source
# File lib/review/preprocessor/repository.rb, line 162
def check_type(type)
  app_error "wrong type: #{type.inspect}" unless Preprocessor::TYPES.index(type)
  type
end
file_descripter(fname) click to toggle source
# File lib/review/preprocessor/repository.rb, line 40
def file_descripter(fname)
  @leave_content = File.extname(fname) == '.re'
  return @repository[fname] if @repository[fname]

  @repository[fname] = git?(fname) ? parse_git_blob(fname) : parse_file(fname)
end
git?(fname) click to toggle source
# File lib/review/preprocessor/repository.rb, line 47
def git?(fname)
  fname.start_with?('git|')
end
location() click to toggle source
# File lib/review/preprocessor/repository.rb, line 172
def location
  "#{@inf.path}:#{@inf.lineno}"
end
parse_file(fname) click to toggle source
# File lib/review/preprocessor/repository.rb, line 58
def parse_file(fname)
  File.open(fname, 'rt:BOM|utf-8') do |f|
    @inf = f
    return _parse_file(f)
  end
end
parse_git_blob(g_obj) click to toggle source
# File lib/review/preprocessor/repository.rb, line 51
def parse_git_blob(g_obj)
  IO.popen('git show ' + g_obj.sub(/\Agit\|/, ''), 'r') do |f|
    @inf = f
    return _parse_file(f)
  end
end