Module: Maccro::CodeUtil
- Defined in:
- lib/maccro/code_util.rb
Class Method Summary collapse
- .code_position_to_index(source, lineno, column) ⇒ Object
- .code_range_to_code(source, code_range) ⇒ Object
- .code_range_to_range(source, code_range) ⇒ Object
- .dig_method_node(node, def_type, method_name_index, method_name, lineno, column) ⇒ Object
- .extend_tree_with_wrapper(tree) ⇒ Object
- .get_method_node(node, method_name, lineno, column, singleton_method: false) ⇒ Object
- .get_source_path_iseq(method) ⇒ Object
- .parse_to_ast(code) ⇒ Object
- .proc_to_ast(block) ⇒ Object
- .proc_to_iseq(block) ⇒ Object
- .suppress_warning ⇒ Object
Class Method Details
.code_position_to_index(source, lineno, column) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/maccro/code_util.rb', line 3 def self.code_position_to_index(source, lineno, column) source_lines = source.lines # including newline at the end of line if source_lines.size < lineno raise "too few lines for specified position: lineno:#{lineno}, column:#{column}" end counter = 1 index = 0 while counter < lineno index += source_lines.shift.size counter += 1 end if source_lines.empty? raise "too few lines for specified position: lineno:#{lineno}, column:#{column}" end # column is 0 origin if source_lines.first.size < 1 raise "empty line at the end of source" end if source_lines.first.size < column raise "too few chars in the line for specified position: lineno:#{lineno}, column:#{column}" end return index + column end |
.code_range_to_code(source, code_range) ⇒ Object
33 34 35 |
# File 'lib/maccro/code_util.rb', line 33 def self.code_range_to_code(source, code_range) source[code_range_to_range(source, code_range)] end |
.code_range_to_range(source, code_range) ⇒ Object
27 28 29 30 31 |
# File 'lib/maccro/code_util.rb', line 27 def self.code_range_to_range(source, code_range) begin_index = code_position_to_index(source, code_range.first_lineno, code_range.first_column) end_index = code_position_to_index(source, code_range.last_lineno, code_range.last_column) Range.new(begin_index, end_index, true) # exclude end char end |
.dig_method_node(node, def_type, method_name_index, method_name, lineno, column) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/maccro/code_util.rb', line 93 def self.dig_method_node(node, def_type, method_name_index, method_name, lineno, column) return nil unless node.is_a?(RubyVM::AbstractSyntaxTree::Node) if node.type == def_type && node.children[method_name_index] == method_name && node.first_lineno == lineno && node.first_column == column return node elsif node.respond_to?(:children) node.children.each do |n| r = dig_method_node(n, def_type, method_name_index, method_name, lineno, column) return r if r end end nil end |
.extend_tree_with_wrapper(tree) ⇒ Object
61 62 63 64 65 66 67 |
# File 'lib/maccro/code_util.rb', line 61 def self.extend_tree_with_wrapper(tree) return unless tree.is_a?(RubyVM::AbstractSyntaxTree::Node) tree.extend Maccro::DSL::ASTNodeWrapper unless tree.is_a?(Maccro::DSL::ASTNodeWrapper) tree.children.each do |c| extend_tree_with_wrapper(c) end end |
.get_method_node(node, method_name, lineno, column, singleton_method: false) ⇒ Object
83 84 85 86 87 88 89 90 91 |
# File 'lib/maccro/code_util.rb', line 83 def self.get_method_node(node, method_name, lineno, column, singleton_method: false) if singleton_method # TODO: consider receiver filter # 0: (SELF@57:6-57:10) dig_method_node(node, :DEFS, 1, method_name, lineno, column) else dig_method_node(node, :DEFN, 0, method_name, lineno, column) end end |
.get_source_path_iseq(method) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/maccro/code_util.rb', line 69 def self.get_source_path_iseq(method) iseq ||= CodeUtil.proc_to_iseq(method) if !iseq raise "Native methods can't be redefined" end path ||= iseq.absolute_path if !path # STDIN or -e raise "Methods from stdin or -e can't be redefined" end source ||= File.read(path) return source, path, iseq end |
.parse_to_ast(code) ⇒ Object
45 46 47 48 49 |
# File 'lib/maccro/code_util.rb', line 45 def self.parse_to_ast(code) suppress_warning do RubyVM::AbstractSyntaxTree.parse(code) end end |
.proc_to_ast(block) ⇒ Object
51 52 53 54 55 |
# File 'lib/maccro/code_util.rb', line 51 def self.proc_to_ast(block) suppress_warning do RubyVM::AbstractSyntaxTree.of(block) end end |
.proc_to_iseq(block) ⇒ Object
57 58 59 |
# File 'lib/maccro/code_util.rb', line 57 def self.proc_to_iseq(block) RubyVM::InstructionSequence.of(block) end |
.suppress_warning ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/maccro/code_util.rb', line 37 def self.suppress_warning v = $VERBOSE $VERBOSE = nil yield ensure $VERBOSE = v end |