xyc
2024-05-17 6b24f642b01cf3cd1be0d5833273fa2867d389e1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* eslint-env node */
/**
 * @todo Fork find-in-files to get ignore pattern support
 */
const fif = require('find-in-files');
(async () => {
/**
 * @typedef {PlainObject} FileResult
 * @property {string[]} matches
 * @property {Integer} count
 * @property {string[]} line
 */
const fileMatchPatterns = ['editor'];
/**
 * Keys are file name strings
 * @type {Object.<string, FileResult>}
 */
let results = await Promise.all(fileMatchPatterns.map(async (fileMatchPattern) => {
  return fif.find(
    {
      // We grab to the end of the line as the `line` result for `find-in-files`
      //  only grabs from the beginning of the file to the end of the match.
      term: `(@[^{\\n]*{[^}\\n]*(\\bobject|\\barray\\b|[^.]function|\\bnumber|\\*)[^}\\n]*}|@.*{}).*`,
      flags: 'gi'
    },
    fileMatchPattern,
    '([^n]|[^i]n|[^m]in|[^.]min).js$'
  );
}));
results = Object.assign(...results);
let total = 0;
let output = '';
Object.entries(results).forEach(([file, res]) => {
  reduceFalseMatches(file, res);
  if (!res.line.length) {
    return;
  }
  output += `\nFound ${res.count} potentially overly generic JSDoc expression${res.count === 1 ? '' : 's'} in file ${file}:\n`;
  res.line.forEach((line) => {
    output += line + '\n';
  });
  total += res.line.length;
  /*
  res.matches.forEach((match) => {
    console.log(match);
  });
  */
});
console.log(`${output}\nTotal failures found: ${total}.\n`);
 
function reduceFalseMatches (file, res) {
  switch (file) {
  case 'editor/external/jamilih/jml-es.js':
  case 'editor/xdomain-svgedit-config-iife.js': // Ignore
    res.line = [];
    break;
  case 'editor/external/dynamic-import-polyfill/importModule.js':
    res.line = res.line.filter((line) => {
      return ![
        '* @returns {*} The return depends on the export of the targeted module.',
        '* @returns {ArbitraryModule|*} The return depends on the export of the targeted module.'
      ].includes(line);
    });
    break;
  case 'editor/embedapi.js':
    res.line = res.line.filter((line) => {
      return ![
        '* @param {...*} args Signature dependent on the function'
      ].includes(line);
    });
    break;
  case 'editor/typedefs.js':
    res.line = res.line.filter((line) => {
      return ![
        '* @typedef {number} Float',
        '* @typedef {Object} ArbitraryObject',
        '* @typedef {Object} ArbitraryModule',
        '* @typedef {Array} GenericArray',
        '* @typedef {*} Any',
        '* @param {...*} args Signature dependent on the function',
        '* @returns {*} Return dependent on the function'
      ].includes(line);
    });
    break;
  }
  res.count = res.line.length;
}
})();