You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

113 lines
2.8 KiB

  1. /**
  2. * @fileoverview Utility functions for AST
  3. */
  4. 'use strict';
  5. /**
  6. * Find a return statment in the current node
  7. *
  8. * @param {ASTNode} ASTnode The AST node being checked
  9. */
  10. function findReturnStatement(node) {
  11. if (
  12. (!node.value || !node.value.body || !node.value.body.body) &&
  13. (!node.body || !node.body.body)
  14. ) {
  15. return false;
  16. }
  17. const bodyNodes = (node.value ? node.value.body.body : node.body.body);
  18. let i = bodyNodes.length - 1;
  19. for (; i >= 0; i--) {
  20. if (bodyNodes[i].type === 'ReturnStatement') {
  21. return bodyNodes[i];
  22. }
  23. }
  24. return false;
  25. }
  26. /**
  27. * Get node with property's name
  28. * @param {Object} node - Property.
  29. * @returns {Object} Property name node.
  30. */
  31. function getPropertyNameNode(node) {
  32. if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {
  33. return node.key;
  34. } else if (node.type === 'MemberExpression') {
  35. return node.property;
  36. }
  37. return null;
  38. }
  39. /**
  40. * Get properties name
  41. * @param {Object} node - Property.
  42. * @returns {String} Property name.
  43. */
  44. function getPropertyName(node) {
  45. const nameNode = getPropertyNameNode(node);
  46. return nameNode ? nameNode.name : '';
  47. }
  48. /**
  49. * Get properties for a given AST node
  50. * @param {ASTNode} node The AST node being checked.
  51. * @returns {Array} Properties array.
  52. */
  53. function getComponentProperties(node) {
  54. switch (node.type) {
  55. case 'ClassDeclaration':
  56. case 'ClassExpression':
  57. return node.body.body;
  58. case 'ObjectExpression':
  59. return node.properties;
  60. default:
  61. return [];
  62. }
  63. }
  64. /**
  65. * Checks if the node is the first in its line, excluding whitespace.
  66. * @param {Object} context The node to check
  67. * @param {ASTNode} node The node to check
  68. * @return {Boolean} true if it's the first node in its line
  69. */
  70. function isNodeFirstInLine(context, node) {
  71. const sourceCode = context.getSourceCode();
  72. let token = node;
  73. let lines;
  74. do {
  75. token = sourceCode.getTokenBefore(token);
  76. lines = token.type === 'JSXText'
  77. ? token.value.split('\n')
  78. : null;
  79. } while (
  80. token.type === 'JSXText' &&
  81. /^\s*$/.test(lines[lines.length - 1])
  82. );
  83. const startLine = node.loc.start.line;
  84. const endLine = token ? token.loc.end.line : -1;
  85. return startLine !== endLine;
  86. }
  87. /**
  88. * Checks if the node is a function or arrow function expression.
  89. * @param {Object} context The node to check
  90. * @return {Boolean} true if it's a function-like expression
  91. */
  92. function isFunctionLikeExpression(node) {
  93. return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';
  94. }
  95. module.exports = {
  96. findReturnStatement: findReturnStatement,
  97. getPropertyName: getPropertyName,
  98. getPropertyNameNode: getPropertyNameNode,
  99. getComponentProperties: getComponentProperties,
  100. isNodeFirstInLine: isNodeFirstInLine,
  101. isFunctionLikeExpression: isFunctionLikeExpression
  102. };