mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
allow default values for parameters to contain brackets (#640)
Squashed commit of the following:
commit 5363a9850f1279c1ea5f916455899479aca71261
Author: Jeff Williams <jeffrey.l.williams@gmail.com>
Date: Sat Nov 1 15:13:33 2014 -0700
DRY out; delint; remove unused capture group
commit e3066068f91ba5f2c920cb5389eae15ac70f45aa
Author: Christopher D. Parks <christopher.daniel.parks@gmail.com>
Date: Fri Apr 25 16:32:20 2014 -0700
Add missing semi-colon caught by eslint
commit 7bd864eecba67df99bae7b338685bf6cf31e2516
Author: Christopher D. Parks <christopher.daniel.parks@gmail.com>
Date: Fri Apr 25 16:14:12 2014 -0700
Adding tests for fix #640
Without the fix, we get the following when running ./jsdoc -T
Failures:
jsdoc/name splitName
1) should allow default values to have brackets
Message:
Expected '[path=["home",' to be '[path=["home", "user"]]'.
Stacktrace:
undefined
2) should allow default values to have brackets
Message:
Expected '"user"]] - Path split into components' to be 'Path split into components'.
Stacktrace:
undefined
3) should allow default values to have brackets inside strings
Message:
Expected '[path=["Unmatched' to be '[path=["Unmatched begin: ["]]'.
Stacktrace:
undefined
4) should allow default values to have brackets inside strings
Message:
Expected 'begin: ["]] - Path split into components' to be 'Path split into components'.
Stacktrace:
undefined
Finished in 5.704 seconds
870 tests, 2331 assertions, 4 failures
These tests pass with the fix
commit 531b13893dc2c715e5cb988fdb872897547e6375
Author: Christopher D. Parks <christopher.daniel.parks@gmail.com>
Date: Fri Apr 25 15:59:47 2014 -0700
Fix for #640 - Allow default values for parameters to contain brackets
Because JSDoc uses brackets to delimit default values inside the @param tag,
default values containing brackets can get misparsed. We solve this by
redefining splitName() in terms of splitNameMatchingBrackets() which tries
to find the matching end bracket if the name starts with an open bracket.
Ignores brackets inside strings. If splitNameMatchingBrackets() fails to find
the closing bracket, we fall back to the original regex method.
This commit is contained in:
parent
2224bee3be
commit
5399745a97
@ -69,12 +69,16 @@ var puncToScope = exports.puncToScope = _.invert(scopeToPunc);
|
||||
|
||||
var DEFAULT_SCOPE = SCOPE.NAMES.STATIC;
|
||||
var SCOPE_PUNC = _.values(SCOPE.PUNC);
|
||||
var REGEXP_SCOPE_PUNC = '[' + SCOPE_PUNC.join() + ']';
|
||||
var REGEXP_LEADING_SCOPE = new RegExp('^(' + REGEXP_SCOPE_PUNC + ')');
|
||||
var REGEXP_TRAILING_SCOPE = new RegExp('(' + REGEXP_SCOPE_PUNC + ')$');
|
||||
var SCOPE_PUNC_STRING = '[' + SCOPE_PUNC.join() + ']';
|
||||
var REGEXP_LEADING_SCOPE = new RegExp('^(' + SCOPE_PUNC_STRING + ')');
|
||||
var REGEXP_TRAILING_SCOPE = new RegExp('(' + SCOPE_PUNC_STRING + ')$');
|
||||
|
||||
var DESCRIPTION = '(?:(?:[ \\t]*\\-\\s*|\\s+)(\\S[\\s\\S]*))?$';
|
||||
var REGEXP_DESCRIPTION = new RegExp(DESCRIPTION);
|
||||
var REGEXP_NAME_DESCRIPTION = new RegExp('^(\\[[^\\]]+\\]|\\S+)' + DESCRIPTION);
|
||||
|
||||
function nameIsLongname(name, memberof) {
|
||||
var regexp = new RegExp('^' + escape(memberof) + REGEXP_SCOPE_PUNC);
|
||||
var regexp = new RegExp('^' + escape(memberof) + SCOPE_PUNC_STRING);
|
||||
|
||||
return regexp.test(name);
|
||||
}
|
||||
@ -347,6 +351,52 @@ exports.longnamesToTree = function longnamesToTree(longnames, doclets) {
|
||||
return tree;
|
||||
};
|
||||
|
||||
/**
|
||||
Split a string that starts with a name and ends with a description into its parts.
|
||||
Allows the defaultvalue (if present) to contain brackets. If the name is found to have
|
||||
mismatched brackets, null is returned.
|
||||
@param {string} nameDesc
|
||||
@returns {object} Hash with "name" and "description" properties.
|
||||
*/
|
||||
function splitNameMatchingBrackets(nameDesc) {
|
||||
var buffer = [];
|
||||
var c;
|
||||
var stack = 0;
|
||||
var stringEnd = null;
|
||||
|
||||
for (var i = 0; i < nameDesc.length; ++i) {
|
||||
c = nameDesc[i];
|
||||
buffer.push(c);
|
||||
|
||||
if (stringEnd) {
|
||||
if (c === '\\' && i + 1 < nameDesc.length) {
|
||||
buffer.push(nameDesc[++i]);
|
||||
} else if (c === stringEnd) {
|
||||
stringEnd = null;
|
||||
}
|
||||
} else if (c === '"' || c === "'") {
|
||||
stringEnd = c;
|
||||
} else if (c === '[') {
|
||||
++stack;
|
||||
} else if (c === ']') {
|
||||
if (--stack === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stack || stringEnd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
nameDesc.substr(i).match(REGEXP_DESCRIPTION);
|
||||
return {
|
||||
name: buffer.join(''),
|
||||
description: RegExp.$1
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Split a string that starts with a name and ends with a description into its parts.
|
||||
@param {string} nameDesc
|
||||
@ -356,9 +406,15 @@ exports.splitName = function(nameDesc) {
|
||||
// like: name, [name], name text, [name] text, name - text, or [name] - text
|
||||
// the hyphen must be on the same line as the name; this prevents us from treating a Markdown
|
||||
// dash as a separator
|
||||
nameDesc.match(/^(\[[^\]]+\]|\S+)((?:[ \t]*\-\s*|\s+)(\S[\s\S]*))?$/);
|
||||
|
||||
// optional values get special treatment
|
||||
if (nameDesc[0] === '[') {
|
||||
return splitNameMatchingBrackets(nameDesc);
|
||||
}
|
||||
|
||||
nameDesc.match(REGEXP_NAME_DESCRIPTION);
|
||||
return {
|
||||
name: RegExp.$1,
|
||||
description: RegExp.$3
|
||||
description: RegExp.$2
|
||||
};
|
||||
};
|
||||
|
||||
@ -248,6 +248,22 @@ describe('jsdoc/name', function() {
|
||||
expect(parts.name).toBe('socket');
|
||||
expect(parts.description).toBe('- The networking kind, not the wrench.');
|
||||
});
|
||||
|
||||
it('should allow default values to have brackets', function() {
|
||||
var startName = '[path=["home", "user"]] - Path split into components'
|
||||
var parts = jsdoc.name.splitName(startName);
|
||||
|
||||
expect(parts.name).toBe('[path=["home", "user"]]');
|
||||
expect(parts.description).toBe('Path split into components');
|
||||
});
|
||||
|
||||
it('should allow default values to have unmatched brackets inside strings', function() {
|
||||
var startName = '[path=["Unmatched begin: ["]] - Path split into components'
|
||||
var parts = jsdoc.name.splitName(startName);
|
||||
|
||||
expect(parts.name).toBe('[path=["Unmatched begin: ["]]');
|
||||
expect(parts.description).toBe('Path split into components');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolve', function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user