@runtime-type-inspector/transpiler 5.0.4 → 5.0.5
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/index.cjs +158 -19
- package/index.mjs +139 -17
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -449,9 +449,9 @@
|
|
|
449
449
|
TypeQuery = _ts$SyntaxKind.TypeQuery,
|
|
450
450
|
TypeOperator = _ts$SyntaxKind.TypeOperator,
|
|
451
451
|
KeyOfKeyword = _ts$SyntaxKind.KeyOfKeyword,
|
|
452
|
-
ReadonlyKeyword = _ts$SyntaxKind.ReadonlyKeyword
|
|
453
|
-
_ts$SyntaxKind.UniqueKeyword
|
|
454
|
-
|
|
452
|
+
ReadonlyKeyword = _ts$SyntaxKind.ReadonlyKeyword,
|
|
453
|
+
UniqueKeyword = _ts$SyntaxKind.UniqueKeyword,
|
|
454
|
+
ConstructorType = _ts$SyntaxKind.ConstructorType,
|
|
455
455
|
NamedTupleMember = _ts$SyntaxKind.NamedTupleMember,
|
|
456
456
|
MappedType = _ts$SyntaxKind.MappedType,
|
|
457
457
|
MinusToken = _ts$SyntaxKind.MinusToken,
|
|
@@ -639,6 +639,11 @@
|
|
|
639
639
|
// readonly erased at runtime, same shape as the inner type.
|
|
640
640
|
return toSourceTS(node.type);
|
|
641
641
|
}
|
|
642
|
+
if (node.operator === UniqueKeyword) {
|
|
643
|
+
// `unique symbol` is a symbol at runtime; the uniqueness refers to
|
|
644
|
+
// a specific declaration which we cannot track here.
|
|
645
|
+
return toSourceTS(node.type);
|
|
646
|
+
}
|
|
642
647
|
console.warn("unimplemented TypeOperator", node);
|
|
643
648
|
return 'any';
|
|
644
649
|
case TypeReference:
|
|
@@ -1370,7 +1375,7 @@
|
|
|
1370
1375
|
return expandTypeDepFree(type.slice(9).trim());
|
|
1371
1376
|
}
|
|
1372
1377
|
if (type === 'unique symbol') {
|
|
1373
|
-
return '
|
|
1378
|
+
return 'symbol';
|
|
1374
1379
|
}
|
|
1375
1380
|
// Conditionals before nullable: `A extends B ? C : D?` must keep the
|
|
1376
1381
|
// nullable on the false branch, not lift it over the whole condition.
|
|
@@ -2634,6 +2639,21 @@
|
|
|
2634
2639
|
var matches = _toConsumableArray(src.matchAll(regexTemplateTyped));
|
|
2635
2640
|
/** @type {Record<string, ExpandTypeReturnType>} */
|
|
2636
2641
|
var templates = Object.create(null);
|
|
2642
|
+
// `@template {Constraint} [Name=Default]` (or `[Name]`): constraint wins,
|
|
2643
|
+
// the default only matters when nothing is inferred.
|
|
2644
|
+
var regexTemplateConstrainedDefault = /@template \{(.*?)\}\s*\[([a-zA-Z0-9_$]+)(?:=([^\]]+))?\]/g;
|
|
2645
|
+
var _iterator = _createForOfIteratorHelper(src.matchAll(regexTemplateConstrainedDefault)),
|
|
2646
|
+
_step;
|
|
2647
|
+
try {
|
|
2648
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2649
|
+
var match = _step.value;
|
|
2650
|
+
templates[match[2]] = expandType(match[1].trim());
|
|
2651
|
+
}
|
|
2652
|
+
} catch (err) {
|
|
2653
|
+
_iterator.e(err);
|
|
2654
|
+
} finally {
|
|
2655
|
+
_iterator.f();
|
|
2656
|
+
}
|
|
2637
2657
|
matches.forEach(function (_) {
|
|
2638
2658
|
var type = expandType(_[1].trim());
|
|
2639
2659
|
var name = _[2].trim();
|
|
@@ -2641,34 +2661,34 @@
|
|
|
2641
2661
|
});
|
|
2642
2662
|
// `@template [A=X]` defaults: constraint X under name A.
|
|
2643
2663
|
var regexTemplateDefault = /@template \[([a-zA-Z0-9_$]+)=([^\]]+)\]/g;
|
|
2644
|
-
var
|
|
2645
|
-
|
|
2664
|
+
var _iterator2 = _createForOfIteratorHelper(src.matchAll(regexTemplateDefault)),
|
|
2665
|
+
_step2;
|
|
2646
2666
|
try {
|
|
2647
|
-
for (
|
|
2648
|
-
var
|
|
2649
|
-
templates[
|
|
2667
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
2668
|
+
var _match = _step2.value;
|
|
2669
|
+
templates[_match[1]] = expandType(_match[2].trim());
|
|
2650
2670
|
}
|
|
2651
2671
|
// Bare `@template T`: unconstrained, stands in as any.
|
|
2652
2672
|
} catch (err) {
|
|
2653
|
-
|
|
2673
|
+
_iterator2.e(err);
|
|
2654
2674
|
} finally {
|
|
2655
|
-
|
|
2675
|
+
_iterator2.f();
|
|
2656
2676
|
}
|
|
2657
2677
|
var regexTemplateBare = /@template ([a-zA-Z0-9_$]+)(?![a-zA-Z0-9_$])/g;
|
|
2658
|
-
var
|
|
2659
|
-
|
|
2678
|
+
var _iterator3 = _createForOfIteratorHelper(src.matchAll(regexTemplateBare)),
|
|
2679
|
+
_step3;
|
|
2660
2680
|
try {
|
|
2661
|
-
for (
|
|
2662
|
-
var
|
|
2663
|
-
var name =
|
|
2681
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
2682
|
+
var _match2 = _step3.value;
|
|
2683
|
+
var name = _match2[1];
|
|
2664
2684
|
if (!(name in templates)) {
|
|
2665
2685
|
templates[name] = 'any';
|
|
2666
2686
|
}
|
|
2667
2687
|
}
|
|
2668
2688
|
} catch (err) {
|
|
2669
|
-
|
|
2689
|
+
_iterator3.e(err);
|
|
2670
2690
|
} finally {
|
|
2671
|
-
|
|
2691
|
+
_iterator3.f();
|
|
2672
2692
|
}
|
|
2673
2693
|
if (!Object.keys(templates).length) {
|
|
2674
2694
|
return;
|
|
@@ -5363,6 +5383,115 @@
|
|
|
5363
5383
|
params: params
|
|
5364
5384
|
};
|
|
5365
5385
|
}
|
|
5386
|
+
/**
|
|
5387
|
+
* Reads `@template` bindings from every lexically enclosing scope, outer
|
|
5388
|
+
* to inner: classes (declaration or expression, incl. `export` wrappers)
|
|
5389
|
+
* and functions with their own `@template` tags. Class templates scope
|
|
5390
|
+
* over the constructor and methods, mirroring TypeScript:
|
|
5391
|
+
* `new Asset('x', ...)` infers `K` from the constructor's `@param {K}`
|
|
5392
|
+
* occurrences. Inner scopes shadow outer names on conflict.
|
|
5393
|
+
* @param {Node} node - The function or block node being checked.
|
|
5394
|
+
* @returns {Record<string, any>|undefined} Merged scope templates or undefined.
|
|
5395
|
+
*/
|
|
5396
|
+
}, {
|
|
5397
|
+
key: "getScopeTemplates",
|
|
5398
|
+
value: function getScopeTemplates(node) {
|
|
5399
|
+
var fnNode = node;
|
|
5400
|
+
if (node.type === 'BlockStatement') {
|
|
5401
|
+
fnNode = this.parent;
|
|
5402
|
+
}
|
|
5403
|
+
var anchorIdx = this.parents.findLastIndex(function (_) {
|
|
5404
|
+
return _ === node;
|
|
5405
|
+
});
|
|
5406
|
+
if (anchorIdx === -1) {
|
|
5407
|
+
return;
|
|
5408
|
+
}
|
|
5409
|
+
var merged;
|
|
5410
|
+
for (var i = 0; i <= anchorIdx; i++) {
|
|
5411
|
+
var ancestor = this.parents[i];
|
|
5412
|
+
if (!ancestor || ancestor === fnNode) {
|
|
5413
|
+
// Never inherit the node's own bindings: they merge separately and win.
|
|
5414
|
+
continue;
|
|
5415
|
+
}
|
|
5416
|
+
var templates = void 0;
|
|
5417
|
+
if (ancestor.type === 'ClassDeclaration' || ancestor.type === 'ClassExpression') {
|
|
5418
|
+
templates = this.classTemplatesOf(ancestor);
|
|
5419
|
+
} else if (nodeIsFunctionLike(ancestor)) {
|
|
5420
|
+
templates = this.functionTemplatesOf(ancestor);
|
|
5421
|
+
}
|
|
5422
|
+
if (templates) {
|
|
5423
|
+
merged = _objectSpread2(_objectSpread2({}, merged), templates);
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
return merged;
|
|
5427
|
+
}
|
|
5428
|
+
/**
|
|
5429
|
+
* Reads the `@template` bindings off one class node.
|
|
5430
|
+
* @param {Node} classDecl - The ClassDeclaration or ClassExpression node.
|
|
5431
|
+
* @returns {Record<string, any>|undefined} Its templates or undefined.
|
|
5432
|
+
*/
|
|
5433
|
+
}, {
|
|
5434
|
+
key: "classTemplatesOf",
|
|
5435
|
+
value: function classTemplatesOf(classDecl) {
|
|
5436
|
+
var _leadingComments;
|
|
5437
|
+
var leadingComments = classDecl.leadingComments;
|
|
5438
|
+
if (!leadingComments) {
|
|
5439
|
+
var exportNamed = this.findParentOfType(classDecl, 'ExportNamedDeclaration');
|
|
5440
|
+
leadingComments = exportNamed === null || exportNamed === void 0 ? void 0 : exportNamed.leadingComments;
|
|
5441
|
+
if (!leadingComments) {
|
|
5442
|
+
var exportDefault = this.findParentOfType(classDecl, 'ExportDefaultDeclaration');
|
|
5443
|
+
leadingComments = exportDefault === null || exportDefault === void 0 ? void 0 : exportDefault.leadingComments;
|
|
5444
|
+
}
|
|
5445
|
+
if (!leadingComments && classDecl.type === 'ClassExpression') {
|
|
5446
|
+
// `/** @template K */ const Box = class {...}`: the comment lives on
|
|
5447
|
+
// the declaration, mirroring function-expression handling.
|
|
5448
|
+
var varDecl = this.findParentOfType(classDecl, 'VariableDeclaration');
|
|
5449
|
+
leadingComments = varDecl === null || varDecl === void 0 ? void 0 : varDecl.leadingComments;
|
|
5450
|
+
}
|
|
5451
|
+
}
|
|
5452
|
+
if (!((_leadingComments = leadingComments) !== null && _leadingComments !== void 0 && _leadingComments.length)) {
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5455
|
+
var lastComment = leadingComments[leadingComments.length - 1];
|
|
5456
|
+
if (lastComment.type !== 'CommentBlock') {
|
|
5457
|
+
return;
|
|
5458
|
+
}
|
|
5459
|
+
return parseJSDocTemplates(lastComment.value);
|
|
5460
|
+
}
|
|
5461
|
+
/**
|
|
5462
|
+
* Reads the `@template` bindings off one enclosing function: its own
|
|
5463
|
+
* leading comment, resolving the same `export`/declarator wrappers the
|
|
5464
|
+
* node's own JSDoc lookup uses.
|
|
5465
|
+
* @param {Node} fnNode - The enclosing function-like node.
|
|
5466
|
+
* @returns {Record<string, any>|undefined} Its templates or undefined.
|
|
5467
|
+
*/
|
|
5468
|
+
}, {
|
|
5469
|
+
key: "functionTemplatesOf",
|
|
5470
|
+
value: function functionTemplatesOf(fnNode) {
|
|
5471
|
+
var _leadingComments2;
|
|
5472
|
+
var leadingComments;
|
|
5473
|
+
if (fnNode.type === 'FunctionDeclaration') {
|
|
5474
|
+
var _fnNode$leadingCommen, _this$findParentOfTyp;
|
|
5475
|
+
leadingComments = (_fnNode$leadingCommen = fnNode.leadingComments) !== null && _fnNode$leadingCommen !== void 0 ? _fnNode$leadingCommen : (_this$findParentOfTyp = this.findParentOfType(fnNode, 'ExportNamedDeclaration')) === null || _this$findParentOfTyp === void 0 ? void 0 : _this$findParentOfTyp.leadingComments;
|
|
5476
|
+
} else if (fnNode.type === 'FunctionExpression') {
|
|
5477
|
+
var _this$getLeadingComme;
|
|
5478
|
+
leadingComments = (_this$getLeadingComme = this.getLeadingCommentsNodeForFunctionExpression(fnNode)) === null || _this$getLeadingComme === void 0 ? void 0 : _this$getLeadingComme.leadingComments;
|
|
5479
|
+
} else if (fnNode.type === 'ArrowFunctionExpression') {
|
|
5480
|
+
var _this$getLeadingComme2;
|
|
5481
|
+
leadingComments = (_this$getLeadingComme2 = this.getLeadingCommentsNodeForArrowFunctionExpression(fnNode)) === null || _this$getLeadingComme2 === void 0 ? void 0 : _this$getLeadingComme2.leadingComments;
|
|
5482
|
+
} else {
|
|
5483
|
+
// ObjectMethod, ClassMethod, ClassPrivateMethod: docs sit on the node.
|
|
5484
|
+
leadingComments = fnNode.leadingComments;
|
|
5485
|
+
}
|
|
5486
|
+
if (!((_leadingComments2 = leadingComments) !== null && _leadingComments2 !== void 0 && _leadingComments2.length)) {
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
var lastComment = leadingComments[leadingComments.length - 1];
|
|
5490
|
+
if (lastComment.type !== 'CommentBlock') {
|
|
5491
|
+
return;
|
|
5492
|
+
}
|
|
5493
|
+
return parseJSDocTemplates(lastComment.value);
|
|
5494
|
+
}
|
|
5366
5495
|
/**
|
|
5367
5496
|
* Retrieves the name of a parameter from a Babel AST node.
|
|
5368
5497
|
*
|
|
@@ -5510,7 +5639,7 @@
|
|
|
5510
5639
|
stat.checked++;
|
|
5511
5640
|
return this.emitDefaultChecks(node, inferred, true);
|
|
5512
5641
|
}
|
|
5513
|
-
var
|
|
5642
|
+
var ownTemplates = jsdoc.templates,
|
|
5514
5643
|
params = jsdoc.params;
|
|
5515
5644
|
if (!params) {
|
|
5516
5645
|
console.warn("This should never happen, please check your input code.", this.getLeadingComment(node), {
|
|
@@ -5519,6 +5648,11 @@
|
|
|
5519
5648
|
stat.unchecked++;
|
|
5520
5649
|
return '';
|
|
5521
5650
|
}
|
|
5651
|
+
// Lexically enclosing `@template`s (classes and functions) scope over
|
|
5652
|
+
// this node: merge them under method-local templates so `K` in
|
|
5653
|
+
// `@param {K}` resolves jointly. Inner scopes shadow outer ones.
|
|
5654
|
+
var scopeTemplates = this.getScopeTemplates(node);
|
|
5655
|
+
var templates = scopeTemplates ? _objectSpread2(_objectSpread2({}, scopeTemplates), ownTemplates) : ownTemplates;
|
|
5522
5656
|
stat.checked++;
|
|
5523
5657
|
var spaces = this.spaces;
|
|
5524
5658
|
var out = '';
|
|
@@ -6606,6 +6740,11 @@
|
|
|
6606
6740
|
argument: keyofArg
|
|
6607
6741
|
};
|
|
6608
6742
|
}
|
|
6743
|
+
if (node.operator === 'unique') {
|
|
6744
|
+
// `unique symbol` is a symbol at runtime; uniqueness refers to a
|
|
6745
|
+
// specific declaration which we cannot track here.
|
|
6746
|
+
return toSourceBabelTS(node.typeAnnotation);
|
|
6747
|
+
}
|
|
6609
6748
|
console.warn('unimplemented TSTypeOperator', node.operator);
|
|
6610
6749
|
return 'any';
|
|
6611
6750
|
case 'TSQualifiedName':
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { parse } from '@babel/parser';
|
|
2
2
|
import ts from 'typescript';
|
|
3
3
|
|
|
4
|
+
function _extends() {
|
|
5
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
6
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
7
|
+
var source = arguments[i];
|
|
8
|
+
for (var key in source) {
|
|
9
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
10
|
+
target[key] = source[key];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
return _extends.apply(this, arguments);
|
|
17
|
+
}
|
|
18
|
+
|
|
4
19
|
/**
|
|
5
20
|
* @typedef DocType
|
|
6
21
|
* @property {boolean} optional - Type is optional.
|
|
@@ -406,6 +421,11 @@ function toSourceTS(node) {
|
|
|
406
421
|
// readonly erased at runtime, same shape as the inner type.
|
|
407
422
|
return toSourceTS(node.type);
|
|
408
423
|
}
|
|
424
|
+
if (node.operator === UniqueKeyword) {
|
|
425
|
+
// `unique symbol` is a symbol at runtime; the uniqueness refers to
|
|
426
|
+
// a specific declaration which we cannot track here.
|
|
427
|
+
return toSourceTS(node.type);
|
|
428
|
+
}
|
|
409
429
|
console.warn("unimplemented TypeOperator", node);
|
|
410
430
|
return 'any';
|
|
411
431
|
case TypeReference:
|
|
@@ -1119,7 +1139,7 @@ function expandTypeDepFree(type) {
|
|
|
1119
1139
|
return expandTypeDepFree(type.slice(9).trim());
|
|
1120
1140
|
}
|
|
1121
1141
|
if (type === 'unique symbol') {
|
|
1122
|
-
return '
|
|
1142
|
+
return 'symbol';
|
|
1123
1143
|
}
|
|
1124
1144
|
// Conditionals before nullable: `A extends B ? C : D?` must keep the
|
|
1125
1145
|
// nullable on the false branch, not lift it over the whole condition.
|
|
@@ -1365,21 +1385,6 @@ function expandTypeDepFree(type) {
|
|
|
1365
1385
|
return type;
|
|
1366
1386
|
}
|
|
1367
1387
|
|
|
1368
|
-
function _extends() {
|
|
1369
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
1370
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1371
|
-
var source = arguments[i];
|
|
1372
|
-
for (var key in source) {
|
|
1373
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1374
|
-
target[key] = source[key];
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
return target;
|
|
1379
|
-
};
|
|
1380
|
-
return _extends.apply(this, arguments);
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
1388
|
/**
|
|
1384
1389
|
* Extracts the parameter name and its optionality from a JSDoc parameter string.
|
|
1385
1390
|
*
|
|
@@ -2303,6 +2308,12 @@ function parseJSDocTemplates(src, expandType = expandTypeDepFree) {
|
|
|
2303
2308
|
const matches = [...src.matchAll(regexTemplateTyped)];
|
|
2304
2309
|
/** @type {Record<string, ExpandTypeReturnType>} */
|
|
2305
2310
|
const templates = Object.create(null);
|
|
2311
|
+
// `@template {Constraint} [Name=Default]` (or `[Name]`): constraint wins,
|
|
2312
|
+
// the default only matters when nothing is inferred.
|
|
2313
|
+
const regexTemplateConstrainedDefault = /@template \{(.*?)\}\s*\[([a-zA-Z0-9_$]+)(?:=([^\]]+))?\]/g;
|
|
2314
|
+
for (const match of src.matchAll(regexTemplateConstrainedDefault)) {
|
|
2315
|
+
templates[match[2]] = expandType(match[1].trim());
|
|
2316
|
+
}
|
|
2306
2317
|
matches.forEach(_ => {
|
|
2307
2318
|
const type = expandType(_[1].trim());
|
|
2308
2319
|
const name = _[2].trim();
|
|
@@ -4916,6 +4927,107 @@ class Asserter extends Stringifier {
|
|
|
4916
4927
|
params
|
|
4917
4928
|
};
|
|
4918
4929
|
}
|
|
4930
|
+
/**
|
|
4931
|
+
* Reads `@template` bindings from every lexically enclosing scope, outer
|
|
4932
|
+
* to inner: classes (declaration or expression, incl. `export` wrappers)
|
|
4933
|
+
* and functions with their own `@template` tags. Class templates scope
|
|
4934
|
+
* over the constructor and methods, mirroring TypeScript:
|
|
4935
|
+
* `new Asset('x', ...)` infers `K` from the constructor's `@param {K}`
|
|
4936
|
+
* occurrences. Inner scopes shadow outer names on conflict.
|
|
4937
|
+
* @param {Node} node - The function or block node being checked.
|
|
4938
|
+
* @returns {Record<string, any>|undefined} Merged scope templates or undefined.
|
|
4939
|
+
*/
|
|
4940
|
+
getScopeTemplates(node) {
|
|
4941
|
+
let fnNode = node;
|
|
4942
|
+
if (node.type === 'BlockStatement') {
|
|
4943
|
+
fnNode = this.parent;
|
|
4944
|
+
}
|
|
4945
|
+
const anchorIdx = this.parents.findLastIndex(_ => _ === node);
|
|
4946
|
+
if (anchorIdx === -1) {
|
|
4947
|
+
return;
|
|
4948
|
+
}
|
|
4949
|
+
let merged;
|
|
4950
|
+
for (let i = 0; i <= anchorIdx; i++) {
|
|
4951
|
+
const ancestor = this.parents[i];
|
|
4952
|
+
if (!ancestor || ancestor === fnNode) {
|
|
4953
|
+
// Never inherit the node's own bindings: they merge separately and win.
|
|
4954
|
+
continue;
|
|
4955
|
+
}
|
|
4956
|
+
let templates;
|
|
4957
|
+
if (ancestor.type === 'ClassDeclaration' || ancestor.type === 'ClassExpression') {
|
|
4958
|
+
templates = this.classTemplatesOf(ancestor);
|
|
4959
|
+
} else if (nodeIsFunctionLike(ancestor)) {
|
|
4960
|
+
templates = this.functionTemplatesOf(ancestor);
|
|
4961
|
+
}
|
|
4962
|
+
if (templates) {
|
|
4963
|
+
merged = _extends({}, merged, templates);
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
return merged;
|
|
4967
|
+
}
|
|
4968
|
+
/**
|
|
4969
|
+
* Reads the `@template` bindings off one class node.
|
|
4970
|
+
* @param {Node} classDecl - The ClassDeclaration or ClassExpression node.
|
|
4971
|
+
* @returns {Record<string, any>|undefined} Its templates or undefined.
|
|
4972
|
+
*/
|
|
4973
|
+
classTemplatesOf(classDecl) {
|
|
4974
|
+
var _leadingComments;
|
|
4975
|
+
let leadingComments = classDecl.leadingComments;
|
|
4976
|
+
if (!leadingComments) {
|
|
4977
|
+
const exportNamed = this.findParentOfType(classDecl, 'ExportNamedDeclaration');
|
|
4978
|
+
leadingComments = exportNamed == null ? void 0 : exportNamed.leadingComments;
|
|
4979
|
+
if (!leadingComments) {
|
|
4980
|
+
const exportDefault = this.findParentOfType(classDecl, 'ExportDefaultDeclaration');
|
|
4981
|
+
leadingComments = exportDefault == null ? void 0 : exportDefault.leadingComments;
|
|
4982
|
+
}
|
|
4983
|
+
if (!leadingComments && classDecl.type === 'ClassExpression') {
|
|
4984
|
+
// `/** @template K */ const Box = class {...}`: the comment lives on
|
|
4985
|
+
// the declaration, mirroring function-expression handling.
|
|
4986
|
+
const varDecl = this.findParentOfType(classDecl, 'VariableDeclaration');
|
|
4987
|
+
leadingComments = varDecl == null ? void 0 : varDecl.leadingComments;
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
if (!((_leadingComments = leadingComments) != null && _leadingComments.length)) {
|
|
4991
|
+
return;
|
|
4992
|
+
}
|
|
4993
|
+
const lastComment = leadingComments[leadingComments.length - 1];
|
|
4994
|
+
if (lastComment.type !== 'CommentBlock') {
|
|
4995
|
+
return;
|
|
4996
|
+
}
|
|
4997
|
+
return parseJSDocTemplates(lastComment.value);
|
|
4998
|
+
}
|
|
4999
|
+
/**
|
|
5000
|
+
* Reads the `@template` bindings off one enclosing function: its own
|
|
5001
|
+
* leading comment, resolving the same `export`/declarator wrappers the
|
|
5002
|
+
* node's own JSDoc lookup uses.
|
|
5003
|
+
* @param {Node} fnNode - The enclosing function-like node.
|
|
5004
|
+
* @returns {Record<string, any>|undefined} Its templates or undefined.
|
|
5005
|
+
*/
|
|
5006
|
+
functionTemplatesOf(fnNode) {
|
|
5007
|
+
var _leadingComments2;
|
|
5008
|
+
let leadingComments;
|
|
5009
|
+
if (fnNode.type === 'FunctionDeclaration') {
|
|
5010
|
+
var _fnNode$leadingCommen, _this$findParentOfTyp;
|
|
5011
|
+
leadingComments = (_fnNode$leadingCommen = fnNode.leadingComments) != null ? _fnNode$leadingCommen : (_this$findParentOfTyp = this.findParentOfType(fnNode, 'ExportNamedDeclaration')) == null ? void 0 : _this$findParentOfTyp.leadingComments;
|
|
5012
|
+
} else if (fnNode.type === 'FunctionExpression') {
|
|
5013
|
+
var _this$getLeadingComme;
|
|
5014
|
+
leadingComments = (_this$getLeadingComme = this.getLeadingCommentsNodeForFunctionExpression(fnNode)) == null ? void 0 : _this$getLeadingComme.leadingComments;
|
|
5015
|
+
} else if (fnNode.type === 'ArrowFunctionExpression') {
|
|
5016
|
+
var _this$getLeadingComme2;
|
|
5017
|
+
leadingComments = (_this$getLeadingComme2 = this.getLeadingCommentsNodeForArrowFunctionExpression(fnNode)) == null ? void 0 : _this$getLeadingComme2.leadingComments;
|
|
5018
|
+
} else {
|
|
5019
|
+
// ObjectMethod, ClassMethod, ClassPrivateMethod: docs sit on the node.
|
|
5020
|
+
leadingComments = fnNode.leadingComments;
|
|
5021
|
+
}
|
|
5022
|
+
if (!((_leadingComments2 = leadingComments) != null && _leadingComments2.length)) {
|
|
5023
|
+
return;
|
|
5024
|
+
}
|
|
5025
|
+
const lastComment = leadingComments[leadingComments.length - 1];
|
|
5026
|
+
if (lastComment.type !== 'CommentBlock') {
|
|
5027
|
+
return;
|
|
5028
|
+
}
|
|
5029
|
+
return parseJSDocTemplates(lastComment.value);
|
|
5030
|
+
}
|
|
4919
5031
|
/**
|
|
4920
5032
|
* Retrieves the name of a parameter from a Babel AST node.
|
|
4921
5033
|
*
|
|
@@ -5064,7 +5176,7 @@ class Asserter extends Stringifier {
|
|
|
5064
5176
|
return this.emitDefaultChecks(node, inferred, true);
|
|
5065
5177
|
}
|
|
5066
5178
|
const {
|
|
5067
|
-
templates,
|
|
5179
|
+
templates: ownTemplates,
|
|
5068
5180
|
params
|
|
5069
5181
|
} = jsdoc;
|
|
5070
5182
|
if (!params) {
|
|
@@ -5074,6 +5186,11 @@ class Asserter extends Stringifier {
|
|
|
5074
5186
|
stat.unchecked++;
|
|
5075
5187
|
return '';
|
|
5076
5188
|
}
|
|
5189
|
+
// Lexically enclosing `@template`s (classes and functions) scope over
|
|
5190
|
+
// this node: merge them under method-local templates so `K` in
|
|
5191
|
+
// `@param {K}` resolves jointly. Inner scopes shadow outer ones.
|
|
5192
|
+
const scopeTemplates = this.getScopeTemplates(node);
|
|
5193
|
+
const templates = scopeTemplates ? _extends({}, scopeTemplates, ownTemplates) : ownTemplates;
|
|
5077
5194
|
stat.checked++;
|
|
5078
5195
|
const {
|
|
5079
5196
|
spaces
|
|
@@ -6071,6 +6188,11 @@ function toSourceBabelTS(node) {
|
|
|
6071
6188
|
argument: keyofArg
|
|
6072
6189
|
};
|
|
6073
6190
|
}
|
|
6191
|
+
if (node.operator === 'unique') {
|
|
6192
|
+
// `unique symbol` is a symbol at runtime; uniqueness refers to a
|
|
6193
|
+
// specific declaration which we cannot track here.
|
|
6194
|
+
return toSourceBabelTS(node.typeAnnotation);
|
|
6195
|
+
}
|
|
6074
6196
|
console.warn('unimplemented TSTypeOperator', node.operator);
|
|
6075
6197
|
return 'any';
|
|
6076
6198
|
case 'TSQualifiedName':
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"ts2js": "ts2js.js"
|
|
5
5
|
},
|
|
6
6
|
"name": "@runtime-type-inspector/transpiler",
|
|
7
|
-
"version": "5.0.
|
|
7
|
+
"version": "5.0.5",
|
|
8
8
|
"description": "Validating JSDoc types at runtime for high-quality types - Trust is good, control is better.",
|
|
9
9
|
"main": "index.cjs",
|
|
10
10
|
"module": "index.mjs",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"homepage": "https://github.com/kungfooman/RuntimeTypeInspector.js#readme",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@babel/parser": "^7.23.0",
|
|
25
|
-
"@runtime-type-inspector/runtime": "^5.0.
|
|
25
|
+
"@runtime-type-inspector/runtime": "^5.0.5",
|
|
26
26
|
"typescript": "^5.1.6"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|