Skip to content

Commit

Permalink
refactor: decouple tree_sitter grammar and bindings (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
ttytm authored Mar 25, 2024
1 parent da0005b commit bf89fe4
Show file tree
Hide file tree
Showing 27 changed files with 104 additions and 129 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ cache

# generated executables on unix:
install
generate_types
cmd/v-analyzer/v-analyzer
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "v_tree_sitter/core"]
path = v_tree_sitter/core
[submodule "tree_sitter_v/bindings/core"]
path = tree_sitter_v/bindings/core
url = https://github.com/tree-sitter/tree-sitter.git
branch = master
11 changes: 5 additions & 6 deletions analyzer/parser/parser.v
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
module parser

import tree_sitter_v as v
import v_tree_sitter.tree_sitter
import tree_sitter_v.bindings
import os

// ParseResult represents the result of a parsing operation.
pub struct ParseResult {
pub:
tree &tree_sitter.Tree[v.NodeType] = unsafe { nil } // Resulting tree or nil if the source could not be parsed.
tree &bindings.Tree[bindings.NodeType] = unsafe { nil } // Resulting tree or nil if the source could not be parsed.
source_text string // Source code.
pub mut:
path string // Path of the file that was parsed.
Expand Down Expand Up @@ -95,9 +94,9 @@ pub fn parse_code(code string) ParseResult {
// res2 = parser.parse_code_with_tree(code2, res.tree)
// println(res2.tree
// }
pub fn parse_code_with_tree(code string, old_tree &tree_sitter.Tree[v.NodeType]) ParseResult {
mut parser := tree_sitter.new_parser[v.NodeType](v.type_factory)
parser.set_language(v.language)
pub fn parse_code_with_tree(code string, old_tree &bindings.Tree[bindings.NodeType]) ParseResult {
mut parser := bindings.new_parser[bindings.NodeType](bindings.type_factory)
parser.set_language(bindings.language)
raw_tree := if isnil(old_tree) { unsafe { nil } } else { old_tree.raw_tree }
tree := parser.parse_string(source: code, tree: raw_tree)
return ParseResult{
Expand Down
4 changes: 2 additions & 2 deletions analyzer/psi/AstNode.v
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module psi

import tree_sitter_v as v
import tree_sitter_v.bindings

pub fn (node AstNode) parent_of_type(typ v.NodeType) ?AstNode {
pub fn (node AstNode) parent_of_type(typ bindings.NodeType) ?AstNode {
mut res := node
for {
res = res.parent()?
Expand Down
29 changes: 14 additions & 15 deletions analyzer/psi/PsiElement.v
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
module psi

import v_tree_sitter.tree_sitter
import tree_sitter_v as v
import tree_sitter_v.bindings

pub type ID = int

pub type AstNode = tree_sitter.Node[v.NodeType]
pub type AstNode = bindings.Node[bindings.NodeType]

pub interface PsiElement {
node AstNode // base node from Tree Sitter
containing_file &PsiFile // file where the element is located
stub_id StubId
get_stub() ?&StubBase
stub_list() &StubList
element_type() v.NodeType
element_type() bindings.NodeType
node() AstNode // return base node from Tree Sitter
containing_file() &PsiFile // return file where the element is located
is_equal(other PsiElement) bool // return true if the element is equal to the other element
Expand All @@ -32,21 +31,21 @@ pub interface PsiElement {
parent_nth(depth int) ?PsiElement
// parent_of_type returns the parent node with the specified type.
// If no such node exists, none is returned.
parent_of_type(typ v.NodeType) ?PsiElement
parent_of_type(typ bindings.NodeType) ?PsiElement
// parent_of_any_type returns the parent node with one of the specified types.
// If no such node exists, none is returned.
parent_of_any_type(types ...v.NodeType) ?PsiElement
parent_of_any_type(types ...bindings.NodeType) ?PsiElement
// inside returns true if the node is inside a node with the specified type.
inside(typ v.NodeType) bool
inside(typ bindings.NodeType) bool
// is_parent_of returns true if the passed node is a child of the given node.
is_parent_of(element PsiElement) bool
// sibling_of_type_backward returns the previous node at the same nesting level with the specified type.
// If no such node exists, none is returned.
sibling_of_type_backward(typ v.NodeType) ?PsiElement
sibling_of_type_backward(typ bindings.NodeType) ?PsiElement
// parent_of_type_or_self returns the parent node with the specified type, or the
// node itself if its type matches the specified one.
// If no such node exists, none is returned.
parent_of_type_or_self(typ v.NodeType) ?PsiElement
parent_of_type_or_self(typ bindings.NodeType) ?PsiElement
// children returns all child nodes.
children() []PsiElement
// named_children returns child nodes except unknown nodes.
Expand Down Expand Up @@ -74,27 +73,27 @@ pub interface PsiElement {
prev_sibling() ?PsiElement
// prev_sibling_of_type returns the previous node at the same nesting level with the specified type.
// If no such node exists, none is returned.
prev_sibling_of_type(typ v.NodeType) ?PsiElement
prev_sibling_of_type(typ bindings.NodeType) ?PsiElement
// prev_sibling_or_stub returns the previous node at the same nesting level or stub.
// If the node is the first child node or stub, none is returned.
prev_sibling_or_stub() ?PsiElement
// find_child_by_type returns the first child node with the specified type.
// If no such node is found, none is returned.
find_child_by_type(typ v.NodeType) ?PsiElement
find_child_by_type(typ bindings.NodeType) ?PsiElement
// has_child_of_type returns true if the node has a child with the specified type.
has_child_of_type(typ v.NodeType) bool
has_child_of_type(typ bindings.NodeType) bool
// find_child_by_type_or_stub returns the first child node with the specified type or stub.
// If no such node is found, none is returned.
find_child_by_type_or_stub(typ v.NodeType) ?PsiElement
find_child_by_type_or_stub(typ bindings.NodeType) ?PsiElement
// find_child_by_name returns the first child node with the specified name.
// If no such node is found, none is returned.
find_child_by_name(name string) ?PsiElement
// find_children_by_type returns all child nodes with the specified type.
// If no such nodes are found, an empty array is returned.
find_children_by_type(typ v.NodeType) []PsiElement
find_children_by_type(typ bindings.NodeType) []PsiElement
// find_children_by_type_or_stub returns all child nodes with the specified type or stub.
// If no such nodes are found, an empty array is returned.
find_children_by_type_or_stub(typ v.NodeType) []PsiElement
find_children_by_type_or_stub(typ bindings.NodeType) []PsiElement
// get_text returns the text of the node.
get_text() string
// text_matches returns true if the text of the node matches the specified value.
Expand Down
28 changes: 14 additions & 14 deletions analyzer/psi/PsiElementImpl.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module psi

import tree_sitter_v as v
import tree_sitter_v.bindings

pub struct PsiElementImpl {
pub:
Expand Down Expand Up @@ -48,7 +48,7 @@ pub fn (n &PsiElementImpl) stub_list() &StubList {
return n.stubs_list
}

pub fn (n &PsiElementImpl) element_type() v.NodeType {
pub fn (n &PsiElementImpl) element_type() bindings.NodeType {
if stub := n.get_stub() {
return stub.element_type()
}
Expand Down Expand Up @@ -138,7 +138,7 @@ pub fn (n &PsiElementImpl) parent_nth(depth int) ?PsiElement {
return create_element(parent, n.containing_file)
}

pub fn (n &PsiElementImpl) parent_of_type(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) parent_of_type(typ bindings.NodeType) ?PsiElement {
mut res := PsiElement(n)
for {
res = res.parent()?
Expand All @@ -150,7 +150,7 @@ pub fn (n &PsiElementImpl) parent_of_type(typ v.NodeType) ?PsiElement {
return none
}

pub fn (n &PsiElementImpl) parent_of_any_type(types ...v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) parent_of_any_type(types ...bindings.NodeType) ?PsiElement {
mut res := PsiElement(n)
for {
res = res.parent()?
Expand All @@ -163,7 +163,7 @@ pub fn (n &PsiElementImpl) parent_of_any_type(types ...v.NodeType) ?PsiElement {
return none
}

pub fn (n &PsiElementImpl) inside(typ v.NodeType) bool {
pub fn (n &PsiElementImpl) inside(typ bindings.NodeType) bool {
mut res := PsiElement(n)
for {
res = res.parent() or { return false }
Expand Down Expand Up @@ -196,7 +196,7 @@ pub fn (n &PsiElementImpl) is_parent_of(element PsiElement) bool {
return false
}

pub fn (n &PsiElementImpl) sibling_of_type_backward(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) sibling_of_type_backward(typ bindings.NodeType) ?PsiElement {
mut res := PsiElement(n)
for {
res = res.prev_sibling_or_stub()?
Expand All @@ -208,7 +208,7 @@ pub fn (n &PsiElementImpl) sibling_of_type_backward(typ v.NodeType) ?PsiElement
return none
}

pub fn (n &PsiElementImpl) parent_of_type_or_self(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) parent_of_type_or_self(typ bindings.NodeType) ?PsiElement {
if n.node.type_name == typ {
return create_element(n.node, n.containing_file)
}
Expand Down Expand Up @@ -311,7 +311,7 @@ pub fn (n &PsiElementImpl) prev_sibling() ?PsiElement {
return create_element(sibling, n.containing_file)
}

pub fn (n &PsiElementImpl) prev_sibling_of_type(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) prev_sibling_of_type(typ bindings.NodeType) ?PsiElement {
mut res := PsiElement(n)
for {
res = res.prev_sibling_or_stub()?
Expand All @@ -335,12 +335,12 @@ pub fn (n &PsiElementImpl) prev_sibling_or_stub() ?PsiElement {
return n.prev_sibling()
}

pub fn (n &PsiElementImpl) find_child_by_type(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) find_child_by_type(typ bindings.NodeType) ?PsiElement {
ast_node := n.node.first_node_by_type(typ)?
return create_element(ast_node, n.containing_file)
}

pub fn (n &PsiElementImpl) has_child_of_type(typ v.NodeType) bool {
pub fn (n &PsiElementImpl) has_child_of_type(typ bindings.NodeType) bool {
if stub := n.get_stub() {
return stub.has_child_of_type(node_type_to_stub_type(typ))
}
Expand All @@ -352,7 +352,7 @@ pub fn (n &PsiElementImpl) has_child_of_type(typ v.NodeType) bool {
return false
}

pub fn (n &PsiElementImpl) find_child_by_type_or_stub(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) find_child_by_type_or_stub(typ bindings.NodeType) ?PsiElement {
if stub := n.get_stub() {
child := stub.get_child_by_type(node_type_to_stub_type(typ))?
return child.get_psi()
Expand All @@ -367,7 +367,7 @@ pub fn (n &PsiElementImpl) find_child_by_name(name string) ?PsiElement {
return create_element(ast_node, n.containing_file)
}

pub fn (n &PsiElementImpl) find_children_by_type(typ v.NodeType) []PsiElement {
pub fn (n &PsiElementImpl) find_children_by_type(typ bindings.NodeType) []PsiElement {
mut result := []PsiElement{}
mut child := n.node.first_child() or { return [] }
for {
Expand All @@ -379,7 +379,7 @@ pub fn (n &PsiElementImpl) find_children_by_type(typ v.NodeType) []PsiElement {
return result
}

pub fn (n &PsiElementImpl) find_children_by_type_or_stub(typ v.NodeType) []PsiElement {
pub fn (n &PsiElementImpl) find_children_by_type_or_stub(typ bindings.NodeType) []PsiElement {
if stub := n.get_stub() {
return stub.get_children_by_type(node_type_to_stub_type(typ)).get_psi()
}
Expand All @@ -395,7 +395,7 @@ pub fn (n &PsiElementImpl) find_children_by_type_or_stub(typ v.NodeType) []PsiEl
return result
}

pub fn (n &PsiElementImpl) find_last_child_by_type(typ v.NodeType) ?PsiElement {
pub fn (n &PsiElementImpl) find_last_child_by_type(typ bindings.NodeType) ?PsiElement {
ast_node := n.node.last_node_by_type(typ)?
return create_element(ast_node, n.containing_file)
}
Expand Down
7 changes: 3 additions & 4 deletions analyzer/psi/PsiFile.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ import lsp
import time
import utils
import loglib
import tree_sitter_v as v
import analyzer.parser
import v_tree_sitter.tree_sitter
import tree_sitter_v.bindings

@[heap]
pub struct PsiFile {
pub:
path string
stub_list &StubList = unsafe { nil }
pub mut:
tree &tree_sitter.Tree[v.NodeType] = unsafe { nil }
tree &bindings.Tree[bindings.NodeType] = unsafe { nil }
source_text string
root PsiElement
}

pub fn new_psi_file(path string, tree &tree_sitter.Tree[v.NodeType], source_text string) &PsiFile {
pub fn new_psi_file(path string, tree &bindings.Tree[bindings.NodeType], source_text string) &PsiFile {
mut file := &PsiFile{
path: path
tree: unsafe { tree }
Expand Down
4 changes: 2 additions & 2 deletions analyzer/psi/PsiNamedElement.v
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module psi

import tree_sitter_v as v
import tree_sitter_v.bindings

pub interface PsiNamedElement {
parent_of_type(typ v.NodeType) ?PsiElement
parent_of_type(typ bindings.NodeType) ?PsiElement
identifier_text_range() TextRange
identifier() ?PsiElement
name() string
Expand Down
4 changes: 2 additions & 2 deletions analyzer/psi/StubBase.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module psi

import tree_sitter_v as v
import tree_sitter_v.bindings

pub type StubId = int

Expand Down Expand Up @@ -74,7 +74,7 @@ pub fn (s &StubBase) stub_type() StubType {
return s.stub_type
}

pub fn (s &StubBase) element_type() v.NodeType {
pub fn (s &StubBase) element_type() bindings.NodeType {
return match s.stub_type {
.root { .unknown }
.function_declaration { .function_declaration }
Expand Down
4 changes: 2 additions & 2 deletions analyzer/psi/StubbedElementTypeImpl.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module psi

import utils
import tree_sitter_v
import tree_sitter_v.bindings

pub enum StubType as u8 {
root
Expand Down Expand Up @@ -60,7 +60,7 @@ pub enum StubType as u8 {
embedded_definition
}

pub fn node_type_to_stub_type(typ tree_sitter_v.NodeType) StubType {
pub fn node_type_to_stub_type(typ bindings.NodeType) StubType {
return match typ {
.function_declaration { .function_declaration }
.receiver { .receiver }
Expand Down
5 changes: 2 additions & 3 deletions analyzer/psi/TreeWalker.v
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module psi

import v_tree_sitter.tree_sitter
import tree_sitter_v
import tree_sitter_v.bindings

struct TreeWalker {
mut:
already_visited_children bool
cursor tree_sitter.TreeCursor[tree_sitter_v.NodeType] @[required]
cursor bindings.TreeCursor[bindings.NodeType] @[required]
}

pub fn (mut tw TreeWalker) next() ?AstNode {
Expand Down
22 changes: 0 additions & 22 deletions tree_sitter_v/bindings.v

This file was deleted.

Loading

0 comments on commit bf89fe4

Please sign in to comment.