1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _debug = _interopRequireDefault(require("debug"));
|
9 |
|
10 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
11 |
|
12 | const debug = (0, _debug.default)('requireExportJsdoc');
|
13 |
|
14 | const createNode = function createNode() {
|
15 | return {
|
16 | props: {}
|
17 | };
|
18 | };
|
19 |
|
20 | const getSymbolValue = function getSymbolValue(symbol) {
|
21 |
|
22 | if (!symbol) {
|
23 |
|
24 | return null;
|
25 | }
|
26 |
|
27 |
|
28 |
|
29 | if (symbol.type === 'literal') {
|
30 | return symbol.value.value;
|
31 | }
|
32 |
|
33 |
|
34 |
|
35 | return null;
|
36 | };
|
37 |
|
38 | const getIdentifier = function getIdentifier(node, globals, scope, opts) {
|
39 | if (opts.simpleIdentifier) {
|
40 |
|
41 | const identifierLiteral = createNode();
|
42 | identifierLiteral.type = 'literal';
|
43 | identifierLiteral.value = {
|
44 | value: node.name
|
45 | };
|
46 | return identifierLiteral;
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 | const block = scope || globals;
|
52 |
|
53 | if (block.props[node.name]) {
|
54 | return block.props[node.name];
|
55 | }
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | if (globals.props[node.name]) {
|
61 | return globals.props[node.name];
|
62 | }
|
63 |
|
64 | return null;
|
65 | };
|
66 |
|
67 | let _createSymbol = null;
|
68 |
|
69 | const getSymbol = function getSymbol(node, globals, scope, opt) {
|
70 | const opts = opt || {};
|
71 |
|
72 | switch (node.type) {
|
73 | case 'Identifier':
|
74 | {
|
75 | return getIdentifier(node, globals, scope, opts);
|
76 | }
|
77 |
|
78 | case 'MemberExpression':
|
79 | {
|
80 | const obj = getSymbol(node.object, globals, scope, opts);
|
81 | const propertySymbol = getSymbol(node.property, globals, scope, {
|
82 | simpleIdentifier: !node.computed
|
83 | });
|
84 | const propertyValue = getSymbolValue(propertySymbol);
|
85 |
|
86 |
|
87 | if (obj && propertyValue && obj.props[propertyValue]) {
|
88 | const block = obj.props[propertyValue];
|
89 | return block;
|
90 | }
|
91 | |
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 | debug(`MemberExpression: Missing property ${node.property.name}`);
|
102 |
|
103 |
|
104 | return null;
|
105 | }
|
106 |
|
107 | case 'ClassDeclaration':
|
108 | case 'ClassExpression':
|
109 | case 'FunctionExpression':
|
110 | case 'FunctionDeclaration':
|
111 | case 'ArrowFunctionExpression':
|
112 | {
|
113 | const val = createNode();
|
114 | val.props.prototype = createNode();
|
115 | val.props.prototype.type = 'object';
|
116 | val.type = 'object';
|
117 | val.value = node;
|
118 | return val;
|
119 | }
|
120 |
|
121 | case 'AssignmentExpression':
|
122 | {
|
123 | return _createSymbol(node.left, globals, node.right, scope, opts);
|
124 | }
|
125 |
|
126 | case 'ClassBody':
|
127 | {
|
128 | const val = createNode();
|
129 | node.body.forEach(method => {
|
130 | val.props[method.key.name] = createNode();
|
131 | val.props[method.key.name].type = 'object';
|
132 | val.props[method.key.name].value = method.value;
|
133 | });
|
134 | val.type = 'object';
|
135 | val.value = node;
|
136 | return val;
|
137 | }
|
138 |
|
139 | case 'ObjectExpression':
|
140 | {
|
141 | const val = createNode();
|
142 | val.type = 'object';
|
143 | node.properties.forEach(prop => {
|
144 | if (prop.type === 'ExperimentalSpreadProperty') {
|
145 | return;
|
146 | }
|
147 |
|
148 | const propVal = getSymbol(prop.value, globals, scope, opts);
|
149 |
|
150 |
|
151 | if (propVal) {
|
152 | val.props[prop.key.name] = propVal;
|
153 | }
|
154 | });
|
155 | return val;
|
156 | }
|
157 |
|
158 | case 'Literal':
|
159 | {
|
160 | const val = createNode();
|
161 | val.type = 'literal';
|
162 | val.value = node;
|
163 | return val;
|
164 | }
|
165 | }
|
166 |
|
167 |
|
168 |
|
169 | return null;
|
170 | };
|
171 |
|
172 | const createBlockSymbol = function createBlockSymbol(block, name, value, globals, isGlobal) {
|
173 | block.props[name] = value;
|
174 |
|
175 | if (isGlobal && globals.props.window && globals.props.window.special) {
|
176 | globals.props.window.props[name] = value;
|
177 | }
|
178 | };
|
179 |
|
180 | _createSymbol = function createSymbol(node, globals, value, scope, isGlobal) {
|
181 | const block = scope || globals;
|
182 | let symbol;
|
183 |
|
184 | switch (node.type) {
|
185 | case 'ClassDeclaration':
|
186 | {
|
187 | if (node.id && node.id.type === 'Identifier') {
|
188 | return _createSymbol(node.id, globals, node, globals);
|
189 | }
|
190 |
|
191 | break;
|
192 | }
|
193 |
|
194 | case 'Identifier':
|
195 | {
|
196 | if (value) {
|
197 | const valueSymbol = getSymbol(value, globals, block);
|
198 |
|
199 |
|
200 | if (valueSymbol) {
|
201 | createBlockSymbol(block, node.name, valueSymbol, globals, isGlobal);
|
202 | return block.props[node.name];
|
203 | }
|
204 |
|
205 |
|
206 |
|
207 | debug('Identifier: Missing value symbol for %s', node.name);
|
208 | } else {
|
209 | createBlockSymbol(block, node.name, createNode(), globals, isGlobal);
|
210 | return block.props[node.name];
|
211 | }
|
212 |
|
213 |
|
214 |
|
215 | break;
|
216 | }
|
217 |
|
218 | case 'MemberExpression':
|
219 | {
|
220 | symbol = getSymbol(node.object, globals, block);
|
221 | const propertySymbol = getSymbol(node.property, globals, block, {
|
222 | simpleIdentifier: !node.computed
|
223 | });
|
224 | const propertyValue = getSymbolValue(propertySymbol);
|
225 |
|
226 | if (symbol && propertyValue) {
|
227 | createBlockSymbol(symbol, propertyValue, getSymbol(value, globals, block), globals, isGlobal);
|
228 | return symbol.props[propertyValue];
|
229 | }
|
230 |
|
231 |
|
232 |
|
233 | debug('MemberExpression: Missing symbol: %s', node.property.name);
|
234 | break;
|
235 | }
|
236 |
|
237 | case 'FunctionDeclaration':
|
238 | {
|
239 | if (node.id && node.id.type === 'Identifier') {
|
240 | return _createSymbol(node.id, globals, node, globals);
|
241 | }
|
242 |
|
243 | break;
|
244 | }
|
245 | }
|
246 |
|
247 | return null;
|
248 | };
|
249 |
|
250 |
|
251 | const initVariables = function initVariables(node, globals, opts) {
|
252 | switch (node.type) {
|
253 | case 'Program':
|
254 | {
|
255 | node.body.forEach(childNode => {
|
256 | initVariables(childNode, globals, opts);
|
257 | });
|
258 | break;
|
259 | }
|
260 |
|
261 | case 'ExpressionStatement':
|
262 | {
|
263 | initVariables(node.expression, globals, opts);
|
264 | break;
|
265 | }
|
266 |
|
267 | case 'VariableDeclaration':
|
268 | {
|
269 | node.declarations.forEach(declaration => {
|
270 |
|
271 | const symbol = _createSymbol(declaration.id, globals, null, globals);
|
272 |
|
273 | if (opts.initWindow && node.kind === 'var' && globals.props.window) {
|
274 |
|
275 | globals.props.window.props[declaration.id.name] = symbol;
|
276 | }
|
277 | });
|
278 | break;
|
279 | }
|
280 |
|
281 | case 'ExportNamedDeclaration':
|
282 | {
|
283 | if (node.declaration) {
|
284 | initVariables(node.declaration, globals, opts);
|
285 | }
|
286 |
|
287 | break;
|
288 | }
|
289 | }
|
290 | };
|
291 |
|
292 |
|
293 | const mapVariables = function mapVariables(node, globals, opt, isExport) {
|
294 |
|
295 | const opts = opt || {};
|
296 |
|
297 |
|
298 | switch (node.type) {
|
299 | case 'Program':
|
300 | {
|
301 | if (opts.ancestorsOnly) {
|
302 | return false;
|
303 | } else {
|
304 | node.body.forEach(childNode => {
|
305 | mapVariables(childNode, globals, opts);
|
306 | });
|
307 | }
|
308 |
|
309 | break;
|
310 | }
|
311 |
|
312 | case 'ExpressionStatement':
|
313 | {
|
314 | mapVariables(node.expression, globals, opts);
|
315 | break;
|
316 | }
|
317 |
|
318 | case 'AssignmentExpression':
|
319 | {
|
320 | _createSymbol(node.left, globals, node.right);
|
321 |
|
322 | break;
|
323 | }
|
324 |
|
325 | case 'VariableDeclaration':
|
326 | {
|
327 | node.declarations.forEach(declaration => {
|
328 | const isGlobal = opts.initWindow && node.kind === 'var' && globals.props.window;
|
329 |
|
330 | const symbol = _createSymbol(declaration.id, globals, declaration.init, globals, isGlobal);
|
331 |
|
332 | if (symbol && isExport) {
|
333 | symbol.exported = true;
|
334 | }
|
335 | });
|
336 | break;
|
337 | }
|
338 |
|
339 | case 'FunctionDeclaration':
|
340 | {
|
341 |
|
342 | if (node.id.type === 'Identifier') {
|
343 | _createSymbol(node.id, globals, node, globals, true);
|
344 | }
|
345 |
|
346 | break;
|
347 | }
|
348 |
|
349 | case 'ExportDefaultDeclaration':
|
350 | {
|
351 | const symbol = _createSymbol(node.declaration, globals, node.declaration);
|
352 |
|
353 | if (symbol) {
|
354 | symbol.exported = true;
|
355 | } else if (!node.id) {
|
356 | globals.ANONYMOUS_DEFAULT = node.declaration;
|
357 | }
|
358 |
|
359 | break;
|
360 | }
|
361 |
|
362 | case 'ExportNamedDeclaration':
|
363 | {
|
364 | if (node.declaration) {
|
365 | if (node.declaration.type === 'VariableDeclaration') {
|
366 | mapVariables(node.declaration, globals, opts, true);
|
367 | } else {
|
368 | const symbol = _createSymbol(node.declaration, globals, node.declaration);
|
369 |
|
370 |
|
371 |
|
372 | if (symbol) {
|
373 | symbol.exported = true;
|
374 | }
|
375 | }
|
376 | }
|
377 |
|
378 | node.specifiers.forEach(specifier => {
|
379 | mapVariables(specifier, globals, opts);
|
380 | });
|
381 | break;
|
382 | }
|
383 |
|
384 | case 'ExportSpecifier':
|
385 | {
|
386 | const symbol = getSymbol(node.local, globals, globals);
|
387 |
|
388 |
|
389 | if (symbol) {
|
390 | symbol.exported = true;
|
391 | }
|
392 |
|
393 | break;
|
394 | }
|
395 |
|
396 | case 'ClassDeclaration':
|
397 | {
|
398 | _createSymbol(node.id, globals, node.body, globals);
|
399 |
|
400 | break;
|
401 | }
|
402 |
|
403 | default:
|
404 | {
|
405 |
|
406 | return false;
|
407 | }
|
408 | }
|
409 |
|
410 | return true;
|
411 | };
|
412 |
|
413 | const findNode = function findNode(node, block, cache) {
|
414 | let blockCache = cache || [];
|
415 |
|
416 |
|
417 | if (!block || blockCache.includes(block)) {
|
418 | return false;
|
419 | }
|
420 |
|
421 | blockCache = blockCache.slice();
|
422 | blockCache.push(block);
|
423 |
|
424 | if (block.type === 'object') {
|
425 | if (block.value === node) {
|
426 | return true;
|
427 | }
|
428 | }
|
429 |
|
430 | const props = block.props;
|
431 |
|
432 | for (const prop in props) {
|
433 |
|
434 | if (Object.prototype.hasOwnProperty.call(props, prop)) {
|
435 | const propval = props[prop];
|
436 |
|
437 | if (propval && findNode(node, propval, blockCache)) {
|
438 | return true;
|
439 | }
|
440 | }
|
441 | }
|
442 |
|
443 | return false;
|
444 | };
|
445 |
|
446 | const findExportedNode = function findExportedNode(block, node, cache) {
|
447 | if (block.ANONYMOUS_DEFAULT === node) {
|
448 | return true;
|
449 | }
|
450 |
|
451 |
|
452 |
|
453 | if (block === null) {
|
454 | return false;
|
455 | }
|
456 |
|
457 | const blockCache = cache || [];
|
458 | const props = block.props;
|
459 |
|
460 | for (const key in props) {
|
461 |
|
462 | if (Object.prototype.hasOwnProperty.call(props, key)) {
|
463 | blockCache.push(props[key]);
|
464 |
|
465 | if (props[key].exported) {
|
466 | if (node === props[key].value || findNode(node, props[key].value)) {
|
467 | return true;
|
468 | }
|
469 | }
|
470 |
|
471 |
|
472 | }
|
473 | }
|
474 |
|
475 | return false;
|
476 | };
|
477 |
|
478 | const isNodeExported = function isNodeExported(node, globals, opt) {
|
479 | if (opt.initModuleExports && globals.props.module && globals.props.module.props.exports) {
|
480 | if (findNode(node, globals.props.module.props.exports)) {
|
481 | return true;
|
482 | }
|
483 | }
|
484 |
|
485 | if (opt.initWindow && globals.props.window) {
|
486 | if (findNode(node, globals.props.window)) {
|
487 | return true;
|
488 | }
|
489 | }
|
490 |
|
491 | if (opt.esm && findExportedNode(globals, node)) {
|
492 | return true;
|
493 | }
|
494 |
|
495 | return false;
|
496 | };
|
497 |
|
498 | const parseRecursive = function parseRecursive(node, globalVars, opts) {
|
499 |
|
500 | if (node.parent) {
|
501 | if (parseRecursive(node.parent, globalVars, opts)) {
|
502 | return true;
|
503 | }
|
504 | }
|
505 |
|
506 | return mapVariables(node, globalVars, opts);
|
507 | };
|
508 |
|
509 | const parse = function parse(ast, node, opt) {
|
510 |
|
511 | const opts = opt || {
|
512 | ancestorsOnly: false,
|
513 | esm: true,
|
514 | initModuleExports: true,
|
515 | initWindow: true
|
516 | };
|
517 | const globalVars = createNode();
|
518 |
|
519 | if (opts.initModuleExports) {
|
520 | globalVars.props.module = createNode();
|
521 | globalVars.props.module.props.exports = createNode();
|
522 | globalVars.props.exports = globalVars.props.module.props.exports;
|
523 | }
|
524 |
|
525 | if (opts.initWindow) {
|
526 | globalVars.props.window = createNode();
|
527 | globalVars.props.window.special = true;
|
528 | }
|
529 |
|
530 | if (opts.ancestorsOnly) {
|
531 | parseRecursive(node, globalVars, opts);
|
532 | } else {
|
533 | initVariables(ast, globalVars, opts);
|
534 | mapVariables(ast, globalVars, opts);
|
535 | }
|
536 |
|
537 | return {
|
538 | globalVars
|
539 | };
|
540 | };
|
541 |
|
542 | const isExported = function isExported(node, parseResult, opt) {
|
543 | return isNodeExported(node, parseResult.globalVars, opt);
|
544 | };
|
545 |
|
546 | var _default = {
|
547 | isExported,
|
548 | parse
|
549 | };
|
550 | exports.default = _default;
|
551 | module.exports = exports.default;
|
552 |
|
\ | No newline at end of file |