@mnemonik/shared 7.142.0 → 7.143.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/dist/ast/grammars.d.ts +1 -1
- package/dist/ast/grammars.d.ts.map +1 -1
- package/dist/ast/grammars.js +10 -1
- package/dist/ast/grammars.js.map +1 -1
- package/dist/codeScanner.d.ts +3 -0
- package/dist/codeScanner.d.ts.map +1 -1
- package/dist/codeScanner.js +5 -0
- package/dist/codeScanner.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sourceRedaction.d.ts.map +1 -1
- package/dist/sourceRedaction.js +364 -2
- package/dist/sourceRedaction.js.map +1 -1
- package/package.json +1 -1
- package/queries/sql.tags.scm +5 -0
- package/queries/swift.tags.scm +11 -0
- package/scripts/jsx-bare-ampersand.patch +61 -0
- package/scripts/vendor-grammars.ts +274 -8
- package/src/ast/grammars.ts +10 -1
- package/src/codeScanner.ts +6 -0
- package/src/index.ts +2 -0
- package/src/sourceRedaction.ts +391 -2
- package/wasm/javascript.wasm +0 -0
- package/wasm/lua.LICENSE +21 -0
- package/wasm/lua.tags.scm +36 -0
- package/wasm/lua.wasm +0 -0
- package/wasm/sql.LICENSE +21 -0
- package/wasm/sql.tags.scm +5 -0
- package/wasm/sql.wasm +0 -0
- package/wasm/swift.LICENSE +21 -0
- package/wasm/swift.tags.scm +11 -0
- package/wasm/swift.wasm +0 -0
- package/wasm/tsx.wasm +0 -0
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
* nothing at runtime - which is the whole reason this plan chose WebAssembly
|
|
18
18
|
* over the native bindings.
|
|
19
19
|
*
|
|
20
|
-
* Run: npx tsx packages/shared/scripts/vendor-grammars.ts [--check]
|
|
20
|
+
* Run: npx tsx packages/shared/scripts/vendor-grammars.ts [--check | --only=<id>]
|
|
21
|
+
* JSX repair: run --only=javascript and --only=tsx; other assets stay untouched.
|
|
21
22
|
* --check verify every manifest entry is present and non-empty; write nothing.
|
|
22
23
|
* This is what CI should run to catch a grammar that silently stopped
|
|
23
24
|
* shipping an artifact.
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
|
|
26
27
|
import { execFileSync } from 'node:child_process';
|
|
27
28
|
import {
|
|
29
|
+
chmodSync,
|
|
28
30
|
copyFileSync,
|
|
29
31
|
existsSync,
|
|
30
32
|
mkdirSync,
|
|
@@ -42,13 +44,13 @@ import { Language, Parser, Query } from 'web-tree-sitter';
|
|
|
42
44
|
import { AST_LANGUAGE_IDS, QUERY_CHAIN, grammarArtifactBasename } from '../src/ast/grammars.js';
|
|
43
45
|
|
|
44
46
|
const WASM_DIR = fileURLToPath(new URL('../wasm/', import.meta.url));
|
|
45
|
-
/**
|
|
47
|
+
/** Local queries for missing or unsuitable upstream declaration captures. */
|
|
46
48
|
const OURS_DIR = fileURLToPath(new URL('../queries/', import.meta.url));
|
|
47
49
|
|
|
48
50
|
interface GrammarSpec {
|
|
49
51
|
/** Vendored artifact basename, and the id the registry keys on. */
|
|
50
52
|
id: string;
|
|
51
|
-
/** npm package to fetch. */
|
|
53
|
+
/** npm package or pinned source archive to fetch with npm pack. */
|
|
52
54
|
pkg: string;
|
|
53
55
|
/**
|
|
54
56
|
* `.wasm` basename inside the tarball when it differs from the package's own
|
|
@@ -59,7 +61,7 @@ interface GrammarSpec {
|
|
|
59
61
|
/**
|
|
60
62
|
* Where the tag query comes from. 'upstream' copies queries/tags.scm out of
|
|
61
63
|
* the tarball; 'ours' copies packages/shared/queries/<id>.tags.scm, which we
|
|
62
|
-
* maintain
|
|
64
|
+
* maintain when the upstream query is absent or captures unsuitable ranges.
|
|
63
65
|
*/
|
|
64
66
|
tags: 'upstream' | 'ours' | 'inherited';
|
|
65
67
|
}
|
|
@@ -80,7 +82,7 @@ interface GrammarSpec {
|
|
|
80
82
|
* predates the current wasm ABI. Presence is not loadability, which is why
|
|
81
83
|
* --check verifies both. Flutter matters, so this is worth revisiting by
|
|
82
84
|
* compiling from source with tree-sitter-cli.
|
|
83
|
-
* kotlin,
|
|
85
|
+
* kotlin, perl, zig - bundle no .wasm, so they need a build step
|
|
84
86
|
* with tree-sitter-cli. Deferred until the grammars above are proven; they
|
|
85
87
|
* keep the heuristic chunker meanwhile.
|
|
86
88
|
* markdown - keeps chunkMarkdown. Headers already are a document's semantic
|
|
@@ -99,7 +101,7 @@ const GRAMMARS: GrammarSpec[] = [
|
|
|
99
101
|
wasmFile: 'tree-sitter-tsx.wasm',
|
|
100
102
|
tags: 'inherited',
|
|
101
103
|
},
|
|
102
|
-
{ id: 'javascript', pkg: 'tree-sitter-javascript', tags: 'upstream' },
|
|
104
|
+
{ id: 'javascript', pkg: 'tree-sitter-javascript@0.25.0', tags: 'upstream' },
|
|
103
105
|
{ id: 'python', pkg: 'tree-sitter-python', tags: 'upstream' },
|
|
104
106
|
{ id: 'go', pkg: 'tree-sitter-go', tags: 'upstream' },
|
|
105
107
|
{ id: 'java', pkg: 'tree-sitter-java', tags: 'upstream' },
|
|
@@ -118,8 +120,29 @@ const GRAMMARS: GrammarSpec[] = [
|
|
|
118
120
|
{ id: 'elixir', pkg: 'tree-sitter-elixir', tags: 'upstream' },
|
|
119
121
|
{ id: 'solidity', pkg: 'tree-sitter-solidity', tags: 'upstream' },
|
|
120
122
|
{ id: 'bash', pkg: 'tree-sitter-bash', tags: 'ours' },
|
|
123
|
+
{
|
|
124
|
+
// Upstream MIT 0.4.1, gitHead 816840c592ab973500ae9750763c707b447e7fef; shipped ABI-15 WASM.
|
|
125
|
+
id: 'lua',
|
|
126
|
+
pkg: '@tree-sitter-grammars/tree-sitter-lua@0.4.1',
|
|
127
|
+
wasmFile: 'tree-sitter-lua.wasm',
|
|
128
|
+
tags: 'upstream',
|
|
129
|
+
},
|
|
121
130
|
{ id: 'groovy', pkg: 'tree-sitter-groovy', tags: 'ours' },
|
|
122
131
|
{ id: 'powershell', pkg: 'tree-sitter-powershell', tags: 'ours' },
|
|
132
|
+
{
|
|
133
|
+
id: 'swift',
|
|
134
|
+
// Upstream 0.7.3, MIT. Pin source, not an opaque workflow WASM.
|
|
135
|
+
pkg: 'https://codeload.github.com/alex-pinkus/tree-sitter-swift/tar.gz/b8b22bffbb3441780e6471665bacfb263741c86a',
|
|
136
|
+
wasmFile: 'tree-sitter-swift.wasm',
|
|
137
|
+
tags: 'ours',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'sql',
|
|
141
|
+
// @derekstride/tree-sitter-sql 0.3.11 gitHead, MIT; source includes the external scanner.
|
|
142
|
+
pkg: 'https://codeload.github.com/derekstride/tree-sitter-sql/tar.gz/7b51ecda191d36b92f5a90a8d1bc3faef1c7b8b8',
|
|
143
|
+
wasmFile: 'tree-sitter-sql.wasm',
|
|
144
|
+
tags: 'ours',
|
|
145
|
+
},
|
|
123
146
|
];
|
|
124
147
|
|
|
125
148
|
/**
|
|
@@ -229,7 +252,7 @@ async function checkOnly(): Promise<Problem[]> {
|
|
|
229
252
|
* Source: https://github.com/tree-sitter/tree-sitter-typescript/tree/v0.23.2
|
|
230
253
|
* MIT; CLI 0.24.4 uses emscripten/emsdk:3.1.64 for the WASM build.
|
|
231
254
|
*/
|
|
232
|
-
function rebuildTypescript(dir: string, work: string): void {
|
|
255
|
+
function rebuildTypescript(dir: string, work: string, only?: string): void {
|
|
233
256
|
const grammarPath = join(dir, 'common', 'define-grammar.js');
|
|
234
257
|
let grammar = readFileSync(grammarPath, 'utf8');
|
|
235
258
|
for (const [before, after] of [
|
|
@@ -260,6 +283,12 @@ function rebuildTypescript(dir: string, work: string): void {
|
|
|
260
283
|
]);
|
|
261
284
|
const cli = join(tools, 'node_modules', '.bin', 'tree-sitter');
|
|
262
285
|
for (const dialect of ['typescript', 'tsx']) {
|
|
286
|
+
if (only && only !== dialect) continue;
|
|
287
|
+
// TypeScript has no JSX; keep its existing WASM bytes unchanged.
|
|
288
|
+
if (dialect === 'tsx') {
|
|
289
|
+
patchJsxScanner(join(dir, 'common', 'scanner.h'));
|
|
290
|
+
patchJsxAttributes(join(tools, 'node_modules', 'tree-sitter-javascript', 'grammar.js'));
|
|
291
|
+
}
|
|
263
292
|
const options = {
|
|
264
293
|
cwd: join(dir, dialect),
|
|
265
294
|
env: { ...process.env, NODE_PATH: join(tools, 'node_modules') },
|
|
@@ -273,7 +302,235 @@ function rebuildTypescript(dir: string, work: string): void {
|
|
|
273
302
|
}
|
|
274
303
|
}
|
|
275
304
|
|
|
305
|
+
/** Upstream f8637eb: preserve entity boundaries while accepting bare JSX ampersands. */
|
|
306
|
+
function patchJsxScanner(scannerPath: string): void {
|
|
307
|
+
execFileSync('patch', ['--batch', scannerPath], {
|
|
308
|
+
input: readFileSync(new URL('./jsx-bare-ampersand.patch', import.meta.url)),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Bare attribute ampersands are fragments; complete entity tokens retain precedence. */
|
|
313
|
+
function patchJsxAttributes(grammarPath: string): void {
|
|
314
|
+
let grammar = readFileSync(grammarPath, 'utf8');
|
|
315
|
+
for (const [before, after] of [
|
|
316
|
+
[
|
|
317
|
+
'alias($.unescaped_double_jsx_string_fragment, $.string_fragment),',
|
|
318
|
+
"alias($.unescaped_double_jsx_string_fragment, $.string_fragment),\n alias(token.immediate(prec(-1, '&')), $.string_fragment),",
|
|
319
|
+
],
|
|
320
|
+
[
|
|
321
|
+
'alias($.unescaped_single_jsx_string_fragment, $.string_fragment),',
|
|
322
|
+
"alias($.unescaped_single_jsx_string_fragment, $.string_fragment),\n alias(token.immediate(prec(-1, '&')), $.string_fragment),",
|
|
323
|
+
],
|
|
324
|
+
['/([^"&]|&[^#A-Za-z])+/', '/[^"&]+/'],
|
|
325
|
+
["/([^'&]|&[^#A-Za-z])+/", "/[^'&]+/"],
|
|
326
|
+
] as const) {
|
|
327
|
+
if (!grammar.includes(before)) throw new Error('JSX attribute patch no longer applies');
|
|
328
|
+
grammar = grammar.replace(before, after);
|
|
329
|
+
}
|
|
330
|
+
writeFileSync(grammarPath, grammar);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** 0.25.0's reserved-word DSL needs generator 0.25.8; keep the existing WASM build tool. */
|
|
334
|
+
function rebuildJavascript(dir: string, work: string): void {
|
|
335
|
+
patchJsxScanner(join(dir, 'src', 'scanner.c'));
|
|
336
|
+
patchJsxAttributes(join(dir, 'grammar.js'));
|
|
337
|
+
const generator = join(work, 'javascript-generator');
|
|
338
|
+
execFileSync('npm', [
|
|
339
|
+
'install',
|
|
340
|
+
'--prefix',
|
|
341
|
+
generator,
|
|
342
|
+
'--no-audit',
|
|
343
|
+
'--no-fund',
|
|
344
|
+
'--no-package-lock',
|
|
345
|
+
'tree-sitter-cli@0.25.8',
|
|
346
|
+
]);
|
|
347
|
+
execFileSync(join(generator, 'node_modules', '.bin', 'tree-sitter'), ['generate'], { cwd: dir });
|
|
348
|
+
const tools = join(work, 'javascript-build');
|
|
349
|
+
execFileSync('npm', [
|
|
350
|
+
'install',
|
|
351
|
+
'--prefix',
|
|
352
|
+
tools,
|
|
353
|
+
'--no-audit',
|
|
354
|
+
'--no-fund',
|
|
355
|
+
'--no-package-lock',
|
|
356
|
+
'tree-sitter-cli@0.24.4',
|
|
357
|
+
]);
|
|
358
|
+
// CLI 0.24.4 pins emscripten/emsdk:3.1.64 for --docker.
|
|
359
|
+
execFileSync(
|
|
360
|
+
join(tools, 'node_modules', '.bin', 'tree-sitter'),
|
|
361
|
+
['build', '--wasm', '--docker', '--output', join(dir, 'tree-sitter-javascript.wasm')],
|
|
362
|
+
{ cwd: dir }
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** Same CLI/emsdk as the repaired TS grammars; no native binding or grammar dependency. */
|
|
367
|
+
function rebuildSwift(dir: string, work: string): void {
|
|
368
|
+
// A double optional marker must be adjacent to its type. The external ?? token
|
|
369
|
+
// skips whitespace, swallowing `as? Int ?? 0` into optional_type and rejecting 0.
|
|
370
|
+
const grammarPath = join(dir, 'grammar.js');
|
|
371
|
+
const grammar = readFileSync(grammarPath, 'utf8');
|
|
372
|
+
const before = ' alias($._nil_coalescing_operator, "??")';
|
|
373
|
+
if (!grammar.includes(before)) throw new Error('Swift optional-marker patch no longer applies');
|
|
374
|
+
writeFileSync(grammarPath, grammar.replace(before, ' token.immediate("??")'));
|
|
375
|
+
const scannerPath = join(dir, 'src', 'scanner.c');
|
|
376
|
+
const scanner = readFileSync(scannerPath, 'utf8');
|
|
377
|
+
const continuation =
|
|
378
|
+
' // Let\'s consume operators that can live after a "semicolon" style newline.';
|
|
379
|
+
if (!scanner.includes(continuation))
|
|
380
|
+
throw new Error('Swift multiplication patch no longer applies');
|
|
381
|
+
writeFileSync(
|
|
382
|
+
scannerPath,
|
|
383
|
+
scanner.replace(
|
|
384
|
+
continuation,
|
|
385
|
+
` // A whitespace-delimited multiplication operator continues the preceding expression.
|
|
386
|
+
// Keep mark_end before '*' so a non-binary spelling can still emit the newline.
|
|
387
|
+
if (ws_directive == CONTINUE_PARSING_TOKEN_FOUND && lookahead == '*') {
|
|
388
|
+
lexer->advance(lexer, false);
|
|
389
|
+
if (iswspace(lexer->lookahead)) return STOP_PARSING_NOTHING_FOUND;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
${continuation}`
|
|
393
|
+
)
|
|
394
|
+
);
|
|
395
|
+
const tools = join(work, 'swift-build');
|
|
396
|
+
execFileSync('npm', [
|
|
397
|
+
'install',
|
|
398
|
+
'--prefix',
|
|
399
|
+
tools,
|
|
400
|
+
'--no-audit',
|
|
401
|
+
'--no-fund',
|
|
402
|
+
'--no-package-lock',
|
|
403
|
+
'tree-sitter-cli@0.24.4',
|
|
404
|
+
]);
|
|
405
|
+
const cli = join(tools, 'node_modules', '.bin', 'tree-sitter');
|
|
406
|
+
execFileSync(cli, ['generate'], { cwd: dir });
|
|
407
|
+
// CLI 0.24.4 pins emscripten/emsdk:3.1.64 for --docker.
|
|
408
|
+
execFileSync(
|
|
409
|
+
cli,
|
|
410
|
+
['build', '--wasm', '--docker', '--output', join(dir, 'tree-sitter-swift.wasm')],
|
|
411
|
+
{ cwd: dir }
|
|
412
|
+
);
|
|
413
|
+
copyFileSync(join(dir, 'LICENSE'), join(WASM_DIR, 'swift.LICENSE'));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/** Upstream package.json pins CLI 0.24.7. SQL function bodies only, not general PL/pgSQL. */
|
|
417
|
+
function rebuildSql(dir: string, work: string): void {
|
|
418
|
+
const grammarPath = join(dir, 'grammar.js');
|
|
419
|
+
let grammar = readFileSync(grammarPath, 'utf8');
|
|
420
|
+
const patch = (before: string, after: string): void => {
|
|
421
|
+
if (!grammar.includes(before)) throw new Error(`SQL patch no longer applies: ${before}`);
|
|
422
|
+
grammar = grammar.replace(before, after);
|
|
423
|
+
};
|
|
424
|
+
// Bounded repairs demonstrated by migrations 289/279/283 and the escaped-name regression.
|
|
425
|
+
const constraint = ` _constraint_literal: $ => seq(
|
|
426
|
+
$.keyword_constraint,
|
|
427
|
+
field('name', $.identifier),
|
|
428
|
+
choice(`;
|
|
429
|
+
patch(constraint, constraint + '\n $._key_constraint,');
|
|
430
|
+
patch('_double_quote_string: _ => /"[^"]*"/', '_double_quote_string: _ => /"([^"]|"")*"/');
|
|
431
|
+
patch(
|
|
432
|
+
'wrapped_in_parenthesis($.binary_expression)\n ),\n\n _default_expression',
|
|
433
|
+
'wrapped_in_parenthesis($._expression)\n ),\n\n _default_expression'
|
|
434
|
+
);
|
|
435
|
+
patch(
|
|
436
|
+
'field("custom_type", $.object_reference)',
|
|
437
|
+
'seq(field("custom_type", $.object_reference), optional(wrapped_in_parenthesis($._natural_number)))'
|
|
438
|
+
);
|
|
439
|
+
patch(
|
|
440
|
+
` $.keyword_conflict,
|
|
441
|
+
seq(`,
|
|
442
|
+
` $.keyword_conflict,
|
|
443
|
+
optional($._column_list),
|
|
444
|
+
seq(`
|
|
445
|
+
);
|
|
446
|
+
patch(
|
|
447
|
+
` $.keyword_brin
|
|
448
|
+
),`,
|
|
449
|
+
` $.keyword_brin,
|
|
450
|
+
$.identifier
|
|
451
|
+
),`
|
|
452
|
+
);
|
|
453
|
+
patch(
|
|
454
|
+
` $.index_fields
|
|
455
|
+
),`,
|
|
456
|
+
` $.index_fields
|
|
457
|
+
),
|
|
458
|
+
optional($.storage_parameters),`
|
|
459
|
+
);
|
|
460
|
+
patch(
|
|
461
|
+
` $.drop_function,
|
|
462
|
+
),`,
|
|
463
|
+
` $.drop_function,
|
|
464
|
+
$.drop_trigger,
|
|
465
|
+
),`
|
|
466
|
+
);
|
|
467
|
+
patch(
|
|
468
|
+
' drop_table: $ => seq(',
|
|
469
|
+
` drop_trigger: $ => seq(
|
|
470
|
+
$.keyword_drop, $.keyword_trigger, optional($._if_exists),
|
|
471
|
+
$.identifier, $.keyword_on, $.object_reference, optional($._drop_behavior),
|
|
472
|
+
),
|
|
473
|
+
|
|
474
|
+
drop_table: $ => seq(`
|
|
475
|
+
);
|
|
476
|
+
// Dollar-quoted procedural code is one literal, never a parsed SQL statement list.
|
|
477
|
+
patch(' $.reset_statement,', ' $.reset_statement,\n $.do_statement,');
|
|
478
|
+
patch(
|
|
479
|
+
' _cte: $ => seq(',
|
|
480
|
+
` do_statement: $ => seq($.keyword_do, alias($._dollar_quoted_string, $.literal)),
|
|
481
|
+
|
|
482
|
+
_cte: $ => seq(`
|
|
483
|
+
);
|
|
484
|
+
patch(' conflicts: $ => [', ' conflicts: $ => [\n [$.create_function],');
|
|
485
|
+
const functionStart = grammar.indexOf(' create_function: $ => seq(');
|
|
486
|
+
const functionEnd = grammar.indexOf(' _function_return:', functionStart);
|
|
487
|
+
if (functionStart < 0 || functionEnd < 0) throw new Error('SQL function patch no longer applies');
|
|
488
|
+
const original = grammar.slice(functionStart, functionEnd).trimEnd();
|
|
489
|
+
const languageOption = ' $.function_language,\n';
|
|
490
|
+
const optionsStart = original.indexOf(' repeat(');
|
|
491
|
+
const optionsEnd = original.indexOf(' // ensure');
|
|
492
|
+
const options = original.slice(optionsStart, optionsEnd).replace(languageOption, '');
|
|
493
|
+
// A dedicated keyword selects the opaque branch; ordinary LANGUAGE SQL keeps its AST.
|
|
494
|
+
const procedural =
|
|
495
|
+
original.slice(0, optionsStart) +
|
|
496
|
+
options +
|
|
497
|
+
` alias(seq($.keyword_language, alias(make_keyword("plpgsql"), $.identifier)), $.function_language),\n` +
|
|
498
|
+
options +
|
|
499
|
+
` alias(seq($.keyword_as, alias(choice($._dollar_quoted_string, $._single_quote_string, $._double_quote_string), $.literal)), $.function_body),\n` +
|
|
500
|
+
options +
|
|
501
|
+
' )';
|
|
502
|
+
patch(
|
|
503
|
+
original,
|
|
504
|
+
procedural.replace('create_function: $ => seq(', 'create_function: $ => choice(prec(1, seq(') +
|
|
505
|
+
'),\n' +
|
|
506
|
+
original.slice(original.indexOf('seq('), -1) +
|
|
507
|
+
'),'
|
|
508
|
+
);
|
|
509
|
+
writeFileSync(grammarPath, grammar);
|
|
510
|
+
const tools = join(work, 'sql-build');
|
|
511
|
+
execFileSync('npm', [
|
|
512
|
+
'install',
|
|
513
|
+
'--prefix',
|
|
514
|
+
tools,
|
|
515
|
+
'--no-audit',
|
|
516
|
+
'--no-fund',
|
|
517
|
+
'--no-package-lock',
|
|
518
|
+
'tree-sitter-cli@0.24.7',
|
|
519
|
+
]);
|
|
520
|
+
const cli = join(tools, 'node_modules', '.bin', 'tree-sitter');
|
|
521
|
+
execFileSync(cli, ['generate'], { cwd: dir });
|
|
522
|
+
execFileSync(
|
|
523
|
+
cli,
|
|
524
|
+
['build', '--wasm', '--docker', '--output', join(dir, 'tree-sitter-sql.wasm')],
|
|
525
|
+
{ cwd: dir }
|
|
526
|
+
);
|
|
527
|
+
copyFileSync(join(dir, 'LICENSE'), join(WASM_DIR, 'sql.LICENSE'));
|
|
528
|
+
}
|
|
529
|
+
|
|
276
530
|
function vendor(): Problem[] {
|
|
531
|
+
const only = process.argv.find((arg) => arg.startsWith('--only='))?.slice(7);
|
|
532
|
+
if (only && !GRAMMARS.some((spec) => spec.id === only))
|
|
533
|
+
throw new Error(`Unknown grammar: ${only}`);
|
|
277
534
|
mkdirSync(WASM_DIR, { recursive: true });
|
|
278
535
|
const work = mkdtempSync(join(tmpdir(), 'ts-grammars-'));
|
|
279
536
|
const problems: Problem[] = [];
|
|
@@ -283,6 +540,7 @@ function vendor(): Problem[] {
|
|
|
283
540
|
|
|
284
541
|
try {
|
|
285
542
|
for (const spec of GRAMMARS) {
|
|
543
|
+
if (only && spec.id !== only) continue;
|
|
286
544
|
let dir = extracted.get(spec.pkg);
|
|
287
545
|
if (!dir) {
|
|
288
546
|
try {
|
|
@@ -304,7 +562,10 @@ function vendor(): Problem[] {
|
|
|
304
562
|
dir,
|
|
305
563
|
'--strip-components=1',
|
|
306
564
|
]);
|
|
307
|
-
if (spec.id === 'typescript') rebuildTypescript(dir, work);
|
|
565
|
+
if (spec.id === 'typescript' || spec.id === 'tsx') rebuildTypescript(dir, work, only);
|
|
566
|
+
if (spec.id === 'javascript') rebuildJavascript(dir, work);
|
|
567
|
+
if (spec.id === 'swift') rebuildSwift(dir, work);
|
|
568
|
+
if (spec.id === 'sql') rebuildSql(dir, work);
|
|
308
569
|
extracted.set(spec.pkg, dir);
|
|
309
570
|
} catch (err) {
|
|
310
571
|
problems.push({
|
|
@@ -322,8 +583,13 @@ function vendor(): Problem[] {
|
|
|
322
583
|
problems.push({ id: spec.id, detail: `${spec.pkg} ships no ${wasmName}` });
|
|
323
584
|
} else {
|
|
324
585
|
copyFileSync(wasmSrc, join(WASM_DIR, `${spec.id}.wasm`));
|
|
586
|
+
if (spec.id === 'lua') copyFileSync(join(dir, 'LICENSE.md'), join(WASM_DIR, 'lua.LICENSE'));
|
|
587
|
+
if (spec.id === 'javascript' || spec.id === 'tsx')
|
|
588
|
+
chmodSync(join(WASM_DIR, `${spec.id}.wasm`), 0o644);
|
|
325
589
|
}
|
|
326
590
|
|
|
591
|
+
// A targeted JS scanner rebuild must retain our module-scope binding query additions.
|
|
592
|
+
if (only === 'javascript') continue;
|
|
327
593
|
if (spec.tags === 'upstream') {
|
|
328
594
|
const tagsSrc = join(dir, 'queries', 'tags.scm');
|
|
329
595
|
if (!existsSync(tagsSrc)) {
|
package/src/ast/grammars.ts
CHANGED
|
@@ -55,6 +55,9 @@ const AST_LANGUAGE_ID_LIST = [
|
|
|
55
55
|
'bash',
|
|
56
56
|
'groovy',
|
|
57
57
|
'powershell',
|
|
58
|
+
'swift',
|
|
59
|
+
'sql',
|
|
60
|
+
'lua',
|
|
58
61
|
] as const;
|
|
59
62
|
|
|
60
63
|
/** A language this build can AST-parse. Exactly the vendored set, no aspirations. */
|
|
@@ -123,6 +126,9 @@ export const QUERY_CHAIN: Readonly<Record<AstLanguageId, readonly AstLanguageId[
|
|
|
123
126
|
bash: ['bash'],
|
|
124
127
|
groovy: ['groovy'],
|
|
125
128
|
powershell: ['powershell'],
|
|
129
|
+
swift: ['swift'],
|
|
130
|
+
sql: ['sql'],
|
|
131
|
+
lua: ['lua'],
|
|
126
132
|
};
|
|
127
133
|
|
|
128
134
|
/**
|
|
@@ -144,7 +150,7 @@ const EXTENSION_GRAMMARS: Readonly<Record<string, AstLanguageId>> = {
|
|
|
144
150
|
*
|
|
145
151
|
* Absences are deliberate answers, not gaps. `markdown` is missing because
|
|
146
152
|
* headers already are a document's semantic unit and 10,483 production chunks
|
|
147
|
-
* depend on `chunkMarkdown` keeping them; `kotlin`, `
|
|
153
|
+
* depend on `chunkMarkdown` keeping them; `kotlin`, `dart` and friends
|
|
148
154
|
* are missing because no loadable grammar is vendored yet. Both resolve to
|
|
149
155
|
* `null` and the heuristic chunker takes over.
|
|
150
156
|
*/
|
|
@@ -166,6 +172,9 @@ const LANGUAGE_GRAMMARS: Readonly<Record<string, AstLanguageId>> = {
|
|
|
166
172
|
shell: 'bash',
|
|
167
173
|
groovy: 'groovy',
|
|
168
174
|
powershell: 'powershell',
|
|
175
|
+
swift: 'swift',
|
|
176
|
+
sql: 'sql',
|
|
177
|
+
lua: 'lua',
|
|
169
178
|
};
|
|
170
179
|
|
|
171
180
|
/** A loaded grammar plus its compiled query. Compiled once, reused per file. */
|
package/src/codeScanner.ts
CHANGED
|
@@ -563,6 +563,10 @@ export function languageForExtension(filePathOrExt: string): string {
|
|
|
563
563
|
const isMigrationSqlAuthorityPath = (posixRelPath: string): boolean =>
|
|
564
564
|
/^migrations\/.*\.sql$/.test(posixRelPath);
|
|
565
565
|
|
|
566
|
+
/** Content-only build authority, shared by scanner collection and server admission. */
|
|
567
|
+
export const XCODE_AUTHORITY_PATH = /(?:^|\/)[^/]+\.xcodeproj\/project\.pbxproj$|\.xcconfig$/;
|
|
568
|
+
export const isXcodeAuthorityPath = (path: string): boolean => XCODE_AUTHORITY_PATH.test(path);
|
|
569
|
+
|
|
566
570
|
/**
|
|
567
571
|
* Predicates for paths whose verbatim content is ALREADY shipped by
|
|
568
572
|
* `collectAuthorityFiles` and that carry no additional value as embedded code
|
|
@@ -582,6 +586,7 @@ const isMigrationSqlAuthorityPath = (posixRelPath: string): boolean =>
|
|
|
582
586
|
*/
|
|
583
587
|
const AUTHORITY_ONLY_PATH_PREDICATES: readonly ((posixRelPath: string) => boolean)[] = [
|
|
584
588
|
isMigrationSqlAuthorityPath,
|
|
589
|
+
isXcodeAuthorityPath,
|
|
585
590
|
];
|
|
586
591
|
|
|
587
592
|
/**
|
|
@@ -627,6 +632,7 @@ export const AUTHORITY_FILE_MATCHERS: Array<(relPath: string) => boolean> = [
|
|
|
627
632
|
// `AUTHORITY_ONLY_PATH_PREDICATES` by reference, not by a copied regex, so
|
|
628
633
|
// collection and the chunking exclusion cannot disagree.
|
|
629
634
|
isMigrationSqlAuthorityPath,
|
|
635
|
+
isXcodeAuthorityPath,
|
|
630
636
|
];
|
|
631
637
|
|
|
632
638
|
/**
|