diff --git a/lib/lexer.js b/lib/lexer.js index 6bb3aa49..a6f8e657 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -1,8 +1,5 @@ (function(){ var ACCESSORS, ASSIGNMENT, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMMENT_CLEANER, CONVERSIONS, HALF_ASSIGNMENTS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, INTERPOLATION, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, Lexer, MULTILINER, MULTI_DENT, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_ESCAPE, REGEX_FLAGS, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, STRING_NEWLINES, WHITESPACE, balanced_string, compact, count, helpers, include, starts; - var Coffeescript = { - aslice: Array.prototype.slice - }; // The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt // matches against the beginning of the source code. When a match is found, // a token is produced, we consume the match, and start again. Tokens are in the @@ -239,7 +236,7 @@ // balanced (ie. strings, JS literals). Lexer.prototype.balanced_token = function balanced_token() { var delimited; - delimited = Coffeescript.aslice.call(arguments, 0, arguments.length - 0); + delimited = Array.prototype.slice.call(arguments, 0, arguments.length - 0); return balanced_string(this.chunk, delimited); }; // Matches and conumes comments. We pass through comments into JavaScript, diff --git a/lib/nodes.js b/lib/nodes.js index b9ad0220..2210eb92 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -20,12 +20,11 @@ bind: function(func, obj, args) { obj = obj || {}; return (typeof args !== 'undefined' && args !== null) ? function() { - return func.apply(obj, args.concat(Coffeescript.aslice.call(arguments, 0))); + return func.apply(obj, args.concat(Array.prototype.slice.call(arguments, 0))); } : function() { return func.apply(obj, arguments); }; - }, - aslice: Array.prototype.slice + } }; // `nodes.coffee` contains all of the node classes for the syntax tree. Most // nodes are created as the result of actions in the [grammar](grammar.html), @@ -1163,15 +1162,15 @@ o.scope.assign(trailing.compile(o), "arguments[arguments.length - " + this.trailings.length + " + " + i + "]"); i += 1; } - return "" + name + " = " + (o.scope.utility('aslice')) + ".call(arguments, " + this.index + ", arguments.length - " + (this.trailings.length) + ")"; + return "" + name + " = Array.prototype.slice.call(arguments, " + this.index + ", arguments.length - " + (this.trailings.length) + ")"; }; // A compiling a splat as a destructuring assignment means slicing arguments // from the right-hand-side's corresponding array. SplatNode.prototype.compile_value = function compile_value(o, name, index, trailings) { if ((typeof trailings !== "undefined" && trailings !== null)) { - return "" + (o.scope.utility('aslice')) + ".call(" + name + ", " + index + ", " + (name) + ".length - " + trailings + ")"; + return "Array.prototype.slice.call(" + name + ", " + index + ", " + (name) + ".length - " + trailings + ")"; } else { - return "" + (o.scope.utility('aslice')) + ".call(" + name + ", " + index + ")"; + return "Array.prototype.slice.call(" + name + ", " + index + ")"; } }; // Utility function that converts arbitrary number of elements, mixed with diff --git a/lib/rewriter.js b/lib/rewriter.js index db787699..104f602d 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -4,12 +4,11 @@ bind: function(func, obj, args) { obj = obj || {}; return (typeof args !== 'undefined' && args !== null) ? function() { - return func.apply(obj, args.concat(Coffeescript.aslice.call(arguments, 0))); + return func.apply(obj, args.concat(Array.prototype.slice.call(arguments, 0))); } : function() { return func.apply(obj, arguments); }; }, - aslice: Array.prototype.slice, hasProp: Object.prototype.hasOwnProperty }; // The CoffeeScript language has a good deal of optional syntax, implicit syntax, diff --git a/lib/scope.js b/lib/scope.js index 3af3e340..7382fc82 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -107,24 +107,24 @@ _b = (utilities.dependencies[name] || []); for (_a = 0, _c = _b.length; _a < _c; _a++) { dep = _b[_a]; - this.utility(dep); + !this.utilities[dep] ? this.utility(dep) : null; } } - return "" + (utilities.KEY) + "." + name; + return "" + (utilities.key) + "." + name; }; // Formats an javascript object containing the utility methods required // in the scope Scope.prototype.included_utilities = function included_utilities(tab) { - var _a, _b, _c, _d, key, props; - if ((typeof (_d = this.utilities) !== "undefined" && _d !== null)) { + var _a, _b, _c, key, props; + if ((typeof (_c = this.utilities) !== "undefined" && _c !== null)) { props = (function() { _a = []; _b = this.utilities; for (key in _b) { if (Coffeescript.hasProp.call(_b, key)) { - (typeof (_c = this.utilities[key]) !== "undefined" && _c !== null) ? _a.push(utilities.format(key, tab)) : null; + _a.push(utilities.format(key, tab)); }} return _a; }).call(this); - return ["" + (utilities.KEY) + " = {" + (props.join(', ')) + "\n" + tab + "}"]; + return ["" + (utilities.key) + " = {" + (props.join(', ')) + "\n" + tab + "}"]; } else { return []; } diff --git a/lib/utilities.js b/lib/utilities.js index b5948138..51a13cbb 100644 --- a/lib/utilities.js +++ b/lib/utilities.js @@ -1,26 +1,27 @@ (function(){ - var utilities; + var KEY, utilities; if (!((typeof process !== "undefined" && process !== null))) { this.exports = this; } - exports.utilities = (utilities = { - KEY: "Coffeescript" - }); - utilities.format = function format(key, tab) { - return "\n " + tab + key + ": " + (utilities.functions[key].replace(/\n/g, "\n" + tab + " ") || 'undefined'); - }; - utilities.dependencies = { - slice: ['range'], - splice: ['range'], - bind: ['aslice'] - }; - utilities.functions = { - extend: "function(child, parent) {\n var ctor = function(){ };\n ctor.prototype = parent.prototype;\n child.__superClass__ = parent.prototype;\n child.prototype = new ctor();\n child.prototype.constructor = child;\n}", - bind: "function(func, obj, args) {\n obj = obj || {};\n return (typeof args !== 'undefined' && args !== null) ? function() {\n return func.apply(obj, args.concat(" + (utilities.KEY) + ".aslice.call(arguments, 0)));\n } : function() {\n return func.apply(obj, arguments);\n };\n}", - range: "function(array, from, to, exclusive) {\n return [\n (from < 0 ? from + array.length : from || 0),\n (to < 0 ? to + array.length : to || array.length) + (exclusive ? 0 : 1)\n ];\n}", - slice: "function(array, from, to, exclusive) {\n return array.slice.apply(array, " + (utilities.KEY) + ".range(array, from, to, exclusive));\n}", - splice: "function(array, from, to, exclusive, replace) {\n var _a, _r = " + (utilities.KEY) + ".range(array, from, to, exclusive);\n return array.splice.apply(array, [_a = _r[0], _r[1] - _a].concat(replace));\n}", - hasProp: "Object.prototype.hasOwnProperty", - aslice: "Array.prototype.slice" - }; + KEY = "Coffeescript"; + exports.utilities = (function() { + utilities = function utilities() { }; + utilities.key = KEY; + utilities.format = function format(key, tab) { + return "\n " + tab + key + ": " + (utilities.functions[key].replace(/\n/g, "\n" + tab + " ") || 'undefined'); + }; + utilities.dependencies = { + slice: ['range'], + splice: ['range'] + }; + utilities.functions = { + extend: "function(child, parent) {\n var ctor = function(){ };\n ctor.prototype = parent.prototype;\n child.__superClass__ = parent.prototype;\n child.prototype = new ctor();\n child.prototype.constructor = child;\n}", + bind: "function(func, obj, args) {\n obj = obj || {};\n return (typeof args !== 'undefined' && args !== null) ? function() {\n return func.apply(obj, args.concat(Array.prototype.slice.call(arguments, 0)));\n } : function() {\n return func.apply(obj, arguments);\n };\n}", + range: "function(array, from, to, exclusive) {\n return [\n (from < 0 ? from + array.length : from || 0),\n (to < 0 ? to + array.length : to || array.length) + (exclusive ? 0 : 1)\n ];\n}", + slice: "function(array, from, to, exclusive) {\n return array.slice.apply(array, " + (KEY) + ".range(array, from, to, exclusive));\n}", + splice: "function(array, from, to, exclusive, replace) {\n return array.splice.apply(array, [(_a = " + (KEY) + ".range(array, from, to, exclusive))[0], \n _a[1] - _a[0]].concat(replace));\n}", + hasProp: "Object.prototype.hasOwnProperty" + }; + return utilities; + }).call(this); })(); diff --git a/src/nodes.coffee b/src/nodes.coffee index e7f439f8..fcabd953 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -843,13 +843,13 @@ exports.SplatNode: class SplatNode extends BaseNode for trailing in @trailings o.scope.assign(trailing.compile(o), "arguments[arguments.length - $@trailings.length + $i]") i: + 1 - "$name = ${o.scope.utility('aslice')}.call(arguments, $@index, arguments.length - ${@trailings.length})" + "$name = Array.prototype.slice.call(arguments, $@index, arguments.length - ${@trailings.length})" # A compiling a splat as a destructuring assignment means slicing arguments # from the right-hand-side's corresponding array. compile_value: (o, name, index, trailings) -> - if trailings? then "${o.scope.utility('aslice')}.call($name, $index, ${name}.length - $trailings)" \ - else "${o.scope.utility('aslice')}.call($name, $index)" + if trailings? then "Array.prototype.slice.call($name, $index, ${name}.length - $trailings)" \ + else "Array.prototype.slice.call($name, $index)" # Utility function that converts arbitrary number of elements, mixed with # splats, to a proper array diff --git a/src/scope.coffee b/src/scope.coffee index ad08ce7e..3f60ced6 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -69,15 +69,15 @@ exports.Scope: class Scope if utilities.functions[name]? @utilities: or {} @utilities[name]: utilities.functions[name] - @utility(dep) for dep in (utilities.dependencies[name] or []) - "${utilities.KEY}.$name" + @utility(dep) for dep in (utilities.dependencies[name] or []) when not @utilities[dep] + "${utilities.key}.$name" # Formats an javascript object containing the utility methods required # in the scope included_utilities: (tab) -> if @utilities? - props: (utilities.format(key, tab) for key of @utilities when @utilities[key]?) - ["${utilities.KEY} = {${props.join(', ')}\n$tab}"] + props: (utilities.format(key, tab) for key of @utilities) + ["${utilities.key} = {${props.join(', ')}\n$tab}"] else [] # Does this scope reference any variables that need to be declared in the diff --git a/src/utilities.coffee b/src/utilities.coffee index a2b09a24..f22e1d2a 100644 --- a/src/utilities.coffee +++ b/src/utilities.coffee @@ -1,55 +1,54 @@ this.exports: this unless process? -exports.utilities: utilities: { KEY: "Coffeescript" } +KEY: "Coffeescript" -utilities.format: (key, tab) -> - "\n $tab$key: ${utilities.functions[key].replace(/\n/g, "\n$tab ") or 'undefined'}" - -utilities.dependencies: { - slice: ['range'] - splice: ['range'] - bind: ['aslice'] -} - -utilities.functions: { - extend: """ - function(child, parent) { - var ctor = function(){ }; - ctor.prototype = parent.prototype; - child.__superClass__ = parent.prototype; - child.prototype = new ctor(); - child.prototype.constructor = child; - } - """ - bind: """ - function(func, obj, args) { - obj = obj || {}; - return (typeof args !== 'undefined' && args !== null) ? function() { - return func.apply(obj, args.concat(${utilities.KEY}.aslice.call(arguments, 0))); - } : function() { - return func.apply(obj, arguments); - }; - } - """ - range: """ - function(array, from, to, exclusive) { - return [ - (from < 0 ? from + array.length : from || 0), - (to < 0 ? to + array.length : to || array.length) + (exclusive ? 0 : 1) - ]; - } - """ - slice: """ - function(array, from, to, exclusive) { - return array.slice.apply(array, ${utilities.KEY}.range(array, from, to, exclusive)); - } - """ - splice: """ - function(array, from, to, exclusive, replace) { - var _a, _r = ${utilities.KEY}.range(array, from, to, exclusive); - return array.splice.apply(array, [_a = _r[0], _r[1] - _a].concat(replace)); - } - """ +exports.utilities: class utilities + @key: KEY + @format: (key, tab) -> + "\n $tab$key: ${utilities.functions[key].replace(/\n/g, "\n$tab ") or 'undefined'}" - hasProp: "Object.prototype.hasOwnProperty" - aslice: "Array.prototype.slice" -} \ No newline at end of file + @dependencies: { + slice: ['range'] + splice: ['range'] + } + + @functions: { + extend: """ + function(child, parent) { + var ctor = function(){ }; + ctor.prototype = parent.prototype; + child.__superClass__ = parent.prototype; + child.prototype = new ctor(); + child.prototype.constructor = child; + } + """ + bind: """ + function(func, obj, args) { + obj = obj || {}; + return (typeof args !== 'undefined' && args !== null) ? function() { + return func.apply(obj, args.concat(Array.prototype.slice.call(arguments, 0))); + } : function() { + return func.apply(obj, arguments); + }; + } + """ + range: """ + function(array, from, to, exclusive) { + return [ + (from < 0 ? from + array.length : from || 0), + (to < 0 ? to + array.length : to || array.length) + (exclusive ? 0 : 1) + ]; + } + """ + slice: """ + function(array, from, to, exclusive) { + return array.slice.apply(array, ${KEY}.range(array, from, to, exclusive)); + } + """ + splice: """ + function(array, from, to, exclusive, replace) { + return array.splice.apply(array, [(_a = ${KEY}.range(array, from, to, exclusive))[0], + _a[1] - _a[0]].concat(replace)); + } + """ + hasProp: "Object.prototype.hasOwnProperty" + } \ No newline at end of file