@konomanoasa/tree-sitter-gitattributes 0.1.0 → 0.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "konomanoasa-tree-sitter-gitattributes"
3
- version = "0.1.0"
3
+ version = "0.3.0"
4
4
  edition = "2024"
5
5
  description = "Tree-sitter grammar for gitattributes."
6
6
  readme = "README.md"
package/README.md CHANGED
@@ -7,6 +7,11 @@
7
7
  [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) grammar for
8
8
  Git attributes files 2.55.0.
9
9
 
10
+ ## Syntax Issues
11
+
12
+ The parser detects syntax issues, including missing syntax, while preserving the surrounding structure.
13
+ These issues are represented as `syntax_issue` nodes.
14
+
10
15
  ## Installation
11
16
 
12
17
  ```sh
@@ -15,7 +20,7 @@ npm install @konomanoasa/tree-sitter-gitattributes
15
20
 
16
21
  ## Development
17
22
 
18
- Development uses Node.js 24 or later.
23
+ Development uses Node.js 24.21.0 or later.
19
24
 
20
25
  ```sh
21
26
  npm install
package/grammar.js CHANGED
@@ -14,24 +14,36 @@ const issueKinds = [
14
14
  ["missing_name", "invalid_syntax", "missing_attribute_name"],
15
15
  ["incomplete_name", "incomplete_syntax", "missing_attribute_name"],
16
16
  ["invalid_name_character", "invalid_syntax", "invalid_name_character"],
17
+ [
18
+ "invalid_name_escape",
19
+ "invalid_syntax",
20
+ "invalid_name_character",
21
+ "quoted_escape",
22
+ ],
23
+ ];
24
+ const quotedEscapeIssues = [
25
+ "invalid_quoted_escape",
26
+ "ended_quoted_escape",
27
+ "incomplete_quoted_escape",
17
28
  ];
