@marko/tree-sitter 0.1.0 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/tree-sitter",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Tree-sitter grammar for the Marko templating language",
5
5
  "keywords": [
6
6
  "incremental",
@@ -38,6 +38,8 @@
38
38
  "node-gyp-build": "^4.8.4"
39
39
  },
40
40
  "devDependencies": {
41
+ "@changesets/changelog-github": "^0.7.0",
42
+ "@changesets/cli": "^2.31.0",
41
43
  "@types/degit": "^2.8.6",
42
44
  "@types/mocha": "^10.0.6",
43
45
  "@types/node": "^20.11.16",
@@ -61,12 +63,16 @@
61
63
  },
62
64
  "scripts": {
63
65
  "build": "tree-sitter generate && node-gyp rebuild",
66
+ "change": "changeset add",
64
67
  "generate": "tree-sitter generate",
65
68
  "install": "node-gyp-build",
69
+ "release:publish": "changeset publish",
70
+ "release:tag": "changeset tag",
66
71
  "test": "mocha \"./__tests__/*.test.mts\"",
67
72
  "prebuild": "prebuildify --napi --strip",
68
73
  "build:wasm": "tree-sitter build --wasm -o tree-sitter-marko.wasm",
69
- "test:wasm": "tsx tools/check-wasm.mts"
74
+ "test:wasm": "tsx tools/check-wasm.mts",
75
+ "version": "changeset version && node tools/sync-tree-sitter-version.mjs && npm install --package-lock-only"
70
76
  },
