Skip to content

Commit 789fd27

Browse files
committed
Merge pull request #58 from zxqfox/feature/escape-param-names
Allow ticked param names
2 parents dc6bf05 + ee6f897 commit 789fd27

File tree

2 files changed

+130
-1
lines changed

2 files changed

+130
-1
lines changed

lib/jsdoc.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,109 @@ DocLocation.prototype.shift = function(line, column) {
175175
* @private
176176
*/
177177
function _parseComment(comment) {
178+
var notCleanTagRe = /[^\w\d_]/i;
178179
var parsed = commentParser(comment, {
179180
'line_numbers': true,
180181
'raw_value': true
181182
})[0];
183+
184+
if (parsed && Array.isArray(parsed.tags)) {
185+
// additional tag.name parsing logic
186+
parsed.tags = parsed.tags.map(function(tag) {
187+
if (!tag.name || !notCleanTagRe.test(tag.name)) {
188+
return tag;
189+
}
190+
191+
var node = _parseNameAgain(tag.name);
192+
if (node.error) {
193+
tag.error = node.error;
194+
return tag;
195+
}
196+
if (node.ticked) {
197+
tag.ticked = node.ticked;
198+
}
199+
if (node.default) {
200+
tag.default = node.default;
201+
}
202+
if (node.required) {
203+
tag.required = node.required;
204+
}
205+
206+
tag.name = node.name;
207+
208+
return tag;
209+
});
210+
}
211+
182212
return parsed;
183213
}
184214

215+
/**
216+
* Additional name parsing logic for our purposes
217+
* @param {string} str - unparsed name thing
218+
* @return {Object}
219+
*/
220+
function _parseNameAgain(str) { // (?:\s+(\S+))?
221+
var out = {};
222+
223+
// strip ticks (support for ticked variables)
224+
if (str[0] === '`' && str[str.length - 1] === '`') {
225+
out.ticked = true;
226+
str = str.substr(1, str.length - 2);
227+
}
228+
229+
// strip chevrons
230+
if (str[0] === '<' && str[str.length - 1] === '>') {
231+
out.required = true;
232+
str = str.substr(1, str.length - 2);
233+
if (str.replace(/[\s\w\d]+/ig, '') === '') {
234+
out.name = str.replace(/^\s+|\s+$/g, '');
235+
return out;
236+
} else {
237+
out.error = 'Unknown name format';
238+
return out;
239+
}
240+
}
241+
242+
// parsing [name="mix"]
243+
var ch;
244+
var res = '';
245+
var brackets = 0;
246+
var re = /\s/;
247+
var l = str.length;
248+
var pos = 0;
249+
while (pos < l) {
250+
ch = str[pos];
251+
brackets += ch === '[' ? 1 : ch === ']' ? -1 : 0;
252+
res += ch;
253+
pos ++;
254+
if (brackets === 0 && re.test(str[pos])) {
255+
break;
256+
}
257+
}
258+
if (brackets) {
259+
// throw new Error('Unpaired curly in type doc');
260+
out.error = 'Unpaired brackets in type doc';
261+
return out;
262+
}
263+
264+
if (res[0] === '[' && res[res.length - 1] === ']') {
265+
out.optional = true;
266+
res = res.substr(1, res.length - 2);
267+
var eqPos = res.indexOf('=');
268+
if (eqPos !== -1) {
269+
out.name = res.substr(0, eqPos);
270+
out.default = res.substr(eqPos + 1).replace(/^(["'])(.+)(\1)$/, '$2');
271+
} else {
272+
out.name = res;
273+
}
274+
} else {
275+
out.name = res;
276+
}
277+
278+
return out;
279+
}
280+
185281
/**
186282
* @param {String} typeString
187283
* @return {?Array.<SimplifiedType>} - parsed jsdoctype string as array

test/lib/rules/validate-jsdoc/check-param-names.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
describe('lib/rules/validate-jsdoc/check-param-names', function () {
1+
describe('lib/rules/validate-jsdoc/check-param-names', function() {
22
var checker = global.checker({
33
additionalRules: ['lib/rules/validate-jsdoc.js']
44
});
@@ -24,6 +24,7 @@ describe('lib/rules/validate-jsdoc/check-param-names', function () {
2424

2525
checker.cases([
2626
/* jshint ignore:start */
27+
// jscs:disable
2728
{
2829
it: 'should not report',
2930
code: function() {
@@ -93,12 +94,14 @@ describe('lib/rules/validate-jsdoc/check-param-names', function () {
9394
};
9495
}
9596
}
97+
// jscs:enable
9698
/* jshint ignore:end */
9799
]);
98100

99101
// locations
100102
checker.cases([
101103
/* jshint ignore:start */
104+
// jscs:disable
102105
{
103106
it: 'should report error in jsdoc for function',
104107
code: function () {
@@ -123,12 +126,14 @@ describe('lib/rules/validate-jsdoc/check-param-names', function () {
123126
},
124127
errors: {line: 3, column: 23}
125128
}
129+
// jscs:enable
126130
/* jshint ignore:end */
127131
]);
128132

129133
// out-of-order. issue #33
130134
checker.cases([
131135
/* jshint ignore:start */
136+
/* jscs:disable */
132137
{
133138
it: 'should report out of order',
134139
code: function () {
@@ -206,7 +211,35 @@ describe('lib/rules/validate-jsdoc/check-param-names', function () {
206211
errors: [
207212
{message: 'expected zzz but got xxx', column: 14, line: 3, rule: "jsDoc"}
208213
]
214+
215+
}, {
216+
it: 'should not report simple ticked param',
217+
code: function() {
218+
/**
219+
* @param {String} `message`
220+
*/
221+
function methodOne(message) {}
222+
}
223+
}, {
224+
it: 'should not report chevroned params',
225+
code: function() {
226+
/**
227+
* @param {String} <required>
228+
* @param {Object} [optional]
229+
*/
230+
function methodTwo(required, optional) {}
231+
}
232+
}, {
233+
it: 'should not report ticked params',
234+
code: function() {
235+
/**
236+
* @param {String} `<required>`
237+
* @param {Object} `[optional="abcabc"]`
238+
*/
239+
function methodThree(required, optional) {}
240+
}
209241
}
242+
/* jscs: enable */
210243
/* jshint ignore:end */
211244
]);
212245

0 commit comments

Comments
 (0)