forked from gajus/eslint-plugin-jsdoc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
checkParamNames.js
115 lines (92 loc) · 3.07 KB
/
checkParamNames.js
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import iterateJsdoc from '../iterateJsdoc';
const validateParameterNames = (targetTagName : string, functionParameterNames : Array<string>, jsdoc, report) => {
if (!jsdoc || !jsdoc.tags) {
return false;
}
const paramTags = jsdoc.tags.filter((tag) => {
return tag.tag === targetTagName && !tag.name.includes('.');
});
return paramTags.some((tag, index) => {
const dupeTag = paramTags.find((tg, idx) => {
return tg.name === tag.name && idx !== index;
});
if (dupeTag) {
report(`Duplicate @${targetTagName} "${tag.name}"`, null, dupeTag);
return true;
}
const functionParameterName = functionParameterNames[index];
if (!functionParameterName) {
report(
`@${targetTagName} "${tag.name}" does not match an existing function parameter.`,
null,
tag
);
return true;
}
if (functionParameterName === '<ObjectPattern>' || functionParameterName === '<ArrayPattern>') {
return false;
}
if (functionParameterName !== tag.name) {
const expectedNames = functionParameterNames.join(', ');
const actualNames = paramTags.map(({name}) => {
return name;
}).join(', ');
report(
`Expected @${targetTagName} names to be "${expectedNames}". Got "${actualNames}".`,
null,
tag
);
return true;
}
return false;
});
};
const validateParameterNamesDeep = (targetTagName : string, jsdocParameterNames : Array<string>, jsdoc, report : Function) => {
let lastRealParameter;
return jsdocParameterNames.some((jsdocParameterName, idx) => {
const isPropertyPath = jsdocParameterName.includes('.');
if (isPropertyPath) {
if (!lastRealParameter) {
report(`@${targetTagName} path declaration ("${jsdocParameterName}") appears before any real parameter.`, null, jsdoc.tags[idx]);
return true;
}
let pathRootNodeName = jsdocParameterName.slice(0, jsdocParameterName.indexOf('.'));
if (pathRootNodeName.endsWith('[]')) {
pathRootNodeName = pathRootNodeName.slice(0, -2);
}
if (pathRootNodeName !== lastRealParameter) {
report(
`@${targetTagName} path declaration ("${jsdocParameterName}") root node name ("${pathRootNodeName}") ` +
`does not match previous real parameter name ("${lastRealParameter}").`,
null,
jsdoc.tags[idx]
);
return true;
}
} else {
lastRealParameter = jsdocParameterName;
}
return false;
});
};
export default iterateJsdoc(({
jsdoc,
report,
utils
}) => {
const functionParameterNames = utils.getFunctionParameterNames();
const jsdocParameterNamesDeep = utils.getJsdocParameterNamesDeep();
if (!jsdocParameterNamesDeep) {
return;
}
const targetTagName = utils.getPreferredTagName({tagName: 'param'});
const isError = validateParameterNames(targetTagName, functionParameterNames, jsdoc, report);
if (isError) {
return;
}
validateParameterNamesDeep(targetTagName, jsdocParameterNamesDeep, jsdoc, report);
}, {
meta: {
type: 'suggestion'
}
});