Regenerate symbols if parents have changed
The generate-symbols.js task runs JSDoc on source files. Because this takes a long time (13s) to run on the whole library, the resulting symbols file includes additional metadata to make it possible to do incremental symbol generation on subsequent runs. The 'path' and 'extends' metadata for a symbol are used to determine what needs to be regenerated.
This commit is contained in:
@@ -17,7 +17,7 @@ exports.publish = function(data, opts) {
|
|||||||
// get all doclets with the "api" property.
|
// get all doclets with the "api" property.
|
||||||
var docs = data({api: {isString: true}}).get();
|
var docs = data({api: {isString: true}}).get();
|
||||||
|
|
||||||
// get sorted symbols, filter out those that are members of private classes
|
// get symbols data, filter out those that are members of private classes
|
||||||
var symbols = docs.filter(function(doc) {
|
var symbols = docs.filter(function(doc) {
|
||||||
var include = true;
|
var include = true;
|
||||||
var constructor = doc.memberof;
|
var constructor = doc.memberof;
|
||||||
@@ -30,10 +30,9 @@ exports.publish = function(data, opts) {
|
|||||||
}).map(function(doc) {
|
}).map(function(doc) {
|
||||||
return {
|
return {
|
||||||
name: doc.longname,
|
name: doc.longname,
|
||||||
|
extends: doc.augments,
|
||||||
path: path.join(doc.meta.path, doc.meta.filename)
|
path: path.join(doc.meta.path, doc.meta.filename)
|
||||||
};
|
};
|
||||||
}).sort(function(a, b) {
|
|
||||||
return a.name < b.name ? -1 : 1;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.write(JSON.stringify({symbols: symbols}, null, 2));
|
process.stdout.write(JSON.stringify({symbols: symbols}, null, 2));
|
||||||
|
|||||||
@@ -39,6 +39,15 @@ function readSymbols(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function makeUnique(array) {
|
||||||
|
var values = {};
|
||||||
|
array.forEach(function(value) {
|
||||||
|
values[value] = true;
|
||||||
|
});
|
||||||
|
return Object.keys(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a list of .js paths in the source directory that are newer than
|
* Generate a list of .js paths in the source directory that are newer than
|
||||||
* the symbols file.
|
* the symbols file.
|
||||||
@@ -48,16 +57,16 @@ function readSymbols(callback) {
|
|||||||
* any error, the symbols array, and the array of newer source paths.
|
* any error, the symbols array, and the array of newer source paths.
|
||||||
*/
|
*/
|
||||||
function getNewer(symbols, date, callback) {
|
function getNewer(symbols, date, callback) {
|
||||||
var all = [];
|
var allPaths = [];
|
||||||
var newer = [];
|
var newerPaths = [];
|
||||||
|
|
||||||
var walker = walk(sourceDir);
|
var walker = walk(sourceDir);
|
||||||
walker.on('file', function(root, stats, next) {
|
walker.on('file', function(root, stats, next) {
|
||||||
var sourcePath = path.join(root, stats.name);
|
var sourcePath = path.join(root, stats.name);
|
||||||
if (/\.js$/.test(sourcePath)) {
|
if (/\.js$/.test(sourcePath)) {
|
||||||
all.push(sourcePath);
|
allPaths.push(sourcePath);
|
||||||
if (stats.mtime > date) {
|
if (stats.mtime > date) {
|
||||||
newer.push(sourcePath);
|
newerPaths.push(sourcePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
@@ -67,10 +76,47 @@ function getNewer(symbols, date, callback) {
|
|||||||
});
|
});
|
||||||
walker.on('end', function() {
|
walker.on('end', function() {
|
||||||
// prune symbols if file no longer exists or has been modified
|
// prune symbols if file no longer exists or has been modified
|
||||||
symbols = symbols.filter(function(symbol) {
|
var lookup = {};
|
||||||
return newer.indexOf(symbol.path) < 0 && all.indexOf(symbol.path) >= 0;
|
symbols.forEach(function(symbol) {
|
||||||
|
lookup[symbol.name] = symbol;
|
||||||
});
|
});
|
||||||
callback(null, symbols, newer);
|
|
||||||
|
/**
|
||||||
|
* Gather paths for all parent symbols.
|
||||||
|
* @param {Object} symbol Symbol to check.
|
||||||
|
* @param {Array.<string>} paths Current paths.
|
||||||
|
*/
|
||||||
|
function gatherParentPaths(symbol, paths) {
|
||||||
|
if (symbol.extends) {
|
||||||
|
symbol.extends.forEach(function(name) {
|
||||||
|
if (name in lookup) {
|
||||||
|
var parent = lookup[name];
|
||||||
|
paths.push(parent.path);
|
||||||
|
gatherParentPaths(parent, paths);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dirtyPaths = [];
|
||||||
|
|
||||||
|
symbols = symbols.filter(function(symbol) {
|
||||||
|
var dirty = allPaths.indexOf(symbol.path) < 0;
|
||||||
|
if (!dirty) {
|
||||||
|
// confirm that symbol and all parent paths are not newer
|
||||||
|
var paths = [symbol.path];
|
||||||
|
gatherParentPaths(symbol, paths);
|
||||||
|
dirty = paths.some(function(p) {
|
||||||
|
return newerPaths.indexOf(p) >= 0;
|
||||||
|
});
|
||||||
|
if (dirty) {
|
||||||
|
dirtyPaths.push(symbol.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !dirty;
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(null, symbols, makeUnique(newerPaths.concat(dirtyPaths)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +181,9 @@ function writeSymbols(symbols, output, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
symbols = symbols.concat(data.symbols);
|
symbols = symbols.concat(data.symbols).sort(function(a, b) {
|
||||||
|
return a.name < b.name ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
var str = JSON.stringify({symbols: symbols}, null, ' ');
|
var str = JSON.stringify({symbols: symbols}, null, ' ');
|
||||||
fse.outputFile(destPath, str, callback);
|
fse.outputFile(destPath, str, callback);
|
||||||
|
|||||||
Reference in New Issue
Block a user