@g3nomaly/analyze 0.1.5 → 0.1.7

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.
@@ -26,17 +26,40 @@ export interface RawCall {
26
26
  readonly qualifier: readonly string[];
27
27
  }
28
28
  /**
29
- * @brief Reads every call in a function body, each once, in the order they first appear.
29
+ * @brief A call or a passed value of a function body, with every line it is on.
30
30
  *
31
- * Calls inside a nested definition belong to that definition and are left out. Calls inside a lambda or a
32
- * closure belong to the function around it. A call through a variable the body declares itself keeps no
31
+ * @property lines - Lines of the file it is written on, in order, such as `[86, 112]` for a function called twice.
32
+ */
33
+ export interface LocatedCall extends RawCall {
34
+ readonly lines: readonly number[];
35
+ }
36
+ /**
37
+ * @brief The calls in a function body, and the functions it passes on as values.
38
+ *
39
+ * @property calls - Every call, each once, in the order they first appear.
40
+ * @property passes - Every name the body hands on as a value without calling it, such as the callback in
41
+ * `run(onDone)` or the entry of `{ add: addCommand }`, each once. A name the body binds itself is left out.
42
+ */
43
+ export interface BodyReferences {
44
+ readonly calls: readonly LocatedCall[];
45
+ readonly passes: readonly LocatedCall[];
46
+ }
47
+ /**
48
+ * @brief Reads the calls of a function body, and the functions it passes on as values.
49
+ *
50
+ * Calls and values inside a nested definition belong to that definition and are left out. Those inside a lambda
51
+ * or a closure belong to the function around it. A call through a variable the body declares itself keeps no
33
52
  * variable, since that local may hide a parameter or field of the same name and its type is unknown.
34
53
  *
54
+ * A value counts when it is an argument of a call, an element of an array or a list, or the value of a key of an
55
+ * object or a dict, and names a function: `onDone`, `this.flush` or `Timer.once`. A name the body binds, as a
56
+ * local, a loop variable, a catch variable or a lambda parameter, never counts, since it is no function of the scan.
57
+ *
35
58
  * @param body - Body node of the function.
36
59
  * @param definitions - Ids of the definition nodes of the file.
37
- * @returns The calls the body makes.
60
+ * @returns The calls and the passed values of the body.
38
61
  */
39
- export declare function readCalls(body: Node, definitions: ReadonlySet<number>): RawCall[];
62
+ export declare function readReferences(body: Node, definitions: ReadonlySet<number>): BodyReferences;
40
63
  /**
41
64
  * @brief What a call can be resolved with: where it is, the names around its function, and the declared types
42
65
  * of the variables it can go through.
@@ -55,7 +78,8 @@ export interface CallContext {
55
78
  readonly implicitReceiver: boolean;
56
79
  }
57
80
  /**
58
- * @brief Turns the calls of a function into `calls` edges to the functions of the scan they reach.
81
+ * @brief Turns the calls of a function into `calls` edges, and the functions it passes on into `passes` edges, to
82
+ * the functions of the scan they reach.
59
83
  *
60
84
  * A call only links when it names one function its file sees: one in the same file or in a file it imports, directly
61
85
  * or not. For a language whose imports the scan does not read, a bare call only reaches a free function of the same
@@ -63,13 +87,14 @@ export interface CallContext {
63
87
  * the declared type of the parameter or field it goes through, else a static method of a type of that name; a call
64
88
  * through any other expression links nowhere, since its type is unknown.
65
89
  *
66
- * Holds the indexes it resolves against, the graph it adds edges to, and the fields of each type. Created per scan
90
+ * Holds the indexes it resolves against, the graph it adds edges to, the fields of each type, and the getters and
91
+ * setters, which a value never hands on. Created per scan
67
92
  * by `RepositoryScanner` in `scanner/scanner.ts`; `SymbolPlanner` in `symbols.ts` registers the fields of each type
68
93
  * and links the calls of each function once every declaration is known.
69
94
  *
70
95
  * @example
71
96
  * const calls = new CallLinker(types, callables, sources, graph);
72
- * calls.link(functionRef, rawSymbol.calls, { scope, owners: ['geo'], variables: new Map() });
97
+ * calls.link(functionRef, rawSymbol.calls, { scope, owners: ['geo'], variables: new Map() }, 'calls');
73
98
  */
