Class: SeeingIsBelieving::Code
- Inherits:
-
Object
- Object
- SeeingIsBelieving::Code
- Defined in:
- lib/seeing_is_believing/code.rb
Constant Summary collapse
- InlineComment =
HashStruct.for :line_number, :whitespace_col, :whitespace, :text_col, :text, :full_range, :whitespace_range, :comment_range
- Syntax =
HashStruct.for error_message: nil, line_number: nil do def valid?() ! end def invalid?() !valid? end end
Instance Attribute Summary collapse
-
#body_range ⇒ Object
readonly
Returns the value of attribute body_range.
-
#buffer ⇒ Object
readonly
Returns the value of attribute buffer.
-
#inline_comments ⇒ Object
readonly
Returns the value of attribute inline_comments.
-
#parser ⇒ Object
readonly
Returns the value of attribute parser.
-
#raw ⇒ Object
readonly
Returns the value of attribute raw.
-
#raw_comments ⇒ Object
readonly
Returns the value of attribute raw_comments.
-
#rewriter ⇒ Object
readonly
Returns the value of attribute rewriter.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#syntax ⇒ Object
readonly
Returns the value of attribute syntax.
Instance Method Summary collapse
- #heredoc?(ast) ⇒ Boolean
- #index_to_linenum(char_index) ⇒ Object
- #indexes_of_ors_at_eol ⇒ Object
-
#initialize(raw_code, name = nil) ⇒ Code
constructor
A new instance of Code.
- #line_indexes ⇒ Object
- #linenum_to_index(line_num) ⇒ Object
- #range_for(start_index, end_index) ⇒ Object
- #void_value?(ast) ⇒ Boolean
Constructor Details
#initialize(raw_code, name = nil) ⇒ Code
Returns a new instance of Code.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/seeing_is_believing/code.rb', line 23 def initialize(raw_code, name=nil) raw_code[-1] == "\n" || raise(SyntaxError, "Code must end in a newline for the sake of consistency (sanity)") @raw = raw_code @buffer = Parser::Source::Buffer.new(name||"SeeingIsBelieving") @buffer.source = raw @rewriter = Parser::Source::TreeRewriter.new buffer builder = Parser::Builders::Default.new.tap { |b| b.emit_file_line_as_literals = false } @parser = Parser::CurrentRuby.new builder @syntax = Syntax.new parser.diagnostics.consumer = lambda do |diagnostic| if :fatal == diagnostic.level || :error == diagnostic.level @syntax = Syntax.new error_message: diagnostic., line_number: index_to_linenum(diagnostic.location.begin_pos) end end @root, @raw_comments, @tokens = parser.tokenize(@buffer, true) @body_range = body_range_from_tokens(@tokens) @inline_comments = raw_comments.select(&:inline?).map { |c| wrap_comment c } @root ||= null_node end |
Instance Attribute Details
#body_range ⇒ Object (readonly)
Returns the value of attribute body_range.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def body_range @body_range end |
#buffer ⇒ Object (readonly)
Returns the value of attribute buffer.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def buffer @buffer end |
#inline_comments ⇒ Object (readonly)
Returns the value of attribute inline_comments.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def inline_comments @inline_comments end |
#parser ⇒ Object (readonly)
Returns the value of attribute parser.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def parser @parser end |
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def raw @raw end |
#raw_comments ⇒ Object (readonly)
Returns the value of attribute raw_comments.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def raw_comments @raw_comments end |
#rewriter ⇒ Object (readonly)
Returns the value of attribute rewriter.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def rewriter @rewriter end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def root @root end |
#syntax ⇒ Object (readonly)
Returns the value of attribute syntax.
21 22 23 |
# File 'lib/seeing_is_believing/code.rb', line 21 def syntax @syntax end |
Instance Method Details
#heredoc?(ast) ⇒ Boolean
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/seeing_is_believing/code.rb', line 56 def heredoc?(ast) # some strings are fucking weird. # e.g. the "1" in `%w[1]` returns nil for ast.location.begin # and `__FILE__` is a string whose location is a Parser::Source::Map instead of a Parser::Source::Map::Collection, # so it has no #begin ast.kind_of?(Parser::AST::Node) && (ast.type == :dstr || ast.type == :str) && (location = ast.location) && (location.kind_of? Parser::Source::Map::Heredoc) end |
#index_to_linenum(char_index) ⇒ Object
47 48 49 |
# File 'lib/seeing_is_believing/code.rb', line 47 def index_to_linenum(char_index) line_indexes.index { |line_index| char_index < line_index } || line_indexes.size end |
#indexes_of_ors_at_eol ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/seeing_is_believing/code.rb', line 91 def indexes_of_ors_at_eol Set.new( @tokens.select { |type, *| type == :tGVAR } .select { |_, (var, _range)| var == '$\\'.freeze } .map { |_, (_var, range)| range.end_pos } ) end |
#line_indexes ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/seeing_is_believing/code.rb', line 82 def line_indexes @line_indexes ||= [ 0, *raw.each_char .with_index(1) .select { |char, index| char == "\n" } .map { |char, index| index }, ].freeze end |
#linenum_to_index(line_num) ⇒ Object
51 52 53 54 |
# File 'lib/seeing_is_believing/code.rb', line 51 def linenum_to_index(line_num) return raw.size if line_indexes.size < line_num line_indexes[line_num - 1] end |
#range_for(start_index, end_index) ⇒ Object
43 44 45 |
# File 'lib/seeing_is_believing/code.rb', line 43 def range_for(start_index, end_index) Parser::Source::Range.new buffer, start_index, end_index end |
#void_value?(ast) ⇒ Boolean
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/seeing_is_believing/code.rb', line 67 def void_value?(ast) case ast && ast.type when :begin, :kwbegin, :resbody void_value?(ast.children.last) when :rescue, :ensure ast.children.any? { |child| void_value? child } when :if void_value?(ast.children[1]) || void_value?(ast.children[2]) when :return, :next, :redo, :retry, :break true else false end end |