@xberg-io/tree-sitter-language-pack 1.14.2 → 1.15.6

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/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ <!-- This file is auto-generated by alef — DO NOT EDIT. -->
2
+ <!-- alef:hash:5f53c35a3c177554fec1d69a57b489f951570b04e3ea933ee9e68f7c59452458 -->
3
+ <!-- To regenerate: alef readme -->
4
+ <!-- To verify freshness: alef verify -->
5
+
1
6
  <p align="center">
2
7
  <picture>
3
8
  <source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/xberg-io/assets@v1/banner/readme-banner-dark.svg">
@@ -113,12 +118,14 @@ npm install @xberg-io/tree-sitter-language-pack
113
118
 
114
119
  ## Quick Start
115
120
 
116
- ```typescript
117
- import { getParser } from "@xberg-io/tree-sitter-language-pack";
121
+ ```typescript title="TypeScript"
122
+ import { process } from "@xberg-io/tree-sitter-language-pack";
123
+ function main() {
124
+ const result = process("# A comment\ndef greet(name):\n \"\"\"Say hello.\"\"\"\n return f'Hi {name}'\n\nimport os\n", { language: "python" });
125
+ console.log(result);
126
+ }
118
127
 
119
- const parser = getParser("python");
120
- const tree = parser.parse("def hello(): pass");
121
- console.log(tree.rootNode.toString());
128
+ void main();
122
129
  ```
123
130
 
124
131
  ## Features
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated by alef — DO NOT EDIT.
2
- // alef:hash:976e3b6b83d187cee6bb9dd6b0b8644f15198c5e45d5a66a3b2d2f7573374a9d
2
+ // alef:hash:dfcbc4453ca8c45a492f2bb6653993898741a1008761931894bf829abd29e46a
3
3
  // To regenerate: alef generate
4
- // To verify freshness: alef verify --exit-code
4
+ // To verify freshness: alef verify
5
5
  /* eslint-disable */
6
6
  import type { Language } from "tree-sitter";
7
7
 
@@ -18,16 +18,23 @@ export declare function availableLanguages(): Array<string>;
18
18
  /**
19
19
  * Return the effective cache directory path.
20
20
  *
21
- * This is either the custom path set via [`configure`] / [`init`] or the
22
- * default: `~/.cache/tree-sitter-language-pack/v{version}/libs/`.
23
- * @throws Returns an error if the system cache directory cannot be determined.
21
+ * This is `{base}/tree-sitter-language-pack/v{version}/libs/`, where `{base}` is
22
+ * either the custom BASE directory set via `configure` / `init`
23
+ * (`PackConfig.cache_dir`) or the platform default cache directory — both are
24
+ * suffixed identically, so a custom `cache_dir` is never used as the final libs
25
+ * path. The default resolves to `~/.cache/tree-sitter-language-pack/v{version}/libs/`
26
+ * on a typical Unix system.
27
+ * @throws Returns an error if no cache directory can be resolved: `version` is somehow
28
+ * invalid, or (with no custom `cache_dir` configured) the platform reports none
29
+ * and `TREE_SITTER_LANGUAGE_PACK_CACHE_DIR` is unset. This crate no longer falls
30
+ * back to the temporary directory for the latter case — see #101 H2.
24
31
  */
25
32
  export declare function cacheDir(): string;
26
33
 
27
34
  /**
28
35
  * Delete all cached parser shared libraries.
29
36
  *
30
- * Resets the cache registration so the next call to [`get_language`] or
37
+ * Resets the cache registration so the next call to `get_language` or
31
38
  * a download function will re-register the (now empty) cache directory.
32
39
  * @throws Returns an error if the cache directory cannot be removed.
33
40
  */
@@ -37,9 +44,16 @@ export declare function cleanCache(): void;
37
44
  * Apply download configuration without downloading anything.
38
45
  *
39
46
  * Use this to set a custom cache directory before the first call to
40
- * [`get_language`] or any download function. Changing the cache dir
47
+ * `get_language` or any download function. Changing the cache dir
41
48
  * after languages have been registered has no effect on already-loaded
42
49
  * languages.
50
+ *
51
+ * `PackConfig.cache_dir` is a BASE directory, not the final libs path: this
52
+ * crate appends `tree-sitter-language-pack/v{version}/libs` to it, the same
53
+ * suffix applied to the platform default cache directory. In the example below,
54
+ * files actually land under `/tmp/my-parsers/tree-sitter-language-pack/v{version}/libs/`,
55
+ * never directly in `/tmp/my-parsers/`. Call `cache_dir` to read back the
56
+ * resolved, fully-suffixed path.
43
57
  * @throws Returns an error if the lock cannot be acquired.
44
58
  */
45
59
  export declare function configure(config?: PackConfig | undefined | null): void;
@@ -65,15 +79,11 @@ export declare function detectLanguage(path: string): string | null;
65
79
  * The `-S` flag accepted by some `env` implementations is skipped automatically.
66
80
  * Version suffixes (e.g. `python3.11`, `ruby3.2`) are stripped before matching.
67
81
  *
68
- * Returns `None` when content does not start with `#!`, the shebang is
69
- * malformed, or the interpreter is not recognised.
82
+ * A leading UTF-8 BOM (`U+FEFF`) is skipped before the `#!` check, so a
83
+ * BOM-prefixed script is still detected by its shebang.
70
84
  *
71
- * ```
72
- * use tree_sitter_language_pack::detect_language_from_content;
73
- * assert_eq!(detect_language_from_content("#!/usr/bin/env python3\npass"), Some("python"));
74
- * assert_eq!(detect_language_from_content("#!/bin/bash\necho hi"), Some("bash"));
75
- * assert_eq!(detect_language_from_content("no shebang here"), None);
76
- * ```
85
+ * Returns `None` when content does not start with `#!` (after stripping a
86
+ * leading BOM), the shebang is malformed, or the interpreter is not recognised.
77
87
  */
78
88
  export declare function detectLanguageFromContent(content: string): string | null;
79
89
 
@@ -81,13 +91,6 @@ export declare function detectLanguageFromContent(content: string): string | nul
81
91
  * Detect language name from a file extension (without leading dot).
82
92
  *
