diff --git a/.gitignore b/.gitignore index d8cead4..deda974 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,3 @@ node_modules/ cover_html/ npm-debug.log - -lib/ diff --git a/lib/clean.js b/lib/clean.js new file mode 100644 index 0000000..9a666a5 --- /dev/null +++ b/lib/clean.js @@ -0,0 +1,69 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var clean, coffee, ignoreString, semver, utilities; + + coffee = require('coffee-script'); + + semver = require('semver'); + + ignoreString = '/* istanbul ignore next: coffeescript utility boilerplate */'; + + utilities = { + "extends": { + '1.8.0': { + original: '__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }', + replacement: "__extends = function(child, parent) { for (var key in parent) { " + ignoreString + " if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + }, + '1.9.0': { + original: 'extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }', + replacement: "extend = function(child, parent) { for (var key in parent) { " + ignoreString + " if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + }, + '1.10.0': { + original: 'extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }', + replacement: "extend = function(child, parent) { for (var key in parent) { " + ignoreString + " if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + } + }, + indexOf: { + '1.8.0': { + original: '__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }', + replacement: "__indexOf = " + ignoreString + " [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { " + ignoreString + " if (i in this && this[i] === item) return i; } return -1; }" + }, + '1.9.0': { + original: 'indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }', + replacement: "indexOf = " + ignoreString + " [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { " + ignoreString + " if (i in this && this[i] === item) return i; } return -1; }" + }, + '1.10.0': { + original: 'indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }', + replacement: "indexOf = " + ignoreString + " [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { " + ignoreString + " if (i in this && this[i] === item) return i; } return -1; }" + } + } + }; + + clean = function(compiledJS) { + var newCompiledJS, utility, utilityKey, utilityVersions, version; + switch (semver.minor(coffee.VERSION)) { + case 8: + version = '1.8.0'; + break; + case 9: + version = '1.9.0'; + break; + case 10: + version = '1.10.0'; + break; + default: + return compiledJS; + } + newCompiledJS = compiledJS; + for (utilityKey in utilities) { + utilityVersions = utilities[utilityKey]; + if (utility = utilityVersions[version]) { + newCompiledJS = newCompiledJS.replace(utility.original, utility.replacement); + } + } + return newCompiledJS; + }; + + module.exports = clean; + +}).call(this); diff --git a/lib/command.js b/lib/command.js index 7009f00..3b43b0e 100644 --- a/lib/command.js +++ b/lib/command.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { var COMMANDS, TAB, argv, c, command, fs, optimist, possibilities, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; diff --git a/lib/cover.js b/lib/cover.js index 3e7898f..b0c7419 100644 --- a/lib/cover.js +++ b/lib/cover.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { var DEFAULT_REPORT_FORMAT, Module, existsSync, fileset, fs, ibrik, istanbul, mkdirp, path, which, slice = [].slice; @@ -24,7 +24,7 @@ DEFAULT_REPORT_FORMAT = 'lcov'; module.exports = function(opts, callback) { - var args, cmd, e, excludes, file, ref, reportClassNames, reportingDir, reports, runFn; + var args, cmd, e, error, excludes, file, ref, reportClassNames, reportingDir, reports, runFn; ref = opts._, cmd = ref[0], file = ref[1], args = 3 <= ref.length ? slice.call(ref, 2) : []; if (!file) { return callback("Need a filename argument for the " + cmd + " command!"); @@ -32,8 +32,8 @@ if (!existsSync(file)) { try { file = which.sync(file); - } catch (_error) { - e = _error; + } catch (error) { + e = error; return callback("Unable to resolve file [" + file + "]"); } } else { diff --git a/lib/hook.js b/lib/hook.js index 253807e..a3c8b87 100644 --- a/lib/hook.js +++ b/lib/hook.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { var Module, coffee, endsWith, fs, hook, istanbul, originalJSLoader, originalLoader, transformFn; @@ -20,7 +20,7 @@ transformFn = function(matcher, transformer, verbose) { return function(code, filename) { - var changed, ex, shouldHook, transformed; + var changed, error, ex, shouldHook, transformed; shouldHook = matcher(filename); changed = false; if (shouldHook) { @@ -30,8 +30,8 @@ try { transformed = transformer(code, filename); changed = true; - } catch (_error) { - ex = _error; + } catch (error) { + ex = error; console.error('Transformation error; return original code'); console.error(ex.stack); console.error(ex); diff --git a/lib/ibrik.js b/lib/ibrik.js index 770e298..53dfc85 100644 --- a/lib/ibrik.js +++ b/lib/ibrik.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { var istanbul, key, value, hasProp = {}.hasOwnProperty; diff --git a/lib/instrumenter.js b/lib/instrumenter.js index a50a94b..d0ed276 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -1,6 +1,6 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { - var Instrumenter, _, coffee, esprima, estraverse, fs, globalEval, istanbul, path, + var Instrumenter, _, clean, coffee, esprima, estraverse, fs, globalEval, istanbul, path, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; @@ -18,6 +18,8 @@ fs = require('fs'); + clean = require('./clean'); + globalEval = function(source) { var geval; geval = eval; @@ -32,7 +34,7 @@ } Instrumenter.prototype.instrumentSync = function(code, filename) { - var e, program; + var e, error, program; filename = filename || ((Date.now()) + ".js"); if (typeof code !== 'string') { throw new Error('Code must be string'); @@ -41,6 +43,7 @@ code = coffee.compile(code, { sourceMap: true }); + code.js = clean(code.js); program = esprima.parse(code.js, { loc: true, range: true, @@ -50,8 +53,8 @@ }); this.fixupLoc(program, code.sourceMap); return this.instrumentASTSync(program, filename, code); - } catch (_error) { - e = _error; + } catch (error) { + e = error; e.message = "Error compiling " + filename + ": " + e.message; throw e; } diff --git a/lib/report.js b/lib/report.js index 841ee84..b4e28f9 100644 --- a/lib/report.js +++ b/lib/report.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.2 +// Generated by CoffeeScript 1.10.0 (function() { var istanbul; diff --git a/package.json b/package.json index 2290c17..98b2420 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "url": "git://github.com/Constellation/ibrik.git" }, "dependencies": { - "coffee-script": "~1.8.0", + "coffee-script": "~1.10.0", "esprima": "1.2.x", "estraverse": "^1.9.0", "fileset": "0.1.x", @@ -34,6 +34,7 @@ "lodash": "~2.4.1", "mkdirp": "~0.5.0", "optimist": "~0.6.1", + "semver": "^4.3.6", "which": "~1.0.5" }, "devDependencies": { diff --git a/src/clean.coffee b/src/clean.coffee new file mode 100644 index 0000000..f750d9d --- /dev/null +++ b/src/clean.coffee @@ -0,0 +1,67 @@ +# Copyright (C) 2012-2014 Yusuke Suzuki +# Copyright (C) 2013-2014 Jeff Stamerjohn +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +coffee = require 'coffee-script' +semver = require 'semver' + +ignoreString = '/* istanbul ignore next: coffeescript utility boilerplate */' + +utilities = + extends: + '1.8.0': + original: '__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }' + replacement: "__extends = function(child, parent) { for (var key in parent) { #{ignoreString} if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + '1.9.0': + original: 'extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }' + replacement: "extend = function(child, parent) { for (var key in parent) { #{ignoreString} if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + '1.10.0': + original: 'extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }' + replacement: "extend = function(child, parent) { for (var key in parent) { #{ignoreString} if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }" + + indexOf: + '1.8.0': + original: '__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }' + replacement: "__indexOf = #{ignoreString} [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { #{ignoreString} if (i in this && this[i] === item) return i; } return -1; }" + '1.9.0': + original: 'indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }' + replacement: "indexOf = #{ignoreString} [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { #{ignoreString} if (i in this && this[i] === item) return i; } return -1; }" + '1.10.0': + original: 'indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }' + replacement: "indexOf = #{ignoreString} [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { #{ignoreString} if (i in this && this[i] === item) return i; } return -1; }" + +clean = (compiledJS) -> + switch semver.minor coffee.VERSION + when 8 then version = '1.8.0' + when 9 then version = '1.9.0' + when 10 then version = '1.10.0' + else return compiledJS + + newCompiledJS = compiledJS + + for utilityKey, utilityVersions of utilities when utility = utilityVersions[version] + newCompiledJS = newCompiledJS.replace utility.original, utility.replacement + + return newCompiledJS + +module.exports = clean +# vim: set sw=4 ts=4 et tw=80 : diff --git a/src/instrumenter.coffee b/src/instrumenter.coffee index 3edfde5..cf57f96 100644 --- a/src/instrumenter.coffee +++ b/src/instrumenter.coffee @@ -28,6 +28,7 @@ _ = require 'lodash' esprima = require 'esprima' path = require 'path' fs = require 'fs' +clean = require './clean' # Use ECMAScript 5.1th indirect call to eval instead of direct eval call. globalEval = (source) -> @@ -45,6 +46,7 @@ class Instrumenter extends istanbul.Instrumenter try code = coffee.compile code, sourceMap: true + code.js = clean code.js program = esprima.parse(code.js, { loc: true range: true