Current section
Files
Jump to
Current section
Files
lib/treesitter.ex
defmodule TreeSitter.Nif do
def so_contents, do: unquote(File.read!("priv/treesitter_nif.so"))
def load_nifs do
# NOTE: Traditionally this is done using the priv dir, but we want to support escript.build, which does not support priv.
# Instead so_contents() contains the binary contents of the ".so" file and we write it to a temp file and load it.
# TODO: Can we skip the writing to a file and pass the binary directly to :erlang.load_nif?
# :erlang.load_nif("priv/treesitter_nif", 0)
{:ok, path} = Briefly.create()
File.write!(path <> ".so", so_contents())
:erlang.load_nif(path, 0)
end
@doc """
Return the full language name and the full path, needed for `parser_set_language` given the language name and the path to search
## Examples:
TreeSitter.Nif.language_path("c", "/usr/lib")
"""
def language_path(language, path)
def language_path(nm, pth) do
# TODO: Use path join, so it is more likely to work on windows
{"tree_sitter_#{nm}", "#{pth}/libtree-sitter-#{nm}.so"}
end
def parser_new() do
:erlang.nif_error(:nif_not_loaded)
end
@doc """
Get the langage given a full name of the language and the path to the shared library implementing the language.
`language_path` is a useful helper function to get the full language name and path if needed
## Examples:
TreeSitter.Nif.language("tree_sitter_c", "/usr/lib/libtree-sitter-c.so")
"""
def language(language, full_path)
def language(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def parser_set_language(parser, language)
def parser_set_language(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def parser_parse_string(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def parse(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def tree_root_node(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_parent(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_child(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_next_sibling(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_prev_sibling(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_string(_) do
:erlang.nif_error(:nif_not_loaded)
end
def node_type(_) do
:erlang.nif_error(:nif_not_loaded)
end
@doc """
Return the start and end index of the bytestring
"""
def node_byte_range(_) do
:erlang.nif_error(:nif_not_loaded)
# :erlang.nif_error(:nif_not_loaded)
end
def node_point_range(_) do
:erlang.nif_error(:nif_not_loaded)
end
def query_new(language, query_string)
def query_new(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def query_cursor_exec(query, node)
def query_cursor_exec(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def query_cursor_next_match(cursor)
def query_cursor_next_match(_) do
:erlang.nif_error(:nif_not_loaded)
end
def query_pattern_byte_range(query, pattern_index)
def query_pattern_byte_range(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
def query_capture_name_for_id(query, pattern_index)
def query_capture_name_for_id(_, _) do
:erlang.nif_error(:nif_not_loaded)
end
end
defmodule TreeSitter.Application do
@moduledoc """
Opens a window (tb_init) and kills it on shutdown (tb_shutdown)
"""
use Application
@impl true
def start(_type, _args) do
TreeSitter.Nif.load_nifs()
# TODO: Get rid of this dummy supervisor that is only used for its return value
children = []
opts = [strategy: :one_for_one, name: TreeSitter.Supervisor]
sup = Supervisor.start_link(children, opts)
sup
end
end