mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Merge pull request #35 from tschaub/augment
Add inherited members based on @augments or @extends
This commit is contained in:
commit
d8503ed9ab
1
jsdoc.js
1
jsdoc.js
@ -222,6 +222,7 @@ function main() {
|
|||||||
|
|
||||||
indexAll(docs);
|
indexAll(docs);
|
||||||
|
|
||||||
|
require('jsdoc/augment').addInherited(docs);
|
||||||
require('jsdoc/borrow').resolveBorrows(docs);
|
require('jsdoc/borrow').resolveBorrows(docs);
|
||||||
|
|
||||||
if (env.opts.explain) {
|
if (env.opts.explain) {
|
||||||
|
|||||||
121
rhino_modules/jsdoc/augment.js
Normal file
121
rhino_modules/jsdoc/augment.js
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
exports.addInherited = function(docs) {
|
||||||
|
var dependencies = mapDependencies(docs.index);
|
||||||
|
var sorted = sort(dependencies);
|
||||||
|
var additions = [];
|
||||||
|
sorted.forEach(function(name) {
|
||||||
|
var doclets = docs.index[name];
|
||||||
|
Array.prototype.push.apply(additions, getAdditions(doclets, docs));
|
||||||
|
});
|
||||||
|
additions.forEach(function(doc) {
|
||||||
|
var name = doc.longname;
|
||||||
|
if (!(docs.index.hasOwnProperty(name))) {
|
||||||
|
docs.index[name] = [];
|
||||||
|
}
|
||||||
|
docs.index[name].push(doc);
|
||||||
|
docs.push(doc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDependencies(index) {
|
||||||
|
var doclets, doc, len, dependencies = {};
|
||||||
|
for (var name in index) {
|
||||||
|
doclets = index[name];
|
||||||
|
for (var i=0, ii=doclets.length; i<ii; ++i) {
|
||||||
|
doc = doclets[i];
|
||||||
|
if (doc.kind === "class") {
|
||||||
|
dependencies[name] = {};
|
||||||
|
len = doc.augments && doc.augments.length || 0;
|
||||||
|
for (var j=0; j<len; ++j) {
|
||||||
|
dependencies[name][doc.augments[j]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAdditions(doclets, docs) {
|
||||||
|
var additions = [];
|
||||||
|
var doc, parents, members, member;
|
||||||
|
for (var i=0, ii=doclets.length; i<ii; ++i) {
|
||||||
|
doc = doclets[i];
|
||||||
|
parents = doc.augments;
|
||||||
|
if (parents && doc.kind === "class") {
|
||||||
|
for (var j=0, jj=parents.length; j<jj; ++j) {
|
||||||
|
members = getMembers(parents[j], docs);
|
||||||
|
for (var k=0, kk=members.length; k<kk; ++k) {
|
||||||
|
member = doop(members[k]);
|
||||||
|
member.memberof = doc.longname;
|
||||||
|
parts = member.longname.split("#");
|
||||||
|
parts[0] = doc.longname;
|
||||||
|
member.longname = parts.join("#");
|
||||||
|
additions.push(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return additions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMembers(longname, docs) {
|
||||||
|
var candidate, members = [];
|
||||||
|
for (var i=0, ii=docs.length; i<ii; ++i) {
|
||||||
|
candidate = docs[i];
|
||||||
|
if (candidate.memberof === longname && candidate.scope === "instance") {
|
||||||
|
members.push(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doop(o) {
|
||||||
|
if (o instanceof Object && o.constructor != Function) {
|
||||||
|
var clone = o instanceof Array ? [] : {}, prop;
|
||||||
|
|
||||||
|
for (prop in o){
|
||||||
|
if ( o.hasOwnProperty(prop) ) {
|
||||||
|
clone[prop] = (o[prop] instanceof Object)? doop(o[prop]) : o[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Sorter = function(dependencies) {
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
this.visited = {};
|
||||||
|
this.sorted = [];
|
||||||
|
};
|
||||||
|
Sorter.prototype = {
|
||||||
|
sort: function() {
|
||||||
|
for (var key in this.dependencies) {
|
||||||
|
this.visit(key);
|
||||||
|
}
|
||||||
|
return this.sorted;
|
||||||
|
},
|
||||||
|
visit: function(key) {
|
||||||
|
if (!(key in this.visited)) {
|
||||||
|
this.visited[key] = true;
|
||||||
|
if (!(key in this.dependencies)) {
|
||||||
|
throw new Error("Missing dependency: " + key);
|
||||||
|
}
|
||||||
|
for (var path in this.dependencies[key]) {
|
||||||
|
this.visit(path);
|
||||||
|
}
|
||||||
|
this.sorted.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function sort(dependencies) {
|
||||||
|
var sorter = new Sorter(dependencies);
|
||||||
|
return sorter.sort();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
@ -1,14 +1,39 @@
|
|||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function Foo() {
|
function Foo() {
|
||||||
|
/** First property */
|
||||||
|
this.prop1 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second property
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
Foo.prototype.prop2 = "parent prop2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First parent method.
|
||||||
|
*/
|
||||||
|
Foo.prototype.method1 = function() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second parent method.
|
||||||
|
*/
|
||||||
|
Foo.prototype.method2 = function() {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends Foo
|
* @constructor
|
||||||
*/
|
* @extends Foo
|
||||||
|
*/
|
||||||
function Bar() {
|
function Bar() {
|
||||||
|
/** Thrid prop **/
|
||||||
|
this.prop3 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second child method.
|
||||||
|
*/
|
||||||
|
Bar.prototype.method2 = function() {};
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,11 @@ var testhelpers = {
|
|||||||
|
|
||||||
doclets = testParser.parse('javascript:' + sourceCode);
|
doclets = testParser.parse('javascript:' + sourceCode);
|
||||||
testhelpers.indexAll(doclets);
|
testhelpers.indexAll(doclets);
|
||||||
|
|
||||||
|
require('jsdoc/augment').addInherited(doclets);
|
||||||
|
|
||||||
|
// test assume borrows have not yet been resolved
|
||||||
|
// require('jsdoc/borrow').resolveBorrows(doclets);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
doclets: doclets,
|
doclets: doclets,
|
||||||
|
|||||||
@ -1,10 +1,51 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var docSet = testhelpers.getDocSetFromFile('test/cases/augmentstag.js'),
|
var docSet = testhelpers.getDocSetFromFile('test/cases/augmentstag.js'),
|
||||||
foo = docSet.getByLongname('Foo')[0],
|
foo = docSet.getByLongname('Foo')[0],
|
||||||
bar = docSet.getByLongname('Bar')[0];
|
fooProp1 = docSet.getByLongname('Foo#prop1')[0],
|
||||||
|
fooProp2 = docSet.getByLongname('Foo#prop2')[0],
|
||||||
|
fooProp3 = docSet.getByLongname('Foo#prop3')[0],
|
||||||
|
fooMethod1 = docSet.getByLongname('Foo#method1')[0],
|
||||||
|
fooMethod2 = docSet.getByLongname('Foo#method2')[0],
|
||||||
|
bar = docSet.getByLongname('Bar')[0],
|
||||||
|
barProp1 = docSet.getByLongname('Bar#prop1')[0],
|
||||||
|
barProp2 = docSet.getByLongname('Bar#prop2')[0],
|
||||||
|
barProp3 = docSet.getByLongname('Bar#prop3')[0],
|
||||||
|
barMethod1 = docSet.getByLongname('Bar#method1')[0],
|
||||||
|
barMethod2 = docSet.getByLongname('Bar#method2')[0];
|
||||||
|
|
||||||
test('When a symbol has an @augments tag, the doclet has a augments property that includes that value.', function() {
|
test('When a symbol has an @augments tag, the doclet has a augments property that includes that value.', function() {
|
||||||
assert.equal(typeof bar.augments, 'object');
|
assert.equal(typeof bar.augments, 'object');
|
||||||
assert.equal(bar.augments[0], 'Foo');
|
assert.equal(bar.augments[0], 'Foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('When an object is extended, the original is not modified', function() {
|
||||||
|
assert.equal(fooProp3, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('When an object is extended, it inherits properties set in parent constructor', function() {
|
||||||
|
assert.equal(fooProp1.memberof, "Foo");
|
||||||
|
assert.equal(barProp1.memberof, "Bar");
|
||||||
|
assert.equal(barProp1.description, fooProp1.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('When an object is extended, it inherits properties set on parent prototype', function() {
|
||||||
|
assert.equal(fooProp2.memberof, "Foo");
|
||||||
|
assert.equal(barProp2.memberof, "Bar");
|
||||||
|
assert.equal(barProp2.description, fooProp2.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('When an object is extended, it inherits methods set on parent prototype', function() {
|
||||||
|
assert.equal(fooMethod1.memberof, "Foo");
|
||||||
|
assert.equal(barMethod1.memberof, "Bar");
|
||||||
|
assert.equal(barMethod1.description, fooMethod1.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('When an object is extended, it may override methods set on parent prototype', function() {
|
||||||
|
assert.equal(fooMethod2.memberof, "Foo");
|
||||||
|
assert.equal(fooMethod2.description, "Second parent method.");
|
||||||
|
assert.equal(barMethod2.memberof, "Bar");
|
||||||
|
assert.equal(barMethod2.description, "Second child method.");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
Loading…
x
Reference in New Issue
Block a user