@@ -271,6 +271,48 @@ module.exports = {
271
271
return members . reverse ( )
272
272
} ,
273
273
274
+ /**
275
+ * Gets the property name of a given node.
276
+ * @param {ASTNode } node - The node to get.
277
+ * @return {string|null } The property name if static. Otherwise, null.
278
+ */
279
+ getStaticPropertyName ( node ) {
280
+ let prop
281
+ switch ( node && node . type ) {
282
+ case 'Property' :
283
+ case 'MethodDefinition' :
284
+ prop = node . key
285
+ break
286
+ case 'MemberExpression' :
287
+ prop = node . property
288
+ break
289
+ case 'Literal' :
290
+ case 'TemplateLiteral' :
291
+ case 'Identifier' :
292
+ prop = node
293
+ break
294
+ // no default
295
+ }
296
+
297
+ switch ( prop && prop . type ) {
298
+ case 'Literal' :
299
+ return String ( prop . value )
300
+ case 'TemplateLiteral' :
301
+ if ( prop . expressions . length === 0 && prop . quasis . length === 1 ) {
302
+ return prop . quasis [ 0 ] . value . cooked
303
+ }
304
+ break
305
+ case 'Identifier' :
306
+ if ( ! node . computed ) {
307
+ return prop . name
308
+ }
309
+ break
310
+ // no default
311
+ }
312
+
313
+ return null
314
+ } ,
315
+
274
316
/**
275
317
* Get all computed properties by looking at all component's properties
276
318
* @param {ObjectExpression } Object with component definition
@@ -397,5 +439,72 @@ module.exports = {
397
439
cb ( node . arguments . slice ( - 1 ) [ 0 ] )
398
440
}
399
441
}
442
+ } ,
443
+
444
+ /**
445
+ * Return generator with all properties
446
+ * @param {ASTNode } node Node to check
447
+ * @param {string } groupName Name of parent group
448
+ */
449
+ * iterateProperties ( node , groups ) {
450
+ const nodes = node . properties . filter ( p => p . type === 'Property' && groups . has ( this . getStaticPropertyName ( p . key ) ) )
451
+ for ( const item of nodes ) {
452
+ const name = this . getStaticPropertyName ( item . key )
453
+ if ( item . value . type === 'ArrayExpression' ) {
454
+ yield * this . iterateArrayExpression ( item . value , name )
455
+ } else if ( item . value . type === 'ObjectExpression' ) {
456
+ yield * this . iterateObjectExpression ( item . value , name )
457
+ } else if ( item . value . type === 'FunctionExpression' ) {
458
+ yield * this . iterateFunctionExpression ( item . value , name )
459
+ }
460
+ }
461
+ } ,
462
+
463
+ /**
464
+ * Return generator with all elements inside ArrayExpression
465
+ * @param {ASTNode } node Node to check
466
+ * @param {string } groupName Name of parent group
467
+ */
468
+ * iterateArrayExpression ( node , groupName ) {
469
+ assert ( node . type === 'ArrayExpression' )
470
+ for ( const item of node . elements ) {
471
+ const name = this . getStaticPropertyName ( item )
472
+ if ( name ) {
473
+ const obj = { name, groupName, node : item }
474
+ yield obj
475
+ }
476
+ }
477
+ } ,
478
+
479
+ /**
480
+ * Return generator with all elements inside ObjectExpression
481
+ * @param {ASTNode } node Node to check
482
+ * @param {string } groupName Name of parent group
483
+ */
484
+ * iterateObjectExpression ( node , groupName ) {
485
+ assert ( node . type === 'ObjectExpression' )
486
+ for ( const item of node . properties ) {
487
+ const name = this . getStaticPropertyName ( item )
488
+ if ( name ) {
489
+ const obj = { name, groupName, node : item . key }
490
+ yield obj
491
+ }
492
+ }
493
+ } ,
494
+
495
+ /**
496
+ * Return generator with all elements inside FunctionExpression
497
+ * @param {ASTNode } node Node to check
498
+ * @param {string } groupName Name of parent group
499
+ */
500
+ * iterateFunctionExpression ( node , groupName ) {
501
+ assert ( node . type === 'FunctionExpression' )
502
+ if ( node . body . type === 'BlockStatement' ) {
503
+ for ( const item of node . body . body ) {
504
+ if ( item . type === 'ReturnStatement' && item . argument . type === 'ObjectExpression' ) {
505
+ yield * this . iterateObjectExpression ( item . argument , groupName )
506
+ }
507
+ }
508
+ }
400
509
}
401
510
}
0 commit comments