class Solargraph::Source::SourceChainer
results for completion and definition queries.
location is inside a string or comment. ApiMaps use Fragments to provide
and signature, literal values at the base of signatures, and whether the
Information about a location in a source, including the location’s word
def chain source, position
-
(Source::Chain)-
Parameters:
-
position(Position) -- -
source(Source) --
def chain source, position raise "Not a source" unless source.is_a?(Source) new(source, position).chain end
def chain
-
(Source::Chain)-
def chain return Chain.new([Chain::Literal.new('Symbol')]) if phrase.start_with?(':') && !phrase.start_with?('::') # return Chain.new([Chain::UNDEFINED_CALL]) unless infer_literal_node_type(source.node_at(position.line, position.column)).nil? begin return Chain.new([]) if phrase.end_with?('..') if !source.repaired? && source.parsed? node = source.node_at(position.line, position.column) else node = nil node = source.node_at(fixed_position.line, fixed_position.column) unless source.error_ranges.any?{|r| r.include?(fixed_position)} node = Source.parse(fixed_phrase) if node.nil? end rescue Parser::SyntaxError return Chain.new([Chain::UNDEFINED_CALL]) end return Chain.new([Chain::UNDEFINED_CALL]) if node.nil? || (node.type == :sym && !phrase.start_with?(':')) chain = NodeChainer.chain(node, source.filename) if source.repaired? || !source.parsed? if end_of_phrase.strip == '.' chain.links.push Chain::UNDEFINED_CALL elsif end_of_phrase.strip == '::' chain.links.push Chain::UNDEFINED_CONSTANT end end chain end
def character
-
(Integer)-
def character @column end
def end_of_phrase
-
(String)-
def end_of_phrase @end_of_phrase ||= begin match = phrase.match(/[\s]*(\.{1}|::)[\s]*$/) if match match[0] else '' end end end
def fixed_phrase
-
(String)-
def fixed_phrase @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)] end
def fixed_position
-
(Position)-
def fixed_position @fixed_position ||= Position.from_offset(source.code, offset - end_of_phrase.length) end
def get_offset line, column
-
(Integer)-
Parameters:
-
column(Integer) -- -
line(Integer) --
def get_offset line, column Position.line_char_to_offset(@source.code, line, column) end
def get_signature_data_at index
def get_signature_data_at index brackets = 0 squares = 0 parens = 0 signature = '' index -=1 in_whitespace = false while index >= 0 pos = Position.from_offset(@source.code, index) break if index > 0 and @source.comment_at?(pos) unless !in_whitespace and string? break if brackets > 0 or parens > 0 or squares > 0 char = @source.code[index, 1] break if char.nil? # @todo Is this the right way to handle this? if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char) in_whitespace = true else if brackets.zero? and parens.zero? and squares.zero? and in_whitespace unless char == '.' or @source.code[index+1..-1].strip.start_with?('.') old = @source.code[index+1..-1] nxt = @source.code[index+1..-1].lstrip index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length) break end end if char == ')' parens -=1 elsif char == ']' squares -=1 elsif char == '}' brackets -= 1 elsif char == '(' parens += 1 elsif char == '{' brackets += 1 elsif char == '[' squares += 1 signature = ".[]#{signature}" if parens.zero? and brackets.zero? and squares.zero? and @source.code[index-2] != '%' end if brackets.zero? and parens.zero? and squares.zero? break if ['"', "'", ',', ';', '%'].include?(char) signature = char + signature if char.match(/[a-z0-9:\._@\$\?\!]/i) and @source.code[index - 1] != '%' break if char == '$' if char == '@' signature = "@#{signature}" if @source.code[index-1, 1] == '@' break end elsif parens == 1 || brackets == 1 || squares == 1 break end in_whitespace = false end end index -= 1 end # @todo Smelly exceptional case for integer literals # match = signature.match(/^[0-9]+/) # if match # index += match[0].length # signature = signature[match[0].length..-1].to_s # @base_literal = 'Integer' # # @todo Smelly exceptional case for array literals # elsif signature.start_with?('.[]') # index += 2 # signature = signature[3..-1].to_s # @base_literal = 'Array' # elsif signature.start_with?('.') # pos = Position.from_offset(@source.code, index) # node = @source.node_at(pos.line, pos.character) # lit = infer_literal_node_type(node) # unless lit.nil? # signature = signature[1..-1].to_s # index += 1 # @base_literal = lit # end # end [index + 1, signature] end
def initialize source, position
-
position(Position) -- -
source(Source) --
def initialize source, position @source = source # @source.code = source.code @position = position # @todo Get rid of line/column @line = position.line @column = position.column @calculated_literal = false end
def offset
-
(Integer)-
def offset @offset ||= get_offset(line, column) end
def phrase
-
(String)-
def phrase @phrase ||= source.code[signature_data[0]..offset-1] end
def signature_data
def signature_data @signature_data ||= get_signature_data_at(offset) end
def string?
-
(Boolean)-
def string? # @string ||= (node.type == :str or node.type == :dstr) @string ||= @source.string_at?(position) end