71
77
  "tree-sitter": [
72
78
  {
package/src/parser.c CHANGED
@@ -7864,7 +7864,7 @@ TS_PUBLIC const TSLanguage *tree_sitter_marko(void) {
7864
7864
  .max_reserved_word_set_size = 0,
7865
7865
  .metadata = {
7866
7866
  .major_version = 0,
7867
- .minor_version = 1,
7867
+ .minor_version = 2,
7868
7868
  .patch_version = 0,
7869
7869
  },
7870
7870
  };
package/src/scanner.c CHANGED
@@ -623,6 +623,7 @@ static int64_t look_behind_for_operator(EStream *es, ExprState *e,
623
623
  }
624
624
 
625
625
  default: {
626
+ if (code < 'a' || code > 'z') return -1;
626
627
  const char *const *keywords =
627
628
  e->in_type ? TS_UNARY_KEYWORDS : UNARY_KEYWORDS;
628
629
  for (int i = 0; keywords[i]; i++) {
@@ -659,6 +660,7 @@ static int64_t look_ahead_for_operator(EStream *es, ExprState *e, uint32_t k) {
659
660
  }
660
661
 
661
662
  default: {
663
+ if (c < 'a' || c > 'z') return -1;
662
664
  for (int i = 0; BINARY_KEYWORDS[i]; i++) {
663
665
  const char *kw = BINARY_KEYWORDS[i];
664
666
  size_t len = strlen(kw);
@@ -880,6 +882,11 @@ static bool scan_expr_inner(EStream *es, ExprState *e) {
880
882
  continue;
881
883
  }
882
884
 
885
+ if (is_word_code(code)) {
886
+ es_next(es);
887
+ continue;
888
+ }
889
+
883
890
  if (!e->group_len) {
884
891
  if (e->cfg.terminated_by_whitespace && is_ws(code)) {
885
892
  if (!check_for_operators(es, e, false)) return true;
@@ -1017,6 +1024,12 @@ static bool scan_expr_inner(EStream *es, ExprState *e) {
1017
1024
  es_next(es);
1018
1025
  break;
1019
1026
  case '{':
1027
+ if (e->in_type && !e->force_type) {
1028
+ int64_t prev_pos = look_behind_while_ws(es, (int64_t)s->buf_len - 1);
1029
+ if (look_behind_for_operator(es, e, prev_pos) == -1) {
1030
+ e->in_type = false;
1031
+ }
1032
+ }
1020
1033
  if (e->group_len >= sizeof(e->group)) return false;
1021
1034
  e->group[e->group_len++] = '}';
1022
1035
  es_next(es);
@@ -1235,14 +1248,53 @@ static bool scan_open_tag_es(Scanner *s, TSLexer *lexer, const bool *valid,
1235
1248
  static bool scan_frame_content(Scanner *s, TSLexer *lexer, const bool *valid,
1236
1249
  TSSymbol *result);
1237
1250
 
1251
+ static inline void skip_or_peek(Scanner *s, TSLexer *lexer, bool consume) {
1252
+ if (consume) skipc(s, lexer);
1253
+ else lexer->advance(lexer, false);
1254
+ }
1255
+
1256
+ // Skip whitespace and `//`/`/* */` comments, returning true if a `,` follows.
1257
+ // `consume` skips them as trivia, otherwise it is raw lookahead beyond the
1258
+ // committed token end. Mirrors the concise-mode eol scan in OPEN_TAG.
1259
+ static bool scan_line_attr_trivia(Scanner *s, TSLexer *lexer, bool consume) {
1260
+ for (;;) {
1261
+ if (at_eof(lexer)) return false;
1262
+ int32_t c = lexer->lookahead;
1263
+ if (is_ws(c)) {
1264
+ skip_or_peek(s, lexer, consume);
1265
+ } else if (c == '/') {
1266
+ skip_or_peek(s, lexer, consume);
1267
+ if (lexer->lookahead == '/') {
1268
+ // line comment
1269
+ skip_or_peek(s, lexer, consume);
1270
+ while (!at_eof(lexer) && !is_line(lexer->lookahead))
1271
+ skip_or_peek(s, lexer, consume);
1272
+ } else if (lexer->lookahead == '*') {
1273
+ // block comment
1274
+ int32_t prev = 0;
1275
+ skip_or_peek(s, lexer, consume);
1276
+ while (!at_eof(lexer) && !(prev == '*' && lexer->lookahead == '/')) {
1277
+ prev = lexer->lookahead;
1278
+ skip_or_peek(s, lexer, consume);
1279
+ }
1280
+ if (at_eof(lexer)) return false;
1281
+ skip_or_peek(s, lexer, consume);
1282
+ } else {
1283
+ return false;
1284
+ }
1285
+ } else {
1286
+ break;
1287
+ }
1288
+ }
1289
+ return lexer->lookahead == ',';
1290
+ }
1291
+
1238
1292
  // After most tokens inside a concise open tag, look ahead to see whether a
1239
- // `,` follows (over any whitespace, including newlines): if so the open tag
1240
- // continues on the next line (consumeWhitespaceIfBefore(",")).
1293
+ // `,` follows (over whitespace and comments): if so the open tag continues on
1294
+ // the next line with another line attribute.
1241
1295
  static void concise_tag_epilogue(Scanner *s, TSLexer *lexer) {
1242
1296
  if (!s->tag_open || !is_concise(s) || s->in_attr_group) return;
1243
- // raw lookahead beyond the committed token end
1244
- while (!at_eof(lexer) && is_ws(lexer->lookahead)) lexer->advance(lexer, false);
1245
- s->tag_comma_continue = !at_eof(lexer) && lexer->lookahead == ',';
1297
+ s->tag_comma_continue = scan_line_attr_trivia(s, lexer, false);
1246
1298
  }
1247
1299
 
1248
1300
  // --------------------------------------------------------------------------
@@ -2939,9 +2991,8 @@ static bool scan_open_tag_es(Scanner *s, TSLexer *lexer, const bool *valid,
2939
2991
  continue;
2940
2992
  }
2941
2993
  if (s->tag_comma_continue) {
2942
- // consumeWhitespaceIfBefore(","): skip to and through the comma.
2943
- while (!at_eof(lexer) && is_ws(lexer->lookahead)) skipc(s, lexer);
2944
- if (!at_eof(lexer) && lexer->lookahead == ',') skipc(s, lexer);
2994
+ // comma continues the open tag with another line attribute
2995
+ if (scan_line_attr_trivia(s, lexer, true)) skipc(s, lexer);
2945
2996
  while (!at_eof(lexer) && is_ws(lexer->lookahead)) skipc(s, lexer);
2946
2997
  s->tag_comma_continue = 0;
2947
2998
  continue;
Binary file
package/tree-sitter.json CHANGED
@@ -7,14 +7,16 @@
7
7
  "title": "Marko",
8
8
  "scope": "source.marko",
9
9
  "path": ".",
10
- "file-types": ["marko"],
10
+ "file-types": [
11
+ "marko"
12
+ ],
11
13
  "injection-regex": "^marko$",
12
14
  "highlights": "queries/highlights.scm",
13
15
  "injections": "queries/injections.scm"
14
16
  }
15
17
  ],
16
18
  "metadata": {
17
- "version": "0.1.0",
19
+ "version": "0.2.0",
18
20
  "license": "MIT",
19
21
  "description": "Tree-sitter grammar for the Marko templating language",
20
22
  "links": {