@esportsplus/typescript 0.31.1 → 0.33.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.
Files changed (69) hide show
  1. package/README.md +34 -44
  2. package/build/cli/tsc.d.ts +3 -2
  3. package/build/cli/tsc.js +15 -97
  4. package/build/{probe → guard}/adapter.d.ts +1 -2
  5. package/build/{probe → guard}/adapter.js +1 -4
  6. package/build/{probe → guard}/async/channel.d.ts +1 -1
  7. package/build/{probe → guard}/async/channel.js +12 -192
  8. package/build/{probe → guard}/async/value.d.ts +1 -2
  9. package/build/{probe → guard}/async/value.js +1 -4
  10. package/build/guard/channels.d.ts +4 -0
  11. package/build/guard/channels.js +13 -0
  12. package/build/{probe → guard}/exceptions/channel.d.ts +3 -2
  13. package/build/{probe → guard}/exceptions/channel.js +173 -101
  14. package/build/guard/exceptions/derive.d.ts +49 -0
  15. package/build/guard/exceptions/derive.js +478 -0
  16. package/build/{probe → guard}/exceptions/jsdoc.d.ts +1 -1
  17. package/build/{probe → guard}/exceptions/jsdoc.js +1 -1
  18. package/build/guard/exceptions/resolve-js.d.ts +2 -0
  19. package/build/guard/exceptions/resolve-js.js +26 -0
  20. package/build/{probe → guard}/exceptions/value.d.ts +4 -3
  21. package/build/{probe → guard}/exceptions/value.js +13 -5
  22. package/build/{probe → guard}/kernel/analyze.d.ts +3 -2
  23. package/build/guard/kernel/analyze.js +84 -0
  24. package/build/guard/kernel/ast.d.ts +13 -0
  25. package/build/guard/kernel/ast.js +56 -0
  26. package/build/guard/kernel/config.js +93 -0
  27. package/build/guard/kernel/fixpoint.d.ts +6 -0
  28. package/build/{probe → guard}/kernel/fixpoint.js +8 -48
  29. package/build/guard/kernel/graph.d.ts +4 -0
  30. package/build/guard/kernel/graph.js +268 -0
  31. package/build/{probe → guard}/kernel/ids.d.ts +3 -4
  32. package/build/{probe → guard}/kernel/ids.js +2 -7
  33. package/build/{probe → guard}/kernel/program.d.ts +1 -1
  34. package/build/{probe → guard}/kernel/types.d.ts +4 -33
  35. package/build/{probe → guard}/overlay/base/async.jsonc +1 -1
  36. package/build/{probe → guard}/overlay/base/exceptions.jsonc +16 -3
  37. package/build/{probe → guard}/overlay/base/resources.jsonc +7 -8
  38. package/build/{probe → guard}/overlay/load.d.ts +3 -7
  39. package/build/{probe → guard}/overlay/load.js +38 -121
  40. package/build/{probe → guard}/resources/channel.d.ts +1 -1
  41. package/build/{probe → guard}/resources/channel.js +80 -158
  42. package/build/{probe → guard}/resources/value.d.ts +1 -2
  43. package/build/{probe → guard}/resources/value.js +1 -14
  44. package/build/lsp/diagnostics.d.ts +2 -2
  45. package/build/lsp/diagnostics.js +2 -2
  46. package/build/lsp/server.js +41 -3
  47. package/build/lsp/workspace.d.ts +6 -3
  48. package/build/lsp/workspace.js +19 -5
  49. package/build/tsconfig.d.ts +2 -1
  50. package/build/tsconfig.js +44 -102
  51. package/package.json +8 -8
  52. package/tsconfig.base.json +12 -19
  53. package/tsconfig.package.json +6 -1
  54. package/build/probe/channels.d.ts +0 -4
  55. package/build/probe/channels.js +0 -16
  56. package/build/probe/kernel/analyze.js +0 -68
  57. package/build/probe/kernel/ast.d.ts +0 -11
  58. package/build/probe/kernel/ast.js +0 -49
  59. package/build/probe/kernel/config.js +0 -209
  60. package/build/probe/kernel/fixpoint.d.ts +0 -6
  61. package/build/probe/kernel/graph.d.ts +0 -4
  62. package/build/probe/kernel/graph.js +0 -507
  63. package/build/probe/overlay/presets/express.jsonc +0 -25
  64. package/build/probe/overlay/presets/node.jsonc +0 -17
  65. /package/build/{probe → guard}/kernel/config.d.ts +0 -0
  66. /package/build/{probe → guard}/kernel/format.d.ts +0 -0
  67. /package/build/{probe → guard}/kernel/format.js +0 -0
  68. /package/build/{probe → guard}/kernel/program.js +0 -0
  69. /package/build/{probe → guard}/kernel/types.js +0 -0