74
99
  export declare class CallLinker {
75
100
  private readonly types;
@@ -77,6 +102,7 @@ export declare class CallLinker {
77
102
  private readonly sources;
78
103
  private readonly graph;
79
104
  private readonly fields;
105
+ private readonly accessors;
80
106
  /**
81
107
  * Takes the indexes the calls resolve against and the graph the edges are added to.
82
108
  *
@@ -102,13 +128,22 @@ export declare class CallLinker {
102
128
  */
103
129
  fieldsAround(context: Pick<CallContext, 'scope' | 'owners'>): ReadonlyMap<string, string>;
104
130
  /**
105
- * @brief Records a `calls` edge from `from` to each function its calls reach.
131
+ * @brief Records an edge from `from` to each function its calls or its passed values reach.
132
+ *
133
+ * A passed value resolves the way a call of the same name would.
106
134
  *
107
- * @param from - Node of the calling function.
108
- * @param calls - The calls in its body.
135
+ * @param from - Node of the function.
136
+ * @param calls - The calls in its body, or the values it passes on.
109
137
  * @param context - Where the function is.
138
+ * @param kind - `calls` for calls, `passes` for values passed on.
139
+ */
140
+ link(from: NodeRef, calls: readonly LocatedCall[], context: CallContext, kind: 'calls' | 'passes'): void;
141
+ /**
142
+ * @brief Records that a method is a getter or a setter, which a value names without handing it on.
143
+ *
144
+ * @param method - Node of the getter or setter.
110
145
  */
111
- link(from: NodeRef, calls: readonly RawCall[], context: CallContext): void;
146
+ registerAccessor(method: NodeRef): void;
112
147
  /**
113
148
  * @brief The function one call reaches.
114
149
  *
@@ -0,0 +1,70 @@
1
+ import type { Node } from 'web-tree-sitter';
2
+ import type { SourceFileIndex } from './imports';
3
+ /**
4
+ * @brief One name an `export { … } from` statement hands on.
5
+ *
6
+ * @property name - Name the other file exports it under, such as `hashFile`.
7
+ * @property as - Name this file exports it under: the same name, or the alias of `name as alias`.
8
+ */
9
+ export interface ReexportedName {
10
+ readonly name: string;
11
+ readonly as: string;
12
+ }
13
+ /**
14
+ * @brief One `export … from` statement.
15
+ *
16
+ * @property specifier - The file it names, as written, such as `./hash`.
17
+ * @property names - The names it hands on, or `null` for `export * from`, which hands on every name.
18
+ */
19
+ export interface Reexport {
20
+ readonly specifier: string;
21
+ readonly names: readonly ReexportedName[] | null;
22
+ }
23
+ /**
24
+ * @brief What a file exports by name. A default export is left out.
25
+ *
26
+ * @property declared - What the file declares and exports itself, each with the name it is exported under:
27
+ * `export function load()`, `export { load }` or `export { load as start }`.
28
+ * @property reexports - The `export … from` statements of the file in file order, and each `export { name }` of a name
29
+ * the file imports, which hands that name on from the file it came from.
30
+ */
31
+ export interface FileExports {
32
+ readonly declared: readonly ReexportedName[];
33
+ readonly reexports: readonly Reexport[];
34
+ }
35
+ /**
36
+ * @brief How code outside a package imports a symbol: by the package name, or one of its subpaths, and the name the
37
+ * entry file there exports.
38
+ *
39
+ * @property specifier - What the import names: the package, such as `@g3nomaly/skills`, or a subpath of it, such as
40
+ * `@g3nomaly/core/hash`.
41
+ * @property name - Name the entry file exports the symbol under, such as `hashFile`.
42
+ */
43
+ export interface PackageImport {
44
+ readonly specifier: string;
45
+ readonly name: string;
46
+ }
47
+ /** The exports of a file that exports nothing by name, or whose language has no exports. */
48
+ export declare const NO_EXPORTS: FileExports;
49
+ /**
50
+ * @brief Reads the exports of a JavaScript or TypeScript file.
51
+ *
52
+ * @param root - Root node of the parsed file.
53
+ * @returns The names it declares and exports, and the names it hands on from other files. `export default` and
54
+ * `export * as name from` are left out, since neither exports a name of the other file.
55
+ */
56
+ export declare function readEcmascriptExports(root: Node): FileExports;
57
+ /**
58
+ * @brief Finds how code outside a package imports a symbol: through the first entry point of the package the file is
59
+ * in whose entry file exports the symbol, itself or through `export … from` statements.
60
+ *
61
+ * The entry points are the package name and the subpaths its manifest lists. The entry file of one is the file an
62
+ * import of it resolves to, such as `packages/core/src/hash/index.ts` for `@g3nomaly/core/hash`.
63
+ *
64
+ * @param sources - The source files and packages of the scan.
65
+ * @param path - Display path of the file that declares the symbol.
66
+ * @param name - Name the file declares the symbol under.
67
+ * @returns The specifier and the name the entry exports, or `null` when the file is in no package of the scan or
68
+ * no entry file exports the symbol.
69
+ */
70
+ export declare function packageImportOf(sources: SourceFileIndex, path: string, name: string): PackageImport | null;
@@ -1,6 +1,7 @@
1
1
  import { type SymbolKind } from '../../model';
2
2
  import type { Node, Query } from 'web-tree-sitter';
3
- import { type RawCall } from './calls';
3
+ import { type BodyReferences } from './calls';
4
+ import { type FileExports } from './exports';
4
5
  import type { ImportRequest } from './imports';
5
6
  import type { LanguageSpec } from './language';
6
7
  /**
@@ -41,6 +42,8 @@ export interface RawField {
41
42
  * @brief One definition as found in the syntax tree, before rendering.
42
43
  *
43
44
  * @property kind - Kind of the symbol, such as `function`, `method`, `class` or `enum`.
45
+ * @property line - Line of the file where the declaration starts.
46
+ * @property endLine - Line of the file where the declaration ends.
44
47
  * @property signature - Declaration head. Empty when `inferred`.
45
48
  * @property modifiers - Keywords in front of the name, such as `export` or `static`.
46
49
  * @property comment - Cleaned doc comment text, or `null`.
@@ -54,13 +57,16 @@ export interface RawField {
54
57
  * @property returnsValue - True when a call to the symbol yields a value.
55
58
  * @property inferred - True for an owner type that is not declared in this file.
56
59
  * @property internal - True for a function only its own file can call, as the spec's `isInternal` decides.
60
+ * @property accessor - True for a getter or a setter, such as `get size()` or a Python `@property`. Reading it runs it.
57
61
  * @property calls - For a function or method: the calls in its body, each once.
62
+ * @property passes - For a function or method: the names its body passes on as values, each once.
58
63
  * @property children - Members nested under this symbol.
59
64
  */
60
- export interface RawSymbol {
65
+ export interface RawSymbol extends BodyReferences {
61
66
  kind: SymbolKind;
62
67
  readonly name: string;
63
68
  readonly line: number;
69
+ readonly endLine: number;
64
70
  readonly signature: string;
65
71
  readonly modifiers: readonly string[];
66
72
  readonly annotations: readonly string[];
@@ -76,7 +82,7 @@ export interface RawSymbol {
76
82
  returnsValue: boolean;
77
83
  readonly inferred: boolean;
78
84
  readonly internal: boolean;
79
- readonly calls: readonly RawCall[];
85
+ readonly accessor: boolean;
80
86
  readonly children: RawSymbol[];
81
87
  }
82
88
  /**
@@ -85,11 +91,13 @@ export interface RawSymbol {
85
91
  * @property symbols - Top-level symbols of the file, each with its members nested under it.
86
92
  * @property packageName - Package or namespace the file declares, or `null` when the language has none.
87
93
  * @property imports - The files the file imports, as it writes them. Empty for a language without `imports`.
94
+ * @property exports - The names the file exports. Empty for a language whose imports do not read exports.
88
95
  */
89
96
  export interface ExtractedFile {
90
97
  readonly symbols: RawSymbol[];
91
98
  readonly packageName: string | null;
92
99
  readonly imports: readonly ImportRequest[];
100
+ readonly exports: FileExports;
93
101
  }
94
102
  /**
95
103
  * @brief Turns a parsed file into a tree of {@link RawSymbol}s, driven by a {@link LanguageSpec}.
@@ -1,12 +1,31 @@
1
1
  import type { Node } from 'web-tree-sitter';
2
2
  import type { NodeRef } from '../../model';
3
+ import { type FileExports } from './exports';
3
4
  /**
4
- * @brief One import of a file: the paths it can stand for, most specific first. The first one that names a
5
- * file of the scan wins.
5
+ * @brief One way to read an import: the path it names, and what it takes from that file.
6
6
  *
7
- * `from .models import Booking` is `['.models.Booking', '.models']`: `Booking` may be a module of its own.
7
+ * @property specifier - The path as written, such as `./store`, `slam/pose.hpp` or `.models`.
8
+ * @property whole - Whether it takes the file as a whole: `import './x'`, `import * as x`, a default import,
9
+ * `export * from`, `require('./x')`, an `#include`, or Python's `import a.b`.
10
+ * @property names - Names it takes from the file, as that file exports them: `['load']` for
11
+ * `import { load as start } from './x'` or `export { load } from './x'`.
8
12
  */
9
- export type ImportRequest = readonly string[];
13
+ export interface ImportTarget {
14
+ readonly specifier: string;
15
+ readonly whole: boolean;
16
+ readonly names: readonly string[];
17
+ }
18
+ /**
19
+ * @brief One import of a file: the ways it can be read, and the line it is on.
20
+ *
21
+ * @property targets - The ways to read it, most specific first. The first whose path names a file of the scan wins.
22
+ * `from .models import Booking` gives the module `.models.Booking` as a whole, then the name `Booking` of `.models`.
23
+ * @property line - Line of the file the import starts on.
24
+ */
25
+ export interface ImportRequest {
26
+ readonly targets: readonly ImportTarget[];
27
+ readonly line: number;
28
+ }
10
29
  /**
11
30
  * @brief How a language names the files a file imports.
12
31
  *
@@ -21,6 +40,13 @@ export interface ImportSyntax {
21
40
  * @returns One request per import, as the file writes it.
22
41
  */
23
42
  read(root: Node): ImportRequest[];
43
+ /**
44
+ * @brief Reads the names a parsed file exports, for a language whose packages export names from an entry file.
45
+ *
46
+ * @param root - Root node of the parsed file.
47
+ * @returns The names it declares and exports, and the files it re-exports from.
48
+ */
49
+ readExports?(root: Node): FileExports;
24
50
  /**
25
51
  * @brief Finds the file an import names.
26
52
  *
@@ -43,15 +69,19 @@ export interface ImportSyntax {
43
69
  * @property entries - Each file by display path.
44
70
  * @property byName - Display paths of the files with each file name.
45
71
  * @property packages - Directory of each package of the scan, by the name its manifest gives.
72
+ * @property entryPoints - The subpaths each package is imported by, by the name its manifest gives.
46
73
  * @property resolved - Display paths each file imports, resolved on first use.
47
74
  * @property seen - Display paths each file sees, computed on first use.
75
+ * @property declarations - Node of each top-level declaration of each file, by display path and then by name.
48
76
  */
49
77
  export declare class SourceFileIndex {
50
78
  private readonly entries;
51
79
  private readonly byName;
52
80
  private packages;
81
+ private entryPoints;
53
82
  private readonly resolved;
54
83
  private readonly seen;
84
+ private readonly declarations;
55
85
  /**
56
86
  * @brief Adds a source file.
57
87
  *
@@ -59,8 +89,9 @@ export declare class SourceFileIndex {
59
89
  * @param ref - Node of the file.
60
90
  * @param syntax - How its language names imports, or `null` when its imports are not read.
61
91
  * @param requests - Its imports, as the file writes them.
92
+ * @param exports - The names it exports, from `readExports` of its language.
62
93
  */
63
- add(path: string, ref: NodeRef, syntax: ImportSyntax | null, requests: readonly ImportRequest[]): void;
94
+ add(path: string, ref: NodeRef, syntax: ImportSyntax | null, requests: readonly ImportRequest[], exports: FileExports): void;
64
95
  /**
65
96
  * @brief Tells the index where each package of the scan is, so an import of a package by name finds its files.
66
97
  *
@@ -68,7 +99,15 @@ export declare class SourceFileIndex {
68
99
  */
69
100
  usePackages(packages: ReadonlyMap<string, {
70
101
  readonly packageName: string;
102
+ readonly entryPoints: readonly string[];
71
103
  }>): void;
104
+ /**
105
+ * @brief The subpaths a package is imported by.
106
+ *
107
+ * @param name - Name its manifest gives, such as `@g3nomaly/core`.
108
+ * @returns `''` for the name itself, then subpaths such as `hash`. `['']` for a package the scan does not have.
109
+ */
110
+ entryPointsOf(name: string): readonly string[];
72
111
  /**
73
112
  * @brief Directory of the package with a name.
74
113
  *
@@ -76,6 +115,36 @@ export declare class SourceFileIndex {
76
115
  * @returns Display path of its directory, `''` for the root, or `undefined` when the scan has no such package.
77
116
  */
78
117
  packageDirectory(name: string): string | undefined;
118
+ /**
119
+ * @brief Names the package a file is in: the package of the scan whose directory holds it most closely.
120
+ *
121
+ * @param path - Display path of a file.
122
+ * @returns The name its manifest gives, such as `@g3nomaly/core`, or `null` when no package holds the file.
123
+ */
124
+ packageOf(path: string): string | null;
125
+ /**
126
+ * @brief Finds the file one import of a file names, with the import syntax of that file's language.
127
+ *
128
+ * @param specifier - The import as written, such as `./hash` or `@g3nomaly/core`.
129
+ * @param from - Display path of the importing file.
130
+ * @returns Display path of the file, or `null` when the scan has none or the file's imports are not read.
131
+ */
132
+ resolveImport(specifier: string, from: string): string | null;
133
+ /**
134
+ * @brief The names a file exports.
135
+ *
136
+ * @param path - Display path of a file.
137
+ * @returns Its exports, empty for a file the scan does not have.
138
+ */
139
+ exportsOf(path: string): FileExports;
140
+ /**
141
+ * @brief Tells whether other files can import a name a file declares.
142
+ *
143
+ * @param path - Display path of the file.
144
+ * @param name - Name the file declares, such as `hashFile`.
145
+ * @returns True when the file exports the name, and always for a file whose exports the scan does not read.
146
+ */
147
+ exportsName(path: string, name: string): boolean;
79
148
  /**
80
149
  * @brief Node of the source file at `path`.
81
150
  *
@@ -104,6 +173,43 @@ export declare class SourceFileIndex {
104
173
  * @returns Display paths of the imported files, in the order the file imports them.
105
174
  */
106
175
  importsOf(path: string): readonly string[];
176
+ /**
177
+ * @brief What the imports of a file link to, each with the lines of the imports. An import of a whole file links
178
+ * to the file. An import by name links to the declaration of each name, through any `export … from` files in
179
+ * between, and to the file it names for a name that is no declaration of the scan, such as a constant.
180
+ *
181
+ * @param path - Display path of the importing file.
182
+ * @returns Each node the file imports, once, with the lines of the imports that reach it, in file order.
183
+ */
184
+ importLinksOf(path: string): {
185
+ readonly to: NodeRef;
186
+ readonly lines: readonly number[];
187
+ }[];
188
+ /**
189
+ * @brief Each import of a file that names a file of the scan, with that file and the way of reading it that won.
190
+ *
191
+ * @param path - Normalized display path of the importing file.
192
+ * @returns Every such import in file order.
193
+ */
194
+ private resolvedRequests;
195
+ /**
196
+ * @brief Records a top-level declaration of a file, so an import of its name can reach its node. The first
197
+ * declaration of a name wins, as for the overloads of one function.
198
+ *
199
+ * @param path - Display path of the file.
200
+ * @param name - Name it is declared with, such as `hashFile`.
201
+ * @param ref - Node of the declaration.
202
+ */
203
+ declare(path: string, name: string, ref: NodeRef): void;
204
+ /**
205
+ * @brief The declaration a file hands out under a name: its own, or one it re-exports from another file.
206
+ *
207
+ * @param path - Display path of the file.
208
+ * @param name - Name the file exports, such as `recordedHashes`.
209
+ * @param visited - Files already followed, so a cycle of re-exports ends.
210
+ * @returns Node of the declaration, or `null` when the file exports no declaration of the scan under the name.
211
+ */
212
+ private declarationOf;
107
213
  /**
108
214
  * @brief Tells whether the scan reads the imports of a file, so what it sees is known.
109
215
  *
@@ -1,5 +1,6 @@
1
1
  import type { SymbolKind } from '../../model';
2
2
  import type { Node } from 'web-tree-sitter';
3
+ import type { PackageImport } from './exports';
3
4
  import type { ImportSyntax } from './imports';
4
5
  /**
5
6
  * @brief Doc comment dialect, which decides how the scanner reads doc comments.
@@ -35,6 +36,8 @@ export interface DefinitionFacts {
35
36
  * @property kind - Kind of that outermost symbol.
36
37
  * @property modifiers - Keywords in front of the name, such as `export` or `default`.
37
38
  * @property packageName - Package or namespace the file declares with a statement, e.g. `a.b` for Java's `package a.b;`, or `null`.
39
+ * @property packageImport - For a symbol the entry file of its package exports, the package name and the name it is
40
+ * exported under, as code outside the package imports it. `null` when no package of the scan exports it.
38
41
  */
39
42
  export interface ImportContext {
40
43
  readonly filePath: string;
@@ -42,6 +45,7 @@ export interface ImportContext {
42
45
  readonly kind: SymbolKind;
43
46
  readonly modifiers: readonly string[];
44
47
  readonly packageName: string | null;
48
+ readonly packageImport: PackageImport | null;
45
49
  }
46
50
  /**
47
51
  * How a language spells a call. Drives generated examples.
@@ -102,7 +102,8 @@ export declare class CodePlanner {
102
102
  */
103
103
  private add;
104
104
  /**
105
- * @brief Records an `imports` edge from a file to each file of the scan it imports.
105
+ * @brief Records an `imports` edge from a file to each file it imports as a whole and to each declaration it
106
+ * imports by name, with the lines of its imports.
106
107
  *
107
108
  * @param from - Node of the importing file.
108
109
  * @param path - Display path of the importing file.
@@ -73,6 +73,14 @@ export declare class SymbolPlanner {
73
73
  * @param scope - Where the symbol sits in the file.
74
74
  */
75
75
  private planSymbol;
76
+ /**
77
+ * @brief Tells whether a name in a file can mean a declaration: only a test file reaches into test files, and only
78
+ * the package of a declaration reaches one it does not export.
79
+ *
80
+ * @param from - Display path of the file the name is in.
81
+ * @param declaration - Declaration the name may mean.
82
+ */
83
+ private admits;
76
84
  /**
77
85
  * @brief Builds the content of a symbol node: highlighted signature, rendered description,
78
86
  * return value, tags and example.
@@ -88,8 +96,8 @@ export declare class SymbolPlanner {
88
96
  */
89
97
  private symbolContent;
90
98
  /**
91
- * @brief Records the `calls` edges of a function, with its parameters and the fields of its type as the
92
- * variables a call can go through.
99
+ * @brief Records the `calls` and `passes` edges of a function, with its parameters and the fields of its type as
100
+ * the variables a call can go through. A parameter passed on by name is a value, never a function of the scan.
93
101
  *
94
102
  * @param symbol - The calling function.
95
103
  * @param scope - Where the function sits in the file.
@@ -10,6 +10,11 @@ import type { GraphBuilder } from '../graph/builder';
10
10
  * `namespaceSeparator`. Unset where a qualifier may be a module or a variable, which says nothing about the declaration.
11
11
  * @property sees - Tells whether the file of the name sees a file, through what it imports. Unset where every file
12
12
  * counts, as for prose.
13
+ * @property admits - Tells whether the name can mean the declaration it resolves to, whether the file sees it or
14
+ * not: one that another package does not export, or a test helper outside the tests, it cannot. Unset where every
15
+ * declaration can, as for prose.
16
+ * @property locals - Names the symbol of a description declares itself, its parameters and fields. Inline code with
17
+ * one of these names means that one, so it never links. Unset outside descriptions.
13
18
  */
14
19
  export interface TypeScope {
15
20
  readonly path: string | null;
@@ -17,6 +22,8 @@ export interface TypeScope {
17
22
  readonly typeParameters: ReadonlySet<string>;
18
23
  readonly namespaceSeparator?: string;
19
24
  readonly sees?: (path: string) => boolean;
25
+ readonly admits?: (declaration: DeclarationSite) => boolean;
26
+ readonly locals?: ReadonlySet<string>;
20
27
  }
21
28
  /** Scope of a name in a document: any language, no file. */
22
29
  export declare const PROSE_SCOPE: TypeScope;
@@ -30,6 +37,8 @@ export declare const PROSE_SCOPE: TypeScope;
30
37
  * @property local - Whether only its own file can see it, as a type in a C++ source file or a `static` C function.
31
38
  * @property privateFile - Whether its file is one the other files cannot see, such as a C++ source file. A
32
39
  * declaration there that has a twin in a header is the definition of that twin.
40
+ * @property exported - Whether other files can import it: its file exports its outermost name, or its language has
41
+ * no exports the scan reads.
33
42
  */
34
43
  export interface DeclarationSite {
35
44
  readonly ref: NodeRef;
@@ -38,6 +47,7 @@ export interface DeclarationSite {
38
47
  readonly owners: readonly string[];
39
48
  readonly local: boolean;
40
49
  readonly privateFile: boolean;
50
+ readonly exported: boolean;
41
51
  }
42
52
  /**
43
53
  * @brief Every class, interface, struct, enum, trait and type alias of the scan, by name.
@@ -100,6 +110,9 @@ export declare class CallableIndex {
100
110
  /**
101
111
  * @brief The function a piece of inline code names.
102
112
  *
113
+ * A bare name names a method only in the file of that method. Elsewhere a method is named with its owner, as
114
+ * `Invoice.add`.
115
+ *
103
116
  * @param text - Inline code, such as `choose_route()` or `Invoice.add`.
104
117
  * @param scope - Where the code is used.
105
118
  * @returns The function, or `null` when the text names none or more than one.
@@ -179,7 +192,8 @@ export declare class TypeLinker {
179
192
  * @param from - Node the code is written in. The edge starts here.
180
193
  * @param scope - Where the code is used.
181
194
  * @param relation - Kind of edge to record, `mentions` by default.
182
- * @returns The node the code names, or `null` when it names none, more than one, or `from` itself.
195
+ * @returns The node the code names, or `null` when it names none, more than one, a parameter or field of the
196
+ * symbol it describes, or `from` itself.
183
197
  */
184
198
  mention(text: string, from: NodeRef, scope: TypeScope, relation?: EdgeKind): NodeRef | null;
185
199
  }
@@ -58,7 +58,9 @@ export declare class RepoFileLister implements FileLister {
58
58
  */
59
59
  private isExcluded;
60
60
  /**
61
- * @brief Lists the tracked and untracked files git does not ignore.
61
+ * @brief Lists the tracked and untracked files git does not ignore, without symlinks and files whose real path
62
+ * leaves `root`. A path missing from disk stays in the list. Turns off `core.fsmonitor`, so the repository's
63
+ * config cannot make git run a command.
62
64
  *
63
65
  * @param root - Absolute directory.
64
66
  * @returns Root-relative paths, or `null` when `root` is not in a git work tree or git fails.
@@ -100,13 +100,15 @@ export declare class GraphBuilder {
100
100
  */
101
101
  href(ref: NodeRef, fragment?: string): string;
102
102
  /**
103
- * @brief Records an edge. The same edge recorded twice is kept once.
103
+ * @brief Records an edge. The same edge recorded twice is kept once, with the lines of both.
104
104
  *
105
105
  * @param from - Node the edge starts at.
106
106
  * @param kind - Relation the edge expresses.
107
107
  * @param to - Node the edge ends at.
108
+ * @param lines - Lines of the file of `from` where the link is made, such as those of a call. Empty when the link
109
+ * has no line of its own.
108
110
  */
109
- link(from: NodeRef, kind: EdgeKind, to: NodeRef): void;
111
+ link(from: NodeRef, kind: EdgeKind, to: NodeRef, lines?: readonly number[]): void;
110
112
  /**
111
113
  * @brief Runs the content source of every node and returns the finished graph.
112
114
  *
@@ -3,8 +3,9 @@ import type { CommunityIndex, Edge, GraphNode } from '../../model';
3
3
  * @brief Splits the nodes of a scan into communities: groups whose nodes link to each other more than to the rest.
4
4
  *
5
5
  * Every page and entry is one unit: a file, a class, a function, a term, a table. A parameter or field counts
6
- * as the entry it belongs to. A section, folder or package belongs to no community. Every edge between two
7
- * units links them, and so does each unit with the unit it is in, such as a method with its class.
6
+ * as the entry it belongs to. A section, folder or package belongs to no community, and nor does a unit that would
7
+ * be alone in one. Every edge between two units links them, and so does each unit with the unit it is in, such as a
8
+ * method with its class.
8
9
  *
9
10
  * The split maximises modularity with the Louvain method: nodes move to the community of a neighbour while
10
11
  * that raises modularity, then each community becomes one node and the next level starts. It walks the nodes
@@ -1,4 +1,4 @@
1
- export { CallLinker, type CallContext, type CallVia, type RawCall, readCalls } from './code/calls';
1
+ export { type BodyReferences, CallLinker, type CallContext, type CallVia, type LocatedCall, type RawCall, readReferences } from './code/calls';
2
2
  export { type ExtractedFile, type RawField, type RawParameter, type RawSymbol, SymbolExtractor } from './code/extract';
3
3
  export { GrammarLoader } from './code/grammar';
4
4
  export { C_INCLUDES, ECMASCRIPT_IMPORTS, type ImportRequest, type ImportSyntax, PYTHON_IMPORTS, SourceFileIndex, } from './code/imports';
@@ -8,6 +8,9 @@ import type { Source } from './files';
8
8
  * @property manifest - Display path of the manifest that marks the package, such as `packages/core/package.json`.
9
9
  * @property version - Version the manifest gives, or `null`.
10
10
  * @property description - Description the manifest gives, or `''`.
11
+ * @property entryPoints - The subpaths code outside the package imports it by, `''` for the package name itself,
12
+ * such as `['', 'hash']` for `@g3nomaly/core` and `@g3nomaly/core/hash`. The `exports` of a `package.json` lists
13
+ * them; any other manifest has `['']`.
11
14
  */
12
15
  export interface PackageInfo {
13
16
  readonly packageName: string;
@@ -15,6 +18,7 @@ export interface PackageInfo {
15
18
  readonly manifest: string;
16
19
  readonly version: string | null;
17
20
  readonly description: string;
21
+ readonly entryPoints: readonly string[];
18
22
  }
19
23
  /**
20
24
  * @brief Finds the packages of a set of sources: every directory below a root with a manifest that one of the readers understands.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g3nomaly/analyze",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Turns a repository into one offline HTML documentation site, and queries the same linked model from the terminal and from hooks.",
5
5
  "keywords": [
6
6
  "documentation",
@@ -40,7 +40,7 @@
40
40
  "docs": "bun run build && bun dist/cli.js create_docs"
41
41
  },
42
42
  "dependencies": {
43
- "@g3nomaly/core": "^0.3.6",
43
+ "@g3nomaly/core": "^0.3.7",
44
44
  "@t3-oss/env-core": "^0.13.11",
45
45
  "hast-util-to-string": "^3.0.1",
46
46
  "rehype-parse": "^9.0.1",
@@ -58,7 +58,7 @@
58
58
  "zod": "^4.6.5"
59
59
  },
60
60
  "devDependencies": {
61
- "@g3nomaly/ui": "^0.3.7",
61
+ "@g3nomaly/ui": "^0.3.8",
62
62
  "@tanstack/react-router": "^1.170.41",
63
63
  "@tanstack/react-store": "^0.11.2",
64
64
  "@tree-sitter-grammars/tree-sitter-kotlin": "^1.1.0",