class Code
A Ruby-specific block of code.
Definitions
def initialize(text, index, relative_to: nil, language:)
Initialize a new code block.
Signature
-
parameter
text
String
The code text.
-
parameter
index
Index
The index to use.
-
parameter
relative_to
Definition?
The definition this code is relative to.
-
parameter
language
Language::Generic
The language of the code.
Implementation
def initialize(text, index, relative_to: nil, language:)
@text = text
@root = ::Prism.parse(text)
@index = index
@relative_to = relative_to
@language = language
end
attr :text
Signature
-
attribute
String
The code text.
attr :root
Signature
-
attribute
untyped
The parsed syntax tree.
attr :index
Signature
-
attribute
Index
The index to use for lookups.
attr :relative_to
Signature
-
attribute
Definition?
The definition this code is relative to.
attr :language
Signature
-
attribute
Language::Generic
The language of the code.
def extract(into = [])
Extract definitions from the code.
Signature
-
parameter
into
Array
The array to extract definitions into.
-
returns
Array
The array with extracted definitions.
Implementation
def extract(into = [])
if @index
traverse(@root.value, into)
end
return into
end
def traverse(node, into)
Traverse the syntax tree and extract definitions.
Signature
-
parameter
node
untyped
The syntax tree node to traverse.
-
parameter
into
Array
The array to extract definitions into.
-
returns
self
Implementation
def traverse(node, into)
case node&.type
when :program_node
traverse(node.statements, into)
when :call_node
if reference = Reference.from_const(node, @language)
if definition = @index.lookup(reference, relative_to: @relative_to)
# Use message_loc for the method name, not the entire call
expression = node.message_loc
range = expression.start_offset...expression.end_offset
into << Syntax::Link.new(range, definition)
end
end
# Extract constants from arguments:
if node.arguments
node.arguments.arguments.each do |argument_node|
traverse(argument_node, into)
end
end
when :constant_read_node
if reference = Reference.from_const(node, @language)
if definition = @index.lookup(reference, relative_to: @relative_to)
expression = node.location
range = expression.start_offset...expression.end_offset
into << Syntax::Link.new(range, definition)
end
end
when :statements_node
node.body.each do |child|
traverse(child, into)
end
end
return self
end