-
Notifications
You must be signed in to change notification settings - Fork 10
/
language.go
118 lines (99 loc) · 4.08 KB
/
language.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package tree_sitter
/*
#cgo CFLAGS: -Iinclude -Isrc -std=c11 -D_POSIX_C_SOURCE=200112L -D_DEFAULT_SOURCE
#include <tree_sitter/api.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
// An opaque object that defines how to parse a particular language. The code
// for each `Language` is generated by the Tree-sitter CLI.
type Language struct {
Inner *C.TSLanguage
}
// An error that occurred when trying to assign an incompatible [TSLanguage] to
// a [TSParser].
type LanguageError struct {
version uint32
}
func NewLanguage(ptr unsafe.Pointer) *Language {
return &Language{Inner: (*C.TSLanguage)(ptr)}
}
// Get the ABI version number that indicates which version of the
// Tree-sitter CLI that was used to generate this [Language].
func (l *Language) Version() uint32 {
return uint32(C.ts_language_version(l.Inner))
}
// Get the number of distinct node types in this language.
func (l *Language) NodeKindCount() uint32 {
return uint32(C.ts_language_symbol_count(l.Inner))
}
// Get the number of valid states in this language.
func (l *Language) ParseStateCount() uint32 {
return uint32(C.ts_language_state_count(l.Inner))
}
// Get the name of the node kind for the given numerical id.
func (l *Language) NodeKindForId(id uint16) string {
return C.GoString(C.ts_language_symbol_name(l.Inner, C.TSSymbol(id)))
}
// Get the numeric id for the given node kind.
func (l *Language) IdForNodeKind(kind string, named bool) uint16 {
return uint16(C.ts_language_symbol_for_name(l.Inner, C.CString(kind), C.uint32_t(len(kind)), C.bool(named)))
}
// Check if the node type for the given numerical id is named (as opposed
// to an anonymous node type).
func (l *Language) NodeKindIsNamed(id uint16) bool {
return C.ts_language_symbol_type(l.Inner, C.TSSymbol(id)) == C.TSSymbolTypeRegular
}
// Check if the node type for the given numerical id is visible (as opposed
// to a hidden node type).
func (l *Language) NodeKindIsVisible(id uint16) bool {
return C.ts_language_symbol_type(l.Inner, C.TSSymbol(id)) <= C.TSSymbolTypeAnonymous
}
// Check if the node type for the given numerical id is a supertype.
func (l *Language) NodeKindIsSupertype(id uint16) bool {
return C.ts_language_symbol_type(l.Inner, C.TSSymbol(id)) == C.TSSymbolTypeSupertype
}
// Get the number of distinct field names in this language.
func (l *Language) FieldCount() uint32 {
return uint32(C.ts_language_field_count(l.Inner))
}
// Get the field names for the given numerical id.
func (l *Language) FieldNameForId(id uint16) string {
return C.GoString(C.ts_language_field_name_for_id(l.Inner, C.TSFieldId(id)))
}
// Get the numerical id for the given field name.
func (l *Language) FieldIdForName(name string) uint16 {
return uint16(C.ts_language_field_id_for_name(l.Inner, C.CString(name), C.uint32_t(len(name))))
}
// Get the next parse state. Combine this with
// [Language.LookaheadIterator] to
// generate completion suggestions or valid symbols in error nodes.
func (l *Language) NextState(state uint16, id uint16) uint16 {
return uint16(C.ts_language_next_state(l.Inner, C.TSStateId(state), C.TSSymbol(id)))
}
// Create a new lookahead iterator for this language and parse state.
//
// This returns `nil` if state is invalid for this language.
//
// Iterating [LookaheadIterator] will yield valid symbols in the given
// parse state. Newly created lookahead iterators will return the `ERROR`
// symbol from [LookaheadIterator.Symbol].
//
// Lookahead iterators can be useful to generate suggestions and improve
// syntax error diagnostics. To get symbols valid in an ERROR node, use the
// lookahead iterator on its first leaf node state. For `MISSING` nodes, a
// lookahead iterator created on the previous non-extra leaf node may be
// appropriate.
func (l *Language) LookaheadIterator(state uint16) *LookaheadIterator {
ptr := C.ts_lookahead_iterator_new(l.Inner, C.TSStateId(state))
if ptr == nil {
return nil
}
return newLookaheadIterator(ptr)
}
func (l *LanguageError) Error() string {
return fmt.Sprintf("Incompatible language version %d. Expected minimum %d, maximum %d", l.version, C.TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION, C.TREE_SITTER_LANGUAGE_VERSION)
}