class Temill::SourceFile

Attributes

insertion_points[R]
lines[R]
path[R]
sexp[R]

Public Class Methods

from_inline_source(src, virtual_path, options) click to toggle source
# File lib/temill/core.rb, line 148
def self.from_inline_source(src, virtual_path, options)
  new(src, virtual_path, options)
end
from_path(path, options) click to toggle source
# File lib/temill/core.rb, line 152
def self.from_path(path, options)
  new(File.read(path), path, options)
end
new(src, path, options) click to toggle source
# File lib/temill/core.rb, line 140
def initialize(src, path, options)
  @path = path
  @lines = [nil] + src.lines
  @sexp = Ruby23Parser.new.parse(src, path).value
  @options = options
  @insertion_points = InsertionPointSet.new
end

Public Instance Methods

add_result(caller_loc, v, with_block) click to toggle source

@param [Thread::Backtrace::Location] caller_loc @param [Object] v value to show @param [bool] with_block whether Temill#show is called with block

# File lib/temill/core.rb, line 159
def add_result(caller_loc, v, with_block)
  caller_lineno = caller_loc.lineno
  unless @insertion_points.at_caller_lineno(caller_lineno)
    @insertion_points.add(make_insertion_point(caller_loc, with_block))
  end
  @insertion_points.at_caller_lineno(caller_lineno) << v
  self
end
each_source_line(&block) click to toggle source
# File lib/temill/core.rb, line 168
def each_source_line(&block)
  return enum_for(__method__) unless block
  1.upto(@lines.size-1){| i |
    block.call(@lines[i], i)
  }
end

Private Instance Methods

guess_indent_in_block(range) click to toggle source
# File lib/temill/core.rb, line 230
def guess_indent_in_block(range)
  @lines[range].map{| line |
    line[/\A([ \t]*)\S/] && $1  # remove empty lines
  }.compact.uniq.sort_by{| indent |
    indent.gsub(/\t/, ' ' * @options[:tabstop]).size
  }.first
end
indent_at(lineno) click to toggle source
# File lib/temill/core.rb, line 226
def indent_at(lineno)
  @lines[lineno][/\A[ \t]*/]
end
make_insertion_point(caller_loc, with_block=false) click to toggle source

@param [Thread::Backtrace::Location] caller_loc

# File lib/temill/core.rb, line 178
def make_insertion_point(caller_loc, with_block=false)
  caller_lineno = caller_loc.lineno
  last_line = caller_lineno
  inner_block_range = nil
  #ParserUtils.add_line_ranges_to_sexp(@sexp) # DEBUG
  @sexp.deep_each_with_self{| v |
    if v.kind_of?(Sexp) and
        [:iter, :call].include?(v.first) and
        v.line_range and
        v.line_range.min == caller_lineno
      last_line = [last_line, v.line_range.max].max
      if with_block and v.first == :iter and block_sexp = v[3]
        inner_block_range ||= block_sexp.line_range
        if inner_block_range.max < block_sexp.line_range.max
          inner_block_range = v[3].line_range
        end
      end
    end
  }

  # We don't want to use the caller line to guess the indent level
  # of the inner body of the block.
  if inner_block_range
    if inner_block_range.min == caller_lineno
      if inner_block_range.max == caller_lineno
        inner_block_range = nil
      else
        inner_block_range = (caller_lineno+1)..(inner_block_range.max)
      end
    end
  end

  if inner_block_range
    emitter_lineno = inner_block_range.max
    indent = guess_indent_in_block(inner_block_range)
  elsif with_block and
          end_line = @lines[last_line] and
          /\A\s*(?:end|})\s*$/ =~ end_line
    emitter_lineno = last_line - 1
    indent = indent_at(last_line) + @options[:default_indent]
  else
    emitter_lineno = last_line
    indent = indent_at(caller_lineno)
  end

  InsertionPoint.new(caller_loc, emitter_lineno, with_block, indent)
end