Skip to content

Commit 3b1ed48

Browse files
author
Alexej Yaroshevich
committed
pkg: update deps
Fixes #84
1 parent 72f5a17 commit 3b1ed48

File tree

3 files changed

+108
-89
lines changed

3 files changed

+108
-89
lines changed

.jscsrc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
2+
"plugins": ["jscs-jsdoc"],
23
"preset": "google",
3-
"fileExtensions": [ ".js", "jscs" ],
4+
5+
"fileExtensions": [ ".js", ".jscs" ],
46

57
"requireParenthesesAroundIIFE": true,
68
"maximumLineLength": 120,
@@ -18,8 +20,6 @@
1820
"test/lib/rules/**"
1921
],
2022

21-
"plugins": ["jscs-jsdoc"],
22-
2323
"jsDoc": {
2424
"enforceExistence": true,
2525
"checkAnnotations": "closurecompiler",

lib/jsdoc.js

Lines changed: 100 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
var assert = require('assert');
22
var commentParser = require('comment-parser');
3+
34
var TypeParser = require('jsdoctypeparser').Parser;
45
var TypeBuilder = require('jsdoctypeparser').Builder;
56

67
// wtf but it needed to stop writing warnings to stdout
78
// and revert exceptions functionality
89
TypeBuilder.ENABLE_EXCEPTIONS = true;
910

11+
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
12+
var PARSERS = {
13+
tag: commentParser.PARSERS.parse_tag,
14+
type: commentParser.PARSERS.parse_type,
15+
description: commentParser.PARSERS.parse_description,
16+
};
17+
// jscs:enable
18+
var RE_SPACE = /\s/;
19+
1020
module.exports = {
1121

1222
/**
@@ -94,6 +104,8 @@ function DocTag(tag, loc) {
94104
this.id = tag.tag;
95105
this.line = tag.line;
96106
this.value = tag.value;
107+
this.name = undefined;
108+
this.type = undefined;
97109

98110
this.description = tag.description;
99111
this.optional = tag.optional;
@@ -193,107 +205,114 @@ DocLocation.prototype.shift = function(line, column) {
193205
* @private
194206
*/
195207
function _parseComment(comment) {
196-
var notCleanTagRe = /[^\w\d_]/i;
197-
var parsed = commentParser(comment, {
198-
'line_numbers': true,
199-
'raw_value': true
208+
return commentParser(comment, {
209+
parsers: [
210+
// parse tag
211+
function(str) {
212+
var res = PARSERS.tag.call(this, str);
213+
res.data.value = str;
214+
return res;
215+
},
216+
PARSERS.type,
217+
_parseName,
218+
PARSERS.description,
219+
]
200220
})[0];
201-
202-
if (parsed && Array.isArray(parsed.tags)) {
203-
// additional tag.name parsing logic
204-
parsed.tags = parsed.tags.map(function(tag) {
205-
if (!tag.name || !notCleanTagRe.test(tag.name)) {
206-
return tag;
207-
}
208-
209-
var node = _parseNameAgain(tag.name);
210-
if (node.error) {
211-
tag.error = node.error;
212-
return tag;
213-
}
214-
if (node.ticked) {
215-
tag.ticked = node.ticked;
216-
}
217-
if (node.default) {
218-
tag.default = node.default;
219-
}
220-
if (node.required) {
221-
tag.required = node.required;
222-
}
223-
224-
tag.name = node.name;
225-
226-
return tag;
227-
});
228-
}
229-
230-
return parsed;
231221
}
232222

233223
/**
234-
* Additional name parsing logic for our purposes
235-
* @param {string} str - unparsed name thing
236-
* @returns {Object}
224+
* analogue of str.match(/@(\S+)(?:\s+\{([^\}]+)\})?(?:\s+(\S+))?(?:\s+([^$]+))?/);
225+
* @param {string} str raw jsdoc string
226+
* @returns {?Object} parsed tag node
237227
*/
238-
function _parseNameAgain(str) { // (?:\s+(\S+))?
239-
var out = {};
240-
241-
// strip ticks (support for ticked variables)
242-
if (str[0] === '`' && str[str.length - 1] === '`') {
243-
out.ticked = true;
244-
str = str.substr(1, str.length - 2);
245-
}
246-
247-
// strip chevrons
248-
if (str[0] === '<' && str[str.length - 1] === '>') {
249-
out.required = true;
250-
str = str.substr(1, str.length - 2);
251-
if (str.replace(/[\s\w\d]+/ig, '') === '') {
252-
out.name = str.replace(/^\s+|\s+$/g, '');
253-
return out;
254-
} else {
255-
out.error = 'Unknown name format';
256-
return out;
257-
}
228+
function _parseName(str, data) {
229+
if (data.errors && data.errors.length) {
230+
return null;
258231
}
259232

260-
// parsing [name="mix"]
261-
var ch;
262-
var res = '';
233+
var l = str.length;
234+
var pos = _skipws(str);
235+
var ch = '';
236+
var name = '';
263237
var brackets = 0;
264-
var re = /\s/;
265-
var l = str.length;
266-
var pos = 0;
238+
var chevrons = 0;
239+
var ticks = 0;
240+
267241
while (pos < l) {
268242
ch = str[pos];
269243
brackets += ch === '[' ? 1 : ch === ']' ? -1 : 0;
270-
res += ch;
271-
pos ++;
272-
if (brackets === 0 && re.test(str[pos])) {
244+
chevrons += ch === '<' ? 1 : ch === '>' ? -1 : 0;
245+
if (ch === '`') {
246+
ticks++;
247+
}
248+
if (ticks % 2 === 0 && chevrons === 0 && brackets === 0 && RE_SPACE.test(ch)) {
273249
break;
274250
}
251+
name += ch;
252+
pos ++;
253+
}
254+
255+
if (brackets !== 0) { throw Error('Invalid `name`, unpaired brackets'); }
256+
if (chevrons !== 0) { throw Error('Invalid `name`, unpaired chevrons'); }
257+
if (ticks % 2 !== 0) { throw Error('Invalid `name`, unpaired ticks'); }
258+
259+
var res = {
260+
name: name,
261+
default: undefined,
262+
optional: false,
263+
required: false,
264+
ticked: false
265+
};
266+
267+
// strip ticks (support for ticked variables)
268+
if (name[0] === '`' && name[name.length - 1] === '`') {
269+
res.ticked = true;
270+
name = name.slice(1, -1).trim();
275271
}
276-
if (brackets) {
277-
// throw new Error('Unpaired curly in type doc');
278-
out.error = 'Unpaired brackets in type doc';
279-
return out;
272+
273+
// strip chevrons
274+
if (name[0] === '<' && name[name.length - 1] === '>') {
275+
res.required = true;
276+
name = name.slice(1, -1).trim();
280277
}
281278

282-
if (res[0] === '[' && res[res.length - 1] === ']') {
283-
out.optional = true;
284-
res = res.substr(1, res.length - 2);
285-
var eqPos = res.indexOf('=');
279+
// strip brackets
280+
if (name[0] === '[' && name[name.length - 1] === ']') {
281+
res.optional = true;
282+
name = name.slice(1, -1).trim();
283+
284+
var eqPos = name.indexOf('=');
286285
if (eqPos !== -1) {
287-
out.name = res.substr(0, eqPos);
288-
out.default = res.substr(eqPos + 1).replace(/^(["'])(.+)(\1)$/, '$2');
289-
} else {
290-
out.name = res;
286+
res.default = name.substr(eqPos + 1).trim().replace(/^(["'])(.+)(\1)$/, '$2');
287+
name = name.substr(0, eqPos).trim();
291288
}
292-
} else {
293-
out.name = res;
294289
}
295290

296-
return out;
291+
res.name = name;
292+
293+
return {
294+
source : str.substr(0, pos),
295+
data : res
296+
};
297+
298+
/**
299+
* Returns the next to whitespace char position in a string
300+
*
301+
* @param {string} str
302+
* @return {number}
303+
*/
304+
function _skipws(str) {
305+
var i = 0;
306+
var l = str.length;
307+
var ch;
308+
do {
309+
ch = str[i];
310+
if (ch !== ' ' && ch !== '\t') {
311+
break;
312+
}
313+
} while (++i < l);
314+
return i;
315+
}
297316
}
298317

299318
/**

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
"node": ">= 0.10.0"
2424
},
2525
"dependencies": {
26-
"comment-parser": "0.2.4",
26+
"comment-parser": "0.3.0",
2727
"jsdoctypeparser": "^1.1.4"
2828
},
2929
"devDependencies": {
30-
"chai": "^2.2.0",
31-
"jscs": "^1.12.0",
32-
"jshint": "^2.6.3",
33-
"mocha": "^2.2.1"
30+
"chai": "^2.3.0",
31+
"jscs": "^1.13.1",
32+
"jshint": "^2.7.0",
33+
"mocha": "^2.2.4"
3434
},
3535
"_peerDependencies": {
3636
"jscs": ">=1.8.0 <2.0"

0 commit comments

Comments
 (0)