From f37bd95c6cade59bb53dc3c07ac6afe49b9bec42 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sat, 24 Sep 2011 21:26:09 +0100 Subject: [PATCH 1/3] Added support for @property tags in doclets that have kinds, no template output yet. --- rhino_modules/jsdoc/name.js | 42 +++++++++++++++++++ rhino_modules/jsdoc/src/handlers.js | 23 +++++++--- .../jsdoc/tag/dictionary/definitions.js | 16 ++++--- test/t/jsdoc/name.js | 8 ++++ 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/rhino_modules/jsdoc/name.js b/rhino_modules/jsdoc/name.js index fcc56701..a75a123b 100644 --- a/rhino_modules/jsdoc/name.js +++ b/rhino_modules/jsdoc/name.js @@ -179,3 +179,45 @@ exports.shorten = function(longname) { return {longname: longname, memberof: memberof, scope: scope, name: name, variation: variation}; } +/** + Split a string that starts with a name and ends with a description, into its parts. + @param {string} nameDesc + @returns {object} Hash with "name" and "description" properties. + */ +exports.splitName = function(nameDesc) { + var name = '', + desc = '', + thisChar = '', + inQuote = false; + + for (var i = 0, len = nameDesc.length; i < len; i++) { + thisChar = nameDesc.charAt(i); + + if (thisChar === '\\') { + name += thisChar + nameDesc.charAt(++i); + continue; + } + + if (thisChar === '"') { + inQuote = !inQuote; + } + + if (inQuote) { + name += thisChar; + continue; + } + + if (!inQuote) { + if ( /\s/.test(thisChar) ) { + desc = nameDesc.substr(i); + desc = desc.replace(/^[\s-\s]+/, '').trim(); + break; + } + else { + name += thisChar; + } + } + } + + return { name: name, description: desc }; +} \ No newline at end of file diff --git a/rhino_modules/jsdoc/src/handlers.js b/rhino_modules/jsdoc/src/handlers.js index fd431ab6..a636954f 100644 --- a/rhino_modules/jsdoc/src/handlers.js +++ b/rhino_modules/jsdoc/src/handlers.js @@ -10,7 +10,7 @@ var currentModule = null; @param parser */ exports.attachTo = function(parser) { - var jsdoc = {doclet: require('jsdoc/doclet')}; + var jsdoc = {doclet: require('jsdoc/doclet'), name: require('jsdoc/name')}; // handles JSDoc comments that include a @name tag -- the code is ignored in such a case parser.on('jsdocCommentFound', function(e) { @@ -40,11 +40,11 @@ exports.attachTo = function(parser) { var newDoclet = new jsdoc.doclet.Doclet(docletSrc, e); // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two - if (newDoclet.name) { // there was a @name in comment - // try again, without the comment - e.comment = '@undocumented'; - newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - } + if (newDoclet.name) { // there was a @name in comment + // try again, without the comment + e.comment = '@undocumented'; + newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + } if (newDoclet.alias) { if (newDoclet.alias === '{@thisClass}') { @@ -117,6 +117,17 @@ exports.attachTo = function(parser) { return false; } + // find name and description from each property tag text + if (newDoclet.properties) { + for (var i = 0, len = newDoclet.properties.length; i < len; i++) { + var property = newDoclet.properties[i]; + + var parts = jsdoc.name.splitName(property.description); + property.name = parts.name; + property.description = parts.description; + } + } + addDoclet.call(this, newDoclet); e.doclet = newDoclet; } diff --git a/rhino_modules/jsdoc/tag/dictionary/definitions.js b/rhino_modules/jsdoc/tag/dictionary/definitions.js index b1a70acd..99aca379 100644 --- a/rhino_modules/jsdoc/tag/dictionary/definitions.js +++ b/rhino_modules/jsdoc/tag/dictionary/definitions.js @@ -352,10 +352,16 @@ exports.defineTags = function(dictionary) { dictionary.defineTag('property', { canHaveType: true, onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; + if (doclet.kind) { + if (!doclet.properties) { doclet.properties = []; } + doclet.properties.push(tag.value); + } + else { + setDocletKindToTitle(doclet, tag); + setDocletNameToValue(doclet, tag); + if (tag.value && tag.value.type) { + doclet.type = tag.value.type; + } } } }) @@ -400,7 +406,7 @@ exports.defineTags = function(dictionary) { mustHaveValue: true, canHaveType: true, onTagged: function(doclet, tag) { - if (!doclet.returns) { doclet.returns = []; } + if (!doclet.returns) { doclet.returns = []; } doclet.returns.push(tag.value); } }) diff --git a/test/t/jsdoc/name.js b/test/t/jsdoc/name.js index 570d144a..207c7573 100644 --- a/test/t/jsdoc/name.js +++ b/test/t/jsdoc/name.js @@ -117,3 +117,11 @@ test('The module:jsdoc/name.shorten function finds the variation.', function() { assert.equal(parts.name, 'fadein'); assert.equal(parts.longname, 'anim.fadein(2)'); }); + +test('The module:jsdoc/name.splitName function finds the name and description.', function() { + var startName = 'ns.Page#"last \\"sentence\\"".words~sort(2) - This is a description. ', + parts = jsdoc.name.splitName(startName); + + assert.equal(parts.name, 'ns.Page#"last \\"sentence\\"".words~sort(2)'); + assert.equal(parts.description, 'This is a description.'); +}); \ No newline at end of file From 31161fc9b6380443ee05190d1ee98fba148e591e Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sat, 24 Sep 2011 21:52:35 +0100 Subject: [PATCH 2/3] Rename old @property tag to @member. --- rhino_modules/jsdoc/doclet.js | 2 +- rhino_modules/jsdoc/schema.js | 2 +- .../jsdoc/tag/dictionary/definitions.js | 27 ++++++++++--------- templates/default/publish.js | 10 +++---- templates/default/tmpl/container.tmpl | 12 ++++----- templates/default/tmpl/properties.tmpl | 24 ----------------- test/cases/memberoftag.js | 4 +-- test/cases/quotename.js | 2 +- test/cases/typekind.js | 2 +- 9 files changed, 31 insertions(+), 54 deletions(-) diff --git a/rhino_modules/jsdoc/doclet.js b/rhino_modules/jsdoc/doclet.js index 66dd1177..a5f56a12 100644 --- a/rhino_modules/jsdoc/doclet.js +++ b/rhino_modules/jsdoc/doclet.js @@ -229,7 +229,7 @@ function codetypeToKind(type) { var kind = (type || '').toLowerCase(); if (kind !== 'function') { - return 'property'; + return 'member'; } return kind; diff --git a/rhino_modules/jsdoc/schema.js b/rhino_modules/jsdoc/schema.js index be52250f..5cbc85e2 100644 --- a/rhino_modules/jsdoc/schema.js +++ b/rhino_modules/jsdoc/schema.js @@ -100,7 +100,7 @@ exports.jsdocSchema = { "kind": { // what kind of symbol is this? "type": "string", "maxItems": 1, - "enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "mixin", "file", "version"] + "enum": ["constructor", "module", "event", "namespace", "method", "member", "enum", "class", "interface", "constant", "mixin", "file", "version"] }, "refersto": { // the path to another doc: this doc is simply a renamed alias to that "type": "string", diff --git a/rhino_modules/jsdoc/tag/dictionary/definitions.js b/rhino_modules/jsdoc/tag/dictionary/definitions.js index 99aca379..af434849 100644 --- a/rhino_modules/jsdoc/tag/dictionary/definitions.js +++ b/rhino_modules/jsdoc/tag/dictionary/definitions.js @@ -292,8 +292,7 @@ exports.defineTags = function(dictionary) { onTagged: function(doclet, tag) { setDocletMemberof(doclet, tag); } - }) - .synonym('member'); + }); dictionary.defineTag('mixin', { onTagged: function(doclet, tag) { @@ -352,20 +351,22 @@ exports.defineTags = function(dictionary) { dictionary.defineTag('property', { canHaveType: true, onTagged: function(doclet, tag) { - if (doclet.kind) { - if (!doclet.properties) { doclet.properties = []; } - doclet.properties.push(tag.value); - } - else { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } + if (!doclet.properties) { doclet.properties = []; } + doclet.properties.push(tag.value); + } + }) + .synonym('prop'); + + dictionary.defineTag('member', { + canHaveType: true, + onTagged: function(doclet, tag) { + setDocletKindToTitle(doclet, tag); + setDocletNameToValue(doclet, tag); + if (tag.value && tag.value.type) { + doclet.type = tag.value.type; } } }) - .synonym('prop') .synonym('var'); dictionary.defineTag('protected', { diff --git a/templates/default/publish.js b/templates/default/publish.js index 4649cb04..7e278664 100644 --- a/templates/default/publish.js +++ b/templates/default/publish.js @@ -96,11 +96,11 @@ } if (f.scope && f.scope !== 'instance') { - if (f.kind == 'function' || f.kind == 'property') attribs.push(f.scope); + if (f.kind == 'function' || f.kind == 'member') attribs.push(f.scope); } if (f.readonly === true) { - if (f.kind == 'property') attribs.push('readonly'); + if (f.kind == 'member') attribs.push('readonly'); } f.attribs = ''+htmlsafe(attribs.length? '<'+attribs.join(', ')+'> ' : '')+''; @@ -126,7 +126,7 @@ addAttribs(doclet); } - if (doclet.kind === 'property') { + if (doclet.kind === 'member') { addSignatureType(doclet); addAttribs(doclet) } @@ -156,7 +156,7 @@ data.orderBy(['longname', 'version', 'since']); // kinds of containers - var globals = find( {kind: ['property', 'function'], memberof: {isUndefined: true}} ), + var globals = find( {kind: ['member', 'function'], memberof: {isUndefined: true}} ), modules = find({kind: 'module'}), externals = find({kind: 'external'}), mixins = find({kind: 'mixin'}), @@ -262,7 +262,7 @@ nav = nav + ''; } - var globalNames = find({kind: ['property', 'function'], 'memberof': {'isUndefined': true}}); + var globalNames = find({kind: ['member', 'function'], 'memberof': {'isUndefined': true}}); if (globalNames.length) { nav = nav + '

Global