Browse files

This adds support for applying overlapping patches to the same AST wi…

…thout having to do multiple passes on the entire file.
  • Loading branch information...
1 parent 14f0a05 commit a42b831a85194250336e1ccc076c41718447f830 @oyvindkinsey oyvindkinsey committed Apr 20, 2012
Showing with 26 additions and 6 deletions.
  1. +24 −5 bin/jspatch-cli.js
  2. +2 −1 lib/jsgrep.js
View
29 bin/jspatch-cli.js
@@ -120,17 +120,36 @@ function processPatch(patchSource, patchFilename) {
return chunk;
});
- return function(ast) {
+ return function(matcher) {
_.each(chunks, function(chunk) {
var matchOptions = {
strictMatches: true,
filename: chunk.filename,
lineNumber: chunk.lineNumber
};
- ast.findStrict(chunk.find, function(v) {
- v.node.applyPatch(chunk.patch, patchFilename, chunk.lineNumber);
- }, matchOptions);
+ var reparse;
+ do {
+ if (reparse) {
+ matcher.ast = Narcissus.parser.parse(
+ matcher.ast.tokenizer.source, chunk.filename, 1);
+ reparse = false;
+ }
+ try {
+ matcher.findStrict(chunk.find, function(v) {
+ if (reparse) {
+ throw 'reparse';
+ }
+ v.node.applyPatch(chunk.patch, patchFilename, chunk.lineNumber);
+ reparse = true;
+ }, matchOptions);
+ } catch (ex) {
+ if (ex !== 'reparse') {
+ throw ex;
+ }
+ }
+ } while(reparse);
});
+ return matcher.ast;
};
}
@@ -183,7 +202,7 @@ function doFile(filename, callback) {
var fileMatched = false;
try {
- jsgrep.jsgrep({
+ ast = jsgrep.jsgrep({
source: ast,
matchScript: matchFn,
callback: function(node, variables) {
View
3 lib/jsgrep.js
@@ -508,7 +508,7 @@ var jsgrep = exports.jsgrep = function(options) {
matchFn = options.matchScript;
}
try {
- matchFn(matcher);
+ ast = matchFn(matcher);
} catch(e) {
throw new JsgrepError('Matcher threw exception')
.setSource(ast.tokenizer.filename)
@@ -531,6 +531,7 @@ var jsgrep = exports.jsgrep = function(options) {
}
});
}
+ return ast;
}
/**

0 comments on commit a42b831

Please sign in to comment.