show more info for Closure Compiler type expressions (#618)

This commit is contained in:
Jeff Williams 2014-04-18 16:44:57 -07:00
parent cd9d7f90a7
commit 254dda50b1
4 changed files with 131 additions and 17 deletions

View File

@ -168,7 +168,10 @@ function parseName(tagInfo) {
}
/** @private */
function getTypeStrings(parsedType) {
function getTypeStrings(parsedType, isOutermostType) {
var applications;
var typeString;
var types = [];
var catharsis = require('catharsis');
@ -192,7 +195,19 @@ function getTypeStrings(parsedType) {
types.push('Object');
break;
case TYPES.TypeApplication:
types.push( catharsis.stringify(parsedType) );
// if this is the outermost type, we strip the modifiers; otherwise, we keep them
if (isOutermostType) {
applications = parsedType.applications.map(function(application) {
return getTypeStrings(application);
}).join(', ');
typeString = util.format( '%s.<%s>', getTypeStrings(parsedType.expression),
applications );
types.push(typeString);
}
else {
types.push( catharsis.stringify(parsedType) );
}
break;
case TYPES.TypeUnion:
parsedType.elements.forEach(function(element) {
@ -244,7 +259,7 @@ function parseTypeExpression(tagInfo) {
}
if (parsedType) {
tagInfo.type = tagInfo.type.concat( getTypeStrings(parsedType) );
tagInfo.type = tagInfo.type.concat( getTypeStrings(parsedType, true) );
// Catharsis and JSDoc use the same names for 'optional' and 'nullable'...
['optional', 'nullable'].forEach(function(key) {

View File

@ -519,6 +519,13 @@ exports.getAttribs = function(d) {
attribs.push('constant');
}
if (d.nullable === true) {
attribs.push('nullable');
}
else if (d.nullable === false) {
attribs.push('non-null');
}
return attribs;
};

View File

@ -7,6 +7,7 @@ var template = require('jsdoc/template'),
taffy = require('taffydb').taffy,
logger = require('jsdoc/util/logger'),
helper = require('jsdoc/util/templateHelper'),
util = require('util'),
htmlsafe = helper.htmlsafe,
linkto = helper.linkto,
resolveAuthorLinks = helper.resolveAuthorLinks,
@ -58,33 +59,125 @@ function needsSignature(doclet) {
return needsSig;
}
function addSignatureParams(f) {
var params = helper.getSignatureParams(f, 'optional');
function getSignatureAttributes(item) {
var attributes = [];
f.signature = (f.signature || '') + '('+params.join(', ')+')';
if (item.optional) {
attributes.push('opt');
}
if (item.nullable === true) {
attributes.push('nullable');
}
else if (item.nullable === false) {
attributes.push('non-null');
}
return attributes;
}
function updateItemName(item) {
var attributes = getSignatureAttributes(item);
var itemName = item.name || '';
if (item.variable) {
itemName = '&hellip;' + itemName;
}
if (attributes && attributes.length) {
itemName = util.format( '%s<span class="signature-attributes">%s</span>', itemName,
attributes.join(', ') );
}
return itemName;
}
function addParamAttributes(params) {
return params.map(updateItemName);
}
function buildItemTypeStrings(item) {
var types = [];
if (item.type && item.type.names) {
item.type.names.forEach(function(name) {
types.push( linkto(name, htmlsafe(name)) );
});
}
return types;
}
function buildAttribsString(attribs) {
var attribsString = '';
if (attribs && attribs.length) {
attribsString = htmlsafe( util.format('(%s) ', attribs.join(', ')) );
}
return attribsString;
}
function addNonParamAttributes(items) {
var types = [];
items.forEach(function(item) {
types = types.concat( buildItemTypeStrings(item) );
});
return types;
}
function addSignatureParams(f) {
var params = f.params ? addParamAttributes(f.params) : [];
f.signature = util.format( '%s(%s)', (f.signature || ''), params.join(', ') );
}
function addSignatureReturns(f) {
var returnTypes = helper.getSignatureReturns(f);
var attribs = [];
var attribsString = '';
var returnTypes = [];
var returnTypesString = '';
// jam all the return-type attributes into an array. this could create odd results (for example,
// if there are both nullable and non-nullable return types), but let's assume that most people
// who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa.
if (f.returns) {
f.returns.forEach(function(item) {
helper.getAttribs(item).forEach(function(attrib) {
if (attribs.indexOf(attrib) === -1) {
attribs.push(attrib);
}
});
});
attribsString = buildAttribsString(attribs);
}
if (f.returns) {
returnTypes = addNonParamAttributes(f.returns);
}
if (returnTypes.length) {
returnTypesString = util.format( ' &rarr; %s{%s}', attribsString, returnTypes.join('|') );
}
f.signature = '<span class="signature">' + (f.signature || '') + '</span>' +
'<span class="type-signature">' +
(returnTypes && returnTypes.length ? ' &rarr; {' + returnTypes.join('|') + '}' : '') +
'</span>';
'<span class="type-signature">' + returnTypesString + '</span>';
}
function addSignatureTypes(f) {
var types = helper.getSignatureTypes(f);
var types = f.type ? buildItemTypeStrings(f) : [];
f.signature = (f.signature || '') + '<span class="type-signature">'+(types.length? ' :'+types.join('|') : '')+'</span>';
f.signature = (f.signature || '') + '<span class="type-signature">' +
(types.length ? ' :' + types.join('|') : '') + '</span>';
}
function addAttribs(f) {
var attribs = helper.getAttribs(f);
var attribsString = buildAttribsString(attribs);
f.attribs = '<span class="type-signature">' + htmlsafe(attribs.length ?
// we want the template output to say 'abstract', not 'virtual'
'<' + attribs.join(', ').replace('virtual', 'abstract') + '> ' : '') + '</span>';
f.attribs = util.format('<span class="type-signature">%s</span>', attribsString);
}
function shortenPaths(files, commonPrefix) {

View File

@ -58,8 +58,7 @@ section
display: none;
}
.optional:after {
content: "opt";
.signature-attributes {
font-size: 60%;
color: #aaa;
font-style: italic;