Skip to content

Commit f5f9892

Browse files
committed
docs(merge-params): adds custom merge-params and merge-prop jsdoc
Adds custom tags to jsdoc that allow merging parameter and property definitions: `@merge-params`: used in place of a @param whose type is defined elsewhere. Will expand out all of the properties of the type. `@merge-props`: used in a typedef that inherits from another typedef. Will inherit all properties of that typedef.
1 parent ca7cac9 commit f5f9892

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

conf.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"plugins": ["plugins/markdown", "docs/lib/jsdoc/examples_plugin.js"],
2+
"plugins": ["plugins/markdown", "docs/lib/jsdoc/examples_plugin.js", "docs/lib/jsdoc/merge_params.js"],
33
"source": {
44
"include": [
55
"lib/admin.js",

docs/lib/jsdoc/merge_params.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use strict';
2+
3+
exports.defineTags = function(dictionary) {
4+
dictionary.defineTag('merge-props', {
5+
mustHaveValue: true,
6+
canHaveName: true,
7+
onTagged: function(doclet, tag) {
8+
doclet.mergeProps = doclet.mergeProps || [];
9+
doclet.mergeProps.push(tag.value.name);
10+
}
11+
});
12+
13+
dictionary.defineTag('merge-params', {
14+
mustHaveValue: true,
15+
canHaveType: true,
16+
canHaveName: true,
17+
onTagged: function(doclet, tag) {
18+
doclet.mergeParams = doclet.mergeParams || [];
19+
doclet.mergeParams.push(tag.value);
20+
21+
doclet.params = doclet.params || [];
22+
doclet.params.push(tag.value || {});
23+
}
24+
});
25+
};
26+
27+
exports.handlers = {
28+
parseComplete: function(options) {
29+
const doclets = options.doclets;
30+
const DOCLET_MAP = new Map();
31+
32+
doclets.forEach(doclet => {
33+
DOCLET_MAP.set(doclet.longname, doclet);
34+
});
35+
36+
doclets.forEach(function tapDoclet(doclet) {
37+
doclet.tapped = true;
38+
if (doclet.mergeProps) {
39+
doclet.mergeProps.forEach(name => {
40+
const target = DOCLET_MAP.get(name);
41+
if (!target) {
42+
return;
43+
}
44+
if (!target.tapped) {
45+
tapDoclet(target);
46+
}
47+
if (!target.properties) {
48+
return;
49+
}
50+
51+
doclet.properties = doclet.properties || [];
52+
const propertySet = new Set(doclet.properties.map(prop => prop.name));
53+
54+
target.properties.forEach(prop => {
55+
if (!propertySet.has(prop.name)) {
56+
propertySet.add(prop.name);
57+
doclet.properties.push(prop);
58+
}
59+
});
60+
});
61+
}
62+
if (doclet.mergeParams && doclet.params) {
63+
doclet.mergeParams.forEach(tag => {
64+
const name = tag.name;
65+
const type = tag.type && tag.type.names && tag.type.names[0];
66+
const index = doclet.params.findIndex(param => param.name === name);
67+
const target = DOCLET_MAP.get(type);
68+
if (index < 0 || !target) {
69+
return;
70+
}
71+
if (!target.tapped) {
72+
tapDoclet(target);
73+
}
74+
if (!target.properties) {
75+
return;
76+
}
77+
78+
const firstParams = doclet.params.slice(0, index + 1);
79+
const lastParams = doclet.params.slice(index + 1);
80+
const newParams = target.properties.map(prop => {
81+
const newName = `${name}.${prop.name}`;
82+
return Object.assign({}, prop, { name: newName });
83+
});
84+
85+
doclet.params = firstParams.concat(newParams).concat(lastParams);
86+
});
87+
}
88+
});
89+
}
90+
};

0 commit comments

Comments
 (0)