Skip to content

Instantly share code, notes, and snippets.

@AWinterman
Created May 24, 2013 22:50
Show Gist options
  • Save AWinterman/5647022 to your computer and use it in GitHub Desktop.
Save AWinterman/5647022 to your computer and use it in GitHub Desktop.
suite("name of test suite", function(require) {
var MapPicker = require('../../require/some/module')
test('test something', function() {
assert.equal(some, things)
})
})
var esprima = require('esprima')
, fs = require('fs');
function Parser(file, hooks) {
this.file = file
this.hooks = hooks || {}
this.modifications = []
}
var cons = Parser
, proto = cons.prototype
, parsers = proto.parsers = {}
proto.esprima_options = {range: true}
proto.init = function(done) {
var self = this
fs.readFile(this.file, function(err, code) {
self.raw_code = code.toString()
err ? done(err) : self.parse(done)
})
}
proto.parse = function(done) {
this.parsed_syntax = esprima.parse(this.raw_code, this.esprima_options)
this.parse_node(this.parsed_syntax)
this.apply_modifications()
done()
}
proto.parse_node = function(node, parant) {
var type = node.type
node.parant = parant
this.call_hooks(type, node)
this.parsers[type] && this.parsers[type](node, this)
}
proto.call_hooks = function(type, node) {
var self = this
self.hooks[type] && self.hooks[type].forEach(function(hook) {
hook(node, self)
})
}
proto.add_hook = function(node_type, hook) {
this.hooks[node_type] = this.hooks[node_type] || []
this.hooks[node_type].push(hook)
}
proto.add_modification = function(start, length, replacement) {
var mod = [start, length, replacement]
, i = null
this.modifications.push(mod)
this.modifications.sort(function(a,b) {
return a[0] -b[0]
})
var i = this.modifications.indexOf(mod)
if(i > 0 && !check_overlap(this.modifications[i-1], mod)) {
console.log(mod, " overlaps ", this.modifications[i-1])
this.modifications.splice(i, 1)
} else if(!check_overlap(mod, this.modifications[i+1])) {
console.log(mod, " overlaps ", this.modifications[i+1])
this.modifications.splice(i, 1)
}
function check_overlap(a,b) {
return a[1] >= 0 && (!b || (a[0] + a[1]) < b[0])
}
}
proto.apply_modifications = function() {
var code = this.raw_code.split("")
, diff = 0
this.modifications.forEach(function(mod) {
splice.apply(this, mod)
})
this.raw_code = code.join("")
function splice(start, d, replacement) {
var length = code.length
code.splice(start + diff, d, replacement)
diff += code.length - length
}
}
cons.add_parser = function(name, nodes, node_lists) {
this.prototype.parsers[name] = function(node, parser) {
nodes && nodes.forEach(function(single_node) {
parser.parse_node(node[single_node], node)
})
node_lists && node_lists.forEach(function(node_list) {
node[node_list].forEach(function(single_node) {
parser.parse_node(single_node, node)
})
})
}
}
cons.add_parser("Program", null,["body"])
cons.add_parser("ExpressionStatement", ['expression'])
cons.add_parser("CallExpression", null, ["arguments"])
cons.add_parser("FunctionExpression", ["body"], ["params"])
cons.add_parser("BlockStatement", null, ["body"])
cons.add_parser("VariableDeclaration", null, ["declarations"])
cons.add_parser("VariableDeclarator", ["init"])
var parser = new Parser('example.test.js')
parser.add_hook("CallExpression", function(node, parser) {
if(node.callee.name === 'test') {
parser.add_modification(node.callee.range[0], 4, "better_test")
}
})
parser.init(function() {
console.log(parser.raw_code)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment