Skip to content

Commit

Permalink
jscsrc: add jsdoc rules, fixup code
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexej Yaroshevich committed Nov 27, 2014
1 parent c92384e commit f7ce734
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 26 deletions.
17 changes: 16 additions & 1 deletion .jscsrc
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,20 @@
"excludeFiles": [
"test/data/**",
"test/lib/rules/**"
]
],

"plugins": ["jscs-jsdoc"],

"jsDoc": {
"enforceExistence": true,
"checkAnnotations": "closurecompiler",
"checkParamNames": true,
"requireParamTypes": true,
"checkRedundantParams": true,
"checkReturnTypes": true,
"checkRedundantReturns": true,
"requireReturnTypes": true,
"checkTypes": "strictNativeCase",
"checkRedundantAccess": true
}
}
3 changes: 2 additions & 1 deletion lib/esprima-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ var scopeNodeTypes = [

/**
* Search for the closest scope node tree for Node
* @param {{type: String}} n
* @param {{type: string}} n
* @returns {EsprimaNode}
*/
function closestScopeNode (n) {
while (n && scopeNodeTypes.indexOf(n.type) === -1) {
Expand Down
3 changes: 3 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* @param {module:jscs/lib/Configuration} configuration
*/
module.exports = function(configuration) {
configuration.registerRule(require('./rules/validate-jsdoc'));
};
42 changes: 24 additions & 18 deletions lib/jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var TypeBuilder = require('jsdoctypeparser').Builder;
TypeBuilder.ENABLE_EXCEPTIONS = true;

module.exports = {

/**
* @param {string} commentNode
* @returns {DocComment}
Expand Down Expand Up @@ -57,18 +58,18 @@ function DocComment(value, loc) {
});

/**
* @param {function} fn
* @chainable
* @param {function(this: DocComment, DocTag): DocComment} fn
* @returns {DocComment}
*/
this.iterate = function forEachTag(fn) {
this.tags.forEach(fn);
this.tags.forEach(fn, this);
return this;
};

/**
* @param {string|array} types
* @param {function} fn
* @chainable
* @param {string|Array.<string>} types
* @param {function(this: DocComment, DocTag): DocComment} fn
* @returns {DocComment}
*/
this.iterateByType = function iterateByTypes(types, fn) {
var k = 0;
Expand All @@ -85,7 +86,7 @@ function DocComment(value, loc) {

/**
* Simple jsdoc tag object
* @param {Object} tag
* @param {Object} tag object from comment parser, fields: tag, line, value, name, type, description
* @param {DocLocation} loc
* @constructor
*/
Expand Down Expand Up @@ -159,8 +160,8 @@ function DocType(type, loc) {
/**
* DocLocation
* @constructor
* @param {Number} line
* @param {Number} column
* @param {number} line
* @param {number} column
* @param {(Object|DocLocation)} [rel]
*/
function DocLocation(line, column, rel) {
Expand All @@ -173,9 +174,9 @@ function DocLocation(line, column, rel) {

/**
* Shift location by line and column
* @param {Number|Object} line
* @param {Number} [column]
* @return {DocLocation}
* @param {number|Object} line
* @param {number} [column]
* @returns {DocLocation}
*/
DocLocation.prototype.shift = function(line, column) {
if (typeof line === 'object') {
Expand All @@ -187,7 +188,7 @@ DocLocation.prototype.shift = function(line, column) {

/**
* Comment parsing helper
* @param {String} comment
* @param {string} comment
* @returns {Object}
* @private
*/
Expand Down Expand Up @@ -232,7 +233,7 @@ function _parseComment(comment) {
/**
* Additional name parsing logic for our purposes
* @param {string} str - unparsed name thing
* @return {Object}
* @returns {Object}
*/
function _parseNameAgain(str) { // (?:\s+(\S+))?
var out = {};
Expand Down Expand Up @@ -296,8 +297,8 @@ function _parseNameAgain(str) { // (?:\s+(\S+))?
}

/**
* @param {String} typeString
* @return {?Array.<SimplifiedType>} - parsed jsdoctype string as array
* @param {string} typeString
* @returns {?Array.<SimplifiedType>} - parsed jsdoctype string as array
*/
function _parseDocType(typeString) {
var parser = new TypeParser();
Expand All @@ -313,6 +314,11 @@ function _parseDocType(typeString) {
return node;
}

/**
* @param {EsprimaNode} node
* @param {Function} cb
* @returns {Array}
*/
function _iterateDocTypes(node, cb) {
var res;

Expand Down Expand Up @@ -413,7 +419,7 @@ function _iterateDocTypes(node, cb) {
/**
* Converts AST jsDoc node to simple object
* @param {Object} node
* @returns {!(SimplifiedType[])}
* @returns {!Array.<SimplifiedType>}
* @link https://github.com/Kuniwak/jsdoctypeparser
*/
function _simplifyType(node) {
Expand All @@ -426,7 +432,7 @@ function _simplifyType(node) {
return res;
}

var jsPrimitives = 'String Number Boolean Object Array Date Null Undefined Function Array RegExp'
var jsPrimitives = 'string number boolean null undefined Object Function Array Date RegExp'
.toLowerCase().split(' ');

/**
Expand Down
43 changes: 40 additions & 3 deletions lib/rules/validate-jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ var jsdoc = require('../jsdoc');
var esprimaHelpers = require('../esprima-helpers');
var validators = require('./validate-jsdoc/index');

/**
* Rule constructor
* @this {module:jscs/Rule}
* @constructor
*/
module.exports = function() {};

module.exports.prototype = {

// load all rules and init them
/**
* Load all rules and init them
* @param {Object} options
* @throws {Error} If options is not an Object
*/
configure: function(options) {
assert(typeof options === 'object', 'jsDoc option requires object value');

Expand Down Expand Up @@ -53,10 +62,17 @@ module.exports.prototype = {
}, this);
},

/**
* @returns {string}
*/
getOptionName: function() {
return 'jsDoc';
},

/**
* @param {module:jscs/JsFile} file
* @param {module:jscs/Errors} errors
*/
check: function(file, errors) {
patchNodesInFile(file);
this._iterate = file.iterate;
Expand Down Expand Up @@ -120,6 +136,12 @@ module.exports.prototype = {
});
});

/**
* send error to jscs
* @param {string} text
* @param {number|DocLocation} relLine
* @param {number} [relColumn]
*/
function addError(text, relLine, relColumn) {
var line;
var column;
Expand All @@ -133,6 +155,12 @@ module.exports.prototype = {
errors.add(text, line, column);
}

/**
* Generates function with location fixing logic to send error to jscs
* @param {function(string, number|Object, ?number)} err
* @param {DocTag} tag
* @returns {function(string, number|Object, ?number)}
*/
function fixErrLocation (err, tag) {
return function(text, line, column) {
line = line || tag.line;
Expand All @@ -147,8 +175,7 @@ module.exports.prototype = {
},

/**
* caching scope search
* @todo move to patchNodesInFile
* caching scope search. todo: move to patchNodesInFile
* @param {Object} node
*/
_getReturnStatementsForNode: function(node) {
Expand Down Expand Up @@ -189,6 +216,11 @@ function patchNodesInFile(file) {
});
});

/**
* Fetchs jsdoc block for this
* @this {module:esprima/Node}
* @returns {DocComment}
*/
function getJsdoc() {
if (!this.hasOwnProperty('_jsdoc')) {
var res = findDocCommentBeforeLine(this.loc.start.line);
Expand All @@ -197,6 +229,11 @@ function patchNodesInFile(file) {
return this._jsdoc;
}

/**
* Finds DocComment in file before passed line number
* @param {number} line
* @returns {?module:esprima/Node}
*/
function findDocCommentBeforeLine(line) {
line--; // todo: buggy behaviour, can't jump back over empty lines
for (var i = 0, l = fileComments.length; i < l; i++) {
Expand Down
3 changes: 3 additions & 0 deletions lib/rules/validate-jsdoc/check-annotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ module.exports.options = {

var tags;

/**
* @param {Object} options
*/
validateAnnotations.configure = function(options) {
var o = options.checkAnnotations;

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/validate-jsdoc/check-param-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function validateCheckParamNames(node, err) {
/**
* tag checker
* @param {DocType} tag
* @param {Number} i index
* @param {number} i index
*/
function(tag, i) {
// checking validity
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/validate-jsdoc/check-redundant-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function validateCheckParamNames(node, err) {
/**
* tag checker
* @param {DocType} tag
* @param {Number} i index
* @param {number} i index
*/
function(tag, i) {
// skip if there is dot in param name (object's inner param)
Expand Down
7 changes: 6 additions & 1 deletion lib/rules/validate-jsdoc/check-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ function validateTypesInTags(file, errors) {
return;
}

node.iterateByType(Object.keys(allowedTags), function(tag) {
node.iterateByType(Object.keys(allowedTags),
/**
* @param {DocType} tag
*/
function(tag) {

if (!tag.type) {
// skip untyped params
return;
Expand Down
11 changes: 11 additions & 0 deletions lib/rules/validate-jsdoc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ var validatorsByName = module.exports = {
};

Object.defineProperty(validatorsByName, 'load', {
/**
* loads and initializes existing and required validators
* @param {Object} passedOptions
* @returns {Array.<Function>}
*/
value: function loadValidators(passedOptions) {
if (!passedOptions) {
return [];
Expand Down Expand Up @@ -51,6 +56,12 @@ Object.defineProperty(validatorsByName, 'load', {
});

Object.defineProperty(validatorsByName, 'checkOptions', {
/**
* Validates passed options
* @param {Object} validator
* @param {Object} options
* @throws {Error} If option is not valid
*/
value: function checkOptions(validator, options) {
Object.keys(validator.options).forEach(function(option) {
var data = validator.options[option];
Expand Down
Loading

0 comments on commit f7ce734

Please sign in to comment.