-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathlanguage.go
157 lines (133 loc) · 5.39 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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"
)
const LANGUAGE_VERSION = C.TREE_SITTER_LANGUAGE_VERSION
const MIN_COMPATIBLE_LANGUAGE_VERSION = C.TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
// 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
}
// The metadata associated with a language.
//
// Currently, this metadata can be used to check the [Semantic Version](https://semver.org/)
// of the language. This version information should be used to signal if a given parser might
// be incompatible with existing queries when upgrading between major versions, or minor versions
// if it's in zerover.
type LanguageMetadata struct {
MajorVersion uint8
MinorVersion uint8
PatchVersion uint8
}
func NewLanguage(ptr unsafe.Pointer) *Language {
return &Language{Inner: (*C.TSLanguage)(ptr)}
}
// Deprecated: Use [Language.AbiVersion] instead.
//
// 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 ABI version number that indicates which version of the
// Tree-sitter CLI that was used to generate this [Language].
func (l *Language) AbiVersion() uint32 {
return uint32(C.ts_language_abi_version(l.Inner))
}
// Get the metadata for this language. This information is generated by the
// CLI, and relies on the language author providing the correct metadata in
// the language's `tree-sitter.json` file.
func (l *Language) Metadata() *LanguageMetadata {
ptr := C.ts_language_metadata(l.Inner)
if ptr == nil {
return nil
}
return &LanguageMetadata{
MajorVersion: uint8(ptr.major_version),
MinorVersion: uint8(ptr.minor_version),
PatchVersion: uint8(ptr.patch_version),
}
}
// 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)
}