@@ -1,507 +0,0 @@
1
- import * as ts from '../../probe/adapter.js';
2
- import { isFunctionLike, makeFunctionInfo } from './ids.js';
3
- function buildCallGraph(program, checker, config, overlays) {
4
- const sourceFiles = ts.getSourceFiles(program);
5
- const programFiles = new Set(sourceFiles);
6
- const reached = new Map();
7
- const byId = new Map();
8
- const boundaryIds = new Set();
9
- const worklist = [];
10
- const wholeProject = config.entryPoints.length === 0;
11
- const coreCache = new Map();
12
- const resolutionCache = new Map();
13
- const callsCache = new Map();
14
- const calleesCache = new Map();
15
- const boundaries = config.handlerBoundaries.map((boundary) => ({
16
- boundary,
17
- selector: parseSelector(boundary.callee),
18
- }));
19
- function isAnalyzable(node) {
20
- const sf = node.getSourceFile();
21
- return (!sf.isDeclarationFile &&
22
- programFiles.has(sf) &&
23
- node.body != null);
24
- }
25
- function intern(node) {
26
- if (!isAnalyzable(node)) {
27
- return undefined;
28
- }
29
- const existing = reached.get(node);
30
- if (existing) {
31
- return existing;
32
- }
33
- const info = makeFunctionInfo(node, node.getSourceFile());
34
- reached.set(node, info);
35
- byId.set(info.id, info);
36
- worklist.push(info);
37
- return info;
38
- }
39
- function calleeSymbol(call) {
40
- let sym = checker.getSymbolAtLocation(call.expression);
41
- if (sym && sym.flags & ts.SymbolFlags.Alias) {
42
- sym = checker.getAliasedSymbol(sym);
43
- }
44
- return sym;
45
- }
46
- function functionLikesFromSymbol(sym, isNew) {
47
- const out = [];
48
- for (const decl of ts.symbolDeclarations(sym)) {
49
- if (isFunctionLike(decl)) {
50
- out.push(decl);
51
- continue;
52
- }
53
- if (ts.isVariableDeclaration(decl) &&
54
- decl.initializer &&
55
- isFunctionLike(decl.initializer)) {
56
- out.push(decl.initializer);
57
- continue;
58
- }
59
- if (isNew && ts.isClassLike(decl)) {
60
- const members = decl.members ?? [];
61
- for (const member of members) {
62
- if (ts.isConstructorDeclaration(member)) {
63
- out.push(member);
64
- }
65
- }
66
- }
67
- }
68
- return out;
69
- }
70
- function isAbstract(node) {
71
- const mods = node.modifiers;
72
- return (mods?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) ?? false);
73
- }
74
- function argExpressions(call) {
75
- return call.arguments ? Array.from(call.arguments) : [];
76
- }
77
- function computeCore(call) {
78
- const isNew = ts.isNewExpression(call);
79
- const sym = calleeSymbol(call);
80
- let functionArgs;
81
- const resolveFunctionArgs = () => {
82
- if (functionArgs) {
83
- return functionArgs;
84
- }
85
- const resolved = new Map();
86
- functionArgs = resolved;
87
- argExpressions(call).forEach((arg, index) => {
88
- const infos = resolveFunctionValue(arg);
89
- if (infos.length > 0) {
90
- resolved.set(index, infos);
91
- }
92
- });
93
- return functionArgs;
94
- };
95
- if (!sym) {
96
- return {
97
- symbol: undefined,
98
- targets: [],
99
- functionArgs: resolveFunctionArgs,
100
- unresolved: true,
101
- };
102
- }
103
- const fns = functionLikesFromSymbol(sym, isNew);
104
- const seen = new Set();
105
- const targets = [];
106
- for (const fn of fns) {
107
- const info = intern(fn);
108
- if (info && !seen.has(info.id)) {
109
- seen.add(info.id);
110
- targets.push(info);
111
- }
112
- }
113
- if (targets.length > 0) {
114
- return { symbol: sym, targets, functionArgs: resolveFunctionArgs, unresolved: false };
115
- }
116
- if (fns.length === 0) {
117
- return { symbol: sym, targets: [], functionArgs: resolveFunctionArgs, unresolved: true };
118
- }
119
- if (fns.some(isAbstract)) {
120
- return { symbol: sym, targets: [], functionArgs: resolveFunctionArgs, unresolved: true };
121
- }
122
- return { symbol: sym, targets: [], functionArgs: resolveFunctionArgs, unresolved: false };
123
- }
124
- function getCore(call) {
125
- let core = coreCache.get(call);
126
- if (!core) {
127
- core = computeCore(call);
128
- coreCache.set(call, core);
129
- }
130
- return core;
131
- }
132
- function unwrap(expr) {
133
- let e = expr;
134
- while (true) {
135
- if (ts.isParenthesizedExpression(e) ||
136
- ts.isNonNullExpression(e) ||
137
- ts.isAsExpression(e)) {
138
- e = e.expression;
139
- continue;
140
- }
141
- if (ts.isSatisfiesExpression(e)) {
142
- e = e.expression;
143
- continue;
144
- }
145
- break;
146
- }
147
- return e;
148
- }
149
- function resolveFunctionValue(expr) {
150
- const e = unwrap(expr);
151
- if (isFunctionLike(e)) {
152
- const info = intern(e);
153
- return info ? [info] : [];
154
- }
155
- if (ts.isIdentifier(e) ||
156
- ts.isPropertyAccessExpression(e) ||
157
- ts.isElementAccessExpression(e)) {
158
- let sym = checker.getSymbolAtLocation(e);
159
- if (sym && sym.flags & ts.SymbolFlags.Alias) {
160
- sym = checker.getAliasedSymbol(sym);
161
- }
162
- if (!sym) {
163
- return [];
164
- }
165
- const seen = new Set();
166
- const out = [];
167
- for (const fn of functionLikesFromSymbol(sym, false)) {
168
- const info = intern(fn);
169
- if (info && !seen.has(info.id)) {
170
- seen.add(info.id);
171
- out.push(info);
172
- }
173
- }
174
- return out;
175
- }
176
- return [];
177
- }
178
- function callsIn(fn) {
179
- const cached = callsCache.get(fn.id);
180
- if (cached) {
181
- return cached;
182
- }
183
- const calls = [];
184
- const visit = (node) => {
185
- if (node !== fn.node && isFunctionLike(node)) {
186
- return;
187
- }
188
- if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
189
- calls.push(node);
190
- }
191
- ts.forEachChild(node, visit);
192
- };
193
- const body = fn.node.body;
194
- if (body) {
195
- visit(body);
196
- }
197
- for (const param of fn.node.parameters) {
198
- if (param.initializer) {
199
- visit(param.initializer);
200
- }
201
- }
202
- callsCache.set(fn.id, calls);
203
- return calls;
204
- }
205
- function modulesOfSymbol(sym) {
206
- const mods = new Set();
207
- for (const decl of ts.symbolDeclarations(sym)) {
208
- const sf = decl.getSourceFile();
209
- const parts = sf.fileName.split(/node_modules\//);
210
- if (parts.length > 1) {
211
- const tail = parts[parts.length - 1];
212
- const seg = tail.startsWith('@')
213
- ? tail.split('/').slice(0, 2).join('/')
214
- : tail.split('/')[0];
215
- mods.add(seg.startsWith('@types/')
216
- ? seg.slice('@types/'.length)
217
- : seg);
218
- }
219
- let p = decl.parent;
220
- while (p) {
221
- if (ts.isModuleDeclaration(p) && ts.isStringLiteral(p.name)) {
222
- mods.add(p.name.text);
223
- }
224
- p = p.parent;
225
- }
226
- }
227
- return Array.from(mods);
228
- }
229
- function ownerNames(sym) {
230
- const names = new Set();
231
- for (const decl of ts.symbolDeclarations(sym)) {
232
- let p = decl.parent;
233
- while (p) {
234
- if ((ts.isClassLike(p) ||
235
- ts.isInterfaceDeclaration(p) ||
236
- ts.isModuleDeclaration(p) ||
237
- ts.isTypeAliasDeclaration(p)) &&
238
- 'name' in p &&
239
- p.name &&
240
- ts.isIdentifier(p.name)) {
241
- names.add(p.name.text);
242
- }
243
- p = p.parent;
244
- }
245
- }
246
- return Array.from(names);
247
- }
248
- function isLocalSymbol(sym) {
249
- for (const decl of ts.symbolDeclarations(sym)) {
250
- const sf = decl.getSourceFile();
251
- if (!sf.isDeclarationFile && programFiles.has(sf)) {
252
- return true;
253
- }
254
- }
255
- return false;
256
- }
257
- function matchesSelector(sym, selector) {
258
- if (selector.names.length === 0) {
259
- return false;
260
- }
261
- const last = selector.names[selector.names.length - 1];
262
- if (sym.name !== last) {
263
- return false;
264
- }
265
- if (selector.module !== undefined && !isLocalSymbol(sym)) {
266
- if (!modulesOfSymbol(sym).includes(selector.module)) {
267
- return false;
268
- }
269
- }
270
- const owners = ownerNames(sym);
271
- for (const name of selector.names.slice(0, -1)) {
272
- if (!owners.includes(name)) {
273
- return false;
274
- }
275
- }
276
- return true;
277
- }
278
- function markBoundaryCallbacks(call) {
279
- const sym = getCore(call).symbol;
280
- if (!sym) {
281
- return;
282
- }
283
- const args = argExpressions(call);
284
- for (const { boundary, selector } of boundaries) {
285
- if (!matchesSelector(sym, selector)) {
286
- continue;
287
- }
288
- for (const index of boundary.callbackArgs) {
289
- const arg = args[index];
290
- if (!arg) {
291
- continue;
292
- }
293
- for (const info of resolveFunctionValue(arg)) {
294
- boundaryIds.add(info.id);
295
- }
296
- }
297
- }
298
- }
299
- function functionLikesOfSymbol(symbol) {
300
- const out = [];
301
- for (const decl of ts.symbolDeclarations(symbol)) {
302
- if (decl.getSourceFile().isDeclarationFile) {
303
- continue;
304
- }
305
- if (isFunctionLike(decl)) {
306
- if (!ts.isFunctionDeclaration(decl) || decl.body) {
307
- out.push(decl);
308
- }
309
- }
310
- else if (ts.isVariableDeclaration(decl) &&
311
- decl.initializer &&
312
- isFunctionLike(decl.initializer)) {
313
- out.push(decl.initializer);
314
- }
315
- else if (ts.isExportAssignment(decl) &&
316
- isFunctionLike(decl.expression)) {
317
- out.push(decl.expression);
318
- }
319
- }
320
- return out;
321
- }
322
- function allFunctionLikesIn(sf) {
323
- const out = [];
324
- const visit = (node) => {
325
- if (isFunctionLike(node) &&
326
- (!ts.isFunctionDeclaration(node) || node.body)) {
327
- out.push(node);
328
- }
329
- ts.forEachChild(node, visit);
330
- };
331
- ts.forEachChild(sf, visit);
332
- return out;
333
- }
334
- function entryFunctionsOf(sf) {
335
- if (wholeProject) {
336
- return allFunctionLikesIn(sf);
337
- }
338
- const moduleSymbol = checker.getSymbolAtLocation(sf);
339
- if (!moduleSymbol) {
340
- return [];
341
- }
342
- const out = [];
343
- for (const exported of checker.getExportsOfModule(moduleSymbol)) {
344
- const resolved = exported.flags & ts.SymbolFlags.Alias
345
- ? checker.getAliasedSymbol(exported)
346
- : exported;
347
- out.push(...functionLikesOfSymbol(resolved));
348
- }
349
- return out;
350
- }
351
- function entryFiles() {
352
- if (wholeProject) {
353
- return sourceFiles.filter((sf) => !sf.isDeclarationFile &&
354
- !sf.fileName.includes('/node_modules/'));
355
- }
356
- const root = normalizeSlashes(config.projectRoot).replace(/\/+$/, '');
357
- const patterns = config.entryPoints.map((glob) => {
358
- const g = normalizeSlashes(glob);
359
- const absolute = /^([a-zA-Z]:)?\//.test(g) ? g : `${root}/${g}`;
360
- return globToRegExp(absolute);
361
- });
362
- const files = [];
363
- for (const sf of sourceFiles) {
364
- if (sf.isDeclarationFile) {
365
- continue;
366
- }
367
- if (patterns.some((re) => re.test(sf.fileName))) {
368
- files.push(sf);
369
- }
370
- }
371
- return files;
372
- }
373
- for (const sf of entryFiles()) {
374
- for (const node of entryFunctionsOf(sf)) {
375
- const info = intern(node);
376
- if (info) {
377
- boundaryIds.add(info.id);
378
- }
379
- }
380
- }
381
- for (let workIndex = 0; workIndex < worklist.length; workIndex++) {
382
- const fn = worklist[workIndex];
383
- for (const call of callsIn(fn)) {
384
- getCore(call);
385
- markBoundaryCallbacks(call);
386
- }
387
- }
388
- const reachedList = Array.from(reached.values());
389
- function resolveCall(call, channel) {
390
- let cached = resolutionCache.get(call)?.get(channel);
391
- if (cached) {
392
- return cached;
393
- }
394
- const core = getCore(call);
395
- let result;
396
- if (core.targets.length > 0) {
397
- result = {
398
- targets: core.targets,
399
- overlay: undefined,
400
- get functionArgs() { return core.functionArgs(); },
401
- unresolved: false,
402
- };
403
- }
404
- else {
405
- const overlay = core.symbol
406
- ? overlays.lookup(core.symbol, channel)
407
- : undefined;
408
- result = overlay ? {
409
- targets: [],
410
- overlay,
411
- get functionArgs() { return core.functionArgs(); },
412
- unresolved: false,
413
- } : {
414
- targets: [],
415
- overlay: undefined,
416
- get functionArgs() { return core.functionArgs(); },
417
- unresolved: core.unresolved,
418
- };
419
- }
420
- let resolutions = resolutionCache.get(call);
421
- if (!resolutions) {
422
- resolutions = new Map();
423
- resolutionCache.set(call, resolutions);
424
- }
425
- resolutions.set(channel, result);
426
- return result;
427
- }
428
- function calleesOf(fn) {
429
- const cached = calleesCache.get(fn.id);
430
- if (cached) {
431
- return cached;
432
- }
433
- const seen = new Set();
434
- const out = [];
435
- for (const call of callsIn(fn)) {
436
- for (const target of getCore(call).targets) {
437
- if (reached.has(target.node) && !seen.has(target.id)) {
438
- seen.add(target.id);
439
- out.push(target);
440
- }
441
- }
442
- }
443
- calleesCache.set(fn.id, out);
444
- return out;
445
- }
446
- return {
447
- reachedFunctions() {
448
- return reachedList;
449
- },
450
- boundaries() {
451
- return boundaryIds;
452
- },
453
- calleesOf,
454
- resolveCall,
455
- resolveFunctionValue,
456
- };
457
- }
458
- function normalizeSlashes(p) {
459
- return p.replace(/\\/g, '/');
460
- }
461
- function globToRegExp(glob) {
462
- let re = '';
463
- let i = 0;
464
- const n = glob.length;
465
- while (i < n) {
466
- const ch = glob[i];
467
- if (ch === '*') {
468
- if (glob[i + 1] === '*') {
469
- if (glob[i + 2] === '/') {
470
- re += '(?:[^/]*(?:/|$))*';
471
- i += 3;
472
- }
473
- else {
474
- re += '.*';
475
- i += 2;
476
- }
477
- }
478
- else {
479
- re += '[^/]*';
480
- i += 1;
481
- }
482
- continue;
483
- }
484
- if (ch === '?') {
485
- re += '[^/]';
486
- i += 1;
487
- continue;
488
- }
489
- re += ch.replace(/[.+^${}()|[\]\\]/g, '\\$&');
490
- i += 1;
491
- }
492
- return new RegExp(`^${re}$`, 'i');
493
- }
494
- function parseSelector(selector) {
495
- const hashIndex = selector.indexOf('#');
496
- const dotted = hashIndex >= 0 ? selector.slice(0, hashIndex) : selector;
497
- const method = hashIndex >= 0 ? selector.slice(hashIndex + 1) : undefined;
498
- const segments = dotted.split('.').filter(Boolean);
499
- const hasModule = segments.length > 1;
500
- const module = hasModule ? segments[0] : undefined;
501
- const names = hasModule ? segments.slice(1) : segments.slice(0);
502
- if (method) {
503
- names.push(method);
504
- }
505
- return { module, names };
506
- }
507
- export { buildCallGraph };
@@ -1,25 +0,0 @@
1
- // Express preset bundle. `handlerBoundaries` promote route callbacks to
2
- // analysis boundaries (loadOverlays exposes them via boundariesFromPresets()).
3
- // `overlay` follows the channel -> section -> key shape.
4
- {
5
- "handlerBoundaries": [
6
- { "callee": "express.Router#get", "callbackArgs": [1] },
7
- { "callee": "express.Router#post", "callbackArgs": [1] },
8
- { "callee": "express.Router#put", "callbackArgs": [1] },
9
- { "callee": "express.Router#patch", "callbackArgs": [1] },
10
- { "callee": "express.Router#delete", "callbackArgs": [1] },
11
- { "callee": "express.Router#all", "callbackArgs": [1] },
12
- { "callee": "express.Router#use", "callbackArgs": [0, 1] },
13
- { "callee": "express.Application#get", "callbackArgs": [1] },
14
- { "callee": "express.Application#post", "callbackArgs": [1] },
15
- { "callee": "express.Application#use", "callbackArgs": [0, 1] }
16
- ],
17
- "overlay": {
18
- "exceptions": {
19
- "express": {
20
- "Response#json": { "exceptions": ["TypeError"] },
21
- "Response#sendFile": { "exceptions": ["TypeError"] }
22
- }
23
- }
24
- }
25
- }
@@ -1,17 +0,0 @@
1
- // Node preset bundle. `overlay` is keyed by channel, then section (module),
2
- // then overlay key. A couple of node:fs / node:path throwers prove the shape.
3
- {
4
- "overlay": {
5
- "exceptions": {
6
- "node:fs": {
7
- "readFileSync": { "exceptions": ["Error"] },
8
- "writeFileSync": { "exceptions": ["Error"] },
9
- "mkdirSync": { "exceptions": ["Error"] }
10
- },
11
- "node:path": {
12
- "relative": { "exceptions": ["TypeError"] },
13
- "resolve": { "exceptions": ["TypeError"] }
14
- }
15
- }
16
- }
17
- }
File without changes
File without changes
File without changes
File without changes
File without changes