1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _lodash = _interopRequireDefault(require("lodash"));
|
9 |
|
10 | var _tagNames = require("./tagNames");
|
11 |
|
12 | var _WarnSettings = _interopRequireDefault(require("./WarnSettings"));
|
13 |
|
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
15 |
|
16 | const getFunctionParameterNames = functionNode => {
|
17 | const getParamName = param => {
|
18 | if (_lodash.default.has(param, 'name')) {
|
19 | return param.name;
|
20 | }
|
21 |
|
22 | if (_lodash.default.has(param, 'left.name')) {
|
23 | return param.left.name;
|
24 | }
|
25 |
|
26 | if (param.type === 'ObjectPattern' || _lodash.default.get(param, 'left.type') === 'ObjectPattern') {
|
27 | return '<ObjectPattern>';
|
28 | }
|
29 |
|
30 | if (param.type === 'ArrayPattern' || _lodash.default.get(param, 'left.type') === 'ArrayPattern') {
|
31 | return '<ArrayPattern>';
|
32 | }
|
33 |
|
34 | if (param.type === 'RestElement') {
|
35 | return param.argument.name;
|
36 | }
|
37 |
|
38 | if (param.type === 'TSParameterProperty') {
|
39 | return getParamName(param.parameter);
|
40 | }
|
41 |
|
42 | throw new Error('Unsupported function signature format.');
|
43 | };
|
44 |
|
45 | return functionNode.params.map(getParamName);
|
46 | };
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | const getJsdocParameterNamesDeep = (jsdoc, targetTagName) => {
|
53 | let jsdocParameterNames;
|
54 | jsdocParameterNames = _lodash.default.filter(jsdoc.tags, {
|
55 | tag: targetTagName
|
56 | });
|
57 | jsdocParameterNames = _lodash.default.map(jsdocParameterNames, 'name');
|
58 | return jsdocParameterNames;
|
59 | };
|
60 |
|
61 | const getJsdocParameterNames = (jsdoc, targetTagName) => {
|
62 | let jsdocParameterNames;
|
63 | jsdocParameterNames = getJsdocParameterNamesDeep(jsdoc, targetTagName);
|
64 | jsdocParameterNames = jsdocParameterNames.filter(name => {
|
65 | return !name.includes('.');
|
66 | });
|
67 | return jsdocParameterNames;
|
68 | };
|
69 |
|
70 | const modeWarnSettings = (0, _WarnSettings.default)();
|
71 |
|
72 | const getTagNamesForMode = (mode, context) => {
|
73 | switch (mode) {
|
74 | case 'jsdoc':
|
75 | return _tagNames.jsdocTags;
|
76 |
|
77 | case 'typescript':
|
78 | return _tagNames.typeScriptTags;
|
79 |
|
80 | case 'closure':
|
81 | return _tagNames.closureTags;
|
82 |
|
83 | default:
|
84 | if (!modeWarnSettings.hasBeenWarned(context, 'mode')) {
|
85 | context.report({
|
86 | loc: {
|
87 | start: {
|
88 | column: 1,
|
89 | line: 1
|
90 | }
|
91 | },
|
92 | message: `Unrecognized value \`${mode}\` for \`settings.jsdoc.mode\`.`
|
93 | });
|
94 | modeWarnSettings.markSettingAsWarned(context, 'mode');
|
95 | }
|
96 |
|
97 |
|
98 | return _tagNames.jsdocTags;
|
99 | }
|
100 | };
|
101 |
|
102 | const getPreferredTagName = (context, mode, name, tagPreference = {}) => {
|
103 | const prefValues = _lodash.default.values(tagPreference);
|
104 |
|
105 | if (prefValues.includes(name) || prefValues.some(prefVal => {
|
106 | return prefVal && typeof prefVal === 'object' && prefVal.replacement === name;
|
107 | })) {
|
108 | return name;
|
109 | }
|
110 |
|
111 | if (_lodash.default.has(tagPreference, name)) {
|
112 | return tagPreference[name];
|
113 | }
|
114 |
|
115 | const tagNames = getTagNamesForMode(mode, context);
|
116 |
|
117 | const preferredTagName = _lodash.default.findKey(tagNames, aliases => {
|
118 | return aliases.includes(name);
|
119 | });
|
120 |
|
121 | if (preferredTagName) {
|
122 | return preferredTagName;
|
123 | }
|
124 |
|
125 | return name;
|
126 | };
|
127 |
|
128 | const isValidTag = (context, mode, name, definedTags) => {
|
129 | const tagNames = getTagNamesForMode(mode, context);
|
130 |
|
131 | const validTagNames = _lodash.default.keys(tagNames).concat(_lodash.default.flatten(_lodash.default.values(tagNames)));
|
132 |
|
133 | const additionalTags = definedTags;
|
134 | const allTags = validTagNames.concat(additionalTags);
|
135 | return allTags.includes(name);
|
136 | };
|
137 |
|
138 | const hasTag = (jsdoc, targetTagName) => {
|
139 | const targetTagLower = targetTagName.toLowerCase();
|
140 | return _lodash.default.some(jsdoc.tags, doc => {
|
141 | return doc.tag.toLowerCase() === targetTagLower;
|
142 | });
|
143 | };
|
144 |
|
145 | const hasATag = (jsdoc, targetTagNames) => {
|
146 | return targetTagNames.some(targetTagName => {
|
147 | return hasTag(jsdoc, targetTagName);
|
148 | });
|
149 | };
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 | const hasDefinedTypeReturnTag = tag => {
|
161 |
|
162 | if (typeof tag === 'undefined' || tag === null) {
|
163 | return false;
|
164 | }
|
165 |
|
166 |
|
167 | const tagType = tag.type.trim();
|
168 |
|
169 | if (tagType === 'undefined' || tagType === 'void') {
|
170 | return false;
|
171 | }
|
172 |
|
173 |
|
174 |
|
175 | return true;
|
176 | };
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | const tagsWithMandatoryType = [
|
182 |
|
183 | 'implements',
|
184 | 'type'];
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 | const tagsWithOptionalType = [
|
191 | 'enum', 'member', 'var', 'typedef',
|
192 | 'augments', 'extends', 'class', 'constructor', 'constant', 'const',
|
193 | 'module', 'namespace',
|
194 |
|
195 | 'param', 'arg', 'argument', 'property', 'prop',
|
196 | 'returns', 'return', 'throws', 'exception', 'yields', 'yield',
|
197 |
|
198 |
|
199 | 'modifies'];
|
200 | const tagsWithOptionalTypeClosure = [...tagsWithOptionalType,
|
201 |
|
202 | 'package', 'private', 'protected',
|
203 | 'public', 'static'];
|
204 |
|
205 | const namepathDefiningTags = [
|
206 |
|
207 |
|
208 | 'external', 'host', 'event',
|
209 | 'class', 'constructor', 'constant', 'const', 'function', 'func', 'method', 'interface', 'member', 'var', 'mixin', 'namespace',
|
210 |
|
211 |
|
212 | 'name', 'typedef', 'callback'];
|
213 |
|
214 |
|
215 | const tagsWithOptionalNamepath = [...namepathDefiningTags,
|
216 |
|
217 | 'borrows',
|
218 | 'emits', 'fires', 'listens',
|
219 | 'alias', 'augments', 'extends', 'lends', 'this',
|
220 |
|
221 | 'memberof', 'memberof!',
|
222 | 'mixes',
|
223 | 'see'];
|
224 |
|
225 |
|
226 | const tagsWithMandatoryNamepath = [
|
227 | 'external', 'host',
|
228 | 'callback', 'name', 'typedef'];
|
229 | const tagsWithMandatoryTypeOrNamepath = [
|
230 | 'alias', 'augments', 'extends', 'borrows', 'lends', 'memberof', 'memberof!', 'name', 'this', 'typedef',
|
231 | 'external', 'host',
|
232 | 'mixes'];
|
233 |
|
234 | const isNamepathDefiningTag = tagName => {
|
235 | return namepathDefiningTags.includes(tagName);
|
236 | };
|
237 |
|
238 | const tagMightHaveAType = (mode, tag) => {
|
239 | return tagsWithMandatoryType.includes(tag) || (mode === 'closure' ? tagsWithOptionalTypeClosure.includes(tag) : tagsWithOptionalType.includes(tag));
|
240 | };
|
241 |
|
242 | const tagMustHaveType = tag => {
|
243 | return tagsWithMandatoryType.includes(tag);
|
244 | };
|
245 |
|
246 | const tagMightHaveNamepath = tag => {
|
247 | return tagsWithOptionalNamepath.includes(tag);
|
248 | };
|
249 |
|
250 | const tagMustHaveNamepath = tag => {
|
251 | return tagsWithMandatoryNamepath.includes(tag);
|
252 | };
|
253 |
|
254 | const tagMightHaveEitherTypeOrNamepath = (mode, tag) => {
|
255 | return tagMightHaveAType(mode, tag) || tagMightHaveNamepath(tag);
|
256 | };
|
257 |
|
258 | const tagMustHaveEitherTypeOrNamepath = tag => {
|
259 | return tagsWithMandatoryTypeOrNamepath.includes(tag);
|
260 | };
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | const hasReturnValue = node => {
|
271 | if (!node) {
|
272 | return false;
|
273 | }
|
274 |
|
275 | switch (node.type) {
|
276 | case 'FunctionExpression':
|
277 | case 'FunctionDeclaration':
|
278 | case 'ArrowFunctionExpression':
|
279 | {
|
280 | return node.expression || hasReturnValue(node.body);
|
281 | }
|
282 |
|
283 | case 'BlockStatement':
|
284 | {
|
285 | return node.body.some(bodyNode => {
|
286 | return bodyNode.type !== 'FunctionDeclaration' && hasReturnValue(bodyNode);
|
287 | });
|
288 | }
|
289 |
|
290 | case 'WhileStatement':
|
291 | case 'DoWhileStatement':
|
292 | case 'ForStatement':
|
293 | case 'ForInStatement':
|
294 | case 'ForOfStatement':
|
295 | case 'WithStatement':
|
296 | {
|
297 | return hasReturnValue(node.body);
|
298 | }
|
299 |
|
300 | case 'IfStatement':
|
301 | {
|
302 | return hasReturnValue(node.consequent) || hasReturnValue(node.alternate);
|
303 | }
|
304 |
|
305 | case 'TryStatement':
|
306 | {
|
307 | return hasReturnValue(node.block) || hasReturnValue(node.handler && node.handler.body) || hasReturnValue(node.finalizer);
|
308 | }
|
309 |
|
310 | case 'SwitchStatement':
|
311 | {
|
312 | return node.cases.some(someCase => {
|
313 | return someCase.consequent.some(hasReturnValue);
|
314 | });
|
315 | }
|
316 |
|
317 | case 'ReturnStatement':
|
318 | {
|
319 |
|
320 | if (node.argument === null) {
|
321 | return false;
|
322 | }
|
323 |
|
324 | return true;
|
325 | }
|
326 |
|
327 | default:
|
328 | {
|
329 | return false;
|
330 | }
|
331 | }
|
332 | };
|
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 | const parseClosureTemplateTag = tag => {
|
351 | return (tag.name + ' ' + tag.description).split(',').map(type => {
|
352 | return type.trim();
|
353 | });
|
354 | };
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 | const enforcedContexts = (context, defaultContexts) => {
|
367 | const _ref = context.options[0] || {},
|
368 | _ref$contexts = _ref.contexts,
|
369 | contexts = _ref$contexts === void 0 ? defaultContexts === true ? ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'] : defaultContexts : _ref$contexts;
|
370 |
|
371 | return contexts;
|
372 | };
|
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 | const getContextObject = (contexts, checkJsdoc) => {
|
380 | return contexts.reduce((obj, prop) => {
|
381 | obj[prop] = checkJsdoc;
|
382 | return obj;
|
383 | }, {});
|
384 | };
|
385 |
|
386 | const filterTags = (tags = [], filter) => {
|
387 | return tags.filter(filter);
|
388 | };
|
389 |
|
390 | const tagsWithNamesAndDescriptions = ['param', 'arg', 'argument', 'property', 'prop',
|
391 | 'returns', 'return'];
|
392 |
|
393 | const getTagsByType = (context, mode, tags, tagPreference) => {
|
394 | const descName = getPreferredTagName(context, mode, 'description', tagPreference);
|
395 | const tagsWithoutNames = [];
|
396 | const tagsWithNames = filterTags(tags, tag => {
|
397 | const tagName = tag.tag;
|
398 | const tagWithName = tagsWithNamesAndDescriptions.includes(tagName);
|
399 |
|
400 | if (!tagWithName && tagName !== descName) {
|
401 | tagsWithoutNames.push(tag);
|
402 | }
|
403 |
|
404 | return tagWithName;
|
405 | });
|
406 | return {
|
407 | tagsWithNames,
|
408 | tagsWithoutNames
|
409 | };
|
410 | };
|
411 |
|
412 | const getAncestor = (sourceCode, nde, depth, idx = 0) => {
|
413 | if (idx === depth) {
|
414 | return nde;
|
415 | }
|
416 |
|
417 | const prevToken = sourceCode.getTokenBefore(nde);
|
418 |
|
419 | if (prevToken) {
|
420 | return getAncestor(sourceCode, prevToken, depth, idx + 1);
|
421 | }
|
422 |
|
423 | return null;
|
424 | };
|
425 |
|
426 | const getIndent = sourceCode => {
|
427 | let indent = sourceCode.text.match(/^\n*([ \t]+)/u);
|
428 |
|
429 |
|
430 | indent = indent ? indent[1] + indent[1].charAt() : ' ';
|
431 | return indent;
|
432 | };
|
433 |
|
434 | var _default = {
|
435 | enforcedContexts,
|
436 | filterTags,
|
437 | getAncestor,
|
438 | getContextObject,
|
439 | getFunctionParameterNames,
|
440 | getIndent,
|
441 | getJsdocParameterNames,
|
442 | getJsdocParameterNamesDeep,
|
443 | getPreferredTagName,
|
444 | getTagsByType,
|
445 | hasATag,
|
446 | hasDefinedTypeReturnTag,
|
447 | hasReturnValue,
|
448 | hasTag,
|
449 | isNamepathDefiningTag,
|
450 | isValidTag,
|
451 | parseClosureTemplateTag,
|
452 | tagMightHaveAType,
|
453 | tagMightHaveEitherTypeOrNamepath,
|
454 | tagMightHaveNamepath,
|
455 | tagMustHaveEitherTypeOrNamepath,
|
456 | tagMustHaveNamepath,
|
457 | tagMustHaveType
|
458 | };
|
459 | exports.default = _default;
|
460 | module.exports = exports.default;
|
461 |
|
\ | No newline at end of file |