jsdoc: change errors to warning when unknown tags are encountered in xml

Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Mihai Tudor Panu 2015-05-26 17:22:13 -07:00
parent 33b508110e
commit 54c2c8db76

View File

@ -36,7 +36,7 @@ Promise.promisifyAll(fs);
var xml2js = { var xml2js = {
// js-format specs // js-format specs
// MODULE: <module name> // MODULE: <module name>
// ENUMS: { // ENUMS: {
@ -47,7 +47,7 @@ var xml2js = {
// } // }
// ENUMS_BY_GROUP: { // ENUMS_BY_GROUP: {
// <enum type>: { // <enum type>: {
// description: <enum group description> // description: <enum group description>
// members: [ <enum name>, ... ] // members: [ <enum name>, ... ]
// }, ... // }, ...
// } // }
@ -58,7 +58,7 @@ var xml2js = {
// <param name>: { // <param name>: {
// type: <param type>, // type: <param type>,
// description: <param description > // description: <param description >
// }, ... // }, ...
// }, // },
// return: { // return: {
// type: <return type>, // type: <return type>,
@ -79,7 +79,7 @@ var xml2js = {
// enums: { ... }, // enums: { ... },
// enums_by_group: { ... } // enums_by_group: { ... }
// }, ... // }, ...
// } // }
// CLASSGROUPS: { // CLASSGROUPS: {
// <group name>: { // <group name>: {
// description: <group description>, // description: <group description>,
@ -92,23 +92,23 @@ var xml2js = {
METHODS: {}, METHODS: {},
CLASSES: {}, CLASSES: {},
CLASSGROUPS: {}, CLASSGROUPS: {},
// baseline c -> js type mapping // baseline c -> js type mapping
TYPEMAPS: { TYPEMAPS: {
'^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number', '^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number',
'^bool$': 'Boolean', '^bool$': 'Boolean',
'^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String' // TODO: verify that swig does this mapping '^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String' // TODO: verify that swig does this mapping
}, },
// custom c -> js type mapping for pointers // custom c -> js type mapping for pointers
// ARRAY_TYPEMAPS: { // ARRAY_TYPEMAPS: {
// <pointer data type>: { // <pointer data type>: {
// arrayType: <swig generated array type that will replace pointers of data type>, // arrayType: <swig generated array type that will replace pointers of data type>,
// classes: [ <class that contains arrayType>, ... ] // classes: [ <class that contains arrayType>, ... ]
// }, ... // }, ...
// } // }
// POINTER_TYPEMAPS: { // POINTER_TYPEMAPS: {
// <class that contains pointerType>: { // <class that contains pointerType>: {
// <c pointer data type>: <js swig generated pointer type that will replace pointers of data type>, ... // <c pointer data type>: <js swig generated pointer type that will replace pointers of data type>, ...
@ -116,8 +116,8 @@ var xml2js = {
// } // }
ARRAY_TYPEMAPS: {}, ARRAY_TYPEMAPS: {},
POINTER_TYPEMAPS: {}, POINTER_TYPEMAPS: {},
// add command line options for this module // add command line options for this module
addOptions: function(opts) { addOptions: function(opts) {
xml2js.opts = opts; xml2js.opts = opts;
@ -128,8 +128,8 @@ var xml2js = {
.option('-g, --imagedir [directory]', 'directory to link to where the images will be kept', '') .option('-g, --imagedir [directory]', 'directory to link to where the images will be kept', '')
.option('-s, --strict', 'leave out methods/variables if unknown type') .option('-s, --strict', 'leave out methods/variables if unknown type')
}, },
// parse doxygen xml -> js-format specs // parse doxygen xml -> js-format specs
// TODO: figure out whether we need to document any protected methods/variables // TODO: figure out whether we need to document any protected methods/variables
parse: function() { parse: function() {
@ -138,9 +138,9 @@ var xml2js = {
var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; } var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; }
var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml'; var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml';
xml2js.MODULE = xml2js.opts.module; xml2js.MODULE = xml2js.opts.module;
return Promise.join(createXmlParser(XML_GRAMMAR_SPEC), return Promise.join(createXmlParser(XML_GRAMMAR_SPEC),
xml2js.opts.typemaps ? initCustomPointerTypemaps(xml2js.opts.typemaps) : Promise.resolve(), xml2js.opts.typemaps ? initCustomPointerTypemaps(xml2js.opts.typemaps) : Promise.resolve(),
fs.readFileAsync(NAMESPACE_SPEC, 'utf8'), fs.readFileAsync(NAMESPACE_SPEC, 'utf8'),
fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null), fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null),
function(xmlparser, ignore, xml, xml_types) { function(xmlparser, ignore, xml, xml_types) {
if (xml_types != null) { if (xml_types != null) {
@ -202,7 +202,7 @@ var xml2js = {
validateMethods(); validateMethods();
validateVars(); validateVars();
generateCustomPointerClasses(); generateCustomPointerClasses();
return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES', 'CLASSGROUPS'); return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES', 'CLASSGROUPS');
}); });
} }
}; };
@ -216,7 +216,7 @@ function createXmlParser(XML_GRAMMAR_SPEC) {
} }
// configure c->js typemaps from custom swig directives // configure c->js typemaps from custom swig directives
// TODO: many built in assumptions based on current upm file structures & .i customizations // TODO: many built in assumptions based on current upm file structures & .i customizations
function initCustomPointerTypemaps(typemapsdir) { function initCustomPointerTypemaps(typemapsdir) {
return fs.readdirAsync(typemapsdir).then(function(dirs) { return fs.readdirAsync(typemapsdir).then(function(dirs) {
@ -391,7 +391,7 @@ function generateCustomPointerClasses() {
} }
// override autogenerated methods with custom configuration // override autogenerated methods with custom configuration
function customizeMethods(custom) { function customizeMethods(custom) {
_.each(custom, function(classMethods, className) { _.each(custom, function(classMethods, className) {
_.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) { _.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) {
@ -401,7 +401,7 @@ function customizeMethods(custom) {
} }
// make sure methods have valid types, otherwise warn (& don't include if strict) // make sure methods have valid types, otherwise warn (& don't include if strict)
function validateMethods() { function validateMethods() {
xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) { xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) {
return hasValidTypes(methodSpec, methodName); return hasValidTypes(methodSpec, methodName);
@ -428,18 +428,18 @@ function validateVars() {
} }
}); });
} }
// verify that the json spec is well formatted // verify that the json spec is well formatted
function isValidMethodSpec(methodSpec, methodName) { function isValidMethodSpec(methodSpec, methodName) {
var valid = true; var valid = true;
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); }); var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); });
function checkRule(rule, errMsg) { function checkRule(rule, errMsg) {
if (!rule) { if (!rule) {
printIgnoredMethodOnce(); printIgnoredMethodOnce();
console.log(' ' + errMsg); console.log(' ' + errMsg);
valid = false; valid = false;
} }
} }
checkRule(_.has(methodSpec, 'description'), 'no description given'); checkRule(_.has(methodSpec, 'description'), 'no description given');
checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)'); checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)');
@ -452,17 +452,17 @@ function isValidMethodSpec(methodSpec, methodName) {
checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value'); checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value');
return valid; return valid;
} }
// get enum specifications // get enum specifications
function getEnums(spec_c, bygroup, parent) { function getEnums(spec_c, bygroup, parent) {
var spec_js = {}; var spec_js = {};
var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) { var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
var kind = getAttr(section, 'kind'); var kind = getAttr(section, 'kind');
return ((kind == 'enum') || (kind == 'public-type')); return ((kind == 'enum') || (kind == 'public-type'));
}); });
if (enumGroups) { if (enumGroups) {
_.each(enumGroups.children, function(enumGroup) { _.each(enumGroups.children, function(enumGroup) {
var enumGroupName = getText(getChild(enumGroup, 'name'), 'name'); var enumGroupName = getText(getChild(enumGroup, 'name'), 'name');
var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description'); var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description');
var enumGroupVals = getChildren(enumGroup, 'enumvalue'); var enumGroupVals = getChildren(enumGroup, 'enumvalue');
@ -503,7 +503,7 @@ function getDescription(spec_c) {
} }
// get the classes (xml file names) for the given module // get the classes (xml file names) for the given module
function getSubclasses(spec_c) { function getSubclasses(spec_c) {
return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) {
return getAttr(innerclass, 'refid'); return getAttr(innerclass, 'refid');
@ -511,7 +511,7 @@ function getSubclasses(spec_c) {
} }
// get the classes (class names) for the given module // get the classes (class names) for the given module
function getSubclassNames(spec_c) { function getSubclassNames(spec_c) {
return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) {
return getText(innerclass).replace(xml2js.opts.module + '::', ''); return getText(innerclass).replace(xml2js.opts.module + '::', '');
@ -528,7 +528,7 @@ function getSubmodules(spec_c) {
function hasParams(paramsSpec) { function hasParams(paramsSpec) {
return !(_.isEmpty(paramsSpec) || return !(_.isEmpty(paramsSpec) ||
((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void')); ((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void'));
} }
@ -545,7 +545,7 @@ function getMethods(spec_c, parent) {
if (methods) { if (methods) {
_.each(methods.children, function(method) { _.each(methods.children, function(method) {
var methodName = getText(getChild(method, 'name'), 'name'); var methodName = getText(getChild(method, 'name'), 'name');
if (methodName[0] != '~') { // filter out destructors if (methodName[0] != '~') { // filter out destructors
try { try {
var description = getChild(method, 'detaileddescription'); var description = getChild(method, 'detaileddescription');
var methodDescription = getText(description, 'description'); var methodDescription = getText(description, 'description');
@ -616,7 +616,7 @@ function getParams(spec_c, details, method, parent) {
_.each(spec_c, function(param) { _.each(spec_c, function(param) {
try { try {
var paramType = getType(getText(getChild(param, 'type'), 'type'), parent); var paramType = getType(getText(getChild(param, 'type'), 'type'), parent);
var paramName = getText(getChild(param, 'declname'), 'name'); var paramName = getText(getChild(param, 'declname'), 'name');
spec_js[paramName] = { type: paramType }; spec_js[paramName] = { type: paramType };
} catch(e) { } catch(e) {
if (paramType == '...') { if (paramType == '...') {
@ -672,7 +672,7 @@ function getType(type_c, parent) {
// verify that all types associated with the method are valid // verify that all types associated with the method are valid
function hasValidTypes(methodSpec, methodName, parent) { function hasValidTypes(methodSpec, methodName, parent) {
var valid = true; var valid = true;
var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).'); var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).');
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); }); var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); });
_.each(methodSpec.params, function(paramSpec, paramName) { _.each(methodSpec.params, function(paramSpec, paramName) {
@ -768,7 +768,7 @@ function getReturnDetails(spec_c) {
// get (and flatten) the text of the given object // get (and flatten) the text of the given object
function getText(obj, why) { function getText(obj, why) {
// TODO: links ignored for now, patched for types for // TODO: links ignored for now, patched for types for
var GENERATE_LINK = function(x) { return x + ' '; } var GENERATE_LINK = function(x) { return x + ' '; }
return _.reduce(obj.children, function(text, elem) { return _.reduce(obj.children, function(text, elem) {
if (_.isString(elem)) { if (_.isString(elem)) {
@ -804,7 +804,9 @@ function getText(obj, why) {
return text += '&ndash; '; return text += '&ndash; ';
default: default:
// TODO: incomplete list of doxygen xsd implemented // TODO: incomplete list of doxygen xsd implemented
throw new Error('NYI Unknown Object Type: ' + elem.name); console.warn('NYI Unknown Object Type: ' + elem.name);
return text;
//throw new Error('NYI Unknown Object Type: ' + elem.name);
} }
} else { } else {
throw new Error('NYI Unknown Type: ' + (typeof elem)); throw new Error('NYI Unknown Type: ' + (typeof elem));
@ -842,5 +844,5 @@ function printObj(obj) {
console.log(util.inspect(obj, false, null)); console.log(util.inspect(obj, false, null));
} }
module.exports = xml2js; module.exports = xml2js;