@konomanoasa/tree-sitter-gitattributes 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +1 -1
- package/README.md +5 -1
- package/grammar.js +62 -49
- package/package.json +7 -6
- package/src/grammar.json +206 -112
- package/src/node-types.json +19 -4
- package/src/parser.c +2896 -2663
- package/src/scanner.c +298 -345
- package/test/bindings.test.rs +0 -13
- package/tree-sitter.json +1 -1
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install @konomanoasa/tree-sitter-gitattributes
|
|
|
15
15
|
|
|
16
16
|
## Development
|
|
17
17
|
|
|
18
|
-
Development uses Node.js 24 or later.
|
|
18
|
+
Development uses Node.js 24.21.0 or later.
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
21
|
npm install
|
|
@@ -28,6 +28,10 @@ npm test
|
|
|
28
28
|
- [Git 2.55.0 gitattributes manual](https://git-scm.com/docs/gitattributes/2.55.0)
|
|
29
29
|
- [Git 2.55.0 gitignore manual](https://git-scm.com/docs/gitignore/2.55.0)
|
|
30
30
|
|
|
31
|
+
## Used By
|
|
32
|
+
|
|
33
|
+
[gitfile-ts-mode](https://github.com/konomanoasa/gitfile-ts-mode): Emacs major mode.
|
|
34
|
+
|
|
31
35
|
## License
|
|
32
36
|
|
|
33
37
|
[MIT](LICENSE)
|
package/grammar.js
CHANGED
|
@@ -1,46 +1,71 @@
|
|
|
1
|
+
const missingKinds = (name) => [
|
|
2
|
+
[`missing_${name}`, "invalid_syntax", `missing_${name}`],
|
|
3
|
+
[`incomplete_${name}`, "incomplete_syntax", `missing_${name}`],
|
|
4
|
+
];
|
|
1
5
|
const issueKinds = [
|
|
2
|
-
|
|
3
|
-
["incomplete_set_close", "incomplete_syntax", "missing_set_close"],
|
|
6
|
+
...missingKinds("set_close"),
|
|
4
7
|
["invalid_encoding", "invalid_syntax", "invalid_encoding"],
|
|
5
8
|
["negative_pattern", "invalid_syntax", "negative_pattern"],
|
|
6
|
-
["
|
|
9
|
+
["ended_escape", "invalid_syntax", "incomplete_escape"],
|
|
7
10
|
["incomplete_escape", "incomplete_syntax", "incomplete_escape"],
|
|
8
11
|
["invalid_quoted_escape", "invalid_syntax", "invalid_quoted_escape"],
|
|
9
12
|
["ended_quoted_escape", "invalid_syntax", "incomplete_quoted_escape"],
|
|
10
13
|
["incomplete_quoted_escape", "incomplete_syntax", "incomplete_quoted_escape"],
|
|
11
|
-
|
|
12
|
-
[
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
...missingKinds("quote_close"),
|
|
15
|
+
[
|
|
16
|
+
"missing_attribute_separator",
|
|
17
|
+
"invalid_syntax",
|
|
18
|
+
"missing_attribute_separator",
|
|
19
|
+
],
|
|
20
|
+
...missingKinds("attribute_name"),
|
|
16
21
|
["invalid_name_character", "invalid_syntax", "invalid_name_character"],
|
|
22
|
+
["incomplete_name_character", "incomplete_syntax", "invalid_name_character"],
|
|
23
|
+
[
|
|
24
|
+
"invalid_name_escape",
|
|
25
|
+
"invalid_syntax",
|
|
26
|
+
"invalid_name_character",
|
|
27
|
+
"quoted_escape",
|
|
28
|
+
],
|
|
29
|
+
];
|
|
30
|
+
const quotedEscapeIssues = [
|
|
31
|
+
"invalid_quoted_escape",
|
|
32
|
+
"ended_quoted_escape",
|
|
33
|
+
"incomplete_quoted_escape",
|
|
17
34
|
];
|
|
35
|
+
|
|
18
36
|
const issueRules = Object.fromEntries(
|
|
19
|
-
issueKinds.flatMap(([token, outcome, reason]) => [
|
|
20
|
-
|
|
37
|
+
issueKinds.flatMap(([token, outcome, reason, child]) => [
|
|
38
|
+
...(child
|
|
39
|
+
? [[`_${token}_reason`, ($) => alias($[`_${token}`], $[child])]]
|
|
40
|
+
: []),
|
|
41
|
+
[
|
|
42
|
+
`_${token}_outcome`,
|
|
43
|
+
($) => alias($[child ? `_${token}_reason` : `_${token}`], $[reason]),
|
|
44
|
+
],
|
|
21
45
|
[`_${token}_issue`, ($) => alias($[`_${token}_outcome`], $[outcome])],
|
|
22
46
|
]),
|
|
23
47
|
);
|
|
24
48
|
const issue = ($, name) =>
|
|
25
49
|
field("issue", alias($[`_${name}_issue`], $.syntax_issue));
|
|
26
50
|
const issues = ($, ...names) => names.map((name) => issue($, name));
|
|
27
|
-
|
|
51
|
+
const missing = ($, name) =>
|
|
52
|
+
choice(issue($, `missing_${name}`), issue($, `incomplete_${name}`));
|
|
28
53
|
const heldPrefix = ($, ...names) =>
|
|
29
54
|
seq($._escape_prefix, choice(...issues($, ...names)));
|
|
30
|
-
const quotedEscapeIssues = [
|
|
31
|
-
"invalid_quoted_escape",
|
|
32
|
-
"ended_quoted_escape",
|
|
33
|
-
"incomplete_quoted_escape",
|
|
34
|
-
];
|
|
35
|
-
const missingName = ($) =>
|
|
36
|
-
choice(...issues($, "missing_name", "incomplete_name"));
|
|
37
55
|
const quoteClose = ($) =>
|
|
38
|
-
optional(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
optional(choice(field("closing", $.quote_close), missing($, "quote_close")));
|
|
57
|
+
const attributeName = ($) =>
|
|
58
|
+
choice(field("name", $.attribute_name), missing($, "attribute_name"));
|
|
59
|
+
const globIssues = ($) => [
|
|
60
|
+
...issues(
|
|
61
|
+
$,
|
|
62
|
+
"invalid_encoding",
|
|
63
|
+
"ended_escape",
|
|
64
|
+
"incomplete_escape",
|
|
65
|
+
...quotedEscapeIssues,
|
|
66
|
+
),
|
|
67
|
+
heldPrefix($, "invalid_encoding", ...quotedEscapeIssues),
|
|
68
|
+
];
|
|
44
69
|
|
|
45
70
|
export default grammar({
|
|
46
71
|
name: "gitattributes",
|
|
@@ -51,7 +76,6 @@ export default grammar({
|
|
|
51
76
|
$._rule_start,
|
|
52
77
|
$._macro_start,
|
|
53
78
|
$._eof,
|
|
54
|
-
$.line_ending,
|
|
55
79
|
$._layout,
|
|
56
80
|
$._separator,
|
|
57
81
|
$._attribute_start,
|
|
@@ -105,6 +129,7 @@ export default grammar({
|
|
|
105
129
|
choice($.blank_line, $.comment, $.attribute_rule, $.macro_definition),
|
|
106
130
|
),
|
|
107
131
|
),
|
|
132
|
+
line_ending: () => /\r?\n/,
|
|
108
133
|
_end: ($) => seq(optional($._layout), choice($.line_ending, $._eof)),
|
|
109
134
|
blank_line: ($) => seq($._blank_start, $._end),
|
|
110
135
|
comment: ($) =>
|
|
@@ -126,14 +151,17 @@ export default grammar({
|
|
|
126
151
|
$._macro_start,
|
|
127
152
|
optional(field("opening", $.quote_open)),
|
|
128
153
|
field("marker", $.macro_marker),
|
|
129
|
-
|
|
154
|
+
attributeName($),
|
|
130
155
|
quoteClose($),
|
|
131
156
|
optional($._attributes),
|
|
132
157
|
$._end,
|
|
133
158
|
),
|
|
134
159
|
_attributes: ($) =>
|
|
135
160
|
repeat1(
|
|
136
|
-
seq(
|
|
161
|
+
seq(
|
|
162
|
+
choice($._separator, issue($, "missing_attribute_separator")),
|
|
163
|
+
$.attribute,
|
|
164
|
+
),
|
|
137
165
|
),
|
|
138
166
|
attribute: ($) =>
|
|
139
167
|
seq(
|
|
@@ -141,7 +169,7 @@ export default grammar({
|
|
|
141
169
|
optional(
|
|
142
170
|
field("modifier", choice($.unset_marker, $.unspecified_marker)),
|
|
143
171
|
),
|
|
144
|
-
|
|
172
|
+
attributeName($),
|
|
145
173
|
optional(
|
|
146
174
|
seq(
|
|
147
175
|
field("operator", $.assignment_operator),
|
|
@@ -161,6 +189,8 @@ export default grammar({
|
|
|
161
189
|
$,
|
|
162
190
|
"invalid_encoding",
|
|
163
191
|
"invalid_name_character",
|
|
192
|
+
"incomplete_name_character",
|
|
193
|
+
"invalid_name_escape",
|
|
164
194
|
...quotedEscapeIssues,
|
|
165
195
|
),
|
|
166
196
|
heldPrefix($, "invalid_encoding"),
|
|
@@ -190,15 +220,8 @@ export default grammar({
|
|
|
190
220
|
$.escape,
|
|
191
221
|
$.quoted_escape,
|
|
192
222
|
$.character_set,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"invalid_encoding",
|
|
196
|
-
"negative_pattern",
|
|
197
|
-
"invalid_escape",
|
|
198
|
-
"incomplete_escape",
|
|
199
|
-
...quotedEscapeIssues,
|
|
200
|
-
),
|
|
201
|
-
heldPrefix($, "invalid_encoding", ...quotedEscapeIssues),
|
|
223
|
+
issue($, "negative_pattern"),
|
|
224
|
+
...globIssues($),
|
|
202
225
|
),
|
|
203
226
|
),
|
|
204
227
|
),
|
|
@@ -220,21 +243,11 @@ export default grammar({
|
|
|
220
243
|
$.quoted_escape,
|
|
221
244
|
$.character_range,
|
|
222
245
|
$.character_class,
|
|
223
|
-
...
|
|
224
|
-
$,
|
|
225
|
-
"invalid_encoding",
|
|
226
|
-
"invalid_escape",
|
|
227
|
-
"incomplete_escape",
|
|
228
|
-
...quotedEscapeIssues,
|
|
229
|
-
),
|
|
230
|
-
heldPrefix($, "invalid_encoding", ...quotedEscapeIssues),
|
|
246
|
+
...globIssues($),
|
|
231
247
|
),
|
|
232
248
|
),
|
|
233
249
|
),
|
|
234
|
-
choice(
|
|
235
|
-
field("closing", $.set_close),
|
|
236
|
-
...issues($, "missing_set_close", "incomplete_set_close"),
|
|
237
|
-
),
|
|
250
|
+
choice(field("closing", $.set_close), missing($, "set_close")),
|
|
238
251
|
),
|
|
239
252
|
character_range: ($) =>
|
|
240
253
|
seq(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konomanoasa/tree-sitter-gitattributes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tree-sitter grammar for gitattributes.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "npm run tree-sitter -- build-all",
|
|
24
|
-
"check": "biome check . &&
|
|
25
|
-
"
|
|
24
|
+
"check": "biome check . && tsc --noEmit",
|
|
25
|
+
"check:queries": "npm run tree-sitter -- check-queries",
|
|
26
|
+
"format": "biome format --write .",
|
|
26
27
|
"generate": "npm run tree-sitter -- generate-all",
|
|
27
28
|
"test": "npm run tree-sitter -- test-corpus --rebuild && node --test --test-concurrency=1 \"test/*.test.js\"",
|
|
28
|
-
"test:bindings": "cargo test --locked",
|
|
29
29
|
"test:fuzz": "node --test --test-name-pattern=\"fixed-seed generated histories\" test/incremental.test.js",
|
|
30
30
|
"test:fuzz:corpus": "npm run tree-sitter -- fuzz-all --iterations 100 --edits 5",
|
|
31
31
|
"test:highlights": "node --test test/highlight.test.js",
|
|
32
|
-
"test:incremental": "node --test test/incremental.test.js",
|
|
32
|
+
"test:incremental": "node --test --test-concurrency=1 test/cst.test.js test/parser.test.js test/incremental.test.js",
|
|
33
33
|
"test:sanitize": "node scripts/check-c.js --sanitize",
|
|
34
34
|
"test:scanner": "node scripts/check-c.js",
|
|
35
35
|
"tree-sitter": "node scripts/tree-sitter.js"
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@biomejs/biome": "2.5.14",
|
|
39
39
|
"@types/node": "26.5.1",
|
|
40
|
-
"tree-sitter-cli": "0.27.0"
|
|
40
|
+
"tree-sitter-cli": "0.27.0",
|
|
41
|
+
"typescript": "7.0.2"
|
|
41
42
|
},
|
|
42
43
|
"allowScripts": {
|
|
43
44
|
"tree-sitter-cli": true
|