class SheepAst::StageManager

StageManager manages stages.

Public Class Methods

new(data_store) click to toggle source
Calls superclass method SheepAst::Log::new
# File lib/sheep_ast/stage_manager.rb, line 233
def initialize(data_store)
  @stages = []
  @stages_name = {}
  @save_stages = [{}]
  @data_store = data_store
  super()
end

Public Instance Methods

add_stage(ast) click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 242
def add_stage(ast)
  if ast.full_name.nil? || @stages_name.key?(ast.full_name)
    lfatal "debug => #{@stages_name.keys} is listed, #{ast.full_name} to be added."
    application_error 'ast name should be not nil and not duplicate'
  end

  a_stage = Stage.new(ast)
  @stages_name[ast.full_name] = a_stage
  @stages << a_stage
end
analyze_stages(data) click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 310
def analyze_stages(data) # rubocop: disable all
  ldebug? and ldebug 'Analyze Stages start!', :red

  data.stage_manager = self
  @data = data

  incl = T.must(data.file_info).ast_include
  excl = T.must(data.file_info).ast_exclude

  if incl.nil?
    ldebug? and ldebug 'AST with default domain is procssed'
    incl = 'default'
  end

  if excl.nil?
    excl = ''
  end

  if incl.instance_of?(String)
    incl = [incl]
  end

  if excl.instance_of?(String)
    excl = [excl]
  end

  processed = T.let(false, T::Boolean)
  ret = T.let(MatchResult::Default, MatchResult)
  @stages.each do |stage|
    if filter?(
        T.cast(incl, T::Array[T.any(String, Regexp)]),
        T.cast(excl, T::Array[T.any(String, Regexp)]),
        stage.ast.domain, stage.ast.full_name)
      processed = true
      ldebug? and ldebug "#{stage.name} start analyzing data!", :violet
      ret = stage.analyze(data)

      break if ret == MatchResult::GetNext || ret == MatchResult::Finish
    else
      ldebug? and ldebug "#{stage.name} is filtered", :yellow
    end
  end

  if !processed
    lfatal 'At least one default domain ast shall be registered.'
    lfatal 'Please make sure that your registered AST Manager has default.<name> in its name.'
    lfatal 'Reason: Sheep_ast starts processing default.<name> initially.'
    application_error 'default domain AST Manager cannot be found.'
  end

  application_error 'Should not enter this route. Bug.' if ret == MatchResult::Default

  if ret == MatchResult::NotFound
    if @data_store.value(:_sheep_not_raise_when_lazy_abort)
      ldebug? and ldebug 'All the AST stage not found expression. But return false'
    else
      lfatal 'All the AST stage not found expression. Lazy Abort!'
      expression_not_found "'#{data.expr.inspect}'"
    end
  end

  if data.expr == '__sheep_eof__'
    eof_validation
  end

  ldebug? and ldebug "Analyze Stages Finished with #{ret.inspect} !", :red

  return ret
end
dump_tree(logs) click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 422
def dump_tree(logs) # rubocop: disable all
  if @data&.file_info&.line == nil
    line_no = nil
  else
    line_no = @data&.file_info&.line + 1
  end

  logf = method(logs)
  logf.call
  logf.call '## Analyze information start ##'
  logf.call 'Processing file'
  logf.call "- #{@data&.file_info&.file.inspect}"
  logf.call
  logf.call 'Tokenized Expression'
  logf.call "- expr = #{@data&.expr}"
  logf.call "- tokenized line = #{@data&.tokenized_line.inspect}"
  logf.call "- line no = #{line_no}"
  logf.call "- index = #{@data&.file_info&.index.inspect}"
  logf.call "- max_line = #{@data&.file_info&.max_line.inspect}"
  logf.call "- namespacee = #{@data&.file_info&.namespace_stack.inspect}"
  logf.call "- ast include = #{@data&.file_info&.ast_include.inspect}"
  logf.call "- ast exclude = #{@data&.file_info&.ast_exclude.inspect}"
  logf.call
  @stages.each do |stage|
    logf.call '|'
    logf.call '|'
    logf.call '|'
    logf.call '|/'
    logf.call '================================='
    logf.call "#{stage.name}> tree & Stack"
    logf.call '================================='
    logf.call '[AST]', :cyan
    stage.dump_tree(logs)
    logf.call '---------------------------------'
    logf.call '[Match Stack]', :yellow
    stage.dump_stack(logs)
    logf.call '================================='
  end
  logf.call '|'
  logf.call '|'
  logf.call '|'
  logf.call '|'
  logf.call '|  |\\ Next Expression'
  logf.call '|__|'
  logf.call ''
end
eof_validation() click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 381
def eof_validation
  @stages.each do |stage|
    len = stage.match_id_array.length
    if len != 0
      lfatal "Validation Fail!!! stage = #{stage.name}."
      lfatal 'To reach here means that in spite of end of file processing, some stages are'
      lfatal 'during AST process. This is thought to be invalid scenario.'
      lfatal 'Please check if this is really valid case.'
      lfatal 'You can off this by call disable_eof_validation in the AnalyzerCore'
      lfatal 'But the stiation maybe bug of sheep_ast or user code.'
      application_error 'eof validation error'
    end
  end
end
filter?(incl, excl, domain, full_name) click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 269
def filter?(incl, excl, domain, full_name) # rubocop: disable all
  return true if domain == 'always'

  ret = T.let(false, T::Boolean)
  incl.each do |comp|
    res = comp == domain if comp.instance_of? String

    if !res
      res = comp == full_name if comp.instance_of? String
      res = comp =~ full_name if comp.instance_of? Regexp
    end

    if res
      ldebug? and ldebug "#{comp} is included", :yellow
      ret = true
      break
    end
  end

  if excl&.empty?
    return ret
  end

  T.must(excl).each do |comp|
    res = comp == domain if comp.instance_of? String

    if !res
      res = comp == full_name if comp.instance_of? String
      res = comp =~ full_name if comp.instance_of? Regexp
    end
    if res
      ldebug? and ldebug "#{comp} is excluded", :yellow
      ret = false
      break
    end
  end

  return ret
end
restore_info() click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 409
def restore_info
  save_data = @save_stages.last
  return false if save_data.nil?

  @stages.each do |stage|
    stage.copy(save_data[stage.name])
    ldebug? and ldebug "#{stage.name} resume process !!! info = #{stage.inspect}"
  end
  @save_stages.pop
  return true
end
save_info() click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 397
def save_info
  save_data = {}
  @stages.each do |stage|
    save_stage =
      Stage.new(stage.ast)
    save_data[stage.name] = save_stage.save(stage)
    ldebug? and ldebug "#{stage.name} suspend process !!! info = #{stage.inspect}"
  end
  @save_stages << save_data
end
stage_get(name) click to toggle source
# File lib/sheep_ast/stage_manager.rb, line 254
def stage_get(name)
  res = @stages_name[name]
  application_error 'specified name does not hit any stage' unless res
 
  return res
end