require "tree-sitter"
type CodeSymbol = Hash(String, String | Array(Hash(String, String)))
class RepositoryFile
property name : String
property content : String
def initialize(@name, @content)
end
end
def get_file_content(file : RepositoryFile) : String
file.content
end
def extract_symbols(parser : TreeSitter::Parser, node : TreeSitter::Node, file : RepositoryFile) : Array(CodeSymbol)
symbols = [] of CodeSymbol
case node.type
when "function"
args = [] of Hash(String, String)
node.children.select { |child| child.type == "parameter" }.each do |child|
args << {
"type" => child.children.find { |grandchild| grandchild.type == "type" }.inspect,
"name" => child.children.find { |grandchild| grandchild.type == "identifier" }.text,
}
end
return_type = node.children.find { |child| child.type == "type" }.inspect
symbols << {
"type" => "function",
"name" => node.children.find { |child| child.type == "identifier" }.text,
"args" => args,
"returnType" => return_type,
"visibility" => "public",
}
when "class"
properties = [] of Hash(String, String)
methods = [] of CodeSymbol
constants = [] of Hash(String, String)
node.children.each do |child|
case child.type
when "property"
properties << {
"name" => child.children.find { |grandchild| grandchild.type == "identifier" }.text,
"type" => child.children.find { |grandchild| grandchild.type == "type" }.inspect,
}
when "function"
args = [] of Hash(String, String)
child.children.select { |grandchild| grandchild.type == "parameter" }.each do |grandchild|
args << {
"type" => grandchild.children.find { |great_grandchild| great_grandchild.type == "type" }.inspect,
"name" => grandchild.children.find { |great_grandchild| great_grandchild.type == "identifier" }.text,
}
end
return_type = child.children.find { |grandchild| grandchild.type == "type" }.inspect
methods << {
"name" => child.children.find { |grandchild| grandchild.type == "identifier" }.text,
"args" => args,
"returnType" => return_type,
}
when "constant"
constants << {
"name" => child.children.find { |grandchild| grandchild.type == "identifier" }.text,
"value" => child.children.find { |grandchild| grandchild.type == "type" }.inspect,
}
end
end
symbols << {
"type" => "class",
"name" => node.children.find { |child| child.type == "identifier" }.text,
"properties" => properties,
"methods" => methods,
"constants" => constants,
}
when "constant"
symbols << {
"type" => "constant",
"name" => node.children.find { |child| child.type == "identifier" }.text,
"value" => node.children.find { |child| child.type == "type" }.inspect,
}
end
node.children.each do |child|
symbols.concat(extract_symbols(parser, child, file))
end
symbols
end