83
93
  * Returns `None` for unrecognized extensions. The match is case-insensitive.
84
- *
85
- * ```
86
- * use tree_sitter_language_pack::detect_language_from_extension;
87
- * assert_eq!(detect_language_from_extension("py"), Some("python"));
88
- * assert_eq!(detect_language_from_extension("RS"), Some("rust"));
89
- * assert_eq!(detect_language_from_extension("xyz"), None);
90
- * ```
91
94
  */
92
95
  export declare function detectLanguageFromExtension(ext: string): string | null;
93
96
 
@@ -96,21 +99,17 @@ export declare function detectLanguageFromExtension(ext: string): string | null;
96
99
  *
97
100
  * Extracts the file extension and looks it up. Returns `None` if the
98
101
  * path has no extension or the extension is not recognized.
99
- *
100
- * ```
101
- * use tree_sitter_language_pack::detect_language_from_path;
102
- * assert_eq!(detect_language_from_path("src/main.rs"), Some("rust"));
103
- * assert_eq!(detect_language_from_path("README.md"), Some("markdown"));
104
- * assert_eq!(detect_language_from_path("Makefile"), None);
105
- * ```
106
102
  */
107
103
  export declare function detectLanguageFromPath(path: string): string | null;
108
104
 
109
105
  /**
110
106
  * Download specific languages to the local cache.
111
107
  *
112
- * Returns the number of requested languages available after the call. Already
108
+ * Returns the number of distinct languages available after the call. Already
113
109
  * compiled or cached languages are included in the count.
110
+ *
111
+ * Aliases are resolved before counting, so `["shell", "bash"]` names one
112
+ * language and returns 1.
114
113
  * @throws Returns an error if any language is not available in the manifest or if
115
114
  * the download fails.
116
115
  */
@@ -139,16 +138,23 @@ export declare function downloadAll(): number;
139
138
  export declare function downloadedLanguages(): Array<string>;
140
139
 
141
140
  /**
142
- * Download every language in a named group (e.g. `"web"`, `"data"`).
141
+ * Download every language in a named group.
142
+ *
143
+ * Groups are defined by the remote manifest, not by this crate, and let you
144
+ * ensure a curated set of related grammars in one call instead of listing each
145
+ * name to `download()`. Already-cached languages are skipped.
143
146
  *
144
- * Groups are defined in the remote manifest and let you ensure a curated
145
- * set of related grammars in one call instead of listing each name to
146
- * [`download()`]. Already-cached languages are skipped.
147
+ * Call `manifest_groups` to discover the group names the manifest actually
148
+ * defines. The published manifest currently defines a single group, `"all"`;
149
+ * earlier revisions of this documentation advertised `"web"`, `"data"`, and
150
+ * `"systems"`, which the manifest has never contained, so every call following
151
+ * that example failed. Do not hardcode a group name without checking.
147
152
  *
148
153
  * Returns the total number of languages now available (statically compiled
149
154
  * plus downloaded and cached).
150
- * @throws Returns an error if the manifest cannot be fetched, the group is unknown,
151
- * or any constituent language fails to download.
155
+ * @throws Returns `Error.Download` if the manifest cannot be fetched, if the group
156
+ * is unknown — the message lists the groups the manifest defines — or if any
157
+ * constituent language fails to download.
152
158
  */
153
159
  export declare function downloadGroup(name: string): number;
154
160
 
@@ -185,13 +191,13 @@ export declare function getIndentsQuery(language: string): string | null;
185
191
  export declare function getInjectionsQuery(language: string): string | null;
186
192
 
187
193
  /**
188
- * Get a tree-sitter [`Language`] by name using the global registry.
194
+ * Get a tree-sitter `Language` by name using the global registry.
189
195
  *
190
196
  * Resolves language aliases (e.g., `"shell"` maps to `"bash"`).
191
197
  * When the `download` feature is enabled (default), automatically downloads
192
198
  * the parser from GitHub releases if not found locally.
193
- * @throws Returns [`Error::LanguageNotFound`] if the language is not recognized,
194
- * or [`Error::Download`] if auto-download fails.
199
+ * @throws Returns `Error.LanguageNotFound` if the language is not recognized,
200
+ * or `Error.Download` if auto-download fails.
195
201
  */
196
202
  export declare function getLanguage(name: string): Language;
197
203
 
@@ -204,12 +210,12 @@ export declare function getLanguage(name: string): Language;
204
210
  export declare function getLocalsQuery(language: string): string | null;
205
211
 
206
212
  /**
207
- * Get a [`Parser`] pre-configured for the given language.
213
+ * Get a `Parser` pre-configured for the given language.
208
214
  *
209
- * This is a convenience function that calls [`get_language`] and configures
215
+ * This is a convenience function that calls `get_language` and configures
210
216
  * a new parser in one step.
211
- * @throws Returns [`Error::LanguageNotFound`] if the language is not recognized, or
212
- * [`Error::ParserSetup`] if the language cannot be applied to the parser.
217
+ * @throws Returns `Error.LanguageNotFound` if the language is not recognized, or
218
+ * `Error.ParserSetup` if the language cannot be applied to the parser.
213
219
  */
214
220
  export declare function getParser(name: string): Parser;
215
221
 
