@runtime-type-inspector/transpiler 3.3.6 → 4.0.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/index.cjs +211 -17
- package/index.mjs +203 -18
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -976,10 +976,22 @@
|
|
|
976
976
|
// name: [kwargs={}] The configuration parameters.
|
|
977
977
|
// name: [d = 1.0] Sample spacing
|
|
978
978
|
if (name[0] === '[') {
|
|
979
|
-
//
|
|
980
|
-
var
|
|
979
|
+
// Counting opening/closing brackets for perfect match
|
|
980
|
+
var openCloseCount = 1;
|
|
981
|
+
var i = 1;
|
|
982
|
+
for (; i < name.length; i++) {
|
|
983
|
+
var c = name[i];
|
|
984
|
+
if (c === '[') {
|
|
985
|
+
openCloseCount++;
|
|
986
|
+
} else if (c === ']') {
|
|
987
|
+
openCloseCount--;
|
|
988
|
+
}
|
|
989
|
+
if (openCloseCount === 0) {
|
|
990
|
+
break;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
981
993
|
// Afterwards name will be: d = 1.0
|
|
982
|
-
name = name.substring(1,
|
|
994
|
+
name = name.substring(1, i);
|
|
983
995
|
// mark it for the type:
|
|
984
996
|
optional = true;
|
|
985
997
|
}
|
|
@@ -1251,6 +1263,10 @@
|
|
|
1251
1263
|
_defineProperty(this, "forceCurly", false);
|
|
1252
1264
|
/** @type {Node[]} */
|
|
1253
1265
|
_defineProperty(this, "parents", []);
|
|
1266
|
+
/**
|
|
1267
|
+
* If we encounter JSX elements, we add React's createElement as import.
|
|
1268
|
+
*/
|
|
1269
|
+
_defineProperty(this, "addReactImport", false);
|
|
1254
1270
|
_defineProperty(this, "lastCommentBlockIndex", -1);
|
|
1255
1271
|
_defineProperty(this, "lastCommentLineIndex", -1);
|
|
1256
1272
|
_defineProperty(this, "numSpaces", 0);
|
|
@@ -1507,6 +1523,17 @@
|
|
|
1507
1523
|
}
|
|
1508
1524
|
return out;
|
|
1509
1525
|
}
|
|
1526
|
+
/**
|
|
1527
|
+
* @returns {string} The header.
|
|
1528
|
+
*/
|
|
1529
|
+
}, {
|
|
1530
|
+
key: "getHeader",
|
|
1531
|
+
value: function getHeader() {
|
|
1532
|
+
if (!this.addReactImport) {
|
|
1533
|
+
return '';
|
|
1534
|
+
}
|
|
1535
|
+
return "import {createElement} from 'react';\n";
|
|
1536
|
+
}
|
|
1510
1537
|
}, {
|
|
1511
1538
|
key: "parent",
|
|
1512
1539
|
get: function get() {
|
|
@@ -1889,7 +1916,10 @@
|
|
|
1889
1916
|
out += ' * ';
|
|
1890
1917
|
}
|
|
1891
1918
|
out += this.FunctionDeclarationParams(params);
|
|
1892
|
-
out += ' =>
|
|
1919
|
+
out += ' =>';
|
|
1920
|
+
if (body.type !== 'BlockStatement') {
|
|
1921
|
+
out += ' ';
|
|
1922
|
+
}
|
|
1893
1923
|
out += this.toSource(body);
|
|
1894
1924
|
return out;
|
|
1895
1925
|
}
|
|
@@ -2523,6 +2553,154 @@
|
|
|
2523
2553
|
// createMesh: createMesh$1\n
|
|
2524
2554
|
return "".concat(spaces).concat(right, " as ").concat(left);
|
|
2525
2555
|
}
|
|
2556
|
+
/**
|
|
2557
|
+
* @param {import("@babel/types").JSXAttribute} node - The Babel AST node.
|
|
2558
|
+
* @returns {string} Stringification of the node.
|
|
2559
|
+
*/
|
|
2560
|
+
}, {
|
|
2561
|
+
key: "JSXAttribute",
|
|
2562
|
+
value: function JSXAttribute(node) {
|
|
2563
|
+
var name = node.name,
|
|
2564
|
+
value = node.value;
|
|
2565
|
+
// console.log("JSXAttribute", {name, value});
|
|
2566
|
+
var keySource = this.toSource(name);
|
|
2567
|
+
// E.g. <audio controls/>
|
|
2568
|
+
if (value === null) {
|
|
2569
|
+
return "".concat(this.spaces).concat(keySource, ": true");
|
|
2570
|
+
}
|
|
2571
|
+
var valSource = this.toSource(value);
|
|
2572
|
+
if (keySource === valSource) {
|
|
2573
|
+
return this.spaces + keySource;
|
|
2574
|
+
}
|
|
2575
|
+
return "".concat(this.spaces).concat(keySource, ": ").concat(valSource);
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* @param {import("@babel/types").JSXElement} node - The Babel AST node.
|
|
2579
|
+
* @returns {string} Stringification of the node.
|
|
2580
|
+
*/
|
|
2581
|
+
}, {
|
|
2582
|
+
key: "JSXElement",
|
|
2583
|
+
value: function JSXElement(node) {
|
|
2584
|
+
var _this4 = this;
|
|
2585
|
+
this.addReactImport = true;
|
|
2586
|
+
var openingElement = node.openingElement;
|
|
2587
|
+
node.closingElement;
|
|
2588
|
+
var children = node.children;
|
|
2589
|
+
// console.log("JSXElement", {openingElement, closingElement, children});
|
|
2590
|
+
if (openingElement.type !== 'JSXOpeningElement') {
|
|
2591
|
+
debugger;
|
|
2592
|
+
}
|
|
2593
|
+
var spaces = this.spaces;
|
|
2594
|
+
var name = openingElement.name,
|
|
2595
|
+
attributes = openingElement.attributes;
|
|
2596
|
+
var out = '';
|
|
2597
|
+
out += 'createElement(';
|
|
2598
|
+
this.numSpaces++;
|
|
2599
|
+
spaces = this.spaces;
|
|
2600
|
+
out += '\n';
|
|
2601
|
+
out += spaces;
|
|
2602
|
+
var sourceName = this.toSource(name);
|
|
2603
|
+
if (sourceName[0] === sourceName[0].toLowerCase()) {
|
|
2604
|
+
// If something like 'div', it has to become "'div'"
|
|
2605
|
+
sourceName = JSON.stringify(sourceName);
|
|
2606
|
+
}
|
|
2607
|
+
out += sourceName;
|
|
2608
|
+
out += ',';
|
|
2609
|
+
if (attributes.length) {
|
|
2610
|
+
out += '\n';
|
|
2611
|
+
out += spaces;
|
|
2612
|
+
out += '{\n';
|
|
2613
|
+
this.numSpaces++;
|
|
2614
|
+
out += attributes.map(function (attr) {
|
|
2615
|
+
return _this4.toSource(attr) + ',\n';
|
|
2616
|
+
}).join('');
|
|
2617
|
+
this.numSpaces--;
|
|
2618
|
+
out += spaces;
|
|
2619
|
+
out += '}';
|
|
2620
|
+
} else {
|
|
2621
|
+
out += '\n';
|
|
2622
|
+
out += spaces;
|
|
2623
|
+
out += 'null';
|
|
2624
|
+
}
|
|
2625
|
+
if (children.length) {
|
|
2626
|
+
out += ',\n';
|
|
2627
|
+
var _iterator2 = _createForOfIteratorHelper(children),
|
|
2628
|
+
_step2;
|
|
2629
|
+
try {
|
|
2630
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
2631
|
+
var child = _step2.value;
|
|
2632
|
+
var source = this.toSource(child);
|
|
2633
|
+
if (!source.length) {
|
|
2634
|
+
continue;
|
|
2635
|
+
}
|
|
2636
|
+
out += spaces;
|
|
2637
|
+
out += source;
|
|
2638
|
+
out += ',\n';
|
|
2639
|
+
}
|
|
2640
|
+
} catch (err) {
|
|
2641
|
+
_iterator2.e(err);
|
|
2642
|
+
} finally {
|
|
2643
|
+
_iterator2.f();
|
|
2644
|
+
}
|
|
2645
|
+
} else {
|
|
2646
|
+
out += '\n';
|
|
2647
|
+
}
|
|
2648
|
+
this.numSpaces--;
|
|
2649
|
+
out += this.spaces;
|
|
2650
|
+
out += ')';
|
|
2651
|
+
return out;
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* @param {import("@babel/types").JSXIdentifier} node - The Babel AST node.
|
|
2655
|
+
* @returns {string} Stringification of the node.
|
|
2656
|
+
*/
|
|
2657
|
+
}, {
|
|
2658
|
+
key: "JSXIdentifier",
|
|
2659
|
+
value: function JSXIdentifier(node) {
|
|
2660
|
+
var name = node.name;
|
|
2661
|
+
// console.log('JSXIdentifier', {name});
|
|
2662
|
+
return name;
|
|
2663
|
+
}
|
|
2664
|
+
/**
|
|
2665
|
+
* @param {import("@babel/types").JSXExpressionContainer} node - The Babel AST node.
|
|
2666
|
+
* @returns {string} Stringification of the node.
|
|
2667
|
+
*/
|
|
2668
|
+
}, {
|
|
2669
|
+
key: "JSXExpressionContainer",
|
|
2670
|
+
value: function JSXExpressionContainer(node) {
|
|
2671
|
+
var expression = node.expression;
|
|
2672
|
+
// console.log('JSXExpressionContainer', {expression});
|
|
2673
|
+
return this.toSource(expression);
|
|
2674
|
+
}
|
|
2675
|
+
/**
|
|
2676
|
+
* @param {import("@babel/types").JSXMemberExpression} node - The Babel AST node.
|
|
2677
|
+
* @returns {string} Stringification of the node.
|
|
2678
|
+
*/
|
|
2679
|
+
}, {
|
|
2680
|
+
key: "JSXMemberExpression",
|
|
2681
|
+
value: function JSXMemberExpression(node) {
|
|
2682
|
+
var object = node.object,
|
|
2683
|
+
property = node.property;
|
|
2684
|
+
// console.log('JSXMemberExpression', 'object', object, 'property', property);
|
|
2685
|
+
var o = this.toSource(object);
|
|
2686
|
+
var p = this.toSource(property);
|
|
2687
|
+
return "".concat(o, ".").concat(p);
|
|
2688
|
+
}
|
|
2689
|
+
/**
|
|
2690
|
+
* @param {import("@babel/types").JSXText} node - The Babel AST node.
|
|
2691
|
+
* @returns {string} Stringification of the node.
|
|
2692
|
+
*/
|
|
2693
|
+
}, {
|
|
2694
|
+
key: "JSXText",
|
|
2695
|
+
value: function JSXText(node) {
|
|
2696
|
+
node.extra;
|
|
2697
|
+
var value = node.value;
|
|
2698
|
+
// console.log('JSXText', {extra, value});
|
|
2699
|
+
if (!value.trim().length) {
|
|
2700
|
+
return '';
|
|
2701
|
+
}
|
|
2702
|
+
return JSON.stringify(value);
|
|
2703
|
+
}
|
|
2526
2704
|
/**
|
|
2527
2705
|
* @param {import("@babel/types").Super} node - The Babel AST node.
|
|
2528
2706
|
* @returns {string} Stringification of the node.
|
|
@@ -3204,7 +3382,11 @@
|
|
|
3204
3382
|
} else {
|
|
3205
3383
|
out += ' {\n';
|
|
3206
3384
|
out += this.generateTypeChecks(node);
|
|
3385
|
+
var spaces = this.spaces;
|
|
3386
|
+
this.numSpaces++;
|
|
3207
3387
|
out += this.spaces + 'return ' + this.toSource(body) + ';\n';
|
|
3388
|
+
this.numSpaces--;
|
|
3389
|
+
out += spaces;
|
|
3208
3390
|
out += '}';
|
|
3209
3391
|
}
|
|
3210
3392
|
return out;
|
|
@@ -3250,6 +3432,7 @@
|
|
|
3250
3432
|
* @todo
|
|
3251
3433
|
* Once we went over every node, we can see if we really require registerTypef, registerClass etc.
|
|
3252
3434
|
* @returns {string} The import declaration header for importing RTI.
|
|
3435
|
+
* @override
|
|
3253
3436
|
*/
|
|
3254
3437
|
}, {
|
|
3255
3438
|
key: "getHeader",
|
|
@@ -3257,7 +3440,8 @@
|
|
|
3257
3440
|
if (!this.addHeader) {
|
|
3258
3441
|
return '';
|
|
3259
3442
|
}
|
|
3260
|
-
var header =
|
|
3443
|
+
var header = _get(_getPrototypeOf(Asserter.prototype), "getHeader", this).call(this);
|
|
3444
|
+
header += "import {inspectType, inspectTypeWithTemplates, youCanAddABreakpointHere, registerVariable";
|
|
3261
3445
|
if (this.validateDivision) {
|
|
3262
3446
|
header += ", validateDivision";
|
|
3263
3447
|
}
|
|
@@ -3686,7 +3870,8 @@
|
|
|
3686
3870
|
}
|
|
3687
3871
|
return 0; // continue
|
|
3688
3872
|
} else if (param.left.type === 'ObjectPattern') {
|
|
3689
|
-
|
|
3873
|
+
// If we have properties from JSDoc, we can create individual type inspections.
|
|
3874
|
+
if (type !== null && type !== void 0 && type.properties && Object.keys(type.properties).length) {
|
|
3690
3875
|
// Add a type assertion for each property of the ObjectPattern
|
|
3691
3876
|
var _iterator2 = _createForOfIteratorHelper(param.left.properties),
|
|
3692
3877
|
_step2;
|
|
@@ -3727,7 +3912,7 @@
|
|
|
3727
3912
|
_iterator2.f();
|
|
3728
3913
|
}
|
|
3729
3914
|
return 0; // continue
|
|
3730
|
-
} else
|
|
3915
|
+
} else {
|
|
3731
3916
|
// The case when we have an ObjectPattern with a @typedef
|
|
3732
3917
|
name = "arguments[".concat(paramIndex, "]");
|
|
3733
3918
|
}
|
|
@@ -3988,6 +4173,17 @@
|
|
|
3988
4173
|
return Asserter;
|
|
3989
4174
|
}(Stringifier);
|
|
3990
4175
|
|
|
4176
|
+
/**
|
|
4177
|
+
* We use the same options in different places, so it's nice to keep them in sync without
|
|
4178
|
+
* changing them in multiple locations.
|
|
4179
|
+
* @type {import('@babel/parser').ParserOptions}
|
|
4180
|
+
*/
|
|
4181
|
+
var parserOptions = {
|
|
4182
|
+
sourceType: 'module',
|
|
4183
|
+
createParenthesizedExpressions: true,
|
|
4184
|
+
plugins: ['jsx']
|
|
4185
|
+
};
|
|
4186
|
+
|
|
3991
4187
|
/**
|
|
3992
4188
|
* Simple facade which does all the processing. Processes the input
|
|
3993
4189
|
* source string, adding runtime type checks based on JSDoc comments.
|
|
@@ -4007,11 +4203,10 @@
|
|
|
4007
4203
|
function addTypeChecks(src, options) {
|
|
4008
4204
|
try {
|
|
4009
4205
|
var asserter = new Asserter(options);
|
|
4010
|
-
var ast = parser.parse(src,
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
var out = asserter.getHeader() + asserter.toSource(ast);
|
|
4206
|
+
var ast = parser.parse(src, parserOptions);
|
|
4207
|
+
// Must be called before getHeader since it's keeping an eye open for JSX elements.
|
|
4208
|
+
var source = asserter.toSource(ast);
|
|
4209
|
+
var out = asserter.getHeader() + source;
|
|
4015
4210
|
return out;
|
|
4016
4211
|
} catch (e) {
|
|
4017
4212
|
console.error(e);
|
|
@@ -4059,15 +4254,13 @@
|
|
|
4059
4254
|
* @returns {string | undefined} The new and once parsed and stringified code.
|
|
4060
4255
|
*/
|
|
4061
4256
|
function code2ast2code(code) {
|
|
4062
|
-
var
|
|
4063
|
-
var ast = parser.parse(code, {
|
|
4064
|
-
sourceType: 'module'
|
|
4065
|
-
});
|
|
4257
|
+
var ast = parser.parse(code, parserOptions);
|
|
4066
4258
|
if (!ast) {
|
|
4067
4259
|
return;
|
|
4068
4260
|
}
|
|
4261
|
+
var stringifier = new Stringifier();
|
|
4069
4262
|
var out = stringifier.toSource(ast);
|
|
4070
|
-
return out;
|
|
4263
|
+
return stringifier.getHeader() + out;
|
|
4071
4264
|
}
|
|
4072
4265
|
|
|
4073
4266
|
/**
|
|
@@ -4348,6 +4541,7 @@
|
|
|
4348
4541
|
exports.parseJSDocTypedef = parseJSDocTypedef;
|
|
4349
4542
|
exports.parseType = parseType;
|
|
4350
4543
|
exports.parseTypeBabelTS = parseTypeBabelTS;
|
|
4544
|
+
exports.parserOptions = parserOptions;
|
|
4351
4545
|
exports.requiredTypeofs = requiredTypeofs;
|
|
4352
4546
|
exports.simplifyType = simplifyType;
|
|
4353
4547
|
exports.toSourceBabelTS = toSourceBabelTS;
|
package/index.mjs
CHANGED
|
@@ -756,10 +756,22 @@ function parseJSDoc(src, expandType = expandTypeDepFree) {
|
|
|
756
756
|
// name: [kwargs={}] The configuration parameters.
|
|
757
757
|
// name: [d = 1.0] Sample spacing
|
|
758
758
|
if (name[0] === '[') {
|
|
759
|
-
//
|
|
760
|
-
|
|
759
|
+
// Counting opening/closing brackets for perfect match
|
|
760
|
+
let openCloseCount = 1;
|
|
761
|
+
let i = 1;
|
|
762
|
+
for (; i < name.length; i++) {
|
|
763
|
+
const c = name[i];
|
|
764
|
+
if (c === '[') {
|
|
765
|
+
openCloseCount++;
|
|
766
|
+
} else if (c === ']') {
|
|
767
|
+
openCloseCount--;
|
|
768
|
+
}
|
|
769
|
+
if (openCloseCount === 0) {
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
761
773
|
// Afterwards name will be: d = 1.0
|
|
762
|
-
name = name.substring(1,
|
|
774
|
+
name = name.substring(1, i);
|
|
763
775
|
// mark it for the type:
|
|
764
776
|
optional = true;
|
|
765
777
|
}
|
|
@@ -1009,6 +1021,10 @@ class Stringifier {
|
|
|
1009
1021
|
this.forceCurly = false;
|
|
1010
1022
|
/** @type {Node[]} */
|
|
1011
1023
|
this.parents = [];
|
|
1024
|
+
/**
|
|
1025
|
+
* If we encounter JSX elements, we add React's createElement as import.
|
|
1026
|
+
*/
|
|
1027
|
+
this.addReactImport = false;
|
|
1012
1028
|
this.lastCommentBlockIndex = -1;
|
|
1013
1029
|
this.lastCommentLineIndex = -1;
|
|
1014
1030
|
this.numSpaces = 0;
|
|
@@ -1246,6 +1262,15 @@ class Stringifier {
|
|
|
1246
1262
|
}
|
|
1247
1263
|
return out;
|
|
1248
1264
|
}
|
|
1265
|
+
/**
|
|
1266
|
+
* @returns {string} The header.
|
|
1267
|
+
*/
|
|
1268
|
+
getHeader() {
|
|
1269
|
+
if (!this.addReactImport) {
|
|
1270
|
+
return '';
|
|
1271
|
+
}
|
|
1272
|
+
return "import {createElement} from 'react';\n";
|
|
1273
|
+
}
|
|
1249
1274
|
get parent() {
|
|
1250
1275
|
return this.parents[this.parents.length - 2];
|
|
1251
1276
|
}
|
|
@@ -1606,7 +1631,10 @@ class Stringifier {
|
|
|
1606
1631
|
out += ' * ';
|
|
1607
1632
|
}
|
|
1608
1633
|
out += this.FunctionDeclarationParams(params);
|
|
1609
|
-
out += ' =>
|
|
1634
|
+
out += ' =>';
|
|
1635
|
+
if (body.type !== 'BlockStatement') {
|
|
1636
|
+
out += ' ';
|
|
1637
|
+
}
|
|
1610
1638
|
out += this.toSource(body);
|
|
1611
1639
|
return out;
|
|
1612
1640
|
}
|
|
@@ -2237,6 +2265,146 @@ class Stringifier {
|
|
|
2237
2265
|
// createMesh: createMesh$1\n
|
|
2238
2266
|
return `${spaces}${right} as ${left}`;
|
|
2239
2267
|
}
|
|
2268
|
+
/**
|
|
2269
|
+
* @param {import("@babel/types").JSXAttribute} node - The Babel AST node.
|
|
2270
|
+
* @returns {string} Stringification of the node.
|
|
2271
|
+
*/
|
|
2272
|
+
JSXAttribute(node) {
|
|
2273
|
+
const {
|
|
2274
|
+
name,
|
|
2275
|
+
value
|
|
2276
|
+
} = node;
|
|
2277
|
+
// console.log("JSXAttribute", {name, value});
|
|
2278
|
+
const keySource = this.toSource(name);
|
|
2279
|
+
// E.g. <audio controls/>
|
|
2280
|
+
if (value === null) {
|
|
2281
|
+
return `${this.spaces}${keySource}: true`;
|
|
2282
|
+
}
|
|
2283
|
+
const valSource = this.toSource(value);
|
|
2284
|
+
if (keySource === valSource) {
|
|
2285
|
+
return this.spaces + keySource;
|
|
2286
|
+
}
|
|
2287
|
+
return `${this.spaces}${keySource}: ${valSource}`;
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2290
|
+
* @param {import("@babel/types").JSXElement} node - The Babel AST node.
|
|
2291
|
+
* @returns {string} Stringification of the node.
|
|
2292
|
+
*/
|
|
2293
|
+
JSXElement(node) {
|
|
2294
|
+
this.addReactImport = true;
|
|
2295
|
+
const {
|
|
2296
|
+
openingElement,
|
|
2297
|
+
closingElement,
|
|
2298
|
+
children
|
|
2299
|
+
} = node;
|
|
2300
|
+
// console.log("JSXElement", {openingElement, closingElement, children});
|
|
2301
|
+
if (openingElement.type !== 'JSXOpeningElement') {
|
|
2302
|
+
debugger;
|
|
2303
|
+
}
|
|
2304
|
+
let {
|
|
2305
|
+
spaces
|
|
2306
|
+
} = this;
|
|
2307
|
+
const {
|
|
2308
|
+
name,
|
|
2309
|
+
attributes
|
|
2310
|
+
} = openingElement;
|
|
2311
|
+
let out = '';
|
|
2312
|
+
out += 'createElement(';
|
|
2313
|
+
this.numSpaces++;
|
|
2314
|
+
spaces = this.spaces;
|
|
2315
|
+
out += '\n';
|
|
2316
|
+
out += spaces;
|
|
2317
|
+
let sourceName = this.toSource(name);
|
|
2318
|
+
if (sourceName[0] === sourceName[0].toLowerCase()) {
|
|
2319
|
+
// If something like 'div', it has to become "'div'"
|
|
2320
|
+
sourceName = JSON.stringify(sourceName);
|
|
2321
|
+
}
|
|
2322
|
+
out += sourceName;
|
|
2323
|
+
out += ',';
|
|
2324
|
+
if (attributes.length) {
|
|
2325
|
+
out += '\n';
|
|
2326
|
+
out += spaces;
|
|
2327
|
+
out += '{\n';
|
|
2328
|
+
this.numSpaces++;
|
|
2329
|
+
out += attributes.map(attr => this.toSource(attr) + ',\n').join('');
|
|
2330
|
+
this.numSpaces--;
|
|
2331
|
+
out += spaces;
|
|
2332
|
+
out += '}';
|
|
2333
|
+
} else {
|
|
2334
|
+
out += '\n';
|
|
2335
|
+
out += spaces;
|
|
2336
|
+
out += 'null';
|
|
2337
|
+
}
|
|
2338
|
+
if (children.length) {
|
|
2339
|
+
out += ',\n';
|
|
2340
|
+
for (const child of children) {
|
|
2341
|
+
const source = this.toSource(child);
|
|
2342
|
+
if (!source.length) {
|
|
2343
|
+
continue;
|
|
2344
|
+
}
|
|
2345
|
+
out += spaces;
|
|
2346
|
+
out += source;
|
|
2347
|
+
out += ',\n';
|
|
2348
|
+
}
|
|
2349
|
+
} else {
|
|
2350
|
+
out += '\n';
|
|
2351
|
+
}
|
|
2352
|
+
this.numSpaces--;
|
|
2353
|
+
out += this.spaces;
|
|
2354
|
+
out += ')';
|
|
2355
|
+
return out;
|
|
2356
|
+
}
|
|
2357
|
+
/**
|
|
2358
|
+
* @param {import("@babel/types").JSXIdentifier} node - The Babel AST node.
|
|
2359
|
+
* @returns {string} Stringification of the node.
|
|
2360
|
+
*/
|
|
2361
|
+
JSXIdentifier(node) {
|
|
2362
|
+
const {
|
|
2363
|
+
name
|
|
2364
|
+
} = node;
|
|
2365
|
+
// console.log('JSXIdentifier', {name});
|
|
2366
|
+
return name;
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* @param {import("@babel/types").JSXExpressionContainer} node - The Babel AST node.
|
|
2370
|
+
* @returns {string} Stringification of the node.
|
|
2371
|
+
*/
|
|
2372
|
+
JSXExpressionContainer(node) {
|
|
2373
|
+
const {
|
|
2374
|
+
expression
|
|
2375
|
+
} = node;
|
|
2376
|
+
// console.log('JSXExpressionContainer', {expression});
|
|
2377
|
+
return this.toSource(expression);
|
|
2378
|
+
}
|
|
2379
|
+
/**
|
|
2380
|
+
* @param {import("@babel/types").JSXMemberExpression} node - The Babel AST node.
|
|
2381
|
+
* @returns {string} Stringification of the node.
|
|
2382
|
+
*/
|
|
2383
|
+
JSXMemberExpression(node) {
|
|
2384
|
+
const {
|
|
2385
|
+
object,
|
|
2386
|
+
property
|
|
2387
|
+
} = node;
|
|
2388
|
+
// console.log('JSXMemberExpression', 'object', object, 'property', property);
|
|
2389
|
+
const o = this.toSource(object);
|
|
2390
|
+
const p = this.toSource(property);
|
|
2391
|
+
return `${o}.${p}`;
|
|
2392
|
+
}
|
|
2393
|
+
/**
|
|
2394
|
+
* @param {import("@babel/types").JSXText} node - The Babel AST node.
|
|
2395
|
+
* @returns {string} Stringification of the node.
|
|
2396
|
+
*/
|
|
2397
|
+
JSXText(node) {
|
|
2398
|
+
const {
|
|
2399
|
+
extra,
|
|
2400
|
+
value
|
|
2401
|
+
} = node;
|
|
2402
|
+
// console.log('JSXText', {extra, value});
|
|
2403
|
+
if (!value.trim().length) {
|
|
2404
|
+
return '';
|
|
2405
|
+
}
|
|
2406
|
+
return JSON.stringify(value);
|
|
2407
|
+
}
|
|
2240
2408
|
/**
|
|
2241
2409
|
* @param {import("@babel/types").Super} node - The Babel AST node.
|
|
2242
2410
|
* @returns {string} Stringification of the node.
|
|
@@ -2905,7 +3073,13 @@ class Asserter extends Stringifier {
|
|
|
2905
3073
|
} else {
|
|
2906
3074
|
out += ' {\n';
|
|
2907
3075
|
out += this.generateTypeChecks(node);
|
|
3076
|
+
const {
|
|
3077
|
+
spaces
|
|
3078
|
+
} = this;
|
|
3079
|
+
this.numSpaces++;
|
|
2908
3080
|
out += this.spaces + 'return ' + this.toSource(body) + ';\n';
|
|
3081
|
+
this.numSpaces--;
|
|
3082
|
+
out += spaces;
|
|
2909
3083
|
out += '}';
|
|
2910
3084
|
}
|
|
2911
3085
|
return out;
|
|
@@ -2947,12 +3121,14 @@ class Asserter extends Stringifier {
|
|
|
2947
3121
|
* @todo
|
|
2948
3122
|
* Once we went over every node, we can see if we really require registerTypef, registerClass etc.
|
|
2949
3123
|
* @returns {string} The import declaration header for importing RTI.
|
|
3124
|
+
* @override
|
|
2950
3125
|
*/
|
|
2951
3126
|
getHeader() {
|
|
2952
3127
|
if (!this.addHeader) {
|
|
2953
3128
|
return '';
|
|
2954
3129
|
}
|
|
2955
|
-
let header =
|
|
3130
|
+
let header = super.getHeader();
|
|
3131
|
+
header += "import {inspectType, inspectTypeWithTemplates, youCanAddABreakpointHere, registerVariable";
|
|
2956
3132
|
if (this.validateDivision) {
|
|
2957
3133
|
header += ", validateDivision";
|
|
2958
3134
|
}
|
|
@@ -3366,7 +3542,8 @@ class Asserter extends Stringifier {
|
|
|
3366
3542
|
}
|
|
3367
3543
|
continue;
|
|
3368
3544
|
} else if (param.left.type === 'ObjectPattern') {
|
|
3369
|
-
|
|
3545
|
+
// If we have properties from JSDoc, we can create individual type inspections.
|
|
3546
|
+
if (type != null && type.properties && Object.keys(type.properties).length) {
|
|
3370
3547
|
// Add a type assertion for each property of the ObjectPattern
|
|
3371
3548
|
for (const property of param.left.properties) {
|
|
3372
3549
|
if (property.type !== 'ObjectProperty') {
|
|
@@ -3398,7 +3575,7 @@ class Asserter extends Stringifier {
|
|
|
3398
3575
|
out += `${spaces} youCanAddABreakpointHere();\n${spaces}}\n`;
|
|
3399
3576
|
}
|
|
3400
3577
|
continue;
|
|
3401
|
-
} else
|
|
3578
|
+
} else {
|
|
3402
3579
|
// The case when we have an ObjectPattern with a @typedef
|
|
3403
3580
|
name = `arguments[${paramIndex}]`;
|
|
3404
3581
|
}
|
|
@@ -3618,6 +3795,17 @@ class Asserter extends Stringifier {
|
|
|
3618
3795
|
}
|
|
3619
3796
|
}
|
|
3620
3797
|
|
|
3798
|
+
/**
|
|
3799
|
+
* We use the same options in different places, so it's nice to keep them in sync without
|
|
3800
|
+
* changing them in multiple locations.
|
|
3801
|
+
* @type {import('@babel/parser').ParserOptions}
|
|
3802
|
+
*/
|
|
3803
|
+
const parserOptions = {
|
|
3804
|
+
sourceType: 'module',
|
|
3805
|
+
createParenthesizedExpressions: true,
|
|
3806
|
+
plugins: ['jsx']
|
|
3807
|
+
};
|
|
3808
|
+
|
|
3621
3809
|
/**
|
|
3622
3810
|
* Simple facade which does all the processing. Processes the input
|
|
3623
3811
|
* source string, adding runtime type checks based on JSDoc comments.
|
|
@@ -3637,11 +3825,10 @@ class Asserter extends Stringifier {
|
|
|
3637
3825
|
function addTypeChecks(src, options) {
|
|
3638
3826
|
try {
|
|
3639
3827
|
const asserter = new Asserter(options);
|
|
3640
|
-
const ast = parse(src,
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
const out = asserter.getHeader() + asserter.toSource(ast);
|
|
3828
|
+
const ast = parse(src, parserOptions);
|
|
3829
|
+
// Must be called before getHeader since it's keeping an eye open for JSX elements.
|
|
3830
|
+
const source = asserter.toSource(ast);
|
|
3831
|
+
const out = asserter.getHeader() + source;
|
|
3645
3832
|
return out;
|
|
3646
3833
|
} catch (e) {
|
|
3647
3834
|
console.error(e);
|
|
@@ -3689,15 +3876,13 @@ function ast2jsonForComparison(ast) {
|
|
|
3689
3876
|
* @returns {string | undefined} The new and once parsed and stringified code.
|
|
3690
3877
|
*/
|
|
3691
3878
|
function code2ast2code(code) {
|
|
3692
|
-
const
|
|
3693
|
-
const ast = parse(code, {
|
|
3694
|
-
sourceType: 'module'
|
|
3695
|
-
});
|
|
3879
|
+
const ast = parse(code, parserOptions);
|
|
3696
3880
|
if (!ast) {
|
|
3697
3881
|
return;
|
|
3698
3882
|
}
|
|
3883
|
+
const stringifier = new Stringifier();
|
|
3699
3884
|
const out = stringifier.toSource(ast);
|
|
3700
|
-
return out;
|
|
3885
|
+
return stringifier.getHeader() + out;
|
|
3701
3886
|
}
|
|
3702
3887
|
|
|
3703
3888
|
/**
|
|
@@ -3959,4 +4144,4 @@ function toSourceBabelTS(node) {
|
|
|
3959
4144
|
}
|
|
3960
4145
|
}
|
|
3961
4146
|
|
|
3962
|
-
export { Asserter, Stringifier, addTypeChecks, ast2json, ast2jsonForComparison, code2ast2code, compareAST, expandType, expandTypeBabelTS, expandTypeDepFree, extractCurlyContent, extractNameAndOptionality, nodeIsFunction, parseJSDoc, parseJSDocSetter, parseJSDocTemplates, parseJSDocTypedef, parseType, parseTypeBabelTS, requiredTypeofs, simplifyType, toSourceBabelTS, toSourceTS, trimEndSpaces };
|
|
4147
|
+
export { Asserter, Stringifier, addTypeChecks, ast2json, ast2jsonForComparison, code2ast2code, compareAST, expandType, expandTypeBabelTS, expandTypeDepFree, extractCurlyContent, extractNameAndOptionality, nodeIsFunction, parseJSDoc, parseJSDocSetter, parseJSDocTemplates, parseJSDocTypedef, parseType, parseTypeBabelTS, parserOptions, requiredTypeofs, simplifyType, toSourceBabelTS, toSourceTS, trimEndSpaces };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bin": "bin.js",
|
|
3
3
|
"name": "@runtime-type-inspector/transpiler",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"description": "Validating JSDoc types at runtime for high-quality types - Trust is good, control is better.",
|
|
6
6
|
"main": "index.cjs",
|
|
7
7
|
"module": "index.mjs",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"homepage": "https://github.com/kungfooman/RuntimeTypeInspector.js#readme",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@babel/parser": "^7.23.0",
|
|
22
|
-
"@runtime-type-inspector/runtime": "^
|
|
22
|
+
"@runtime-type-inspector/runtime": "^4.0.0",
|
|
23
23
|
"typescript": "^5.1.6"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|