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);
|
||||
|
||||
require('jsdoc/augment').addInherited(docs);
|
||||
require('jsdoc/borrow').resolveBorrows(docs);
|
||||
|
||||
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() {
|
||||
/** 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() {
|
||||
/** Thrid prop **/
|
||||
this.prop3 = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second child method.
|
||||
*/
|
||||
Bar.prototype.method2 = function() {};
|
||||
|
||||
|
||||
@ -44,6 +44,11 @@ var testhelpers = {
|
||||
|
||||
doclets = testParser.parse('javascript:' + sourceCode);
|
||||
testhelpers.indexAll(doclets);
|
||||
|
||||
require('jsdoc/augment').addInherited(doclets);
|
||||
|
||||
// test assume borrows have not yet been resolved
|
||||
// require('jsdoc/borrow').resolveBorrows(doclets);
|
||||
|
||||
return {
|
||||
doclets: doclets,
|
||||
|
||||
@ -1,10 +1,51 @@
|
||||
(function() {
|
||||
var docSet = testhelpers.getDocSetFromFile('test/cases/augmentstag.js'),
|
||||
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() {
|
||||
assert.equal(typeof bar.augments, 'object');
|
||||
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