29
+
18
30
  const issueRules = Object.fromEntries(
19
- issueKinds.flatMap(([token, outcome, reason]) => [
20
- [`_${token}_outcome`, ($) => alias($[`_${token}`], $[reason])],
31
+ issueKinds.flatMap(([token, outcome, reason, child]) => [
32
+ ...(child
33
+ ? [[`_${token}_reason`, ($) => alias($[`_${token}`], $[child])]]
34
+ : []),
35
+ [
36
+ `_${token}_outcome`,
37
+ ($) => alias($[child ? `_${token}_reason` : `_${token}`], $[reason]),
38
+ ],
21
39
  [`_${token}_issue`, ($) => alias($[`_${token}_outcome`], $[outcome])],
22
40
  ]),
23
41
  );
24
42
  const issue = ($, name) =>
25
43
  field("issue", alias($[`_${name}_issue`], $.syntax_issue));
26
44
  const issues = ($, ...names) => names.map((name) => issue($, name));
27
- // A backslash held by the owner before the issue of the unit it cannot escape.
28
45
  const heldPrefix = ($, ...names) =>
29
46
  seq($._escape_prefix, choice(...issues($, ...names)));
30
- const quotedEscapeIssues = [
31
- "invalid_quoted_escape",
32
- "ended_quoted_escape",
33
- "incomplete_quoted_escape",
34
- ];
35
47
  const missingName = ($) =>
36
48
  choice(...issues($, "missing_name", "incomplete_name"));
37
49
  const quoteClose = ($) =>
@@ -51,7 +63,6 @@ export default grammar({
51
63
  $._rule_start,
52
64
  $._macro_start,
53
65
  $._eof,
54
- $.line_ending,
55
66
  $._layout,
56
67
  $._separator,
57
68
  $._attribute_start,
@@ -105,6 +116,7 @@ export default grammar({
105
116
  choice($.blank_line, $.comment, $.attribute_rule, $.macro_definition),
106
117
  ),
107
118
  ),
119
+ line_ending: () => /\r?\n/,
108
120
  _end: ($) => seq(optional($._layout), choice($.line_ending, $._eof)),
109
121
  blank_line: ($) => seq($._blank_start, $._end),
110
122
  comment: ($) =>
@@ -161,6 +173,7 @@ export default grammar({
161
173
  $,
162
174
  "invalid_encoding",
163
175
  "invalid_name_character",
176
+ "invalid_name_escape",
164
177
  ...quotedEscapeIssues,
165
178
  ),
166
179
  heldPrefix($, "invalid_encoding"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konomanoasa/tree-sitter-gitattributes",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Tree-sitter grammar for gitattributes.",
6
6
  "license": "MIT",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "scripts": {
23
23
  "build": "npm run tree-sitter -- build-all",
24
- "check": "biome check . && node scripts/check-c.js && node scripts/check-generated.js && npm test",
25
- "format": "biome check --write . && node scripts/check-c.js --write",
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",
@@ -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
package/src/grammar.json CHANGED
@@ -35,6 +35,10 @@
35
35
  ]
36
36
  }
37
37
  },
38
+ "line_ending": {
39
+ "type": "PATTERN",
40
+ "value": "\\r?\\n"
41
+ },
38
42
  "_end": {
39
43
  "type": "SEQ",
40
44
  "members": [
@@ -492,6 +496,19 @@
492
496
  "value": "syntax_issue"
493
497
  }
494
498
  },
499
+ {
500
+ "type": "FIELD",
501
+ "name": "issue",
502
+ "content": {
503
+ "type": "ALIAS",
504
+ "content": {
505
+ "type": "SYMBOL",
506
+ "name": "_invalid_name_escape_issue"
507
+ },
508
+ "named": true,
509
+ "value": "syntax_issue"
510
+ }
511
+ },
495
512
  {
496
513
  "type": "FIELD",
497
514
  "name": "issue",
@@ -1588,6 +1605,33 @@
1588
1605
  },
1589
1606
  "named": true,
1590
1607
  "value": "invalid_syntax"
1608
+ },
1609
+ "_invalid_name_escape_reason": {
1610
+ "type": "ALIAS",
1611
+ "content": {
1612
+ "type": "SYMBOL",
1613
+ "name": "_invalid_name_escape"
1614
+ },
1615
+ "named": true,
1616
+ "value": "quoted_escape"
1617
+ },
1618
+ "_invalid_name_escape_outcome": {
1619
+ "type": "ALIAS",
1620
+ "content": {
1621
+ "type": "SYMBOL",
1622
+ "name": "_invalid_name_escape_reason"
1623
+ },
1624
+ "named": true,
1625
+ "value": "invalid_name_character"
1626
+ },
1627
+ "_invalid_name_escape_issue": {
1628
+ "type": "ALIAS",
1629
+ "content": {
1630
+ "type": "SYMBOL",
1631
+ "name": "_invalid_name_escape_outcome"
1632
+ },
1633
+ "named": true,
1634
+ "value": "invalid_syntax"
1591
1635
  }
1592
1636
  },
1593
1637
  "extras": [],
@@ -1618,10 +1662,6 @@
1618
1662
  "type": "SYMBOL",
1619
1663
  "name": "_eof"
1620
1664
  },
1621
- {
1622
- "type": "SYMBOL",
1623
- "name": "line_ending"
1624
- },
1625
1665
  {
1626
1666
  "type": "SYMBOL",
1627
1667
  "name": "_layout"
@@ -1846,6 +1886,10 @@
1846
1886
  "type": "SYMBOL",
1847
1887
  "name": "_invalid_name_character"
1848
1888
  },
1889
+ {
1890
+ "type": "SYMBOL",
1891
+ "name": "_invalid_name_escape"
1892
+ },
1849
1893
  {
1850
1894
  "type": "SYMBOL",
1851
1895
  "name": "_error_sentinel"
@@ -422,6 +422,21 @@
422
422
  ]
423
423
  }
424
424
  },
425
+ {
426
+ "type": "invalid_name_character",
427
+ "named": true,
428
+ "fields": {},
429
+ "children": {
430
+ "multiple": false,
431
+ "required": false,
432
+ "types": [
433
+ {
434
+ "type": "quoted_escape",
435
+ "named": true
436
+ }
437
+ ]
438
+ }
439
+ },
425
440
  {
426
441
  "type": "invalid_syntax",
427
442
  "named": true,
@@ -680,10 +695,6 @@
680
695
  "type": "invalid_encoding",
681
696
  "named": true
682
697
  },
683
- {
684
- "type": "invalid_name_character",
685
- "named": true
686
- },
687
698
  {
688
699
  "type": "invalid_quoted_escape",
689
700
  "named": true