@suss/adapter-python 0.25.0 → 0.27.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/index.cjs +339 -56
- package/dist/index.d.cts +226 -196
- package/dist/index.d.ts +226 -196
- package/dist/index.js +339 -56
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -25,167 +25,43 @@ declare function preloadPythonGrammar(): Promise<void>;
|
|
|
25
25
|
declare function parsePythonSync(source: string): Tree;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
* file's parse tree and records how each name in each scope came to be bound,
|
|
30
|
-
* whether that was an import, an assignment, a def, a parameter, or a `global`
|
|
31
|
-
* or `nonlocal` redirect to another scope.
|
|
28
|
+
* Maps a dotted import onto the file in the repo it refers to.
|
|
32
29
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* definition or import nested inside an `if`, `try`, or `with` block is not
|
|
37
|
-
* found, and a read of it comes back unresolved rather than as a guess.
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
type ScopeKind = "module" | "class" | "function";
|
|
41
|
-
interface Scope {
|
|
42
|
-
kind: ScopeKind;
|
|
43
|
-
/** The module node, or the class_definition / function_definition this scope belongs to. */
|
|
44
|
-
node: Node;
|
|
45
|
-
parent: Scope | null;
|
|
46
|
-
bindings: Map<string, Binding>;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* `relativeLevel` is 0 for an absolute import and the dot count for a
|
|
50
|
-
* relative one. `module` is the dotted path after the dots, empty for
|
|
51
|
-
* a bare `from . import c`.
|
|
30
|
+
* The search walks a small set of configured roots. Finding out what `sys.path`
|
|
31
|
+
* actually is would mean running Python, so when more than one root offers a
|
|
32
|
+
* candidate, the resolver abstains rather than picking one.
|
|
52
33
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
module: string;
|
|
56
|
-
relativeLevel: number;
|
|
57
|
-
localName: string;
|
|
58
|
-
} | {
|
|
59
|
-
kind: "importFrom";
|
|
34
|
+
interface RelativeModuleSpec {
|
|
35
|
+
/** The dotted path after the leading dots. It is empty for a bare `from . import x`. */
|
|
60
36
|
module: string;
|
|
37
|
+
/** Dot count: 0 means absolute, 1 is `.`, 2 is `..`, and so on. */
|
|
61
38
|
relativeLevel: number;
|
|
62
|
-
importedName: string;
|
|
63
|
-
} | {
|
|
64
|
-
kind: "classDef";
|
|
65
|
-
node: Node;
|
|
66
|
-
} | {
|
|
67
|
-
kind: "functionDef";
|
|
68
|
-
node: Node;
|
|
69
|
-
} | {
|
|
70
|
-
kind: "parameter";
|
|
71
|
-
}
|
|
72
|
-
/** The right-hand side, when there is one, so we can trace a decorator's base object one hop back to whatever constructed it. */
|
|
73
|
-
| {
|
|
74
|
-
kind: "assignment";
|
|
75
|
-
value: Node | null;
|
|
76
|
-
}
|
|
77
|
-
/** `global x` inside a function: reads of `x` in this scope resolve in the module scope instead. */
|
|
78
|
-
| {
|
|
79
|
-
kind: "global";
|
|
80
|
-
}
|
|
81
|
-
/** `nonlocal x` inside a function: reads of `x` resolve in the nearest enclosing function scope. */
|
|
82
|
-
| {
|
|
83
|
-
kind: "nonlocal";
|
|
84
|
-
};
|
|
85
|
-
interface ModuleBinding {
|
|
86
|
-
moduleScope: Scope;
|
|
87
|
-
/** The scope a class_definition, a function_definition, or the module node opens, keyed by that node's id. */
|
|
88
|
-
scopeFor: Map<number, Scope>;
|
|
89
|
-
/** The modules a `from X import *` pulls in. We cannot list what a wildcard brings in, so nothing expands them here. */
|
|
90
|
-
openImports: string[];
|
|
91
|
-
}
|
|
92
|
-
declare function bindModule(root: Node): ModuleBinding;
|
|
93
|
-
/**
|
|
94
|
-
* Python does not put a class body's namespace on the lookup chain of a function
|
|
95
|
-
* nested inside it, so a class scope's own bindings only count when the search
|
|
96
|
-
* starts there. A `global` or `nonlocal` marker sends the lookup to the scope it
|
|
97
|
-
* points at.
|
|
98
|
-
*/
|
|
99
|
-
declare function resolveName(scope: Scope, name: string): Binding | null;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Turns a Python annotation into an IR type shape.
|
|
103
|
-
*
|
|
104
|
-
* Nothing here infers anything. A value nobody annotated has no shape at all,
|
|
105
|
-
* and an annotation this module does not recognize comes back as a `ref` by
|
|
106
|
-
* name, which says only what the source called it.
|
|
107
|
-
*/
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* `definitions` stores each converted class shape once, however many annotations
|
|
111
|
-
* mention it. `scopeFor` is here so a name written inside a referenced class's
|
|
112
|
-
* body resolves too, not only one written at the annotation's use site.
|
|
113
|
-
*/
|
|
114
|
-
interface AnnotationContext {
|
|
115
|
-
scopeFor: Map<number, Scope>;
|
|
116
|
-
definitions: Map<string, TypeShape | null>;
|
|
117
|
-
}
|
|
118
|
-
/** `scope` is where the annotation is written, which is how we tell a project-local class from an external name. */
|
|
119
|
-
declare function annotationToShape(typeNode: Node, scope: Scope, ctx: AnnotationContext): TypeShape;
|
|
120
|
-
/** Exported so a decorator keyword that gives a class name reads the same way as that name written in annotation position. */
|
|
121
|
-
declare function shapeFromName(name: string, scope: Scope, ctx: AnnotationContext): TypeShape;
|
|
122
|
-
|
|
123
|
-
interface Range {
|
|
124
|
-
start: number;
|
|
125
|
-
end: number;
|
|
126
39
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
readonly node: Node;
|
|
131
|
-
};
|
|
132
|
-
type DecoratorArgShape = {
|
|
133
|
-
kind: "string";
|
|
134
|
-
value: string;
|
|
135
|
-
} | {
|
|
136
|
-
kind: "number";
|
|
137
|
-
value: number;
|
|
138
|
-
} | {
|
|
139
|
-
kind: "boolean";
|
|
140
|
-
value: boolean;
|
|
141
|
-
} | {
|
|
142
|
-
kind: "none";
|
|
143
|
-
}
|
|
144
|
-
/** A bare name. The caller resolves it, using the scope it already has. */
|
|
145
|
-
| {
|
|
146
|
-
kind: "identifier";
|
|
147
|
-
name: string;
|
|
148
|
-
}
|
|
149
|
-
/** One dotted hop, `routers.orders`. The caller decides what the object is. */
|
|
150
|
-
| {
|
|
151
|
-
kind: "attribute";
|
|
152
|
-
objectName: string;
|
|
153
|
-
attributeName: string;
|
|
154
|
-
} | {
|
|
155
|
-
kind: "list";
|
|
156
|
-
items: DecoratorArg[];
|
|
40
|
+
type ModuleResolution = {
|
|
41
|
+
status: "resolved";
|
|
42
|
+
file: string;
|
|
157
43
|
} | {
|
|
158
|
-
|
|
159
|
-
};
|
|
160
|
-
interface DecoratorClassification {
|
|
161
|
-
/** The name as its source module exports it, not the local alias or attribute path it was written under. */
|
|
162
|
-
importedName: string | null;
|
|
163
|
-
/** The dotted module the name was imported from. It is null whenever `importedName` is null. */
|
|
164
|
-
module: string | null;
|
|
165
|
-
/** The local variable an attribute decorator hangs on, `app` in `@app.get(...)`. */
|
|
166
|
-
objectName: string | null;
|
|
167
|
-
relativeLevel: number;
|
|
168
|
-
args: DecoratorArg[];
|
|
169
|
-
keywordArgs: Record<string, DecoratorArg>;
|
|
170
|
-
/** Where the decorator is written. Anything we read out of its arguments uses this as its provenance. */
|
|
171
|
-
range: Range;
|
|
172
|
-
/**
|
|
173
|
-
* The module the decorator's object lives in, when the decorator was read
|
|
174
|
-
* through a project wrapper written in another file. The router prefix is
|
|
175
|
-
* resolved there, since that is where the namespace is constructed.
|
|
176
|
-
*/
|
|
177
|
-
objectModule?: ModuleBinding;
|
|
44
|
+
status: "unresolved";
|
|
178
45
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
46
|
+
* "external": no configured root has a file for it. "ambiguous": more
|
|
47
|
+
* than one does. "outsideRoots": a relative import had enough dots to walk
|
|
48
|
+
* up past every configured root.
|
|
182
49
|
*/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
50
|
+
reason: "external" | "ambiguous" | "outsideRoots";
|
|
51
|
+
};
|
|
52
|
+
interface ModuleResolverOptions {
|
|
53
|
+
/** The directories an absolute dotted import is resolved against. We cannot see `sys.path` order, since that only exists at runtime. */
|
|
54
|
+
roots: string[];
|
|
187
55
|
}
|
|
188
|
-
declare function
|
|
56
|
+
declare function resolveAbsoluteModule(dotted: string, options: ModuleResolverOptions): ModuleResolution;
|
|
57
|
+
/**
|
|
58
|
+
* The search starts in the importing file's own directory, because Python
|
|
59
|
+
* resolves a relative import against `__package__` and not against `sys.path`.
|
|
60
|
+
* `options.roots` only limits how far the dots can walk up, so a deeply relative
|
|
61
|
+
* import cannot land in an unrelated checkout.
|
|
62
|
+
*/
|
|
63
|
+
declare function resolveRelativeModule(importingFile: string, spec: RelativeModuleSpec, options: ModuleResolverOptions): ModuleResolution;
|
|
64
|
+
declare function resolveModule(importingFile: string, spec: RelativeModuleSpec, options: ModuleResolverOptions): ModuleResolution;
|
|
189
65
|
|
|
190
66
|
/**
|
|
191
67
|
* The Python adapter's own pattern-pack contract.
|
|
@@ -312,7 +188,7 @@ interface PyClientCall {
|
|
|
312
188
|
};
|
|
313
189
|
/** Constructors whose instances take the same calls, `Session`. */
|
|
314
190
|
receiverConstructors?: string[];
|
|
315
|
-
/** What the response object gives a caller, so a guard on
|
|
191
|
+
/** What the response object gives a caller, so a guard on one of its members counts as a guard on a status. */
|
|
316
192
|
response?: PyClientResponse;
|
|
317
193
|
}
|
|
318
194
|
/**
|
|
@@ -355,7 +231,7 @@ interface RouteConventions {
|
|
|
355
231
|
defaultStatusCode?: number;
|
|
356
232
|
/**
|
|
357
233
|
* Set it only when the library reads a status out of the tuple a handler
|
|
358
|
-
* returns,
|
|
234
|
+
* returns, as Flask does with `return body, 201`. Without it
|
|
359
235
|
* the library default applies whatever the body returns, and a route
|
|
360
236
|
* that sets its own status would be reported at the default.
|
|
361
237
|
*/
|
|
@@ -375,7 +251,7 @@ interface RouteConventions {
|
|
|
375
251
|
* own status; a return of anything else keeps the declared one.
|
|
376
252
|
*/
|
|
377
253
|
responseConstructors?: PyStatusCall[];
|
|
378
|
-
/** Unset means the library has no router mounting, and a route's decorator path
|
|
254
|
+
/** Unset means the library has no router mounting, and a route's decorator path is used as written. */
|
|
379
255
|
routerComposition?: RouterComposition;
|
|
380
256
|
/** The ways the library runs a project's own function around a route. The README lists what each one covers. */
|
|
381
257
|
wrappers?: PyWrapperForm[];
|
|
@@ -431,7 +307,7 @@ interface PyDecoratedWrapperForm {
|
|
|
431
307
|
continuationParam?: number;
|
|
432
308
|
/**
|
|
433
309
|
* Set when a value returned ends the request and only a bare return
|
|
434
|
-
* hands on
|
|
310
|
+
* hands on. Flask's `before_request` works this way.
|
|
435
311
|
*/
|
|
436
312
|
returnedValueResponds?: boolean;
|
|
437
313
|
/** The position the library hands the raised exception at. Set on an error handler, which runs only when the handler raised. */
|
|
@@ -576,57 +452,78 @@ type NoValuePrefix = "unstated" | "unreadable";
|
|
|
576
452
|
type PathRepeatedSlashes = "kept" | "merged";
|
|
577
453
|
|
|
578
454
|
/**
|
|
579
|
-
*
|
|
580
|
-
*
|
|
455
|
+
* The lexical binder. It builds module, class, and function scopes over one
|
|
456
|
+
* file's parse tree and records how each name in each scope came to be bound,
|
|
457
|
+
* whether that was an import, an assignment, a def, a parameter, or a `global`
|
|
458
|
+
* or `nonlocal` redirect to another scope.
|
|
459
|
+
*
|
|
460
|
+
* It never has to be complete, because "I could not resolve this name" is a
|
|
461
|
+
* legal answer everywhere a name is read. What it has to avoid is being wrong.
|
|
462
|
+
* So it only binds names written directly in a body's own statement list. A
|
|
463
|
+
* definition or import nested inside an `if`, `try`, or `with` block is not
|
|
464
|
+
* found, and a read of it comes back unresolved rather than as a guess.
|
|
581
465
|
*/
|
|
582
|
-
interface StorageLookup {
|
|
583
|
-
readonly facts: Database;
|
|
584
|
-
readonly factsPath: string;
|
|
585
|
-
readonly patterns: readonly StoragePattern[];
|
|
586
|
-
readonly definitionAt: (key: string) => Node | undefined;
|
|
587
|
-
readonly couldMatch: ReadonlySet<string>;
|
|
588
|
-
/** What a pack says about statements a project writes as SQL itself. */
|
|
589
|
-
readonly rawSql?: readonly RawSqlPattern[];
|
|
590
|
-
}
|
|
591
466
|
|
|
467
|
+
type ScopeKind = "module" | "class" | "function";
|
|
468
|
+
interface Scope {
|
|
469
|
+
kind: ScopeKind;
|
|
470
|
+
/** The module node, or the class_definition / function_definition this scope belongs to. */
|
|
471
|
+
node: Node;
|
|
472
|
+
parent: Scope | null;
|
|
473
|
+
bindings: Map<string, Binding>;
|
|
474
|
+
}
|
|
592
475
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
* actually is would mean running Python, so when more than one root offers a
|
|
597
|
-
* candidate, the resolver abstains rather than picking one.
|
|
476
|
+
* `relativeLevel` is 0 for an absolute import and the dot count for a
|
|
477
|
+
* relative one. `module` is the dotted path after the dots, empty for
|
|
478
|
+
* a bare `from . import c`.
|
|
598
479
|
*/
|
|
599
|
-
|
|
600
|
-
|
|
480
|
+
type Binding = {
|
|
481
|
+
kind: "import";
|
|
601
482
|
module: string;
|
|
602
|
-
/** Dot count: 0 means absolute, 1 is `.`, 2 is `..`, and so on. */
|
|
603
483
|
relativeLevel: number;
|
|
604
|
-
|
|
605
|
-
type ModuleResolution = {
|
|
606
|
-
status: "resolved";
|
|
607
|
-
file: string;
|
|
484
|
+
localName: string;
|
|
608
485
|
} | {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
486
|
+
kind: "importFrom";
|
|
487
|
+
module: string;
|
|
488
|
+
relativeLevel: number;
|
|
489
|
+
importedName: string;
|
|
490
|
+
} | {
|
|
491
|
+
kind: "classDef";
|
|
492
|
+
node: Node;
|
|
493
|
+
} | {
|
|
494
|
+
kind: "functionDef";
|
|
495
|
+
node: Node;
|
|
496
|
+
} | {
|
|
497
|
+
kind: "parameter";
|
|
498
|
+
}
|
|
499
|
+
/** The right-hand side, when there is one, so we can trace a decorator's base object one hop back to whatever constructed it. */
|
|
500
|
+
| {
|
|
501
|
+
kind: "assignment";
|
|
502
|
+
value: Node | null;
|
|
503
|
+
}
|
|
504
|
+
/** `global x` inside a function: reads of `x` in this scope resolve in the module scope instead. */
|
|
505
|
+
| {
|
|
506
|
+
kind: "global";
|
|
507
|
+
}
|
|
508
|
+
/** `nonlocal x` inside a function: reads of `x` resolve in the nearest enclosing function scope. */
|
|
509
|
+
| {
|
|
510
|
+
kind: "nonlocal";
|
|
616
511
|
};
|
|
617
|
-
interface
|
|
618
|
-
|
|
619
|
-
|
|
512
|
+
interface ModuleBinding {
|
|
513
|
+
moduleScope: Scope;
|
|
514
|
+
/** The scope a class_definition, a function_definition, or the module node opens, keyed by that node's id. */
|
|
515
|
+
scopeFor: Map<number, Scope>;
|
|
516
|
+
/** The modules a `from X import *` pulls in. We cannot list what a wildcard brings in, so nothing expands them here. */
|
|
517
|
+
openImports: string[];
|
|
620
518
|
}
|
|
621
|
-
declare function
|
|
519
|
+
declare function bindModule(root: Node): ModuleBinding;
|
|
622
520
|
/**
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
626
|
-
*
|
|
521
|
+
* Python does not put a class body's namespace on the lookup chain of a function
|
|
522
|
+
* nested inside it, so a class scope's own bindings only count when the search
|
|
523
|
+
* starts there. A `global` or `nonlocal` marker sends the lookup to the scope it
|
|
524
|
+
* points at.
|
|
627
525
|
*/
|
|
628
|
-
declare function
|
|
629
|
-
declare function resolveModule(importingFile: string, spec: RelativeModuleSpec, options: ModuleResolverOptions): ModuleResolution;
|
|
526
|
+
declare function resolveName(scope: Scope, name: string): Binding | null;
|
|
630
527
|
|
|
631
528
|
/** One file, already parsed and bound. `buildRouterIndex` takes a project as a list of these. */
|
|
632
529
|
interface BoundPythonFile {
|
|
@@ -688,6 +585,137 @@ interface RouterIndexOptions extends ModuleResolverOptions {
|
|
|
688
585
|
}
|
|
689
586
|
declare function buildRouterIndex(files: BoundPythonFile[], packs: PythonPack[], resolverOptions: RouterIndexOptions): RouterIndex;
|
|
690
587
|
|
|
588
|
+
/**
|
|
589
|
+
* Where an imported name is defined, when the project defines it.
|
|
590
|
+
*
|
|
591
|
+
* The binder resolves a name inside one file only, so `item_in: ItemCreate`
|
|
592
|
+
* with `ItemCreate` imported from a models module comes back as an import
|
|
593
|
+
* binding and nothing more. This asks the resolution rules where the name
|
|
594
|
+
* came from, through any re-exports on the way, and returns the class or
|
|
595
|
+
* the assigned value the defining file binds it to, along with that file's
|
|
596
|
+
* scopes so the definition can be read in the scope it is written in.
|
|
597
|
+
*/
|
|
598
|
+
|
|
599
|
+
interface ImportedDefinition {
|
|
600
|
+
/** The class_definition, or the value an assignment gave the name. */
|
|
601
|
+
node: Node;
|
|
602
|
+
/** The module scope of the file the definition is written in. */
|
|
603
|
+
moduleScope: Scope;
|
|
604
|
+
/** The scopes of that file, keyed by the node that opens each one. */
|
|
605
|
+
scopeFor: Map<number, Scope>;
|
|
606
|
+
}
|
|
607
|
+
/** `scope` is where the name is read, which is what keys the import in the facts. */
|
|
608
|
+
type ImportedDefinitionLookup = (scope: Scope, name: string) => ImportedDefinition | null;
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Turns a Python annotation into an IR type shape.
|
|
612
|
+
*
|
|
613
|
+
* Nothing here infers anything. A value nobody annotated has no shape at all,
|
|
614
|
+
* and an annotation this module does not recognize comes back as a `ref` by
|
|
615
|
+
* name, which says only what the source called it.
|
|
616
|
+
*/
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* `definitions` stores each converted class shape once, however many annotations
|
|
620
|
+
* mention it. `scopeMaps` is here so a name written inside a referenced class's
|
|
621
|
+
* body resolves too, not only one written at the annotation's use site; a class
|
|
622
|
+
* read from another file brings that file's scopes along. `importedDefinition`
|
|
623
|
+
* is absent when a caller reads one file on its own, and an imported name is
|
|
624
|
+
* then a ref by name and nothing more.
|
|
625
|
+
*/
|
|
626
|
+
interface AnnotationContext {
|
|
627
|
+
scopeMaps: Map<number, Scope>[];
|
|
628
|
+
definitions: Map<string, TypeShape | null>;
|
|
629
|
+
importedDefinition: ImportedDefinitionLookup | null;
|
|
630
|
+
/** The alias values being expanded, so `A = B` and `B = A` end rather than recurse. */
|
|
631
|
+
expanding: Set<number>;
|
|
632
|
+
}
|
|
633
|
+
/** `scope` is where the annotation is written, which is how we tell a project-local class from an external name. */
|
|
634
|
+
declare function annotationToShape(typeNode: Node, scope: Scope, ctx: AnnotationContext): TypeShape;
|
|
635
|
+
/** Exported so a decorator keyword that gives a class name reads the same way as that name written in annotation position. */
|
|
636
|
+
declare function shapeFromName(name: string, scope: Scope, ctx: AnnotationContext): TypeShape;
|
|
637
|
+
|
|
638
|
+
interface Range {
|
|
639
|
+
start: number;
|
|
640
|
+
end: number;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** An argument as written, plus its node so a reader can evaluate what it comes down to. */
|
|
644
|
+
type DecoratorArg = DecoratorArgShape & {
|
|
645
|
+
readonly node: Node;
|
|
646
|
+
};
|
|
647
|
+
type DecoratorArgShape = {
|
|
648
|
+
kind: "string";
|
|
649
|
+
value: string;
|
|
650
|
+
} | {
|
|
651
|
+
kind: "number";
|
|
652
|
+
value: number;
|
|
653
|
+
} | {
|
|
654
|
+
kind: "boolean";
|
|
655
|
+
value: boolean;
|
|
656
|
+
} | {
|
|
657
|
+
kind: "none";
|
|
658
|
+
}
|
|
659
|
+
/** A bare name. The caller resolves it, using the scope it already has. */
|
|
660
|
+
| {
|
|
661
|
+
kind: "identifier";
|
|
662
|
+
name: string;
|
|
663
|
+
}
|
|
664
|
+
/** One dotted hop, `routers.orders`. The caller decides what the object is. */
|
|
665
|
+
| {
|
|
666
|
+
kind: "attribute";
|
|
667
|
+
objectName: string;
|
|
668
|
+
attributeName: string;
|
|
669
|
+
} | {
|
|
670
|
+
kind: "list";
|
|
671
|
+
items: DecoratorArg[];
|
|
672
|
+
} | {
|
|
673
|
+
kind: "other";
|
|
674
|
+
};
|
|
675
|
+
interface DecoratorClassification {
|
|
676
|
+
/** The name as its source module exports it, not the local alias or attribute path it was written under. */
|
|
677
|
+
importedName: string | null;
|
|
678
|
+
/** The dotted module the name was imported from. It is null whenever `importedName` is null. */
|
|
679
|
+
module: string | null;
|
|
680
|
+
/** The local variable an attribute decorator hangs on, `app` in `@app.get(...)`. */
|
|
681
|
+
objectName: string | null;
|
|
682
|
+
relativeLevel: number;
|
|
683
|
+
args: DecoratorArg[];
|
|
684
|
+
keywordArgs: Record<string, DecoratorArg>;
|
|
685
|
+
/** Where the decorator is written. Anything we read out of its arguments uses this as its provenance. */
|
|
686
|
+
range: Range;
|
|
687
|
+
/**
|
|
688
|
+
* The module the decorator's object lives in, when the decorator was read
|
|
689
|
+
* through a project wrapper written in another file. The router prefix is
|
|
690
|
+
* resolved there, since that is where the namespace is constructed.
|
|
691
|
+
*/
|
|
692
|
+
objectModule?: ModuleBinding;
|
|
693
|
+
/**
|
|
694
|
+
* The call the rules say built the object this decorator hangs on, when
|
|
695
|
+
* the lexical scope could not say. A router prefix is looked up by this
|
|
696
|
+
* call rather than by a variable name, because there may not be one.
|
|
697
|
+
*/
|
|
698
|
+
subjectConstruction?: {
|
|
699
|
+
key: string;
|
|
700
|
+
constructorName: string;
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
declare function classifyDecorator(decoratorNode: Node, scope: Scope): DecoratorClassification;
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* What discovery uses for one file. `factsPath` is the path the facts were
|
|
707
|
+
* keyed under, which is the absolute one, while a summary shows the short one.
|
|
708
|
+
*/
|
|
709
|
+
interface StorageLookup {
|
|
710
|
+
readonly facts: Database;
|
|
711
|
+
readonly factsPath: string;
|
|
712
|
+
readonly patterns: readonly StoragePattern[];
|
|
713
|
+
readonly definitionAt: (key: string) => Node | undefined;
|
|
714
|
+
readonly couldMatch: ReadonlySet<string>;
|
|
715
|
+
/** What a pack says about statements a project writes as SQL itself. */
|
|
716
|
+
readonly rawSql?: readonly RawSqlPattern[];
|
|
717
|
+
}
|
|
718
|
+
|
|
691
719
|
/**
|
|
692
720
|
* What a call's callee is, read through the binder and the import
|
|
693
721
|
* facts: a function in this run the walk can step into, or a reason it
|
|
@@ -810,6 +838,8 @@ interface DiscoveryOptions {
|
|
|
810
838
|
facts?: Database | undefined;
|
|
811
839
|
/** What the project registered around its routes. Absent when no pack declares a wrapper form, or when a caller reads one file on its own. */
|
|
812
840
|
wrappers?: PythonWrapperIndex | undefined;
|
|
841
|
+
/** Where a name another file defines is written, so an imported model or alias reads as the class or value behind it. Absent when a caller reads one file on its own. */
|
|
842
|
+
importedDefinition?: ImportedDefinitionLookup | undefined;
|
|
813
843
|
}
|
|
814
844
|
declare function discoverUnits(root: Node, module: ModuleBinding, options: DiscoveryOptions): RawCodeStructure[];
|
|
815
845
|
|