TreeSitter Types Builder is a transpiler for generating type definitions for a tree-sitter language definition file. This project was created out lost of personal reseach and interest into the language server protocal, and how tree-sitter is used to provide it’s features.
It primarily aims to solve a symptom of how the tree-sitter builds its node runtime, by converting
the string’s of every possible value in a languages SyntaxNode.type
to a corresponding string literal type
representation.
What does this do?
- Provides autocompletion for type’s of SyntaxNode’s that are not currently possible in the nodejs implementation by default.
- Removes the unnecessarily wide type defintion’s provided by tree-sitter in node.
- Creates an easily customizable design pattern for any union
SyntaxNode
type’s - Promotes a singular location to reference
SyntaxNode
type’s
Links
Example
Using the command provided by this package, as a global executable, follows the behavior below.
tree-sitter-types-builder --wasm path/to/your.wasm --language your_language
Using bash as our language file, we will get the annotated typescript definitions as output.
// tree-sitter-types-builder --wasm tree-sitter-bash.wasm --language bash
/**
* AUTO GENERATED FILE
* tree-sitter-types-builder
*/
export type BashNodeType =
| "end"
| "word"
| "\n"
| "for"
| "select"
| "in"
| "(("
| "))"
| ";"
| "while"
| "until"
| "do"
| "done"
| "if"
| "then"
| "fi"
| "elif"
| "else"
| "case"
| "esac"
| "|"
| ")"
| ";;"
| ";&"
| ";;&"
| "function"
| "("
| "{"
| "}"
| "|&"
| "&&"
| "||"
| "!"
| "["
| "]"
| "[["
| "]]"
| "declare"
| "typeset"
| "export"
| "readonly"
| "local"
| "unset"
| "unsetenv"
| "=~"
| "=="
| "="
| "+="
| "<"
| ">"
| ">>"
| "&>"
| "&>>"
| "<&"
| ">&"
| ">|"
| "<<"
| "<<-"
| "<<<"
| "!="
| "+"
| "-"
| "-="
| "<="
| ">="
| "?"
| ":"
| "++"
| "--"
| "$"
| "_special_character"
| '"'
| "_string_content"
| "raw_string"
| "ansi_c_string"
| "#"
| "${"
| "/"
| ":?"
| ":-"
| "%"
| "$("
| "`"
| "<("
| ">("
| "comment"
| "variable_name"
| "special_variable_name"
| "test_operator"
| "&"
| "heredoc_start"
| "_simple_heredoc_body"
| "_heredoc_body_beginning"
| "_heredoc_body_middle"
| "_heredoc_body_end"
| "file_descriptor"
| "_empty_value"
| "_concat"
| "regex"
| "program"
| "_statements"
| "_statements2"
| "_terminated_statement"
| "redirected_statement"
| "for_statement"
| "c_style_for_statement"
| "while_statement"
| "do_group"
| "if_statement"
| "elif_clause"
| "else_clause"
| "case_statement"
| "case_item"
| "function_definition"
| "compound_statement"
| "subshell"
| "pipeline"
| "list"
| "negated_command"
| "test_command"
| "declaration_command"
| "unset_command"
| "command"
| "command_name"
| "variable_assignment"
| "subscript"
| "file_redirect"
| "heredoc_redirect"
| "heredoc_body"
| "herestring_redirect"
| "_expression"
| "binary_expression"
| "ternary_expression"
| "unary_expression"
| "postfix_expression"
| "parenthesized_expression"
| "concatenation"
| "string"
| "translated_string"
| "array"
| "simple_expansion"
| "expansion"
| "command_substitution"
| "process_substitution"
| "_statements_repeat1"
| "redirected_statement_repeat1"
| "for_statement_repeat1"
| "if_statement_repeat1"
| "case_statement_repeat1"
| "case_item_repeat1"
| "declaration_command_repeat1"
| "unset_command_repeat1"
| "command_repeat1"
| "command_repeat2"
| "heredoc_body_repeat1"
| "_literal_repeat1"
| "concatenation_repeat1"
| "string_repeat1"
| "expansion_repeat1";
export namespace BashNodeType {
export enum Keys {
"end" = 0,
"word" = 1,
"\n" = 2,
"for" = 3,
"select" = 4,
"in" = 5,
"((" = 6,
"))" = 7,
";" = 8,
"while" = 9,
"until" = 10,
"do" = 11,
"done" = 12,
"if" = 13,
"then" = 14,
"fi" = 15,
"elif" = 16,
"else" = 17,
"case" = 18,
"esac" = 19,
"|" = 20,
")" = 21,
";;" = 22,
";&" = 23,
";;&" = 24,
"function" = 25,
"(" = 26,
"{" = 27,
"}" = 28,
"|&" = 29,
"&&" = 30,
"||" = 31,
"!" = 32,
"[" = 33,
"]" = 34,
"[[" = 35,
"]]" = 36,
"declare" = 37,
"typeset" = 38,
"export" = 39,
"readonly" = 40,
"local" = 41,
"unset" = 42,
"unsetenv" = 43,
"=~" = 44,
"==" = 45,
"=" = 46,
"+=" = 47,
"<" = 48,
">" = 49,
">>" = 50,
"&>" = 51,
"&>>" = 52,
"<&" = 53,
">&" = 54,
">|" = 55,
"<<" = 56,
"<<-" = 57,
"<<<" = 58,
"!=" = 59,
"+" = 60,
"-" = 61,
"-=" = 62,
"<=" = 63,
">=" = 64,
"?" = 65,
":" = 66,
"++" = 67,
"--" = 68,
"$" = 69,
"_special_character" = 70,
'"' = 71,
"_string_content" = 72,
"raw_string" = 73,
"ansi_c_string" = 74,
"#" = 75,
"${" = 76,
"/" = 77,
":?" = 78,
":-" = 79,
"%" = 80,
"$(" = 81,
"`" = 82,
"<(" = 83,
">(" = 84,
"comment" = 85,
"variable_name" = 86,
"special_variable_name" = 87,
"test_operator" = 88,
"&" = 89,
"heredoc_start" = 90,
"_simple_heredoc_body" = 91,
"_heredoc_body_beginning" = 92,
"_heredoc_body_middle" = 93,
"_heredoc_body_end" = 94,
"file_descriptor" = 95,
"_empty_value" = 96,
"_concat" = 97,
"regex" = 98,
"program" = 99,
"_statements" = 100,
"_statements2" = 101,
"_terminated_statement" = 102,
"redirected_statement" = 103,
"for_statement" = 104,
"c_style_for_statement" = 105,
"while_statement" = 106,
"do_group" = 107,
"if_statement" = 108,
"elif_clause" = 109,
"else_clause" = 110,
"case_statement" = 111,
"case_item" = 112,
"function_definition" = 113,
"compound_statement" = 114,
"subshell" = 115,
"pipeline" = 116,
"list" = 117,
"negated_command" = 118,
"test_command" = 119,
"declaration_command" = 120,
"unset_command" = 121,
"command" = 122,
"command_name" = 123,
"variable_assignment" = 124,
"subscript" = 125,
"file_redirect" = 126,
"heredoc_redirect" = 127,
"heredoc_body" = 128,
"herestring_redirect" = 129,
"_expression" = 130,
"binary_expression" = 131,
"ternary_expression" = 132,
"unary_expression" = 133,
"postfix_expression" = 134,
"parenthesized_expression" = 135,
"concatenation" = 136,
"string" = 137,
"translated_string" = 138,
"array" = 139,
"simple_expansion" = 140,
"expansion" = 141,
"command_substitution" = 142,
"process_substitution" = 143,
"_statements_repeat1" = 144,
"redirected_statement_repeat1" = 145,
"for_statement_repeat1" = 146,
"if_statement_repeat1" = 147,
"case_statement_repeat1" = 148,
"case_item_repeat1" = 149,
"declaration_command_repeat1" = 150,
"unset_command_repeat1" = 151,
"command_repeat1" = 152,
"command_repeat2" = 153,
"heredoc_body_repeat1" = 154,
"_literal_repeat1" = 155,
"concatenation_repeat1" = 156,
"string_repeat1" = 157,
"expansion_repeat1" = 158,
}
export function getKeys(): BashNodeType[] {
return Object.keys(BashNodeType).map(
x => BashNodeType[x]
) as BashNodeType[];
}
export function hasKeys(...keys: BashNodeType[]) {
const allKeys = getKeys();
return keys.every(k => allKeys.includes(k));
}
}
export type BashFieldNameType =
| "null"
| "alternative"
| "argument"
| "body"
| "condition"
| "consequence"
| "descriptor"
| "destination"
| "fallthrough"
| "index"
| "initializer"
| "left"
| "name"
| "operator"
| "redirect"
| "right"
| "termination"
| "update"
| "value";
export namespace BashFieldNameType {
export enum Keys {
"null" = 0,
"alternative" = 1,
"argument" = 2,
"body" = 3,
"condition" = 4,
"consequence" = 5,
"descriptor" = 6,
"destination" = 7,
"fallthrough" = 8,
"index" = 9,
"initializer" = 10,
"left" = 11,
"name" = 12,
"operator" = 13,
"redirect" = 14,
"right" = 15,
"termination" = 16,
"update" = 17,
"value" = 18,
}
export function getKeys(): BashFieldNameType[] {
return Object.keys(BashFieldNameType).map(
x => BashFieldNameType[x]
) as BashFieldNameType[];
}
export function hasKeys(...keys: BashFieldNameType[]) {
const allKeys = getKeys();
return keys.every(k => allKeys.includes(k));
}
}
Thus, you can now use the types provided by tree-sitter in more reliable manor, by avoiding the use of strings to search through web-tree-sitter Objects. You also now have access to language tools through the tsserver lsp. This allows you to have completions on the BashNodeType
, plus any other possible language feature (like seeing references, definitions, etc…).