Class: Solargraph::ApiMap::Source
- Inherits:
-
Object
- Object
- Solargraph::ApiMap::Source
- Includes:
- NodeMethods
- Defined in:
- lib/solargraph/api_map/source.rb
Instance Attribute Summary collapse
- #code ⇒ String readonly
- #comments ⇒ Array readonly
- #filename ⇒ String readonly
- #node ⇒ Parser::AST::Node readonly
- #stubbed_lines ⇒ Array<Integer> readonly
Class Method Summary collapse
- .beginning_of_line_from(str, i) ⇒ Object
- .fix(code, filename = nil, offset = nil) ⇒ Object
- .get_position_at(code, offset) ⇒ Object
- .load(filename) ⇒ Solargraph::ApiMap::Source
- .virtual(code, filename = nil) ⇒ Solargraph::ApiMap::Source
Instance Method Summary collapse
- #attribute_pins ⇒ Array<Solargraph::Pin::Attribute>
- #class_variable_pins ⇒ Array<Solargraph::Pin::ClassVariable>
- #code_for(node) ⇒ String
- #constant_pins ⇒ Array<Solargraph::Pin::Constant>
- #docstring_for(node) ⇒ YARD::Docstring
- #global_variable_pins ⇒ Array<Solargraph::Pin::GlobalVariable>
- #include?(node) ⇒ Boolean
-
#initialize(code, node, comments, filename, stubbed_lines = []) ⇒ Source
constructor
A new instance of Source.
- #instance_variable_pins ⇒ Array<Solargraph::Pin::InstanceVariable>
- #local_variable_pins ⇒ Array<Solargraph::Pin::LocalVariable>
- #method_pins ⇒ Array<Solargraph::Pin::Method>
- #namespace_for(node) ⇒ String
- #namespace_includes ⇒ Object
- #namespace_nodes ⇒ Object
- #namespace_pins ⇒ Array<Solargraph::Pin::Namespace>
- #namespaces ⇒ Object
- #required ⇒ Array<String>
- #superclasses ⇒ Object
- #symbol_pins ⇒ Array<Solargraph::Pin::Symbol>
- #tree_for(node) ⇒ Object
Methods included from NodeMethods
#const_from, #infer_literal_node_type, #pack_name, #resolve_node_signature, #unpack_name
Constructor Details
#initialize(code, node, comments, filename, stubbed_lines = []) ⇒ Source
Returns a new instance of Source.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/solargraph/api_map/source.rb', line 23 def initialize code, node, comments, filename, stubbed_lines = [] @code = code root = AST::Node.new(:source, [filename]) root = root.append node @node = root @comments = comments @directives = {} @docstring_hash = associate_comments(node, comments) @filename = filename @namespace_nodes = {} @all_nodes = [] @node_stack = [] @node_tree = {} @stubbed_lines = stubbed_lines inner_map_node @node @directives.each_pair do |k, v| v.each do |d| ns = namespace_for(k.node) docstring = YARD::Docstring.parser.parse(d.tag.text).to_docstring if d.tag.tag_name == 'attribute' t = (d.tag.types.nil? || d.tag.types.empty?) ? nil : d.tag.types.flatten.join('') if t.nil? or t.include?('r') attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :reader, docstring, d.tag.name) end if t.nil? or t.include?('w') attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :writer, docstring, "#{d.tag.name}=") end elsif d.tag.tag_name == 'method' gen_src = Source.virtual("def #{d.tag.name};end", filename) gen_pin = gen_src.method_pins.first method_pins.push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name) else STDERR.puts "Nothing to do for directive: #{d}" end end end end |
Instance Attribute Details
#code ⇒ String (readonly)
7 8 9 |
# File 'lib/solargraph/api_map/source.rb', line 7 def code @code end |
#comments ⇒ Array (readonly)
13 14 15 |
# File 'lib/solargraph/api_map/source.rb', line 13 def comments @comments end |
#filename ⇒ String (readonly)
16 17 18 |
# File 'lib/solargraph/api_map/source.rb', line 16 def filename @filename end |
#node ⇒ Parser::AST::Node (readonly)
10 11 12 |
# File 'lib/solargraph/api_map/source.rb', line 10 def node @node end |
#stubbed_lines ⇒ Array<Integer> (readonly)
19 20 21 |
# File 'lib/solargraph/api_map/source.rb', line 19 def stubbed_lines @stubbed_lines end |
Class Method Details
.beginning_of_line_from(str, i) ⇒ Object
383 384 385 386 387 388 |
# File 'lib/solargraph/api_map/source.rb', line 383 def beginning_of_line_from str, i while i > 0 and str[i-1] != "\n" i -= 1 end i end |
.fix(code, filename = nil, offset = nil) ⇒ Object
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/solargraph/api_map/source.rb', line 347 def fix code, filename = nil, offset = nil tries = 0 code.gsub!(/\r/, '') offset = CodeMap.get_offset(code, offset[0], offset[1]) if offset.kind_of?(Array) pos = nil pos = get_position_at(code, offset) unless offset.nil? stubs = [] fixed_position = false tmp = code begin node, comments = Parser::CurrentRuby.parse_with_comments(tmp) Source.new(code, node, comments, filename, stubs) rescue Parser::SyntaxError => e if tries < 10 tries += 1 # Stub periods before the offset to retain the expected node tree if !offset.nil? and tmp[offset-1] == '.' tmp = tmp[0, offset-1] + '_' + tmp[offset..-1] elsif !fixed_position and !offset.nil? fixed_position = true beg = beginning_of_line_from(tmp, offset) tmp = tmp[0, beg] + '#' + tmp[beg+1..-1] stubs.push(pos[0]) elsif e..include?('token $end') tmp += "\nend" elsif e..include?("unexpected `@'") tmp = tmp[0, e.diagnostic.location.begin_pos] + '_' + tmp[e.diagnostic.location.begin_pos+1..-1] end retry end STDERR.puts "Unable to parse code: #{e.}" virt = Source.virtual('', filename) Source.new(code, virt.node, virt.comments, filename) end end |
.get_position_at(code, offset) ⇒ Object
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/solargraph/api_map/source.rb', line 331 def get_position_at(code, offset) cursor = 0 line = 0 col = nil code.each_line do |l| if cursor + l.length >= offset col = offset - cursor break end cursor += l.length line += 1 end raise "Invalid offset" if col.nil? [line, col] end |
.load(filename) ⇒ Solargraph::ApiMap::Source
320 321 322 323 |
# File 'lib/solargraph/api_map/source.rb', line 320 def load filename code = File.read(filename).gsub(/\r/, '') Source.virtual(code, filename) end |
.virtual(code, filename = nil) ⇒ Solargraph::ApiMap::Source
326 327 328 329 |
# File 'lib/solargraph/api_map/source.rb', line 326 def virtual code, filename = nil node, comments = Parser::CurrentRuby.parse_with_comments(code) Source.new(code, node, comments, filename) end |
Instance Method Details
#attribute_pins ⇒ Array<Solargraph::Pin::Attribute>
83 84 85 |
# File 'lib/solargraph/api_map/source.rb', line 83 def attribute_pins @attribute_pins ||= [] end |
#class_variable_pins ⇒ Array<Solargraph::Pin::ClassVariable>
93 94 95 |
# File 'lib/solargraph/api_map/source.rb', line 93 def class_variable_pins @class_variable_pins ||= [] end |
#code_for(node) ⇒ String
134 135 136 137 138 139 |
# File 'lib/solargraph/api_map/source.rb', line 134 def code_for node b = node.location.expression.begin.begin_pos e = node.location.expression.end.end_pos frag = code[b..e-1].to_s frag.strip.gsub(/,$/, '') end |
#constant_pins ⇒ Array<Solargraph::Pin::Constant>
108 109 110 |
# File 'lib/solargraph/api_map/source.rb', line 108 def constant_pins @constant_pins ||= [] end |
#docstring_for(node) ⇒ YARD::Docstring
128 129 130 131 |
# File 'lib/solargraph/api_map/source.rb', line 128 def docstring_for node return @docstring_hash[node.loc] if node.respond_to?(:loc) nil end |
#global_variable_pins ⇒ Array<Solargraph::Pin::GlobalVariable>
103 104 105 |
# File 'lib/solargraph/api_map/source.rb', line 103 def global_variable_pins @global_variable_pins ||= [] end |
#include?(node) ⇒ Boolean
156 157 158 |
# File 'lib/solargraph/api_map/source.rb', line 156 def include? node @all_nodes.include? node end |
#instance_variable_pins ⇒ Array<Solargraph::Pin::InstanceVariable>
88 89 90 |
# File 'lib/solargraph/api_map/source.rb', line 88 def instance_variable_pins @instance_variable_pins ||= [] end |
#local_variable_pins ⇒ Array<Solargraph::Pin::LocalVariable>
98 99 100 |
# File 'lib/solargraph/api_map/source.rb', line 98 def local_variable_pins @local_variable_pins ||= [] end |
#method_pins ⇒ Array<Solargraph::Pin::Method>
78 79 80 |
# File 'lib/solargraph/api_map/source.rb', line 78 def method_pins @method_pins ||= [] end |
#namespace_for(node) ⇒ String
146 147 148 149 150 151 152 153 154 |
# File 'lib/solargraph/api_map/source.rb', line 146 def namespace_for node parts = [] ([node] + (@node_tree[node] || [])).each do |n| if n.type == :class or n.type == :module parts.unshift unpack_name(n.children[0]) end end parts.join('::') end |
#namespace_includes ⇒ Object
69 70 71 |
# File 'lib/solargraph/api_map/source.rb', line 69 def namespace_includes @namespace_includes ||= {} end |
#namespace_nodes ⇒ Object
65 66 67 |
# File 'lib/solargraph/api_map/source.rb', line 65 def namespace_nodes @namespace_nodes end |
#namespace_pins ⇒ Array<Solargraph::Pin::Namespace>
118 119 120 |
# File 'lib/solargraph/api_map/source.rb', line 118 def namespace_pins @namespace_pins ||= [] end |
#namespaces ⇒ Object
61 62 63 |
# File 'lib/solargraph/api_map/source.rb', line 61 def namespaces @namespace_nodes.keys end |
#required ⇒ Array<String>
123 124 125 |
# File 'lib/solargraph/api_map/source.rb', line 123 def required @required ||= [] end |
#superclasses ⇒ Object
73 74 75 |
# File 'lib/solargraph/api_map/source.rb', line 73 def superclasses @superclasses ||= {} end |
#symbol_pins ⇒ Array<Solargraph::Pin::Symbol>
113 114 115 |
# File 'lib/solargraph/api_map/source.rb', line 113 def symbol_pins @symbol_pins ||= [] end |
#tree_for(node) ⇒ Object
141 142 143 |
# File 'lib/solargraph/api_map/source.rb', line 141 def tree_for node @node_tree[node] || [] end |