@@ -263,7 +269,13 @@ export interface ChunkContext {
263
269
  readonly symbolsDefined?: Array<string>
264
270
  /** Comments contained within this chunk. */
265
271
  readonly comments?: Array<CommentInfo>
266
- /** Docstrings contained within this chunk. */
272
+ /**
273
+ * Docstrings contained within this chunk.
274
+ *
275
+ * Populated only for Python — the same language for which
276
+ * `ProcessResult.docstrings` is populated, and by the same
277
+ * classifier. Always empty for every other language.
278
+ */
267
279
  readonly docstrings?: Array<DocstringInfo>
268
280
  /** Whether this chunk contains any tree-sitter error nodes. */
269
281
  readonly hasErrorNodes?: boolean
@@ -279,7 +291,13 @@ export interface CodeChunk {
279
291
  readonly endByte?: number
280
292
  /** Zero-indexed start line of this chunk. */
281
293
  readonly startLine?: number
282
- /** Zero-indexed end line of this chunk. */
294
+ /**
295
+ * Zero-indexed row of the last byte actually included in this chunk
296
+ * (inclusive — the same row a `Span.end_line` would report for a node
297
+ * ending on that byte). Computed the same way regardless of whether the
298
+ * source has a trailing newline: it is always the row of `end_byte - 1`,
299
+ * never a phantom row past the file's real content.
300
+ */
283
301
  readonly endLine?: number
284
302
  /** Contextual metadata about this chunk. */
285
303
  readonly metadata?: ChunkContext
@@ -313,9 +331,9 @@ export declare enum CommentKind {
313
331
  }
314
332
 
315
333
  /**
316
- * An XML-style attribute attached to an [`Element`](DataNodeKind::Element) node.
334
+ * An XML-style attribute attached to an `Element` node.
317
335
  *
318
- * Populated only for `DataNodeKind::Element`; always empty for `KeyValue` and
336
+ * Populated only for `DataNodeKind.Element`; always empty for `KeyValue` and
319
337
  * `Sequence` nodes.
320
338
  */
321
339
  export interface DataAttribute {
@@ -330,9 +348,9 @@ export interface DataAttribute {
330
348
  /**
331
349
  * A node in the hierarchical data tree produced by data-format extraction.
332
350
  *
333
- * When [`ProcessConfig::data_extraction`](crate::ProcessConfig::data_extraction) is
334
- * `true`, [`ProcessResult::data`] is populated with a root `DataNode` whose
335
- * [`children`](DataNode::children) mirror the structure of the parsed file.
351
+ * When `ProcessConfig.data_extraction` is
352
+ * `true`, `ProcessResult.data` is populated with a root `DataNode` whose
353
+ * `children` mirror the structure of the parsed file.
336
354
  *
337
355
  * The `kind` field determines which other fields are meaningful:
338
356
  *
@@ -366,7 +384,7 @@ export interface DataNode {
366
384
  /**
367
385
  * The kind of a data node extracted from a data-format file.
368
386
  *
369
- * Classifies each node in the hierarchical [`DataNode`] tree returned when
387
+ * Classifies each node in the hierarchical `DataNode` tree returned when
370
388
  * `data_extraction` is enabled on `ProcessConfig`.
371
389
  *
372
390
  * # Wire format (public JSON contract)
@@ -470,20 +488,51 @@ export interface DocstringInfo {
470
488
  readonly span?: Span
471
489
  /** Name of the item this docstring documents. */
472
490
  readonly associatedItem?: string
473
- /** Parsed sections of the docstring (Args, Returns, Raises, etc.). */
491
+ /**
492
+ * Parsed sections of the docstring (Args, Returns, Raises, etc.).
493
+ *
494
+ * **Reserved: not yet populated.** Always empty, for every
495
+ * `DocstringFormat`. Parsing a docstring body into sections requires
496
+ * implementing each convention's own layout (Google/NumPy/reST style
497
+ * for Python, `@param`/`@returns` for JSDoc/Javadoc, and so on), which
498
+ * no extractor here does yet. The field is kept rather than removed so
499
+ * a consumer's deserializer does not need updating once it is.
500
+ */
474
501
  readonly parsedSections?: Array<DocSection>
475
502
  }
476
503
 
477
504
  /** Manages downloading and caching of pre-built parser shared libraries. */
478
505
  export declare class DownloadManager {
479
- /** Create a new download manager for the given version. */
506
+ /**
507
+ * Create a new download manager for the given version.
508
+ * @throws Returns `Error.Download` if `version` is empty, contains a path
509
+ * separator or `..`, or contains a character outside `[A-Za-z0-9.+-]` — see
510
+ * `validate_version` — or if no cache directory can be resolved (see
511
+ * `Self.default_cache_dir`).
512
+ */
480
513
  static new(version: string): DownloadManager
481
- /** List languages that are already downloaded and cached. */
514
+ /**
515
+ * List languages that are already downloaded and cached.
516
+ *
517
+ * Derived from the on-disk cache filenames, one canonical name per file, plus
518
+ * every alias that resolves to it (via `aliases_for`) — so
519
+ * this list agrees with the user-facing
520
+ * `LanguageRegistry.available_languages`
521
+ * about which names are "available"; both report `"shell"` once `bash` is
522
+ * cached, for example. A previous version reported canonical names only,
523
+ * which could never agree with `available_languages()`. See #107.
524
+ *
525
+ * Returns an empty list if the cache directory does not exist. If it exists
526
+ * but cannot be read (e.g. a permission error), also returns an empty list —
527
+ * changing this to a `Result` would be a breaking change across every
528
+ * language binding — but logs a `tracing.warn!` so the failure is not
529
+ * silently indistinguishable from "nothing installed".
530
+ */
482
531
  installedLanguages(): Array<string>
483
532
  /**
484
533
  * Download the platform bundle and extract every library file it contains.
485
534
  *
486
- * Unlike [`Self::ensure_languages`], this does not check the manifest language list
535
+ * Unlike `Self.ensure_languages`, this does not check the manifest language list
487
536
  * against archive contents — it simply extracts all `.so`/`.dylib`/`.dll` files
488
537
  * from the bundle. Languages in the manifest that are missing from the archive
489
538
  * are silently ignored rather than returning an error.
@@ -552,11 +601,43 @@ export interface FileMetrics {
552
601
  export interface ImportInfo {
553
602
  /** The module or path being imported from. */
554
603
  readonly source?: string
555
- /** Specific names imported from the source module. */
604
+ /**
605
+ * Specific names imported from the source module.
606
+ *
607
+ * For `import a, b` / `from m import a, b`, every entry's base name
608
+ * (never the alias). For a JavaScript/TypeScript named-imports clause
609
+ * (`import { a, b as c } from 'm'`), every specifier's original name.
610
+ *
611
+ * Populated for Python and JavaScript/TypeScript only. Always empty for
612
+ * every other language this crate recognises import statements for —
613
+ * Rust, Go, Java, Kotlin, and Elixir (`import`/`alias`/`require`/`use`)
614
+ * — and for a JS/TS namespace import (`import * as ns`) or default
615
+ * import (`import x from 'm'`), neither of which names individual items.
616
+ */
556
617
  readonly items?: Array<string>
557
- /** Alias assigned to the import (e.g., `import numpy as np`). */
618
+ /**
619
+ * Alias assigned to the import (e.g., `import numpy as np`).
620
+ *
621
+ * Populated for Python's single-name form (`import numpy as np`,
622
+ * `from m import a as b`) and JavaScript/TypeScript's namespace form
623
+ * (`import * as ns from 'm'`) or a named-imports clause naming exactly
624
+ * one specifier (`import { a as b } from 'm'`). `None` for Rust, Go,
625
+ * Java, Kotlin, and Elixir (which has its own `as:` alias option on
626
+ * `alias` directives, not yet extracted here) — and for a Python
627
+ * statement that aliases several names at once (`import os, sys as s`),
628
+ * where there is no single alias to report for the statement as a
629
+ * whole, so only `items` is populated for it.
630
+ */
558
631
  readonly alias?: string
559
- /** Whether this is a wildcard import (e.g., `import *` or `use foo::*`). */
632
+ /**
633
+ * Whether this is a wildcard import (e.g., `import *` or `use foo.*`).
634
+ *
635
+ * Detected from the syntax tree — a dedicated wildcard node
636
+ * (`wildcard_import` in Python, `use_wildcard` in Rust) or a bare `*`
637
+ * token outside of string-literal content — not by searching the
638
+ * import's source text for a `*` character, so a glob in an import path
639
+ * string (`import a from './glob*.js'`) is not mistaken for one.
640
+ */
560
641
  readonly isWildcard?: boolean
561
642
  /** Source span covering the import statement. */
562
643
  readonly span?: Span
@@ -566,7 +647,7 @@ export interface ImportInfo {
566
647
  * Thread-safe registry of tree-sitter language parsers.
567
648
  *
568
649
  * Manages both statically compiled and dynamically loaded language grammars.
569
- * Use [`LanguageRegistry::new()`] for the default registry, or access the
650
+ * Use `LanguageRegistry.new()` for the default registry, or access the
570
651
  * global instance via the module-level convenience functions
571
652
  * (`get_language`, `available_languages`, etc.).
572
653
  */
@@ -578,16 +659,6 @@ export declare class LanguageRegistry {
578
659
  * about dynamically loadable grammars and will load them on demand.
579
660
  */
580
661
  static new(): LanguageRegistry
581
- /**
582
- * Get a tree-sitter [`Language`] by name.
583
- *
584
- * Resolves aliases (e.g., `"shell"` -> `"bash"`, `"makefile"` -> `"make"`),
585
- * then looks up the language in the static table. When the `dynamic-loading`
586
- * feature is enabled, falls back to loading a shared library on demand.
587
- * @throws Returns [`Error::LanguageNotFound`] if the name (after alias resolution)
588
- * does not match any known grammar.
589
- */
590
- getLanguage(name: string): Language
591
662
  /**
592
663
  * List all available language names, sorted and deduplicated.
593
664
  *
@@ -596,26 +667,28 @@ export declare class LanguageRegistry {
596
667
  */
597
668
  availableLanguages(): Array<string>
598
669
  /**
599
- * Check whether a parser is statically compiled into this build.
670
+ * Check whether this language can be parsed right now, without downloading.
600
671
  *
601
- * Returns `true` only when the grammar was compiled in at build time
602
- * (i.e. it appears in the `STATIC_LANGUAGES` table). This is independent
603
- * of the extension-to-language mapping: `detect_language_from_extension`
604
- * consults the static ext table for all 371 grammars regardless of which
605
- * parsers are compiled in.
672
+ * Resolves aliases, then answers from exactly the lookup
673
+ * `get_language` performs: the statically compiled
674
+ * table, the already-loaded dynamic grammars, and the parser shared
675
+ * libraries present in the primary and extra (download-cache) library
676
+ * directories. It never performs network I/O.
606
677
  *
607
- * Use this when you need to distinguish "we know the language name" from
608
- * "we can actually parse files in that language right now".
678
+ * A previous implementation consulted only the statically compiled table.
679
+ * That table is empty in every build that does not set `TSLP_LANGUAGES`,
680
+ * so the function answered `false` for languages this registry parses
681
+ * perfectly well.
609
682
  *
610
- * ```no_run
611
- * use tree_sitter_language_pack::{detect_language_from_extension, LanguageRegistry};
683
+ * Contrast `has_language`, which is also `true` for a
684
+ * grammar that is merely *known to the manifest* and would have to be
685
+ * downloaded first. The pair distinguishes "we can parse it offline, now"
686
+ * from "we recognise the name".
612
687
  *
613
- * let registry = LanguageRegistry::new();
614
- * // Extension detection uses the static table — independent of compiled parsers.
615
- * let lang = detect_language_from_extension("feature"); // always returns Some("gherkin")
616
- * // Parser availability depends on which grammars were compiled in.
617
- * let can_parse = lang.map(|name| registry.has_parser(name)).unwrap_or(false);
618
- * ```
688
+ * The first `true` answer for a dynamic grammar loads its shared library:
689
+ * loading is the only way to know the grammar is usable, since a truncated
690
+ * or wrong-architecture library exists on disk but cannot parse. Loads are
691
+ * cached process-wide, so repeat calls are cheap.
619
692
  */
620
693
  hasParser(name: string): boolean
621
694
  /**
@@ -623,23 +696,41 @@ export declare class LanguageRegistry {
623
696
  *
624
697
  * Returns `true` if the language can be loaded, either from the static
625
698
  * table or from a dynamic library on disk.
699
+ *
700
+ * Every branch is one more way to answer `true`, so they are ordered
701
+ * cheapest-first and the filesystem is only consulted once every in-memory
702
+ * source has said no. Probing the loaded-grammar map and the manifest ahead
703
+ * of the `stat` calls is what keeps this off the syscall path for the
704
+ * languages a process actually uses.
626
705
  */
627
706
  hasLanguage(name: string): boolean
628
- /** Return the total number of available languages (including aliases). */
707
+ /**
708
+ * Return the total number of available languages (including aliases).
709
+ *
710
+ * Counts the same set `available_languages`
711
+ * lists, without materialising or sorting it.
712
+ */
629
713
  languageCount(): number
630
- /** Parse source code and extract file intelligence based on config in a single pass. */
714
+ /**
715
+ * Parse source code and extract file intelligence based on config in a single pass.
716
+ * @throws Returns `Error.InvalidRange` if the config is invalid (see
717
+ * `ProcessConfig.validate`) or if the source
718
+ * exceeds the configured
719
+ * `max_source_bytes`;
720
+ * `Error.LanguageNotFound` if the language is unknown; or
721
+ * `Error.ParseFailed` if parsing produces no tree.
722
+ */
631
723
  process(source: string, config?: ProcessConfig | undefined | null): ProcessResult
632
724
  static default(): LanguageRegistry
633
725
  }
634
726
 
635
727
  /**
636
- * A single syntax node within a [`Tree`].
728
+ * A single syntax node within a `Tree`.
637
729
  *
638
730
  * Nodes hold a strong reference to their parent tree so they remain valid
639
731
  * regardless of how the tree is moved or stored at the FFI boundary.
640
732
  */
641
733
  export declare class Node {
642
- clone(): Node
643
734
  /** Return the node's kind name (e.g. `"function_definition"`). */
644
735
  kind(): string
645
736
  /**
@@ -647,7 +738,7 @@ export declare class Node {
647
738
  *
648
739
  * Tree-sitter assigns a stable `u16` ID to every node kind in a grammar
649
740
  * (e.g. `"function_definition" → 42`). Comparing `kind_id()` is cheaper
650
- * than comparing the string [`kind()`](Self::kind) in tight AST loops.
741
+ * than comparing the string `kind()` in tight AST loops.
651
742
  */
652
743
  kindId(): number
653
744
  /** Return the inclusive start byte offset of this node. */
@@ -655,15 +746,15 @@ export declare class Node {
655
746
  /** Return the exclusive end byte offset of this node. */
656
747
  endByte(): number
657
748
  /**
658
- * Return the node's byte range as a [`ByteRange`].
749
+ * Return the node's byte range as a `ByteRange`.
659
750
  *
660
751
  * Callers should slice their own source bytes — this is a zero-copy
661
752
  * text accessor.
662
753
  */
663
754
  byteRange(): ByteRange
664
- /** Return the start [`Point`] (row, column). */
755
+ /** Return the start `Point` (row, column). */
665
756
  startPosition(): Point
666
- /** Return the end [`Point`] (row, column). */
757
+ /** Return the end `Point` (row, column). */
667
758
  endPosition(): Point
668
759
  /** True when this node is named (not punctuation/whitespace). */
669
760
  isNamed(): boolean
@@ -689,7 +780,7 @@ export declare class Node {
689
780
  childByFieldName(name: string): Node | null
690
781
  /** Return the S-expression form of this node's subtree. */
691
782
  toSexp(): string
692
- /** Return a [`TreeCursor`] positioned at this node. */
783
+ /** Return a `TreeCursor` positioned at this node. */
693
784
  walk(): TreeCursor
694
785
  }
695
786
 
@@ -702,9 +793,20 @@ export declare class Node {
702
793
  */
703
794
  export interface PackConfig {
704
795
  /**
705
- * Override default cache directory.
796
+ * Override the BASE directory the parser cache lives under.
797
+ *
798
+ * This is a base, not the final library path: the crate appends
799
+ * `tree-sitter-language-pack/v{version}/libs` to it, exactly as it does to the
800
+ * platform default. So `cache_dir = "/tmp/my-parsers"` resolves to
801
+ * `/tmp/my-parsers/tree-sitter-language-pack/v{version}/libs/`.
802
+ *
803
+ * The suffix is not cosmetic. It keeps the whole cache tree — manifest, bundles
804
+ * and lock file included — inside a directory this crate owns and versions.
805
+ * Earlier releases used this path verbatim, which put those files in the
806
+ * configured directory's PARENT and let a cache built by one crate version be
807
+ * reused by another.
706
808
  *
707
- * Default: `~/.cache/tree-sitter-language-pack/v{version}/libs/`
809
+ * Default base: the platform cache dir, e.g. `~/.cache` on Linux.
708
810
  */
709
811
  readonly cacheDir?: string
710
812
  /**
@@ -713,39 +815,84 @@ export interface PackConfig {
713
815
  * Each entry is a language name (e.g. `"python"`, `"rust"`).
714
816
  */
715
817
  readonly languages?: Array<string>
716
- /** Language groups to pre-download (e.g. `"web"`, `"systems"`, `"scripting"`). */
818
+ /**
819
+ * Language groups to pre-download.
820
+ *
821
+ * Group names come from the remote manifest, so the valid set is not fixed
822
+ * by this crate; the published manifest currently defines only `"all"`.
823
+ * Call `manifest_groups` to enumerate them.
824
+ * An unknown name makes `init` fail.
825
+ */
717
826
  readonly groups?: Array<string>
718
827
  }
719
828
 
720
829
  /** A tree-sitter parser configured for one language at a time. */
721
830
  export declare class Parser {
722
831
  /**
723
- * Construct a new parser with no language set.
832
+ * Construct a new parser with no language set and no parse limits.
724
833
  *
725
- * Call [`Parser::set_language`] before parsing.
834
+ * Call `Parser.set_language` before parsing. Limits are opt-in via
835
+ * `set_max_source_bytes` and
836
+ * `set_parse_timeout_ms`; both default to
837
+ * unbounded so that existing callers are unaffected.
726
838
  */
727
839
  static new(): Parser
840
+ /**
841
+ * Refuse to parse sources longer than `max_bytes`.
842
+ *
843
+ * `None` (the default) means no limit. Over-limit input makes
844
+ * `parse` and `parse_bytes` return
845
+ * `None` after emitting a `WARN`; input is never silently truncated.
846
+ *
847
+ * See `RECOMMENDED_MAX_SOURCE_BYTES`.
848
+ */
849
+ setMaxSourceBytes(maxBytes?: number | undefined | null): void
850
+ /**
851
+ * Cancel a parse that exceeds `timeout_ms` milliseconds of wall clock.
852
+ *
853
+ * `None` (the default) means no budget. Cancellation runs through
854
+ * tree-sitter's parse progress callback, so it is granular to that
855
+ * callback's interval rather than exact.
856
+ *
857
+ * See `RECOMMENDED_PARSE_TIMEOUT_MS`.
858
+ */
859
+ setParseTimeoutMs(timeoutMs?: number | undefined | null): void
728
860
  /**
729
861
  * Configure the parser to use the language identified by name (e.g. `"python"`).
730
862
  *
731
863
  * Resolves the language through the global registry — auto-downloading
732
864
  * if necessary, when the `download` feature is enabled.
733
- * @throws Returns [`Error::LanguageNotFound`] if the language is not recognized,
734
- * or [`Error::ParserSetup`] if the language ABI is incompatible.
865
+ * @throws Returns `Error.LanguageNotFound` if the language is not recognized,
866
+ * or `Error.ParserSetup` if the language ABI is incompatible.
735
867
  */
736
868
  setLanguage(name: string): void
737
869
  /**
738
- * Parse a UTF-8 source string. Returns `None` if parsing was cancelled
739
- * or no language is set.
870
+ * Parse a UTF-8 source string.
871
+ *
872
+ * Returns `None` if no language is set, if the parse was cancelled by the
873
+ * configured [timeout](Self.set_parse_timeout_ms), or if the source
874
+ * exceeds the configured [size limit](Self.set_max_source_bytes). Each
875
+ * non-parse outcome is logged, so an empty result is never silent.
876
+ *
877
+ * # Concurrency
878
+ *
879
+ * Parsing runs fully in parallel across threads for almost every language — no lock is
880
+ * taken. The exception is the small set of grammars whose external scanner keeps mutable
881
+ * process-global state (currently just `properties`): parses of that language are
882
+ * serialized against each other through an internal per-language lock, so that concurrent
883
+ * threads can't corrupt shared scanner state. Every other language is unaffected by that
884
+ * lock and never waits on it.
740
885
  */
741
886
  parse(source: string): Tree | null
742
887
  /**
743
- * Parse a raw byte slice. Returns `None` if parsing was cancelled or
744
- * no language is set.
888
+ * Parse a raw byte slice.
889
+ *
890
+ * Same outcomes as `parse`, including the concurrency behaviour documented
891
+ * there.
745
892
  */
746
893
  parseBytes(source: Uint8Array): Tree | null
747
894
  /**
748
- * Reset internal state. The next call to [`parse`](Self::parse) will
895
+ * Reset internal state. The next call to `parse` will
749
896
  * not be incremental.
750
897
  */
751
898
  reset(): void
@@ -756,7 +903,22 @@ export declare class Parser {
756
903
  export interface Point {
757
904
  /** Zero-indexed row number. */
758
905
  readonly row: number
759
- /** Zero-indexed column number, in UTF-16 code units. */
906
+ /**
907
+ * Zero-indexed column, counted in **bytes** from the start of the row.
908
+ *
909
+ * This is `tree_sitter.Point.column` verbatim, and tree-sitter defines it
910
+ * as a byte offset — not characters, and not UTF-16 code units. Measured on
911
+ * a row of the form `x = '<c>'` where `<c>` is a single 4-byte character
912
+ * (an emoji), the string node reports columns `4..10`, identical to its
913
+ * byte range; the character columns would be `4..7` and the UTF-16 columns
914
+ * `4..8`.
915
+ *
916
+ * Anything that builds LSP positions (UTF-16) or editor caret columns
917
+ * (characters) from this field is silently wrong on every row containing a
918
+ * non-ASCII byte, and must re-measure the row against the source text
919
+ * instead. Earlier releases documented this field as UTF-16 code units;
920
+ * that was never what the value contained.
921
+ */
760
922
  readonly column: number
761
923
  }
762
924
 
@@ -782,19 +944,51 @@ export interface ProcessConfig {
782
944
  readonly symbols?: boolean
783
945
  /** Include parse diagnostics. Default: false. */
784
946
  readonly diagnostics?: boolean
785
- /** Maximum chunk size in bytes. `None` disables chunking. */
947
+ /**
948
+ * Maximum chunk size in bytes. `None` disables chunking.
949
+ *
950
+ * `Some(0)` is rejected by `ProcessConfig.validate` with
951
+ * `Error.InvalidRange`. A zero-sized chunk
952
+ * limit previously produced an empty chunk list and silently discarded the
953
+ * whole source; use `None` to mean "do not chunk".
954
+ */
786
955
  readonly chunkMaxSize?: number
787
956
  /**
788
957
  * Extract hierarchical key/value data tree from data-format files. Default: false.
789
958
  *
790
- * When `true`, [`ProcessResult::data`](crate::ProcessResult::data) is populated
791
- * with a [`DataNode`](crate::DataNode) tree for supported languages: JSON, YAML,
959
+ * When `true`, `ProcessResult.data` is populated
960
+ * with a `DataNode` tree for supported languages: JSON, YAML,
792
961
  * TOML, `.properties`, HCL/HOCON, INI, editorconfig, KDL, CUE, CSV, PSV, PO,
793
962
  * nginx config, Caddy config, XML, and DTD.
794
963
  *
795
964
  * For languages outside this set the field is left as `None`.
796
965
  */
797
966
  readonly dataExtraction?: boolean
967
+ /**
968
+ * Reject source longer than this many bytes instead of parsing it.
969
+ * Default: `None` (unbounded).
970
+ *
971
+ * Tree-sitter allocates and walks proportionally to input size, so an
972
+ * unbounded parse of attacker-supplied input is a denial-of-service vector.
973
+ * The default stays unbounded for backward compatibility; services handling
974
+ * untrusted input should opt in, e.g. with
975
+ * `RECOMMENDED_MAX_SOURCE_BYTES`.
976
+ *
977
+ * Exceeding the limit fails the call with
978
+ * `Error.InvalidRange` — the source is never
979
+ * silently truncated.
980
+ */
981
+ readonly maxSourceBytes?: number
982
+ /**
983
+ * Wall-clock budget for the parse step, in milliseconds.
984
+ * Default: `None` (no timeout).
985
+ *
986
+ * Enforced through tree-sitter's parse progress callback, which the parser
987
+ * invokes periodically; cancellation is therefore granular to that callback
988
+ * interval rather than exact. A parse that exceeds the budget fails with
989
+ * `Error.ParseTimeout`.
990
+ */
991
+ readonly parseTimeoutMs?: number
798
992
  }
799
993
 
800
994
  /**
@@ -845,7 +1039,7 @@ export interface ProcessResult {
845
1039
  * HCL, INI, XML, CSV, and more). `None` when `data_extraction` is `false` (the
846
1040
  * default) or when the language is not a recognised data format.
847
1041
  *
848
- * See [`DataNode`] for the shape of the returned tree.
1042
+ * See `DataNode` for the shape of the returned tree.
849
1043
  */
850
1044
  readonly data?: DataNode
851
1045
  }
@@ -863,11 +1057,17 @@ export interface Span {
863
1057
  readonly endByte?: number
864
1058
  /** Zero-indexed line number of the span's start. */
865
1059
  readonly startLine?: number
866
- /** Zero-indexed column number of the span's start. */
1060
+ /**
1061
+ * Zero-indexed column of the span's start, counted in **bytes** from the
1062
+ * start of the line — not characters, not UTF-16 code units.
1063
+ */
867
1064
  readonly startColumn?: number
868
1065
  /** Zero-indexed line number of the span's end. */
869
1066
  readonly endLine?: number
870
- /** Zero-indexed column number of the span's end. */
1067
+ /**
1068
+ * Zero-indexed column of the span's end, counted in **bytes** from the
1069
+ * start of the line — not characters, not UTF-16 code units.
1070
+ */
871
1071
  readonly endColumn?: number
872
1072
  }
873
1073
 
@@ -883,11 +1083,44 @@ export interface StructureItem {
883
1083
  readonly span?: Span
884
1084
  /** Nested structural items (e.g., methods within a class). */
885
1085
  readonly children?: Array<StructureItem>
886
- /** Decorator or attribute names applied to the item. */
1086
+ /**
1087
+ * Decorator or attribute names applied to the item.
1088
+ *
1089
+ * **Reserved: not yet populated.** Always empty, for every language.
1090
+ * Recognising a decorator requires per-language grammar knowledge (a
1091
+ * Python `decorated_definition` wrapper, Java/C# annotations, Rust
1092
+ * attributes each have a different shape), which no extractor here
1093
+ * implements yet. The field is kept rather than removed so a consumer's
1094
+ * deserializer does not need updating once it is.
1095
+ */
887
1096
  readonly decorators?: Array<string>
888
- /** Documentation comment attached to the item, if any. */
1097
+ /**
1098
+ * Documentation comment attached to the item, if any.
1099
+ *
1100
+ * The text of the comment (or run of comments) immediately preceding
1101
+ * the item, with no blank line in between, when that comment is
1102
+ * classified as a doc comment. Multiple adjacent single-line doc
1103
+ * comments (Rust `///`) are joined with `\n` in source order.
1104
+ *
1105
+ * Populated for Rust (`///`/`//!`), Java (`/** * /`), and JavaScript/
1106
+ * TypeScript (`/** * /`). `None` for every other language, and for a
1107
+ * preceding comment that is not in doc-comment form (a plain `#`
1108
+ * comment in Python, Ruby, or Elixir) — Python's docstring convention is
1109
+ * captured separately, as `DocstringInfo`, not through this field.
1110
+ */
889
1111
  readonly docComment?: string
890
- /** Full signature text of the item (e.g., function parameters and return type). */
1112
+ /**
1113
+ * Full signature text of the item (e.g., function parameters and return type).
1114
+ *
1115
+ * The item's own source text from its start up to the start of its body
1116
+ * (see `StructureItem.body_span`), trimmed of trailing whitespace —
1117
+ * for example `fn add(a: i32, b: i32) -> i32` for a Rust function whose
1118
+ * body is `{ a + b }`. `None` only when that text is empty, which does
1119
+ * not happen for any item `StructureKind` currently reports. Populated
1120
+ * for every language and kind this crate extracts structure for, since
1121
+ * it is derived from `body_span`'s boundary rather than per-language
1122
+ * syntax.
1123
+ */
891
1124
  readonly signature?: string
892
1125
  /** Source span covering only the body of the item, if distinct from the declaration. */
893
1126
  readonly bodySpan?: Span
@@ -897,7 +1130,7 @@ export interface StructureItem {
897
1130
  * The kind of structural item found in source code.
898
1131
  *
899
1132
  * Categorizes top-level and nested declarations such as functions, classes,
900
- * structs, enums, traits, and more. Use [`Other`](StructureKind::Other) for
1133
+ * structs, enums, traits, and more. Use `Other` for
901
1134
  * language-specific constructs that do not fit a standard category.
902
1135
  *
903
1136
  * # Wire format (public JSON contract)
@@ -944,7 +1177,18 @@ export interface SymbolInfo {
944
1177
  readonly span?: Span
945
1178
  /** Explicit type annotation, if present in the source. */
946
1179
  readonly typeAnnotation?: string
947
- /** Documentation comment associated with this symbol. */
1180
+ /**
1181
+ * Documentation comment immediately preceding this symbol, resolved by
1182
+ * the same walk `StructureItem.doc_comment` uses (see
1183
+ * `doc_comment_at`) — never hard-coded `None`.
1184
+ *
1185
+ * Populated for Rust (`///`/`//!`), Java (`/** * /`), and JavaScript/
1186
+ * TypeScript (`/** * /`) — the languages whose comment classification
1187
+ * recognizes a doc-kind comment. `None` for every other language (e.g.
1188
+ * Python, Go, Ruby, which have no doc-kind comment classification), and
1189
+ * also `None` when a symbol in a supported language simply has no doc
1190
+ * comment immediately above it.
1191
+ */
948
1192
  readonly doc?: string
949
1193
  }
950
1194
 
@@ -983,15 +1227,15 @@ export declare enum SymbolKind {
983
1227
 
984
1228
  /** A parsed syntax tree. Cheap to clone (refcount bump). */
985
1229
  export declare class Tree {
986
- /** Return the root [`Node`] of this tree. */
1230
+ /** Return the root `Node` of this tree. */
987
1231
  rootNode(): Node
988
- /** Return a [`TreeCursor`] positioned at the root. */
1232
+ /** Return a `TreeCursor` positioned at the root. */
989
1233
  walk(): TreeCursor
990
1234
  }
991
1235
 
992
- /** A cursor for traversing a [`Tree`]. */
1236
+ /** A cursor for traversing a `Tree`. */
993
1237
  export declare class TreeCursor {
994
- /** Return the [`Node`] at the cursor's current position. */
1238
+ /** Return the `Node` at the cursor's current position. */
995
1239
  node(): Node
996
1240
  /**
997
1241
  * Move the cursor to the first child of the current node.
@@ -1020,11 +1264,22 @@ export declare class TreeCursor {
1020
1264
  */
1021
1265
  export declare function languageCount(): number;
1022
1266
 
1267
+ /**
1268
+ * Return the names of every language group the remote manifest defines, sorted.
1269
+ *
1270
+ * Group names are manifest data, not a compile-time constant of this crate, so
1271
+ * this is the only reliable way to learn what `download_group` and
1272
+ * `PackConfig.groups` accept. The published manifest currently defines just
1273
+ * `"all"`.
1274
+ * @throws Returns `Error.Download` if the manifest cannot be fetched.
1275
+ */
1276
+ export declare function manifestGroups(): Array<string>;
1277
+
1023
1278
  /**
1024
1279
  * Return all language names available in the remote manifest (371).
1025
1280
  *
1026
1281
  * Fetches (and caches) the remote manifest to discover the full list of
1027
- * downloadable languages. Use [`downloaded_languages`] to list what is
1282
+ * downloadable languages. Use `downloaded_languages` to list what is
1028
1283
  * already cached locally.
1029
1284
  * @throws Returns an error if the manifest cannot be fetched.
1030
1285
  */
@@ -1034,12 +1289,12 @@ export declare function manifestLanguages(): Array<string>;
1034
1289
  * Prefetch grammars: download any not already loadable from disk, then load every
1035
1290
  * requested language into the process registry so a subsequent hot loop only parses.
1036
1291
  *
1037
- * Unlike [`download()`], this does not trust in-memory availability — it downloads
1292
+ * Unlike `download()`, this does not trust in-memory availability — it downloads
1038
1293
  * whenever a grammar is not actually loadable from disk (fixing the case where a
1039
1294
  * known-but-not-downloaded grammar is reported present), then resolves and caches
1040
1295
  * every requested language. Call it once, up front, before a parallel workload.
1041
- * @throws Returns [`Error::Download`] if a required grammar cannot be fetched, or
1042
- * [`Error::LanguageNotFound`] if a requested name is unknown.
1296
+ * @throws Returns `Error.Download` if a required grammar cannot be fetched, or
1297
+ * `Error.LanguageNotFound` if a requested name is unknown.
1043
1298
  */
1044
1299
  export declare function prefetch(languages: Array<string>): void;
1045
1300
 
@@ -1048,7 +1303,11 @@ export declare function prefetch(languages: Array<string>): void;
1048
1303
  *
1049
1304
  * Parses the source with tree-sitter and extracts metrics, structure, imports,
1050
1305
  * exports, comments, docstrings, symbols, diagnostics, and/or chunks based on
1051
- * the flags set in [`ProcessConfig`].
1052
- * @throws Returns an error if the language is not found or parsing fails.
1306
+ * the flags set in `ProcessConfig`.
1307
+ * @throws Returns `Error.InvalidRange` if the config carries a zero-valued limit or
1308
+ * the source exceeds `ProcessConfig.max_source_bytes`,
1309
+ * `Error.ParseTimeout` if the parse exceeds
1310
+ * `ProcessConfig.parse_timeout_ms`, `Error.LanguageNotFound` if the
1311
+ * language is unknown, or `Error.ParseFailed` if parsing yields no tree.
1053
1312
  */
1054
1313
  export declare function process(source: string, config?: ProcessConfig | undefined | null): ProcessResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xberg-io/tree-sitter-language-pack",
3
- "version": "1.14.2",
3
+ "version": "1.15.6",
4
4
  "description": "Pre-compiled tree-sitter grammars for 371 programming languages",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -18,14 +18,14 @@
18
18
  },
19
19
  "files": ["index.js", "index.d.ts", "*.node"],
20
20
  "optionalDependencies": {
21
- "@xberg-io/tree-sitter-language-pack-linux-x64-gnu": "1.14.2",
22
- "@xberg-io/tree-sitter-language-pack-linux-arm64-gnu": "1.14.2",
23
- "@xberg-io/tree-sitter-language-pack-linux-x64-musl": "1.14.2",
24
- "@xberg-io/tree-sitter-language-pack-linux-arm64-musl": "1.14.2",
25
- "@xberg-io/tree-sitter-language-pack-darwin-x64": "1.14.2",
26
- "@xberg-io/tree-sitter-language-pack-darwin-arm64": "1.14.2",
27
- "@xberg-io/tree-sitter-language-pack-win32-x64-msvc": "1.14.2",
28
- "@xberg-io/tree-sitter-language-pack-win32-arm64-msvc": "1.14.2"
21
+ "@xberg-io/tree-sitter-language-pack-linux-x64-gnu": "1.15.6",
22
+ "@xberg-io/tree-sitter-language-pack-linux-arm64-gnu": "1.15.6",
23
+ "@xberg-io/tree-sitter-language-pack-linux-x64-musl": "1.15.6",
24
+ "@xberg-io/tree-sitter-language-pack-linux-arm64-musl": "1.15.6",
25
+ "@xberg-io/tree-sitter-language-pack-darwin-x64": "1.15.6",
26
+ "@xberg-io/tree-sitter-language-pack-darwin-arm64": "1.15.6",
27
+ "@xberg-io/tree-sitter-language-pack-win32-x64-msvc": "1.15.6",
28
+ "@xberg-io/tree-sitter-language-pack-win32-arm64-msvc": "1.15.6"
29
29
  },
30
30
  "napi": {
31
31
  "packageName": "@xberg-io/tree-sitter-language-pack",
Binary file
Binary file