1
- import { requiredTypeofs } from './expandType.js' ;
2
- import { expandTypeDepFree } from './expandTypeDepFree.js' ;
3
- import { nodeIsFunction } from './nodeIsFunction.js' ;
4
- import { parseJSDoc } from './parseJSDoc.js' ;
5
- import { parseJSDocSetter } from './parseJSDocSetter.js' ;
6
- import { parseJSDocTypedef } from './parseJSDocTypedef.js' ;
7
- import { statReset } from './stat.js' ;
8
- import { Stringifier } from './Stringifier.js' ;
1
+ import { requiredTypeofs } from './expandType.js' ;
2
+ import { expandTypeDepFree } from './expandTypeDepFree.js' ;
3
+ import { nodeIsFunction } from './nodeIsFunction.js' ;
4
+ import { parseJSDoc } from './parseJSDoc.js' ;
5
+ import { parseJSDocSetter } from './parseJSDocSetter.js' ;
6
+ import { parseJSDocTemplates } from './parseJSDocTemplates.js' ;
7
+ import { parseJSDocTypedef } from './parseJSDocTypedef.js' ;
8
+ import { statReset } from './stat.js' ;
9
+ import { Stringifier } from './Stringifier.js' ;
9
10
/** @typedef {import('@babel/types').Node } Node */
10
- /** @typedef {import(" @babel/types" ).ClassMethod } ClassMethod */
11
- /** @typedef {import(" @babel/types" ).ClassPrivateMethod } ClassPrivateMethod */
12
- /** @typedef {import('./stat.js').Stat } Stat */
11
+ /** @typedef {import(' @babel/types' ).ClassMethod } ClassMethod */
12
+ /** @typedef {import(' @babel/types' ).ClassPrivateMethod } ClassPrivateMethod */
13
+ /** @typedef {import('./stat.js').Stat } Stat */
13
14
/**
14
15
* @typedef {object } Options
15
16
* @property {boolean } [forceCurly] - Determines whether curly braces are enforced in Stringifier.
16
17
* @property {boolean } [validateDivision] - Indicates whether division operations should be validated.
17
- * @property {Function } [expandType] - A function that expands shorthand types into full descriptions.
18
+ * @property {import('./parseJSDoc.js').ExpandType } [expandType] - A function that expands shorthand types into full descriptions.
18
19
* @property {string } [filename] - The name of a file to which the instance pertains.
19
20
* @property {boolean } [addHeader] - Whether to add import declarations headers. Defaults to true.
20
21
* @property {string[] } [ignoreLocations] - Ignore these locations because they are known false-positives.
@@ -219,9 +220,9 @@ class Asserter extends Stringifier {
219
220
}
220
221
/**
221
222
* @param {Node } node - The Babel AST node.
222
- * @returns {undefined | {} } The return value of `parseJSDoc `.
223
+ * @returns {string|undefined } The JSDoc comment of `node `.
223
224
*/
224
- getJSDoc ( node ) {
225
+ getLeadingComment ( node ) {
225
226
if ( node . type === 'BlockStatement' ) {
226
227
node = this . parent ;
227
228
}
@@ -245,26 +246,48 @@ class Asserter extends Stringifier {
245
246
if ( leadingComments && leadingComments . length ) {
246
247
const lastComment = leadingComments [ leadingComments . length - 1 ] ;
247
248
if ( lastComment . type === "CommentBlock" ) {
248
- if ( lastComment . value . includes ( '@event' ) ) {
249
- return ;
250
- }
251
- if ( node . type === 'ClassMethod' && node . kind === 'set' ) {
252
- const paramName = this . getNameOfParam ( node . params [ 0 ] ) ;
253
- if ( node . params . length !== 1 ) {
254
- this . warn ( "getJSDoc> setters require exactly one argument" ) ;
255
- }
256
- const setterType = parseJSDocSetter ( lastComment . value , this . expandType ) ;
257
- if ( ! setterType ) {
258
- return ;
259
- }
260
- return { [ paramName ] : setterType } ;
261
- }
262
- if ( lastComment . value . includes ( '@ignoreRTI' ) ) {
263
- return ;
264
- }
265
- return parseJSDoc ( lastComment . value , this . expandType ) ;
249
+ return lastComment . value ;
250
+ }
251
+ }
252
+ }
253
+ /**
254
+ * @param {Node } node - The Babel AST node.
255
+ * @todo ESLint problem:
256
+ * returns {import('./parseJSDoc.js').ParseJSDocReturnType} The return value of `parseJSDoc`
257
+ * returns {Record<string, import('./parseJSDoc.js').ExpandTypeReturnType> | undefined} The
258
+ * return value of `parseJSDoc`.
259
+ * @returns {Record<string, any>|undefined } asd
260
+ */
261
+ getJSDoc ( node ) {
262
+ const comment = this . getLeadingComment ( node ) ;
263
+ if ( ! comment ) {
264
+ return ;
265
+ }
266
+ if ( comment . includes ( '@event' ) ) {
267
+ return ;
268
+ }
269
+ if ( comment . includes ( '@ignoreRTI' ) ) {
270
+ return ;
271
+ }
272
+ // Need to do same resolving as in: this.getLeadingComment(node)
273
+ if ( node . type === 'BlockStatement' ) {
274
+ node = this . parent ;
275
+ }
276
+ if ( node . type === 'ClassMethod' && node . kind === 'set' ) {
277
+ const paramName = this . getNameOfParam ( node . params [ 0 ] ) ;
278
+ if ( node . params . length !== 1 ) {
279
+ this . warn ( "getJSDoc> setters require exactly one argument" ) ;
280
+ }
281
+ const setterType = parseJSDocSetter ( comment , this . expandType ) ;
282
+ if ( ! setterType ) {
283
+ return ;
266
284
}
285
+ const params = { [ paramName ] : setterType } ;
286
+ return { templates : undefined , params} ;
267
287
}
288
+ const templates = parseJSDocTemplates ( comment ) ;
289
+ const params = parseJSDoc ( comment , this . expandType ) ;
290
+ return { templates, params} ;
268
291
}
269
292
/**
270
293
* Retrieves the name of a parameter from a Babel AST node.
@@ -283,8 +306,7 @@ class Asserter extends Stringifier {
283
306
return param . left . name ;
284
307
}
285
308
}
286
- debugger ;
287
- this . warn ( "unable to extra name from param in specified way - may contain too much information" ) ;
309
+ this . warn ( "Unable to retrieve name from param in specified way - may contain too much information." ) ;
288
310
return this . toSource ( param ) ;
289
311
}
290
312
statsReset ( ) {
@@ -391,6 +413,12 @@ class Asserter extends Stringifier {
391
413
stat . unchecked ++ ;
392
414
return '' ;
393
415
}
416
+ const { templates, params} = jsdoc ;
417
+ if ( ! params ) {
418
+ console . warn ( "This should never happen, please check your input code." , this . getLeadingComment ( node ) , { jsdoc} ) ;
419
+ stat . unchecked ++ ;
420
+ return '' ;
421
+ }
394
422
stat . checked ++ ;
395
423
const { spaces} = this ;
396
424
let out = '' ;
@@ -399,17 +427,21 @@ class Asserter extends Stringifier {
399
427
if ( this . ignoreLocations . includes ( loc ) ) {
400
428
return '// IGNORE RTI TYPE VALIDATIONS, KNOWN ISSUES\n' ;
401
429
}
430
+ if ( templates ) {
431
+ const tmp = JSON . stringify ( templates , null , 2 ) . replaceAll ( '\n' , '\n' + spaces ) ;
432
+ out += `\n${ spaces } const rtiTemplates = ${ tmp } ;` ;
433
+ }
402
434
//out += `${spaces}/*${spaces} node.type=${node.type}\n${spaces}
403
435
// ${JSON.stringify(jsdoc)}\n${parent}\n${spaces}*/\n`;
404
- for ( let name in jsdoc ) {
405
- const type = jsdoc [ name ] ;
436
+ for ( let name in params ) {
437
+ const type = params [ name ] ;
406
438
const hasParam = this . nodeHasParamName ( node , name ) ;
407
439
if ( ! hasParam ) {
408
440
let testNode = node ;
409
441
if ( node . type === 'BlockStatement' ) {
410
442
testNode = this . parent ;
411
443
}
412
- const paramIndex = Object . keys ( jsdoc ) . findIndex ( _ => _ === name ) ;
444
+ const paramIndex = Object . keys ( params ) . findIndex ( _ => _ === name ) ;
413
445
const param = testNode . params [ paramIndex ] ;
414
446
if ( param ) {
415
447
const isObjectPattern = param . type === 'ObjectPattern' ;
@@ -439,7 +471,11 @@ class Asserter extends Stringifier {
439
471
continue ;
440
472
}
441
473
const t = JSON . stringify ( type . elementType , null , 2 ) . replaceAll ( '\n' , '\n' + spaces ) ;
442
- out += `${ spaces } if (!inspectType(${ element . name } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
474
+ if ( templates ) {
475
+ out += `${ spaces } if (!inspectTypeWithTemplates(${ element . name } , ${ t } , '${ loc } ', '${ name } ', rtiTemplates)) {\n` ;
476
+ } else {
477
+ out += `${ spaces } if (!inspectType(${ element . name } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
478
+ }
443
479
out += `${ spaces } youCanAddABreakpointHere();\n${ spaces } }\n` ;
444
480
}
445
481
continue ;
@@ -465,7 +501,11 @@ class Asserter extends Stringifier {
465
501
continue ;
466
502
}
467
503
const t = JSON . stringify ( subType , null , 2 ) . replaceAll ( '\n' , '\n' + spaces ) ;
468
- out += `${ spaces } if (!inspectType(${ keyName } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
504
+ if ( templates ) {
505
+ out += `${ spaces } if (!inspectTypeWithTemplates(${ keyName } , ${ t } , '${ loc } ', '${ name } ', rtiTemplates)) {\n` ;
506
+ } else {
507
+ out += `${ spaces } if (!inspectType(${ keyName } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
508
+ }
469
509
out += `${ spaces } youCanAddABreakpointHere();\n${ spaces } }\n` ;
470
510
}
471
511
continue ;
@@ -503,7 +543,11 @@ class Asserter extends Stringifier {
503
543
out += '\n' ;
504
544
first = false ;
505
545
}
506
- out += `${ spaces } if (${ prevCheck } !inspectType(${ name } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
546
+ if ( templates ) {
547
+ out += `${ spaces } if (${ prevCheck } !inspectTypeWithTemplates(${ name } , ${ t } , '${ loc } ', '${ name } ', rtiTemplates)) {\n` ;
548
+ } else {
549
+ out += `${ spaces } if (${ prevCheck } !inspectType(${ name } , ${ t } , '${ loc } ', '${ name } ')) {\n` ;
550
+ }
507
551
out += `${ spaces } youCanAddABreakpointHere();\n${ spaces } }\n` ;
508
552
}
509
553
return out ;
0 commit comments