exportParser.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _jsdoccomment = require("@es-joy/jsdoccomment");
  7. var _debug = _interopRequireDefault(require("debug"));
  8. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9. const debug = (0, _debug.default)('requireExportJsdoc');
  10. /**
  11. * @typedef {{
  12. * value: string
  13. * }} ValueObject
  14. */
  15. /**
  16. * @typedef {{
  17. * type?: string,
  18. * value?: ValueObject|import('eslint').Rule.Node,
  19. * props: {
  20. * [key: string]: CreatedNode|null,
  21. * },
  22. * special?: true,
  23. * globalVars?: CreatedNode,
  24. * exported?: boolean,
  25. * ANONYMOUS_DEFAULT?: import('eslint').Rule.Node
  26. * }} CreatedNode
  27. */
  28. /**
  29. * @returns {CreatedNode}
  30. */
  31. const createNode = function () {
  32. return {
  33. props: {}
  34. };
  35. };
  36. /**
  37. * @param {CreatedNode|null} symbol
  38. * @returns {string|null}
  39. */
  40. const getSymbolValue = function (symbol) {
  41. /* istanbul ignore if */
  42. if (!symbol) {
  43. return null;
  44. }
  45. /* istanbul ignore else */
  46. if (symbol.type === 'literal') {
  47. return /** @type {ValueObject} */symbol.value.value;
  48. }
  49. /* istanbul ignore next */
  50. return null;
  51. };
  52. /**
  53. *
  54. * @param {import('estree').Identifier} node
  55. * @param {CreatedNode} globals
  56. * @param {CreatedNode} scope
  57. * @param {SymbolOptions} opts
  58. * @returns {CreatedNode|null}
  59. */
  60. const getIdentifier = function (node, globals, scope, opts) {
  61. if (opts.simpleIdentifier) {
  62. // Type is Identier for noncomputed properties
  63. const identifierLiteral = createNode();
  64. identifierLiteral.type = 'literal';
  65. identifierLiteral.value = {
  66. value: node.name
  67. };
  68. return identifierLiteral;
  69. }
  70. /* istanbul ignore next */
  71. const block = scope || globals;
  72. // As scopes are not currently supported, they are not traversed upwards recursively
  73. if (block.props[node.name]) {
  74. return block.props[node.name];
  75. }
  76. // Seems this will only be entered once scopes added and entered
  77. /* istanbul ignore next */
  78. if (globals.props[node.name]) {
  79. return globals.props[node.name];
  80. }
  81. return null;
  82. };
  83. /**
  84. * @callback CreateSymbol
  85. * @param {import('eslint').Rule.Node|null} node
  86. * @param {CreatedNode} globals
  87. * @param {import('eslint').Rule.Node|null} value
  88. * @param {CreatedNode} [scope]
  89. * @param {boolean|SymbolOptions} [isGlobal]
  90. * @returns {CreatedNode|null}
  91. */
  92. /** @type {CreateSymbol} */
  93. let createSymbol; // eslint-disable-line prefer-const
  94. /* eslint-disable complexity -- Temporary */
  95. /**
  96. * @typedef {{
  97. * simpleIdentifier?: boolean
  98. * }} SymbolOptions
  99. */
  100. /**
  101. *
  102. * @param {import('eslint').Rule.Node} node
  103. * @param {CreatedNode} globals
  104. * @param {CreatedNode} scope
  105. * @param {SymbolOptions} [opt]
  106. * @returns {CreatedNode|null}
  107. */
  108. const getSymbol = function (node, globals, scope, opt) {
  109. /* eslint-enable complexity -- Temporary */
  110. const opts = opt || {};
  111. /* istanbul ignore next */
  112. switch (node.type) {
  113. case 'Identifier':
  114. {
  115. return getIdentifier(node, globals, scope, opts);
  116. }
  117. case 'MemberExpression':
  118. {
  119. const obj = getSymbol( /** @type {import('eslint').Rule.Node} */
  120. node.object, globals, scope, opts);
  121. const propertySymbol = getSymbol( /** @type {import('eslint').Rule.Node} */
  122. node.property, globals, scope, {
  123. simpleIdentifier: !node.computed
  124. });
  125. const propertyValue = getSymbolValue(propertySymbol);
  126. /* istanbul ignore else */
  127. if (obj && propertyValue && obj.props[propertyValue]) {
  128. const block = obj.props[propertyValue];
  129. return block;
  130. }
  131. /*
  132. if (opts.createMissingProps && propertyValue) {
  133. obj.props[propertyValue] = createNode();
  134. return obj.props[propertyValue];
  135. }
  136. */
  137. /* istanbul ignore next */
  138. debug(`MemberExpression: Missing property ${
  139. /** @type {import('estree').PrivateIdentifier} */node.property.name}`);
  140. /* istanbul ignore next */
  141. return null;
  142. }
  143. case 'ClassExpression':
  144. {
  145. return getSymbol( /** @type {import('eslint').Rule.Node} */
  146. node.body, globals, scope, opts);
  147. }
  148. // @ts-expect-error TS OK
  149. case 'TSTypeAliasDeclaration':
  150. // @ts-expect-error TS OK
  151. // Fallthrough
  152. case 'TSEnumDeclaration':
  153. case 'TSInterfaceDeclaration':
  154. case 'ClassDeclaration':
  155. case 'FunctionExpression':
  156. case 'FunctionDeclaration':
  157. case 'ArrowFunctionExpression':
  158. {
  159. const val = createNode();
  160. val.props.prototype = createNode();
  161. val.props.prototype.type = 'object';
  162. val.type = 'object';
  163. val.value = node;
  164. return val;
  165. }
  166. case 'AssignmentExpression':
  167. {
  168. return createSymbol( /** @type {import('eslint').Rule.Node} */
  169. node.left, globals, /** @type {import('eslint').Rule.Node} */
  170. node.right, scope, opts);
  171. }
  172. case 'ClassBody':
  173. {
  174. const val = createNode();
  175. for (const method of node.body) {
  176. val.props[/** @type {import('estree').Identifier} */( /** @type {import('estree').MethodDefinition} */method.key).name] = createNode();
  177. /** @type {{[key: string]: CreatedNode}} */
  178. val.props[/** @type {import('estree').Identifier} */( /** @type {import('estree').MethodDefinition} */method.key).name].type = 'object';
  179. /** @type {{[key: string]: CreatedNode}} */
  180. val.props[/** @type {import('estree').Identifier} */( /** @type {import('estree').MethodDefinition} */method.key).name].value = /** @type {import('eslint').Rule.Node} */
  181. /** @type {import('estree').MethodDefinition} */method.value;
  182. }
  183. val.type = 'object';
  184. val.value = node.parent;
  185. return val;
  186. }
  187. case 'ObjectExpression':
  188. {
  189. const val = createNode();
  190. val.type = 'object';
  191. for (const prop of node.properties) {
  192. if ([
  193. // @typescript-eslint/parser, espree, acorn, etc.
  194. 'SpreadElement',
  195. // @babel/eslint-parser
  196. 'ExperimentalSpreadProperty'].includes(prop.type)) {
  197. continue;
  198. }
  199. const propVal = getSymbol( /** @type {import('eslint').Rule.Node} */
  200. /** @type {import('estree').Property} */
  201. prop.value, globals, scope, opts);
  202. /* istanbul ignore if */
  203. if (propVal) {
  204. val.props[/** @type {import('estree').PrivateIdentifier} */
  205. ( /** @type {import('estree').Property} */prop.key).name] = propVal;
  206. }
  207. }
  208. return val;
  209. }
  210. case 'Literal':
  211. {
  212. const val = createNode();
  213. val.type = 'literal';
  214. val.value = node;
  215. return val;
  216. }
  217. }
  218. /* istanbul ignore next */
  219. return null;
  220. };
  221. /**
  222. *
  223. * @param {CreatedNode} block
  224. * @param {string} name
  225. * @param {CreatedNode|null} value
  226. * @param {CreatedNode} globals
  227. * @param {boolean|SymbolOptions|undefined} isGlobal
  228. * @returns {void}
  229. */
  230. const createBlockSymbol = function (block, name, value, globals, isGlobal) {
  231. block.props[name] = value;
  232. if (isGlobal && globals.props.window && globals.props.window.special) {
  233. globals.props.window.props[name] = value;
  234. }
  235. };
  236. createSymbol = function (node, globals, value, scope, isGlobal) {
  237. const block = scope || globals;
  238. /* istanbul ignore if */
  239. if (!node) {
  240. return null;
  241. }
  242. let symbol;
  243. switch (node.type) {
  244. case 'FunctionDeclaration':
  245. /* istanbul ignore next */
  246. // @ts-expect-error TS OK
  247. // Fall through
  248. case 'TSEnumDeclaration':
  249. case 'TSInterfaceDeclaration':
  250. /* istanbul ignore next */
  251. // @ts-expect-error TS OK
  252. // Fall through
  253. case 'TSTypeAliasDeclaration':
  254. case 'ClassDeclaration':
  255. {
  256. const nde = /** @type {import('estree').ClassDeclaration} */node;
  257. /* istanbul ignore else */
  258. if (nde.id && nde.id.type === 'Identifier') {
  259. return createSymbol( /** @type {import('eslint').Rule.Node} */nde.id, globals, node, globals);
  260. }
  261. /* istanbul ignore next */
  262. break;
  263. }
  264. case 'Identifier':
  265. {
  266. const nde = /** @type {import('estree').Identifier} */node;
  267. if (value) {
  268. const valueSymbol = getSymbol(value, globals, block);
  269. /* istanbul ignore else */
  270. if (valueSymbol) {
  271. createBlockSymbol(block, nde.name, valueSymbol, globals, isGlobal);
  272. return block.props[nde.name];
  273. }
  274. /* istanbul ignore next */
  275. debug('Identifier: Missing value symbol for %s', nde.name);
  276. } else {
  277. createBlockSymbol(block, nde.name, createNode(), globals, isGlobal);
  278. return block.props[nde.name];
  279. }
  280. /* istanbul ignore next */
  281. break;
  282. }
  283. case 'MemberExpression':
  284. {
  285. const nde = /** @type {import('estree').MemberExpression} */node;
  286. symbol = getSymbol( /** @type {import('eslint').Rule.Node} */nde.object, globals, block);
  287. const propertySymbol = getSymbol( /** @type {import('eslint').Rule.Node} */nde.property, globals, block, {
  288. simpleIdentifier: !nde.computed
  289. });
  290. const propertyValue = getSymbolValue(propertySymbol);
  291. if (symbol && propertyValue) {
  292. createBlockSymbol(symbol, propertyValue, getSymbol( /** @type {import('eslint').Rule.Node} */
  293. value, globals, block), globals, isGlobal);
  294. return symbol.props[propertyValue];
  295. }
  296. debug('MemberExpression: Missing symbol: %s', /** @type {import('estree').Identifier} */nde.property.name);
  297. break;
  298. }
  299. }
  300. return null;
  301. };
  302. /**
  303. * Creates variables from variable definitions
  304. * @param {import('eslint').Rule.Node} node
  305. * @param {CreatedNode} globals
  306. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
  307. * @returns {void}
  308. */
  309. const initVariables = function (node, globals, opts) {
  310. switch (node.type) {
  311. case 'Program':
  312. {
  313. for (const childNode of node.body) {
  314. initVariables( /** @type {import('eslint').Rule.Node} */
  315. childNode, globals, opts);
  316. }
  317. break;
  318. }
  319. case 'ExpressionStatement':
  320. {
  321. initVariables( /** @type {import('eslint').Rule.Node} */
  322. node.expression, globals, opts);
  323. break;
  324. }
  325. case 'VariableDeclaration':
  326. {
  327. for (const declaration of node.declarations) {
  328. // let and const
  329. const symbol = createSymbol( /** @type {import('eslint').Rule.Node} */
  330. declaration.id, globals, null, globals);
  331. if (opts.initWindow && node.kind === 'var' && globals.props.window) {
  332. // If var, also add to window
  333. globals.props.window.props[/** @type {import('estree').Identifier} */
  334. declaration.id.name] = symbol;
  335. }
  336. }
  337. break;
  338. }
  339. case 'ExportNamedDeclaration':
  340. {
  341. if (node.declaration) {
  342. initVariables( /** @type {import('eslint').Rule.Node} */
  343. node.declaration, globals, opts);
  344. }
  345. break;
  346. }
  347. }
  348. };
  349. /* eslint-disable complexity -- Temporary */
  350. /**
  351. * Populates variable maps using AST
  352. * @param {import('eslint').Rule.Node} node
  353. * @param {CreatedNode} globals
  354. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
  355. * @param {true} [isExport]
  356. * @returns {boolean}
  357. */
  358. const mapVariables = function (node, globals, opt, isExport) {
  359. /* eslint-enable complexity -- Temporary */
  360. /* istanbul ignore next */
  361. const opts = opt || {};
  362. /* istanbul ignore next */
  363. switch (node.type) {
  364. case 'Program':
  365. {
  366. if (opts.ancestorsOnly) {
  367. return false;
  368. }
  369. for (const childNode of node.body) {
  370. mapVariables( /** @type {import('eslint').Rule.Node} */
  371. childNode, globals, opts);
  372. }
  373. break;
  374. }
  375. case 'ExpressionStatement':
  376. {
  377. mapVariables( /** @type {import('eslint').Rule.Node} */
  378. node.expression, globals, opts);
  379. break;
  380. }
  381. case 'AssignmentExpression':
  382. {
  383. createSymbol( /** @type {import('eslint').Rule.Node} */
  384. node.left, globals, /** @type {import('eslint').Rule.Node} */
  385. node.right);
  386. break;
  387. }
  388. case 'VariableDeclaration':
  389. {
  390. for (const declaration of node.declarations) {
  391. const isGlobal = Boolean(opts.initWindow && node.kind === 'var' && globals.props.window);
  392. const symbol = createSymbol( /** @type {import('eslint').Rule.Node} */
  393. declaration.id, globals, /** @type {import('eslint').Rule.Node} */
  394. declaration.init, globals, isGlobal);
  395. if (symbol && isExport) {
  396. symbol.exported = true;
  397. }
  398. }
  399. break;
  400. }
  401. case 'FunctionDeclaration':
  402. {
  403. /* istanbul ignore if */
  404. if ( /** @type {import('estree').Identifier} */node.id.type === 'Identifier') {
  405. createSymbol( /** @type {import('eslint').Rule.Node} */
  406. node.id, globals, node, globals, true);
  407. }
  408. break;
  409. }
  410. case 'ExportDefaultDeclaration':
  411. {
  412. const symbol = createSymbol( /** @type {import('eslint').Rule.Node} */
  413. node.declaration, globals, /** @type {import('eslint').Rule.Node} */
  414. node.declaration);
  415. if (symbol) {
  416. symbol.exported = true;
  417. } else {
  418. // if (!node.id) {
  419. globals.ANONYMOUS_DEFAULT = /** @type {import('eslint').Rule.Node} */
  420. node.declaration;
  421. }
  422. break;
  423. }
  424. case 'ExportNamedDeclaration':
  425. {
  426. if (node.declaration) {
  427. if (node.declaration.type === 'VariableDeclaration') {
  428. mapVariables( /** @type {import('eslint').Rule.Node} */
  429. node.declaration, globals, opts, true);
  430. } else {
  431. const symbol = createSymbol( /** @type {import('eslint').Rule.Node} */
  432. node.declaration, globals, /** @type {import('eslint').Rule.Node} */
  433. node.declaration);
  434. /* istanbul ignore if */
  435. if (symbol) {
  436. symbol.exported = true;
  437. }
  438. }
  439. }
  440. for (const specifier of node.specifiers) {
  441. mapVariables( /** @type {import('eslint').Rule.Node} */
  442. specifier, globals, opts);
  443. }
  444. break;
  445. }
  446. case 'ExportSpecifier':
  447. {
  448. const symbol = getSymbol( /** @type {import('eslint').Rule.Node} */
  449. node.local, globals, globals);
  450. /* istanbul ignore if */
  451. if (symbol) {
  452. symbol.exported = true;
  453. }
  454. break;
  455. }
  456. case 'ClassDeclaration':
  457. {
  458. createSymbol( /** @type {import('eslint').Rule.Node|null} */node.id, globals, /** @type {import('eslint').Rule.Node} */node.body, globals);
  459. break;
  460. }
  461. default:
  462. {
  463. /* istanbul ignore next */
  464. return false;
  465. }
  466. }
  467. return true;
  468. };
  469. /**
  470. *
  471. * @param {import('eslint').Rule.Node} node
  472. * @param {CreatedNode|ValueObject|string|undefined|
  473. * import('eslint').Rule.Node} block
  474. * @param {(CreatedNode|ValueObject|string|
  475. * import('eslint').Rule.Node)[]} [cache]
  476. * @returns {boolean}
  477. */
  478. const findNode = function (node, block, cache) {
  479. let blockCache = cache || [];
  480. if (!block || blockCache.includes(block)) {
  481. return false;
  482. }
  483. blockCache = blockCache.slice();
  484. blockCache.push(block);
  485. if (typeof block === 'object' && 'type' in block && (block.type === 'object' || block.type === 'MethodDefinition') && block.value === node) {
  486. return true;
  487. }
  488. if (typeof block !== 'object') {
  489. return false;
  490. }
  491. const props = 'props' in block && block.props || 'body' in block && block.body;
  492. for (const propval of Object.values(props || {})) {
  493. if (Array.isArray(propval)) {
  494. /* istanbul ignore if */
  495. if (propval.some(val => {
  496. return findNode(node, val, blockCache);
  497. })) {
  498. return true;
  499. }
  500. } else if (findNode(node, propval, blockCache)) {
  501. return true;
  502. }
  503. }
  504. return false;
  505. };
  506. const exportTypes = new Set(['ExportNamedDeclaration', 'ExportDefaultDeclaration']);
  507. const ignorableNestedTypes = new Set(['FunctionDeclaration', 'ArrowFunctionExpression', 'FunctionExpression']);
  508. /**
  509. * @param {import('eslint').Rule.Node} nde
  510. * @returns {import('eslint').Rule.Node|false}
  511. */
  512. const getExportAncestor = function (nde) {
  513. let node = nde;
  514. let idx = 0;
  515. const ignorableIfDeep = ignorableNestedTypes.has(nde === null || nde === void 0 ? void 0 : nde.type);
  516. while (node) {
  517. // Ignore functions nested more deeply than say `export default function () {}`
  518. if (idx >= 2 && ignorableIfDeep) {
  519. break;
  520. }
  521. if (exportTypes.has(node.type)) {
  522. return node;
  523. }
  524. node = node.parent;
  525. idx++;
  526. }
  527. return false;
  528. };
  529. const canBeExportedByAncestorType = new Set(['TSPropertySignature', 'TSMethodSignature', 'ClassProperty', 'PropertyDefinition', 'Method']);
  530. const canExportChildrenType = new Set(['TSInterfaceBody', 'TSInterfaceDeclaration', 'TSTypeLiteral', 'TSTypeAliasDeclaration', 'ClassDeclaration', 'ClassBody', 'ClassDefinition', 'ClassExpression', 'Program']);
  531. /**
  532. * @param {import('eslint').Rule.Node} nde
  533. * @returns {false|import('eslint').Rule.Node}
  534. */
  535. const isExportByAncestor = function (nde) {
  536. if (!canBeExportedByAncestorType.has(nde.type)) {
  537. return false;
  538. }
  539. let node = nde.parent;
  540. while (node) {
  541. if (exportTypes.has(node.type)) {
  542. return node;
  543. }
  544. if (!canExportChildrenType.has(node.type)) {
  545. return false;
  546. }
  547. node = node.parent;
  548. }
  549. return false;
  550. };
  551. /**
  552. *
  553. * @param {CreatedNode} block
  554. * @param {import('eslint').Rule.Node} node
  555. * @param {CreatedNode[]} [cache] Currently unused
  556. * @returns {boolean}
  557. */
  558. const findExportedNode = function (block, node, cache) {
  559. /* istanbul ignore if */
  560. if (block === null) {
  561. return false;
  562. }
  563. const blockCache = cache || [];
  564. const {
  565. props
  566. } = block;
  567. for (const propval of Object.values(props)) {
  568. const pval = /** @type {CreatedNode} */propval;
  569. blockCache.push(pval);
  570. if (pval.exported && (node === pval.value || findNode(node, pval.value))) {
  571. return true;
  572. }
  573. // No need to check `propval` for exported nodes as ESM
  574. // exports are only global
  575. }
  576. return false;
  577. };
  578. /**
  579. *
  580. * @param {import('eslint').Rule.Node} node
  581. * @param {CreatedNode} globals
  582. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
  583. * @returns {boolean}
  584. */
  585. const isNodeExported = function (node, globals, opt) {
  586. var _globals$props$module;
  587. const moduleExports = (_globals$props$module = globals.props.module) === null || _globals$props$module === void 0 || (_globals$props$module = _globals$props$module.props) === null || _globals$props$module === void 0 ? void 0 : _globals$props$module.exports;
  588. if (opt.initModuleExports && moduleExports && findNode(node, moduleExports)) {
  589. return true;
  590. }
  591. if (opt.initWindow && globals.props.window && findNode(node, globals.props.window)) {
  592. return true;
  593. }
  594. if (opt.esm && findExportedNode(globals, node)) {
  595. return true;
  596. }
  597. return false;
  598. };
  599. /**
  600. *
  601. * @param {import('eslint').Rule.Node} node
  602. * @param {CreatedNode} globalVars
  603. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
  604. * @returns {boolean}
  605. */
  606. const parseRecursive = function (node, globalVars, opts) {
  607. // Iterate from top using recursion - stop at first processed node from top
  608. if (node.parent && parseRecursive(node.parent, globalVars, opts)) {
  609. return true;
  610. }
  611. return mapVariables(node, globalVars, opts);
  612. };
  613. /**
  614. *
  615. * @param {import('eslint').Rule.Node} ast
  616. * @param {import('eslint').Rule.Node} node
  617. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
  618. * @returns {CreatedNode}
  619. */
  620. const parse = function (ast, node, opt) {
  621. /* istanbul ignore next */
  622. const opts = opt || {
  623. ancestorsOnly: false,
  624. esm: true,
  625. initModuleExports: true,
  626. initWindow: true
  627. };
  628. const globalVars = createNode();
  629. if (opts.initModuleExports) {
  630. globalVars.props.module = createNode();
  631. globalVars.props.module.props.exports = createNode();
  632. globalVars.props.exports = globalVars.props.module.props.exports;
  633. }
  634. if (opts.initWindow) {
  635. globalVars.props.window = createNode();
  636. globalVars.props.window.special = true;
  637. }
  638. if (opts.ancestorsOnly) {
  639. parseRecursive(node, globalVars, opts);
  640. } else {
  641. initVariables(ast, globalVars, opts);
  642. mapVariables(ast, globalVars, opts);
  643. }
  644. return {
  645. globalVars,
  646. props: {}
  647. };
  648. };
  649. const accessibilityNodes = new Set(['PropertyDefinition', 'MethodDefinition']);
  650. /**
  651. *
  652. * @param {import('eslint').Rule.Node} node
  653. * @returns {boolean}
  654. */
  655. const hasAccessibility = node => {
  656. return accessibilityNodes.has(node.type) && 'accessibility' in node && node.accessibility !== 'public' && node.accessibility !== undefined;
  657. };
  658. /**
  659. *
  660. * @param {import('eslint').Rule.Node} node
  661. * @param {import('eslint').SourceCode} sourceCode
  662. * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
  663. * @param {import('./iterateJsdoc.js').Settings} settings
  664. * @returns {boolean}
  665. */
  666. const isUncommentedExport = function (node, sourceCode, opt, settings) {
  667. // console.log({node});
  668. // Optimize with ancestor check for esm
  669. if (opt.esm) {
  670. if (hasAccessibility(node) || node.parent && hasAccessibility(node.parent)) {
  671. return false;
  672. }
  673. const exportNode = getExportAncestor(node);
  674. // Is export node comment
  675. if (exportNode && !(0, _jsdoccomment.findJSDocComment)(exportNode, sourceCode, settings)) {
  676. return true;
  677. }
  678. /**
  679. * Some typescript types are not in variable map, but inherit exported (interface property and method)
  680. */
  681. if (isExportByAncestor(node) && !(0, _jsdoccomment.findJSDocComment)(node, sourceCode, settings)) {
  682. return true;
  683. }
  684. }
  685. const ast = /** @type {unknown} */sourceCode.ast;
  686. const parseResult = parse( /** @type {import('eslint').Rule.Node} */
  687. ast, node, opt);
  688. return isNodeExported(node, /** @type {CreatedNode} */parseResult.globalVars, opt);
  689. };
  690. var _default = exports.default = {
  691. isUncommentedExport,
  692. parse
  693. };
  694. module.exports = exports.default;
  695. //# sourceMappingURL=exportParser.js.map