Skip to content

Commit

Permalink
Regenerate symbols if parents have changed
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tschaub committed Apr 29, 2014
1 parent 1273c26 commit 88d67b7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 10 deletions.
5 changes: 2 additions & 3 deletions buildcfg/jsdoc/symbols/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ exports.publish = function(data, opts) {
// get all doclets with the "api" property.
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 include = true;
var constructor = doc.memberof;
Expand All @@ -30,10 +30,9 @@ exports.publish = function(data, opts) {
}).map(function(doc) {
return {
name: doc.longname,
extends: doc.augments,
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));
Expand Down
62 changes: 55 additions & 7 deletions tasks/generate-symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
* the symbols file.
Expand All @@ -48,16 +57,16 @@ function readSymbols(callback) {
* any error, the symbols array, and the array of newer source paths.
*/
function getNewer(symbols, date, callback) {
var all = [];
var newer = [];
var allPaths = [];
var newerPaths = [];

var walker = walk(sourceDir);
walker.on('file', function(root, stats, next) {
var sourcePath = path.join(root, stats.name);
if (/\.js$/.test(sourcePath)) {
all.push(sourcePath);
allPaths.push(sourcePath);
if (stats.mtime > date) {
newer.push(sourcePath);
newerPaths.push(sourcePath);
}
}
next();
Expand All @@ -67,10 +76,47 @@ function getNewer(symbols, date, callback) {
});
walker.on('end', function() {
// prune symbols if file no longer exists or has been modified
var lookup = {};
symbols.forEach(function(symbol) {
lookup[symbol.name] = symbol;
});

/**
* 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) {
return newer.indexOf(symbol.path) < 0 && all.indexOf(symbol.path) >= 0;
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, newer);

callback(null, symbols, makeUnique(newerPaths.concat(dirtyPaths)));
});
}

Expand Down Expand Up @@ -135,7 +181,9 @@ function writeSymbols(symbols, output, callback) {
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, ' ');
fse.outputFile(destPath, str, callback);
Expand Down

0 comments on commit 88d67b7

Please sign in to comment.