parse comment for templates

This commit is contained in:
Simon Seyock
2021-04-16 20:06:06 +02:00
committed by Andreas Hocevar
parent a5d0b61947
commit aa99de4a6b

View File

@@ -5,7 +5,48 @@
* Inlines option params from typedefs * Inlines option params from typedefs
*/ */
const properties = {}; const docletInfos = {};
/**
* This parses the comment for `@template` annotations and returns an object with name / type pairs for all template
* values
* @param {string} comment a jsdoc comment to parse
* @return {Object<string, string>} results
*/
function parseCommentForTemplates(comment) {
let remainingText = comment;
const results = {};
while (true) {
const templateMatch = remainingText.match(/\* @template\s*([\s\S]*)/);
if (!templateMatch) {
return results;
}
remainingText = templateMatch[1];
let type = '*';
if (remainingText[0] === '{') {
let index = 1;
let openParenthesis = 1;
while (openParenthesis > 0) {
if (remainingText[index] === '{') {
openParenthesis++;
} else if (remainingText[index] === '}') {
openParenthesis--;
}
index++;
}
type = remainingText.slice(1, index - 1);
remainingText = remainingText.slice(index);
}
const name = remainingText.match(/\s*(\S*)/)[1];
results[name] = type;
}
}
exports.handlers = { exports.handlers = {
/** /**
@@ -14,7 +55,9 @@ exports.handlers = {
*/ */
newDoclet: function (e) { newDoclet: function (e) {
if (e.doclet.kind == 'typedef' && e.doclet.properties) { if (e.doclet.kind == 'typedef' && e.doclet.properties) {
properties[e.doclet.longname] = e.doclet.properties; docletInfos[e.doclet.longname] = {
properties: e.doclet.properties,
};
} }
}, },
@@ -25,6 +68,16 @@ exports.handlers = {
*/ */
parseComplete: function (e) { parseComplete: function (e) {
const doclets = e.doclets; const doclets = e.doclets;
// gather type information
for (let i = 0, ii = doclets.length; i < ii; ++i) {
const doclet = doclets[i];
if (doclet.longname in docletInfos) {
docletInfos[doclet.longname].type = doclet.type;
}
}
// inline options
for (let i = 0, ii = doclets.length; i < ii; ++i) { for (let i = 0, ii = doclets.length; i < ii; ++i) {
const doclet = doclets[i]; const doclet = doclets[i];
if (doclet.params) { if (doclet.params) {
@@ -37,13 +90,18 @@ exports.handlers = {
if (genericMatches) { if (genericMatches) {
type = genericMatches[1]; type = genericMatches[1];
} }
if (type in properties) { if (type in docletInfos) {
param.type.names[0] = type; const templateInfo = parseCommentForTemplates(doclet.comment);
param.type = docletInfos[type].type;
params.push.apply( params.push.apply(
params, params,
properties[type].map((p) => { docletInfos[type].properties.map((p) => {
const property = Object.assign({}, p); const property = Object.assign({}, p);
property.name = `${param.name}.${property.name}`; property.name = `${param.name}.${property.name}`;
if (property.type.names[0] in templateInfo) {
property.type.names[0] =
templateInfo[property.type.names[0]];
}
return property; return property;
}) })
); );