@runtime-type-inspector/transpiler 3.2.5 → 3.2.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.
- package/index.cjs +299 -109
- package/index.mjs +325 -109
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -282,24 +282,19 @@
|
|
|
282
282
|
* expandType('typeof Number '); // Outputs:
|
|
283
283
|
* @param {string} type - The type string to be expanded into a structured representation.
|
|
284
284
|
* @todo Share type with expandTypeBabelTS and expandTypeDepFree
|
|
285
|
-
* @returns {string | {type: string, [key: string]: any} | undefined} The structured type
|
|
285
|
+
* @returns {string | number | boolean | {type: string, [key: string]: any} | undefined} The structured type
|
|
286
286
|
* representation obtained from parsing and converting the provided type string.
|
|
287
287
|
*/
|
|
288
288
|
function expandType(type) {
|
|
289
289
|
var ast = parseType(type);
|
|
290
|
+
if (!ast) {
|
|
291
|
+
return 'never';
|
|
292
|
+
}
|
|
290
293
|
return toSourceTS(ast);
|
|
291
294
|
}
|
|
292
|
-
/**
|
|
293
|
-
* @todo I want to use for example: import('typescript').Node
|
|
294
|
-
* But the TS types make no sense to me so far ... need to investigate more.
|
|
295
|
-
* @typedef TypeScriptType
|
|
296
|
-
* @property {object[]|undefined} typeArguments - The type arguments.
|
|
297
|
-
* @property {import('typescript').Node} typeName - The type name.
|
|
298
|
-
* @property {number} kind - The kind for `ts.SyntaxKind[kind]`.
|
|
299
|
-
*/
|
|
300
295
|
/**
|
|
301
296
|
* @param {string} str - The type string.
|
|
302
|
-
* @returns {
|
|
297
|
+
* @returns {ts.TypeNode|undefined} - The node containing all the information about the input type string.
|
|
303
298
|
*/
|
|
304
299
|
function parseType(str) {
|
|
305
300
|
// TS doesn't like ... notation in this context
|
|
@@ -310,7 +305,12 @@
|
|
|
310
305
|
// type tmp = (...string) => 123; to have a function context
|
|
311
306
|
str = "type tmp = ".concat(str, ";");
|
|
312
307
|
var ast = ts.createSourceFile('repl.ts', str, ts.ScriptTarget.Latest, true /*setParentNodes*/);
|
|
313
|
-
|
|
308
|
+
var firstStatement = ast.statements[0];
|
|
309
|
+
if (!ts.isTypeAliasDeclaration(firstStatement)) {
|
|
310
|
+
console.warn('parseType> Expected type alias declaration, got', firstStatement, 'instead.');
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
return firstStatement.type;
|
|
314
314
|
}
|
|
315
315
|
/** @type {Record<string, 'missing'|'found'>} */
|
|
316
316
|
var requiredTypeofs = {};
|
|
@@ -320,7 +320,7 @@
|
|
|
320
320
|
* This function handles various TypeScript AST node types and converts them into a string
|
|
321
321
|
* or an object representing the type.
|
|
322
322
|
*
|
|
323
|
-
* @param {
|
|
323
|
+
* @param {ts.TypeNode|ts.Identifier} node - The TypeScript AST node to convert.
|
|
324
324
|
* @returns {string | number | boolean | {type: string, [key: string]: any} | undefined} The source string/number,
|
|
325
325
|
* or an object with type information based on the node, or `undefined` if the node kind is not handled.
|
|
326
326
|
*/
|
|
@@ -336,7 +336,7 @@
|
|
|
336
336
|
Identifier = _ts$SyntaxKind.Identifier,
|
|
337
337
|
IntersectionType = _ts$SyntaxKind.IntersectionType,
|
|
338
338
|
JSDocAllType = _ts$SyntaxKind.JSDocAllType,
|
|
339
|
-
|
|
339
|
+
ImportType = _ts$SyntaxKind.ImportType,
|
|
340
340
|
LiteralType = _ts$SyntaxKind.LiteralType,
|
|
341
341
|
NullKeyword = _ts$SyntaxKind.NullKeyword,
|
|
342
342
|
NumberKeyword = _ts$SyntaxKind.NumberKeyword,
|
|
@@ -363,6 +363,7 @@
|
|
|
363
363
|
BigIntLiteral = _ts$SyntaxKind.BigIntLiteral,
|
|
364
364
|
ConditionalType = _ts$SyntaxKind.ConditionalType,
|
|
365
365
|
IndexedAccessType = _ts$SyntaxKind.IndexedAccessType,
|
|
366
|
+
IndexSignature = _ts$SyntaxKind.IndexSignature,
|
|
366
367
|
RestType = _ts$SyntaxKind.RestType,
|
|
367
368
|
TypeQuery = _ts$SyntaxKind.TypeQuery,
|
|
368
369
|
TypeOperator = _ts$SyntaxKind.TypeOperator,
|
|
@@ -378,12 +379,18 @@
|
|
|
378
379
|
type: 'bigint'
|
|
379
380
|
};
|
|
380
381
|
case BigIntLiteral:
|
|
382
|
+
if (!ts.isBigIntLiteral(node)) {
|
|
383
|
+
throw Error("Impossible");
|
|
384
|
+
}
|
|
381
385
|
var literal = node.text.slice(0, -1); // Remove the "n"
|
|
382
386
|
return {
|
|
383
387
|
type: 'bigint',
|
|
384
388
|
literal: literal
|
|
385
389
|
};
|
|
386
390
|
case ConditionalType:
|
|
391
|
+
if (!ts.isConditionalTypeNode(node)) {
|
|
392
|
+
throw Error("Impossible");
|
|
393
|
+
}
|
|
387
394
|
// Keys on node:
|
|
388
395
|
// ['pos', 'end', 'flags', 'modifierFlagsCache', 'transformFlags', 'parent', 'kind', 'checkType',
|
|
389
396
|
// 'extendsType', 'trueType', 'falseType', 'locals', 'nextContainer']
|
|
@@ -400,6 +407,9 @@
|
|
|
400
407
|
};
|
|
401
408
|
case ConstructorType:
|
|
402
409
|
{
|
|
410
|
+
if (!ts.isConstructorTypeNode(node)) {
|
|
411
|
+
throw Error("Impossible");
|
|
412
|
+
}
|
|
403
413
|
var _parameters = node.parameters.map(toSourceTS);
|
|
404
414
|
var _ret = toSourceTS(node.type);
|
|
405
415
|
return {
|
|
@@ -409,12 +419,18 @@
|
|
|
409
419
|
};
|
|
410
420
|
}
|
|
411
421
|
case FunctionType:
|
|
422
|
+
if (!ts.isFunctionTypeNode(node)) {
|
|
423
|
+
throw Error("Impossible");
|
|
424
|
+
}
|
|
412
425
|
var parameters = node.parameters.map(toSourceTS);
|
|
413
426
|
return {
|
|
414
427
|
type: 'function',
|
|
415
428
|
parameters: parameters
|
|
416
429
|
};
|
|
417
430
|
case IndexedAccessType:
|
|
431
|
+
if (!ts.isIndexedAccessTypeNode(node)) {
|
|
432
|
+
throw Error("Impossible");
|
|
433
|
+
}
|
|
418
434
|
var index = toSourceTS(node.indexType);
|
|
419
435
|
var object = toSourceTS(node.objectType);
|
|
420
436
|
return {
|
|
@@ -423,12 +439,18 @@
|
|
|
423
439
|
object: object
|
|
424
440
|
};
|
|
425
441
|
case RestType:
|
|
442
|
+
if (!ts.isRestTypeNode(node)) {
|
|
443
|
+
throw Error("Impossible");
|
|
444
|
+
}
|
|
426
445
|
var annotation = toSourceTS(node.type);
|
|
427
446
|
return {
|
|
428
447
|
type: 'rest',
|
|
429
448
|
annotation: annotation
|
|
430
449
|
};
|
|
431
450
|
case JSDocNullableType:
|
|
451
|
+
if (!ts.isJSDocNullableType(node)) {
|
|
452
|
+
throw Error("Impossible");
|
|
453
|
+
}
|
|
432
454
|
var t = toSourceTS(node.type);
|
|
433
455
|
return {
|
|
434
456
|
type: 'union',
|
|
@@ -436,6 +458,9 @@
|
|
|
436
458
|
};
|
|
437
459
|
case MappedType:
|
|
438
460
|
{
|
|
461
|
+
if (!ts.isMappedTypeNode(node)) {
|
|
462
|
+
throw Error("Impossible");
|
|
463
|
+
}
|
|
439
464
|
var result = toSourceTS(node.type);
|
|
440
465
|
var parameter = node.typeParameter;
|
|
441
466
|
if (parameter.kind === TypeParameter) {
|
|
@@ -455,6 +480,9 @@
|
|
|
455
480
|
// todo work out more: const jsdoc = `(...a: ...number) => 123
|
|
456
481
|
// TS even thinks it's two parameters... just go for array/[]
|
|
457
482
|
case Parameter:
|
|
483
|
+
if (!ts.isParameter(node)) {
|
|
484
|
+
throw Error("Impossible");
|
|
485
|
+
}
|
|
458
486
|
var type = node.type ? toSourceTS(node.type) : 'any';
|
|
459
487
|
var name = toSourceTS(node.name);
|
|
460
488
|
var ret = {
|
|
@@ -469,6 +497,9 @@
|
|
|
469
497
|
}
|
|
470
498
|
return ret;
|
|
471
499
|
case TypeQuery:
|
|
500
|
+
if (!ts.isTypeQueryNode(node)) {
|
|
501
|
+
throw Error("Impossible");
|
|
502
|
+
}
|
|
472
503
|
var argument = toSourceTS(node.exprName);
|
|
473
504
|
// Notify Asserter class that we have to register variables with this name
|
|
474
505
|
if (!requiredTypeofs[argument]) {
|
|
@@ -479,6 +510,9 @@
|
|
|
479
510
|
argument: argument
|
|
480
511
|
};
|
|
481
512
|
case TypeOperator:
|
|
513
|
+
if (!ts.isTypeOperatorNode(node)) {
|
|
514
|
+
throw Error("Impossible");
|
|
515
|
+
}
|
|
482
516
|
if (node.operator === KeyOfKeyword) {
|
|
483
517
|
var _argument = toSourceTS(node.type);
|
|
484
518
|
return {
|
|
@@ -489,6 +523,9 @@
|
|
|
489
523
|
console.warn("unimplemented TypeOperator", node);
|
|
490
524
|
case TypeReference:
|
|
491
525
|
{
|
|
526
|
+
if (!ts.isTypeReferenceNode(node)) {
|
|
527
|
+
throw Error("Impossible");
|
|
528
|
+
}
|
|
492
529
|
if ((typeName.text === 'Object' || typeName.text === 'Record') && (typeArguments === null || typeArguments === void 0 ? void 0 : typeArguments.length) === 2) {
|
|
493
530
|
return {
|
|
494
531
|
type: 'record',
|
|
@@ -544,14 +581,16 @@
|
|
|
544
581
|
args: args
|
|
545
582
|
};
|
|
546
583
|
}
|
|
547
|
-
case StringKeyword:
|
|
548
|
-
return node.getText();
|
|
549
|
-
case NumberKeyword:
|
|
550
|
-
return node.getText();
|
|
551
584
|
case NamedTupleMember:
|
|
585
|
+
if (!ts.isNamedTupleMember(node)) {
|
|
586
|
+
throw Error("Impossible");
|
|
587
|
+
}
|
|
552
588
|
return toSourceTS(node.type);
|
|
553
589
|
case IntersectionType:
|
|
554
590
|
{
|
|
591
|
+
if (!ts.isIntersectionTypeNode(node)) {
|
|
592
|
+
throw Error("Impossible");
|
|
593
|
+
}
|
|
555
594
|
var _members = node.types.map(toSourceTS);
|
|
556
595
|
return {
|
|
557
596
|
type: 'intersection',
|
|
@@ -559,35 +598,87 @@
|
|
|
559
598
|
};
|
|
560
599
|
}
|
|
561
600
|
case TupleType:
|
|
601
|
+
if (!ts.isTupleTypeNode(node)) {
|
|
602
|
+
throw Error("Impossible");
|
|
603
|
+
}
|
|
562
604
|
var elements = node.elements.map(toSourceTS);
|
|
563
605
|
return {
|
|
564
606
|
type: 'tuple',
|
|
565
607
|
elements: elements
|
|
566
608
|
};
|
|
567
609
|
case UnionType:
|
|
610
|
+
if (!ts.isUnionTypeNode(node)) {
|
|
611
|
+
throw Error("Impossible");
|
|
612
|
+
}
|
|
568
613
|
var members = node.types.map(toSourceTS);
|
|
569
614
|
return {
|
|
570
615
|
type: 'union',
|
|
571
616
|
members: members
|
|
572
617
|
};
|
|
573
618
|
case TypeLiteral:
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
properties
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
619
|
+
{
|
|
620
|
+
if (!ts.isTypeLiteralNode(node)) {
|
|
621
|
+
throw Error("Impossible");
|
|
622
|
+
}
|
|
623
|
+
var properties = {};
|
|
624
|
+
/** @type {object[]} */
|
|
625
|
+
var indexSignatures;
|
|
626
|
+
node.members.forEach(function (member) {
|
|
627
|
+
if (member.kind === IndexSignature) {
|
|
628
|
+
var _indexSignatures;
|
|
629
|
+
indexSignatures = (_indexSignatures = indexSignatures) !== null && _indexSignatures !== void 0 ? _indexSignatures : [];
|
|
630
|
+
indexSignatures.push(toSourceTS(member));
|
|
631
|
+
} else if (member.kind === PropertySignature) {
|
|
632
|
+
if (!ts.isPropertySignature(member)) {
|
|
633
|
+
throw Error("Impossible");
|
|
634
|
+
}
|
|
635
|
+
var _name2 = toSourceTS(member.name);
|
|
636
|
+
var _type = toSourceTS(member.type);
|
|
637
|
+
properties[_name2] = _type;
|
|
638
|
+
} else {
|
|
639
|
+
console.warn('TypeLiteral: unhandled member', member);
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
var _ret2 = {
|
|
643
|
+
type: 'object'
|
|
644
|
+
};
|
|
645
|
+
if (Object.keys(properties).length) {
|
|
646
|
+
_ret2.properties = properties;
|
|
647
|
+
}
|
|
648
|
+
if (indexSignatures) {
|
|
649
|
+
_ret2.indexSignatures = indexSignatures;
|
|
650
|
+
}
|
|
651
|
+
return _ret2;
|
|
652
|
+
}
|
|
584
653
|
case PropertySignature:
|
|
654
|
+
if (!ts.isPropertySignature(node)) {
|
|
655
|
+
throw Error("Impossible");
|
|
656
|
+
}
|
|
585
657
|
console.warn('toSourceTS> should not happen, handled by TypeLiteral directly');
|
|
586
658
|
return "".concat(toSourceTS(node.name), ": ").concat(toSourceTS(node.type));
|
|
659
|
+
case IndexSignature:
|
|
660
|
+
if (!ts.isIndexSignatureDeclaration(node)) {
|
|
661
|
+
throw Error("Impossible");
|
|
662
|
+
}
|
|
663
|
+
// Only possible modifier I know of, but we don't need it:
|
|
664
|
+
// {readonly [n: number]: string, length: number}
|
|
665
|
+
var indexType = toSourceTS(node.type);
|
|
666
|
+
var indexParameters = node.parameters.map(toSourceTS);
|
|
667
|
+
return {
|
|
668
|
+
type: 'indexSignature',
|
|
669
|
+
indexType: indexType,
|
|
670
|
+
indexParameters: indexParameters
|
|
671
|
+
};
|
|
587
672
|
case Identifier:
|
|
673
|
+
if (!ts.isIdentifier(node)) {
|
|
674
|
+
throw Error("Impossible");
|
|
675
|
+
}
|
|
588
676
|
return node.text;
|
|
589
677
|
case ArrayType:
|
|
590
678
|
{
|
|
679
|
+
if (!ts.isArrayTypeNode(node)) {
|
|
680
|
+
throw Error("Impossible");
|
|
681
|
+
}
|
|
591
682
|
var _elementType4 = toSourceTS(node.elementType);
|
|
592
683
|
return {
|
|
593
684
|
type: 'array',
|
|
@@ -595,18 +686,23 @@
|
|
|
595
686
|
};
|
|
596
687
|
}
|
|
597
688
|
case LiteralType:
|
|
689
|
+
if (!ts.isLiteralTypeNode(node)) {
|
|
690
|
+
throw Error("Impossible");
|
|
691
|
+
}
|
|
598
692
|
return toSourceTS(node.literal);
|
|
599
693
|
case AnyKeyword:
|
|
600
694
|
case BooleanKeyword:
|
|
601
|
-
|
|
602
|
-
case
|
|
695
|
+
case StringKeyword:
|
|
696
|
+
case NeverKeyword:
|
|
603
697
|
case NullKeyword:
|
|
604
|
-
case
|
|
605
|
-
case ThisType:
|
|
698
|
+
case NumberKeyword:
|
|
606
699
|
case UndefinedKeyword:
|
|
607
|
-
case VoidKeyword:
|
|
608
700
|
case UnknownKeyword:
|
|
609
|
-
case
|
|
701
|
+
case VoidKeyword:
|
|
702
|
+
// ts.SyntaxKind[parseType("*").kind] === 'JSDocAllType'
|
|
703
|
+
case JSDocAllType:
|
|
704
|
+
case ThisType:
|
|
705
|
+
case StringLiteral:
|
|
610
706
|
return node.getText();
|
|
611
707
|
case TrueKeyword:
|
|
612
708
|
return true;
|
|
@@ -620,9 +716,16 @@
|
|
|
620
716
|
properties: {}
|
|
621
717
|
};
|
|
622
718
|
case ParenthesizedType:
|
|
719
|
+
if (!ts.isParenthesizedTypeNode(node)) {
|
|
720
|
+
throw Error("Impossible");
|
|
721
|
+
}
|
|
623
722
|
// fall-through for parentheses
|
|
624
723
|
return toSourceTS(node.type);
|
|
625
|
-
case
|
|
724
|
+
case ImportType:
|
|
725
|
+
if (!ts.isImportTypeNode(node)) {
|
|
726
|
+
throw Error("Impossible");
|
|
727
|
+
}
|
|
728
|
+
/** @todo Handle case without any qualifier like `import('test')` */
|
|
626
729
|
return toSourceTS(node.qualifier);
|
|
627
730
|
default:
|
|
628
731
|
// const test = {};
|
|
@@ -844,19 +947,26 @@
|
|
|
844
947
|
return type;
|
|
845
948
|
}
|
|
846
949
|
|
|
950
|
+
/**
|
|
951
|
+
* @typedef {ReturnType<typeof parseJSDoc>} ParseJSDocReturnType
|
|
952
|
+
*/
|
|
953
|
+
/**
|
|
954
|
+
* @typedef {typeof expandTypeDepFree} ExpandType
|
|
955
|
+
* @typedef {ReturnType<ExpandType>} ExpandTypeReturnType
|
|
956
|
+
*/
|
|
847
957
|
/**
|
|
848
958
|
* Parses JSDoc comments to extract parameter type information.
|
|
849
959
|
*
|
|
850
960
|
* @param {string} src - The JSDoc comment string to parse.
|
|
851
|
-
* @param {
|
|
852
|
-
* @returns {Record<string,
|
|
961
|
+
* @param {ExpandType} [expandType] - An optional function to process the types found in the JSDoc.
|
|
962
|
+
* @returns {Record<string, ExpandTypeReturnType> | undefined} An object mapping parameter names to their parsed types, or undefined if no parameters are found.
|
|
853
963
|
*/
|
|
854
964
|
function parseJSDoc(src) {
|
|
855
965
|
var expandType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : expandTypeDepFree;
|
|
856
966
|
// Parse something like: @param {Object} [kwargs={}] Optional arguments.
|
|
857
967
|
var regex = /@param \{(.*?)\} ([\[\]a-zA-Z0-9_$=\{\}\.'" ]+)/g;
|
|
858
968
|
var matches = _toConsumableArray(src.matchAll(regex));
|
|
859
|
-
/** @type {Record<string,
|
|
969
|
+
/** @type {Record<string, ExpandTypeReturnType>} */
|
|
860
970
|
var params = Object.create(null);
|
|
861
971
|
matches.forEach(function (_) {
|
|
862
972
|
var type = expandType(_[1].trim());
|
|
@@ -876,46 +986,42 @@
|
|
|
876
986
|
// Strip the rest (either leftover of optional value or description)
|
|
877
987
|
name = name.split(' ')[0].split('=')[0].trim();
|
|
878
988
|
var simplifiedType = simplifyType(type, optional);
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
src: src,
|
|
911
|
-
toptype: _toptype,
|
|
912
|
-
parts0: _parts,
|
|
913
|
-
parts1: _parts2,
|
|
914
|
-
simplifiedType: simplifiedType
|
|
915
|
-
});
|
|
989
|
+
// Turn "options.stats[].unitsName" into ['options', 'stats', 'unitsName'].
|
|
990
|
+
var parts = name.split(/[\[\]]*\./);
|
|
991
|
+
var properties = params;
|
|
992
|
+
var _iterator = _createForOfIteratorHelper(parts),
|
|
993
|
+
_step;
|
|
994
|
+
try {
|
|
995
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
996
|
+
var part = _step.value;
|
|
997
|
+
var toptype = properties[part];
|
|
998
|
+
if (!toptype) {
|
|
999
|
+
// No toptype means we resolved as far as possible, now we can add `simplifiedType`.
|
|
1000
|
+
console.assert(part === parts.at(-1), 'Current part and last part should be the same.');
|
|
1001
|
+
properties[part] = simplifiedType;
|
|
1002
|
+
} else if (toptype.type === "union") {
|
|
1003
|
+
var typeObject = toptype.members.find(function (_) {
|
|
1004
|
+
return (_ === null || _ === void 0 ? void 0 : _.type) === 'object';
|
|
1005
|
+
});
|
|
1006
|
+
properties = typeObject.properties;
|
|
1007
|
+
} else if (toptype.type === "array") {
|
|
1008
|
+
properties = toptype.elementType.properties;
|
|
1009
|
+
} else if (toptype.type === "object") {
|
|
1010
|
+
toptype.properties = toptype.properties || Object.create(null);
|
|
1011
|
+
properties = toptype.properties;
|
|
1012
|
+
} else {
|
|
1013
|
+
console.warn("parseJSDoc> Skipping @param, unseen syntax detected. Please check if your JSDoc is valid or open an issue about this!", {
|
|
1014
|
+
src: src,
|
|
1015
|
+
toptype: toptype,
|
|
1016
|
+
parts: parts,
|
|
1017
|
+
simplifiedType: simplifiedType
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
916
1020
|
}
|
|
917
|
-
}
|
|
918
|
-
|
|
1021
|
+
} catch (err) {
|
|
1022
|
+
_iterator.e(err);
|
|
1023
|
+
} finally {
|
|
1024
|
+
_iterator.f();
|
|
919
1025
|
}
|
|
920
1026
|
});
|
|
921
1027
|
if (Object.keys(params).length === 0) {
|
|
@@ -942,6 +1048,35 @@
|
|
|
942
1048
|
}
|
|
943
1049
|
}
|
|
944
1050
|
|
|
1051
|
+
/**
|
|
1052
|
+
* @typedef {typeof expandTypeDepFree} ExpandType
|
|
1053
|
+
* @typedef {ReturnType<ExpandType>} ExpandTypeReturnType
|
|
1054
|
+
*/
|
|
1055
|
+
/**
|
|
1056
|
+
* Parses JSDoc comments to extract parameter type information.
|
|
1057
|
+
*
|
|
1058
|
+
* @param {string} src - The JSDoc comment string to parse.
|
|
1059
|
+
* @param {ExpandType} [expandType] - An optional function to process the types found in the JSDoc.
|
|
1060
|
+
* @returns {Record<string, ExpandTypeReturnType> | undefined} An object mapping template names to their parsed types,
|
|
1061
|
+
* or `undefined` if no template tags were found.
|
|
1062
|
+
*/
|
|
1063
|
+
function parseJSDocTemplates(src) {
|
|
1064
|
+
var expandType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : expandTypeDepFree;
|
|
1065
|
+
var regexTemplateTyped = /@template \{(.*?)\} ([a-zA-Z0-9_$=]+)/g;
|
|
1066
|
+
var matches = _toConsumableArray(src.matchAll(regexTemplateTyped));
|
|
1067
|
+
if (!matches.length) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
/** @type {Record<string, ExpandTypeReturnType>} */
|
|
1071
|
+
var templates = Object.create(null);
|
|
1072
|
+
matches.forEach(function (_) {
|
|
1073
|
+
var type = expandType(_[1].trim());
|
|
1074
|
+
var name = _[2].trim();
|
|
1075
|
+
templates[name] = type;
|
|
1076
|
+
});
|
|
1077
|
+
return templates;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
945
1080
|
/**
|
|
946
1081
|
* Extracts the parameter name and its optionality from a JSDoc parameter string.
|
|
947
1082
|
*
|
|
@@ -2946,14 +3081,14 @@
|
|
|
2946
3081
|
}();
|
|
2947
3082
|
|
|
2948
3083
|
/** @typedef {import('@babel/types').Node } Node */
|
|
2949
|
-
/** @typedef {import(
|
|
2950
|
-
/** @typedef {import(
|
|
2951
|
-
/** @typedef {import('./stat.js').Stat
|
|
3084
|
+
/** @typedef {import('@babel/types').ClassMethod } ClassMethod */
|
|
3085
|
+
/** @typedef {import('@babel/types').ClassPrivateMethod} ClassPrivateMethod */
|
|
3086
|
+
/** @typedef {import('./stat.js').Stat } Stat */
|
|
2952
3087
|
/**
|
|
2953
3088
|
* @typedef {object} Options
|
|
2954
3089
|
* @property {boolean} [forceCurly] - Determines whether curly braces are enforced in Stringifier.
|
|
2955
3090
|
* @property {boolean} [validateDivision] - Indicates whether division operations should be validated.
|
|
2956
|
-
* @property {
|
|
3091
|
+
* @property {import('./parseJSDoc.js').ExpandType} [expandType] - A function that expands shorthand types into full descriptions.
|
|
2957
3092
|
* @property {string} [filename] - The name of a file to which the instance pertains.
|
|
2958
3093
|
* @property {boolean} [addHeader] - Whether to add import declarations headers. Defaults to true.
|
|
2959
3094
|
* @property {string[]} [ignoreLocations] - Ignore these locations because they are known false-positives.
|
|
@@ -3230,11 +3365,11 @@
|
|
|
3230
3365
|
}
|
|
3231
3366
|
/**
|
|
3232
3367
|
* @param {Node} node - The Babel AST node.
|
|
3233
|
-
* @returns {undefined
|
|
3368
|
+
* @returns {string|undefined} The JSDoc comment of `node`.
|
|
3234
3369
|
*/
|
|
3235
3370
|
}, {
|
|
3236
|
-
key: "
|
|
3237
|
-
value: function
|
|
3371
|
+
key: "getLeadingComment",
|
|
3372
|
+
value: function getLeadingComment(node) {
|
|
3238
3373
|
if (node.type === 'BlockStatement') {
|
|
3239
3374
|
node = this.parent;
|
|
3240
3375
|
}
|
|
@@ -3259,26 +3394,56 @@
|
|
|
3259
3394
|
if (leadingComments && leadingComments.length) {
|
|
3260
3395
|
var lastComment = leadingComments[leadingComments.length - 1];
|
|
3261
3396
|
if (lastComment.type === "CommentBlock") {
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3397
|
+
return lastComment.value;
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
/**
|
|
3402
|
+
* @param {Node} node - The Babel AST node.
|
|
3403
|
+
* @todo ESLint problem:
|
|
3404
|
+
* returns {import('./parseJSDoc.js').ParseJSDocReturnType} The return value of `parseJSDoc`
|
|
3405
|
+
* returns {Record<string, import('./parseJSDoc.js').ExpandTypeReturnType> | undefined} The
|
|
3406
|
+
* return value of `parseJSDoc`.
|
|
3407
|
+
* @returns {Record<string, any>|undefined} asd
|
|
3408
|
+
*/
|
|
3409
|
+
}, {
|
|
3410
|
+
key: "getJSDoc",
|
|
3411
|
+
value: function getJSDoc(node) {
|
|
3412
|
+
var comment = this.getLeadingComment(node);
|
|
3413
|
+
if (!comment) {
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3416
|
+
if (comment.includes('@event')) {
|
|
3417
|
+
return;
|
|
3418
|
+
}
|
|
3419
|
+
if (comment.includes('@ignoreRTI')) {
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
// Need to do same resolving as in: this.getLeadingComment(node)
|
|
3423
|
+
if (node.type === 'BlockStatement') {
|
|
3424
|
+
node = this.parent;
|
|
3425
|
+
}
|
|
3426
|
+
if (node.type === 'ClassMethod' && node.kind === 'set') {
|
|
3427
|
+
var paramName = this.getNameOfParam(node.params[0]);
|
|
3428
|
+
if (node.params.length !== 1) {
|
|
3429
|
+
this.warn("getJSDoc> setters require exactly one argument");
|
|
3430
|
+
}
|
|
3431
|
+
var setterType = parseJSDocSetter(comment, this.expandType);
|
|
3432
|
+
if (!setterType) {
|
|
3433
|
+
return;
|
|
3280
3434
|
}
|
|
3435
|
+
var _params = _defineProperty({}, paramName, setterType);
|
|
3436
|
+
return {
|
|
3437
|
+
templates: undefined,
|
|
3438
|
+
params: _params
|
|
3439
|
+
};
|
|
3281
3440
|
}
|
|
3441
|
+
var templates = parseJSDocTemplates(comment);
|
|
3442
|
+
var params = parseJSDoc(comment, this.expandType);
|
|
3443
|
+
return {
|
|
3444
|
+
templates: templates,
|
|
3445
|
+
params: params
|
|
3446
|
+
};
|
|
3282
3447
|
}
|
|
3283
3448
|
/**
|
|
3284
3449
|
* Retrieves the name of a parameter from a Babel AST node.
|
|
@@ -3299,8 +3464,7 @@
|
|
|
3299
3464
|
return param.left.name;
|
|
3300
3465
|
}
|
|
3301
3466
|
}
|
|
3302
|
-
|
|
3303
|
-
this.warn("unable to extra name from param in specified way - may contain too much information");
|
|
3467
|
+
this.warn("Unable to retrieve name from param in specified way - may contain too much information.");
|
|
3304
3468
|
return this.toSource(param);
|
|
3305
3469
|
}
|
|
3306
3470
|
}, {
|
|
@@ -3417,6 +3581,15 @@
|
|
|
3417
3581
|
stat.unchecked++;
|
|
3418
3582
|
return '';
|
|
3419
3583
|
}
|
|
3584
|
+
var templates = jsdoc.templates,
|
|
3585
|
+
params = jsdoc.params;
|
|
3586
|
+
if (!params) {
|
|
3587
|
+
console.warn("This should never happen, please check your input code.", this.getLeadingComment(node), {
|
|
3588
|
+
jsdoc: jsdoc
|
|
3589
|
+
});
|
|
3590
|
+
stat.unchecked++;
|
|
3591
|
+
return '';
|
|
3592
|
+
}
|
|
3420
3593
|
stat.checked++;
|
|
3421
3594
|
var spaces = this.spaces;
|
|
3422
3595
|
var out = '';
|
|
@@ -3425,17 +3598,21 @@
|
|
|
3425
3598
|
if (this.ignoreLocations.includes(loc)) {
|
|
3426
3599
|
return '// IGNORE RTI TYPE VALIDATIONS, KNOWN ISSUES\n';
|
|
3427
3600
|
}
|
|
3601
|
+
if (templates) {
|
|
3602
|
+
var tmp = JSON.stringify(templates, null, 2).replaceAll('\n', '\n' + spaces);
|
|
3603
|
+
out += "\n".concat(spaces, "const rtiTemplates = ").concat(tmp, ";");
|
|
3604
|
+
}
|
|
3428
3605
|
//out += `${spaces}/*${spaces} node.type=${node.type}\n${spaces}
|
|
3429
3606
|
// ${JSON.stringify(jsdoc)}\n${parent}\n${spaces}*/\n`;
|
|
3430
3607
|
var _loop = function _loop(name) {
|
|
3431
|
-
var type =
|
|
3608
|
+
var type = params[name];
|
|
3432
3609
|
var hasParam = _this2.nodeHasParamName(node, name);
|
|
3433
3610
|
if (!hasParam) {
|
|
3434
3611
|
var testNode = node;
|
|
3435
3612
|
if (node.type === 'BlockStatement') {
|
|
3436
3613
|
testNode = _this2.parent;
|
|
3437
3614
|
}
|
|
3438
|
-
var paramIndex = Object.keys(
|
|
3615
|
+
var paramIndex = Object.keys(params).findIndex(function (_) {
|
|
3439
3616
|
return _ === name;
|
|
3440
3617
|
});
|
|
3441
3618
|
var param = testNode.params[paramIndex];
|
|
@@ -3471,7 +3648,11 @@
|
|
|
3471
3648
|
continue;
|
|
3472
3649
|
}
|
|
3473
3650
|
var _t = JSON.stringify(type.elementType, null, 2).replaceAll('\n', '\n' + spaces);
|
|
3474
|
-
|
|
3651
|
+
if (templates) {
|
|
3652
|
+
out += "".concat(spaces, "if (!inspectTypeWithTemplates(").concat(element.name, ", ").concat(_t, ", '").concat(_loc, "', '").concat(name, "', rtiTemplates)) {\n");
|
|
3653
|
+
} else {
|
|
3654
|
+
out += "".concat(spaces, "if (!inspectType(").concat(element.name, ", ").concat(_t, ", '").concat(_loc, "', '").concat(name, "')) {\n");
|
|
3655
|
+
}
|
|
3475
3656
|
out += "".concat(spaces, " youCanAddABreakpointHere();\n").concat(spaces, "}\n");
|
|
3476
3657
|
}
|
|
3477
3658
|
} catch (err) {
|
|
@@ -3502,7 +3683,11 @@
|
|
|
3502
3683
|
continue;
|
|
3503
3684
|
}
|
|
3504
3685
|
var _t2 = JSON.stringify(subType, null, 2).replaceAll('\n', '\n' + spaces);
|
|
3505
|
-
|
|
3686
|
+
if (templates) {
|
|
3687
|
+
out += "".concat(spaces, "if (!inspectTypeWithTemplates(").concat(keyName, ", ").concat(_t2, ", '").concat(_loc, "', '").concat(name, "', rtiTemplates)) {\n");
|
|
3688
|
+
} else {
|
|
3689
|
+
out += "".concat(spaces, "if (!inspectType(").concat(keyName, ", ").concat(_t2, ", '").concat(_loc, "', '").concat(name, "')) {\n");
|
|
3690
|
+
}
|
|
3506
3691
|
out += "".concat(spaces, " youCanAddABreakpointHere();\n").concat(spaces, "}\n");
|
|
3507
3692
|
}
|
|
3508
3693
|
} catch (err) {
|
|
@@ -3540,11 +3725,15 @@
|
|
|
3540
3725
|
out += '\n';
|
|
3541
3726
|
first = false;
|
|
3542
3727
|
}
|
|
3543
|
-
|
|
3728
|
+
if (templates) {
|
|
3729
|
+
out += "".concat(spaces, "if (").concat(prevCheck, "!inspectTypeWithTemplates(").concat(name, ", ").concat(t, ", '").concat(loc, "', '").concat(name, "', rtiTemplates)) {\n");
|
|
3730
|
+
} else {
|
|
3731
|
+
out += "".concat(spaces, "if (").concat(prevCheck, "!inspectType(").concat(name, ", ").concat(t, ", '").concat(loc, "', '").concat(name, "')) {\n");
|
|
3732
|
+
}
|
|
3544
3733
|
out += "".concat(spaces, " youCanAddABreakpointHere();\n").concat(spaces, "}\n");
|
|
3545
3734
|
},
|
|
3546
3735
|
_ret;
|
|
3547
|
-
for (var name in
|
|
3736
|
+
for (var name in params) {
|
|
3548
3737
|
_ret = _loop(name);
|
|
3549
3738
|
if (_ret === 0) continue;
|
|
3550
3739
|
}
|
|
@@ -4122,6 +4311,7 @@
|
|
|
4122
4311
|
exports.nodeIsFunction = nodeIsFunction;
|
|
4123
4312
|
exports.parseJSDoc = parseJSDoc;
|
|
4124
4313
|
exports.parseJSDocSetter = parseJSDocSetter;
|
|
4314
|
+
exports.parseJSDocTemplates = parseJSDocTemplates;
|
|
4125
4315
|
exports.parseJSDocTypedef = parseJSDocTypedef;
|
|
4126
4316
|
exports.parseType = parseType;
|
|
4127
4317
|
exports.parseTypeBabelTS = parseTypeBabelTS;
|