From c3f1820ebc862f275267dbe865ce02d5267213ec Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sun, 28 Nov 2010 15:33:43 -0800 Subject: [PATCH] Issue #856. Invert --- Cakefile | 2 +- examples/underscore.coffee | 11 +++++------ lib/grammar.js | 6 +++--- lib/index.js | 2 -- lib/lexer.js | 4 ++-- lib/nodes.js | 6 +++--- lib/parser.js | 8 ++++---- src/cake.coffee | 2 +- src/grammar.coffee | 6 +++--- src/helpers.coffee | 2 +- src/lexer.coffee | 6 +++--- src/nodes.coffee | 6 +++--- src/rewriter.coffee | 4 ++-- test/test_compilation.coffee | 2 +- test/test_comprehensions.coffee | 4 ++-- 15 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Cakefile b/Cakefile index c0e70b51..30132329 100644 --- a/Cakefile +++ b/Cakefile @@ -147,7 +147,7 @@ runTests = (CoffeeScript) -> startTime = Date.now() passedTests = failedTests = 0 - for all name, func of require 'assert' + for name, func of require 'assert' global[name] = -> passedTests += 1 func arguments... diff --git a/examples/underscore.coffee b/examples/underscore.coffee index 79aedb9d..b189d9f9 100644 --- a/examples/underscore.coffee +++ b/examples/underscore.coffee @@ -85,7 +85,7 @@ _.each = (obj, iterator, context) -> else if _.isNumber obj.length iterator.call context, obj[i], i, obj for i in [0...obj.length] else - iterator.call context, val, key, obj for key, val of obj + iterator.call context, val, key, obj for own key, val of obj catch e throw e if e isnt breaker obj @@ -176,8 +176,7 @@ _.some = (obj, iterator, context) -> # based on `===`. _.include = (obj, target) -> return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf - for key, val of obj - return true if val is target + return true for own key, val of obj when val is target false @@ -486,14 +485,14 @@ _.isEqual = (a, b) -> # Different object sizes? return false if aKeys.length isnt bKeys.length # Recursive comparison of contents. - return false for all key, val of a when !(key of b) or !_.isEqual(val, b[key]) + return false for key, val of a when !(key of b) or !_.isEqual(val, b[key]) true # Is a given array or object empty? _.isEmpty = (obj) -> return obj.length is 0 if _.isArray(obj) or _.isString(obj) - return false for key of obj when hasOwnProperty.call(obj, key) + return false for own key of obj true @@ -654,7 +653,7 @@ addToWrapper = (name, func) -> result func.apply(_, args), this._chain -# Add all of the Underscore functions to the wrapper object. +# Add all ofthe Underscore functions to the wrapper object. _.mixin _ diff --git a/lib/grammar.js b/lib/grammar.js index 84a64342..e06593ba 100644 --- a/lib/grammar.js +++ b/lib/grammar.js @@ -382,7 +382,7 @@ vars: [] }; }), o('ForStart ForSource', function() { - $2.raw = $1.raw; + $2.own = $1.own; $2.vars = $1; return $2; }) @@ -390,8 +390,8 @@ ForStart: [ o('FOR ForVariables', function() { return $2; - }), o('FOR ALL ForVariables', function() { - $3.raw = true; + }), o('FOR OWN ForVariables', function() { + $3.own = true; return $3; }) ], diff --git a/lib/index.js b/lib/index.js index 6c38774b..38f7c1e9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,9 +1,7 @@ (function() { var key, val, _ref; - var __hasProp = Object.prototype.hasOwnProperty; _ref = require('./coffee-script'); for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; val = _ref[key]; exports[key] = val; } diff --git a/lib/lexer.js b/lib/lexer.js index 04309dc0..f3dd51d0 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -39,8 +39,8 @@ return 0; } input = match[0], id = match[1], colon = match[2]; - if (id === 'all' && this.tag() === 'FOR') { - this.token('ALL', id); + if (id === 'own' && this.tag() === 'FOR') { + this.token('OWN', id); return id.length; } forcedIdentifier = colon || (prev = last(this.tokens)) && !prev.spaced && ((_ref = prev[0]) === '.' || _ref === '?.' || _ref === '@' || _ref === '::'); diff --git a/lib/nodes.js b/lib/nodes.js index 953dbc77..d20252a4 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1706,7 +1706,7 @@ this.index = index; this.source = source.source, this.guard = source.guard, this.step = source.step; this.body = Expressions.wrap([body]); - this.raw = !!source.raw; + this.own = !!source.own; this.object = !!source.object; if (this.object) { _ref = [this.index, this.name], this.name = _ref[0], this.index = _ref[1]; @@ -1767,7 +1767,7 @@ })); } else { svar = this.source.compile(o, LEVEL_TOP); - if ((name || !this.raw) && !IDENTIFIER.test(svar)) { + if ((name || this.own) && !IDENTIFIER.test(svar)) { defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; svar = ref; } @@ -1794,7 +1794,7 @@ } if (this.object) { forPart = "" + ivar + " in " + svar; - if (!this.raw) { + if (this.own) { guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;"; } } diff --git a/lib/parser.js b/lib/parser.js index a3b1129f..f9e2f286 100755 --- a/lib/parser.js +++ b/lib/parser.js @@ -2,8 +2,8 @@ var parser = (function(){ var parser = {trace: function trace() { }, yy: {}, -symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Throw":11,"Comment":12,"STATEMENT":13,"Value":14,"Invocation":15,"Code":16,"Operation":17,"Assign":18,"If":19,"Try":20,"While":21,"For":22,"Switch":23,"Class":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"BOOL":35,"Assignable":36,"=":37,"AssignObj":38,"ObjAssignable":39,":":40,"ThisProperty":41,"RETURN":42,"HERECOMMENT":43,"PARAM_START":44,"ParamList":45,"PARAM_END":46,"FuncGlyph":47,"->":48,"=>":49,"OptComma":50,",":51,"Param":52,"ParamVar":53,"...":54,"Array":55,"Object":56,"Splat":57,"SimpleAssignable":58,"Accessor":59,"Parenthetical":60,"Range":61,"This":62,".":63,"?.":64,"::":65,"Index":66,"Slice":67,"INDEX_START":68,"INDEX_END":69,"INDEX_SOAK":70,"INDEX_PROTO":71,"{":72,"AssignList":73,"}":74,"CLASS":75,"EXTENDS":76,"OptFuncExist":77,"Arguments":78,"SUPER":79,"FUNC_EXIST":80,"CALL_START":81,"CALL_END":82,"ArgList":83,"THIS":84,"@":85,"[":86,"]":87,"RangeDots":88,"..":89,"Arg":90,"SimpleArgs":91,"TRY":92,"Catch":93,"FINALLY":94,"CATCH":95,"THROW":96,"(":97,")":98,"WhileSource":99,"WHILE":100,"WHEN":101,"UNTIL":102,"Loop":103,"LOOP":104,"ForBody":105,"FOR":106,"ForStart":107,"ForSource":108,"ForVariables":109,"ALL":110,"ForValue":111,"FORIN":112,"FOROF":113,"BY":114,"SWITCH":115,"Whens":116,"ELSE":117,"When":118,"LEADING_WHEN":119,"IfBlock":120,"IF":121,"UNLESS":122,"POST_IF":123,"POST_UNLESS":124,"UNARY":125,"-":126,"+":127,"--":128,"++":129,"?":130,"MATH":131,"SHIFT":132,"COMPARE":133,"LOGIC":134,"RELATION":135,"COMPOUND_ASSIGN":136,"$accept":0,"$end":1}, -terminals_: {"2":"error","6":"TERMINATOR","13":"STATEMENT","25":"INDENT","26":"OUTDENT","28":"IDENTIFIER","30":"NUMBER","31":"STRING","33":"JS","34":"REGEX","35":"BOOL","37":"=","40":":","42":"RETURN","43":"HERECOMMENT","44":"PARAM_START","46":"PARAM_END","48":"->","49":"=>","51":",","54":"...","63":".","64":"?.","65":"::","68":"INDEX_START","69":"INDEX_END","70":"INDEX_SOAK","71":"INDEX_PROTO","72":"{","74":"}","75":"CLASS","76":"EXTENDS","79":"SUPER","80":"FUNC_EXIST","81":"CALL_START","82":"CALL_END","84":"THIS","85":"@","86":"[","87":"]","89":"..","92":"TRY","94":"FINALLY","95":"CATCH","96":"THROW","97":"(","98":")","100":"WHILE","101":"WHEN","102":"UNTIL","104":"LOOP","106":"FOR","110":"ALL","112":"FORIN","113":"FOROF","114":"BY","115":"SWITCH","117":"ELSE","119":"LEADING_WHEN","121":"IF","122":"UNLESS","123":"POST_IF","124":"POST_UNLESS","125":"UNARY","126":"-","127":"+","128":"--","129":"++","130":"?","131":"MATH","132":"SHIFT","133":"COMPARE","134":"LOGIC","135":"RELATION","136":"COMPOUND_ASSIGN"}, +symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Throw":11,"Comment":12,"STATEMENT":13,"Value":14,"Invocation":15,"Code":16,"Operation":17,"Assign":18,"If":19,"Try":20,"While":21,"For":22,"Switch":23,"Class":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"BOOL":35,"Assignable":36,"=":37,"AssignObj":38,"ObjAssignable":39,":":40,"ThisProperty":41,"RETURN":42,"HERECOMMENT":43,"PARAM_START":44,"ParamList":45,"PARAM_END":46,"FuncGlyph":47,"->":48,"=>":49,"OptComma":50,",":51,"Param":52,"ParamVar":53,"...":54,"Array":55,"Object":56,"Splat":57,"SimpleAssignable":58,"Accessor":59,"Parenthetical":60,"Range":61,"This":62,".":63,"?.":64,"::":65,"Index":66,"Slice":67,"INDEX_START":68,"INDEX_END":69,"INDEX_SOAK":70,"INDEX_PROTO":71,"{":72,"AssignList":73,"}":74,"CLASS":75,"EXTENDS":76,"OptFuncExist":77,"Arguments":78,"SUPER":79,"FUNC_EXIST":80,"CALL_START":81,"CALL_END":82,"ArgList":83,"THIS":84,"@":85,"[":86,"]":87,"RangeDots":88,"..":89,"Arg":90,"SimpleArgs":91,"TRY":92,"Catch":93,"FINALLY":94,"CATCH":95,"THROW":96,"(":97,")":98,"WhileSource":99,"WHILE":100,"WHEN":101,"UNTIL":102,"Loop":103,"LOOP":104,"ForBody":105,"FOR":106,"ForStart":107,"ForSource":108,"ForVariables":109,"OWN":110,"ForValue":111,"FORIN":112,"FOROF":113,"BY":114,"SWITCH":115,"Whens":116,"ELSE":117,"When":118,"LEADING_WHEN":119,"IfBlock":120,"IF":121,"UNLESS":122,"POST_IF":123,"POST_UNLESS":124,"UNARY":125,"-":126,"+":127,"--":128,"++":129,"?":130,"MATH":131,"SHIFT":132,"COMPARE":133,"LOGIC":134,"RELATION":135,"COMPOUND_ASSIGN":136,"$accept":0,"$end":1}, +terminals_: {"2":"error","6":"TERMINATOR","13":"STATEMENT","25":"INDENT","26":"OUTDENT","28":"IDENTIFIER","30":"NUMBER","31":"STRING","33":"JS","34":"REGEX","35":"BOOL","37":"=","40":":","42":"RETURN","43":"HERECOMMENT","44":"PARAM_START","46":"PARAM_END","48":"->","49":"=>","51":",","54":"...","63":".","64":"?.","65":"::","68":"INDEX_START","69":"INDEX_END","70":"INDEX_SOAK","71":"INDEX_PROTO","72":"{","74":"}","75":"CLASS","76":"EXTENDS","79":"SUPER","80":"FUNC_EXIST","81":"CALL_START","82":"CALL_END","84":"THIS","85":"@","86":"[","87":"]","89":"..","92":"TRY","94":"FINALLY","95":"CATCH","96":"THROW","97":"(","98":")","100":"WHILE","101":"WHEN","102":"UNTIL","104":"LOOP","106":"FOR","110":"OWN","112":"FORIN","113":"FOROF","114":"BY","115":"SWITCH","117":"ELSE","119":"LEADING_WHEN","121":"IF","122":"UNLESS","123":"POST_IF","124":"POST_UNLESS","125":"UNARY","126":"-","127":"+","128":"--","129":"++","130":"?","131":"MATH","132":"SHIFT","133":"COMPARE","134":"LOGIC","135":"RELATION","136":"COMPOUND_ASSIGN"}, productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,3],[5,2],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[18,3],[18,5],[38,1],[38,3],[38,5],[38,1],[39,1],[39,1],[39,1],[10,2],[10,1],[12,1],[16,5],[16,2],[47,1],[47,1],[50,0],[50,1],[45,0],[45,1],[45,3],[52,1],[52,2],[52,3],[53,1],[53,1],[53,1],[53,1],[57,2],[58,1],[58,2],[58,2],[58,1],[36,1],[36,1],[36,1],[14,1],[14,1],[14,1],[14,1],[14,1],[59,2],[59,2],[59,2],[59,1],[59,1],[59,1],[66,3],[66,2],[66,2],[56,4],[73,0],[73,1],[73,3],[73,4],[73,6],[24,1],[24,2],[24,3],[24,4],[24,2],[24,3],[24,4],[24,5],[15,3],[15,3],[15,1],[15,2],[77,0],[77,1],[78,2],[78,4],[62,1],[62,1],[41,2],[55,2],[55,4],[88,1],[88,1],[61,5],[67,5],[67,4],[67,4],[83,1],[83,3],[83,4],[83,4],[83,6],[90,1],[90,1],[91,1],[91,3],[20,2],[20,3],[20,4],[20,5],[93,3],[11,2],[60,3],[60,5],[99,2],[99,4],[99,2],[99,4],[21,2],[21,2],[21,2],[21,1],[103,2],[103,2],[22,2],[22,2],[22,2],[105,2],[105,2],[107,2],[107,3],[111,1],[111,1],[111,1],[109,1],[109,3],[108,2],[108,2],[108,4],[108,4],[108,4],[108,6],[108,6],[23,5],[23,7],[23,4],[23,6],[116,1],[116,2],[118,3],[118,4],[120,3],[120,3],[120,5],[120,3],[19,1],[19,3],[19,3],[19,3],[19,3],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,5],[17,3]], performAction: function anonymous(yytext,yyleng,yylineno,yy) { @@ -316,7 +316,7 @@ case 146:this.$ = { }; break; case 147:this.$ = (function () { - $$[$0-2+2-1].raw = $$[$0-2+1-1].raw; + $$[$0-2+2-1].own = $$[$0-2+1-1].own; $$[$0-2+2-1].vars = $$[$0-2+1-1]; return $$[$0-2+2-1]; }()); @@ -324,7 +324,7 @@ break; case 148:this.$ = $$[$0-2+2-1]; break; case 149:this.$ = (function () { - $$[$0-3+3-1].raw = true; + $$[$0-3+3-1].own = true; return $$[$0-3+3-1]; }()); break; diff --git a/src/cake.coffee b/src/cake.coffee index 4fbd19ab..2e5f2d9d 100644 --- a/src/cake.coffee +++ b/src/cake.coffee @@ -56,7 +56,7 @@ exports.run = -> # Display the list of Cake tasks in a format similar to `rake -T` printTasks = -> console.log '' - for all name, task of tasks + for name, task of tasks spaces = 20 - name.length spaces = if spaces > 0 then Array(spaces + 1).join(' ') else '' desc = if task.description then "# #{task.description}" else '' diff --git a/src/grammar.coffee b/src/grammar.coffee index 8bdfbd77..bb51e350 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -424,12 +424,12 @@ grammar = ForBody: [ o 'FOR Range', -> source: new Value($2), vars: [] - o 'ForStart ForSource', -> $2.raw = $1.raw; $2.vars = $1; $2 + o 'ForStart ForSource', -> $2.own = $1.own; $2.vars = $1; $2 ] ForStart: [ o 'FOR ForVariables', -> $2 - o 'FOR ALL ForVariables', -> $3.raw = yes; $3 + o 'FOR OWN ForVariables', -> $3.own = yes; $3 ] # An array of all accepted values for a variable inside the loop. @@ -577,7 +577,7 @@ operators = [ # terminals (every symbol which does not appear as the name of a rule above) # as "tokens". tokens = [] -for all name, alternatives of grammar +for name, alternatives of grammar grammar[name] = for alt in alternatives for token in alt[0].split ' ' tokens.push token unless grammar[token] diff --git a/src/helpers.coffee b/src/helpers.coffee index f17a019a..69c204b5 100644 --- a/src/helpers.coffee +++ b/src/helpers.coffee @@ -29,7 +29,7 @@ exports.merge = (options, overrides) -> # Extend a source object with the properties of another object (shallow copy). extend = exports.extend = (object, properties) -> - for all key, val of properties + for key, val of properties object[key] = val object diff --git a/src/lexer.coffee b/src/lexer.coffee index ea9e7533..9ef698b6 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -75,8 +75,8 @@ exports.Lexer = class Lexer return 0 unless match = IDENTIFIER.exec @chunk [input, id, colon] = match - if id is 'all' and @tag() is 'FOR' - @token 'ALL', id + if id is 'own' and @tag() is 'FOR' + @token 'OWN', id return id.length forcedIdentifier = colon or (prev = last @tokens) and not prev.spaced and prev[0] in ['.', '?.', '@', '::'] @@ -499,7 +499,7 @@ JS_KEYWORDS = [ # CoffeeScript-only keywords. COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'] -COFFEE_KEYWORDS.push op for all op of COFFEE_ALIASES = +COFFEE_KEYWORDS.push op for op of COFFEE_ALIASES = and : '&&' or : '||' is : '==' diff --git a/src/nodes.coffee b/src/nodes.coffee index 237b4343..82f32ea6 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1374,7 +1374,7 @@ exports.For = class For extends Base constructor: (body, source, @name, @index) -> {@source, @guard, @step} = source @body = Expressions.wrap [body] - @raw = !!source.raw + @own = !!source.own @object = !!source.object [@name, @index] = [@index, @name] if @object throw SyntaxError 'index cannot be a pattern matching expression' if @index instanceof Value @@ -1418,7 +1418,7 @@ exports.For = class For extends Base forPart = source.compile merge(o, {index: ivar, @step}) else svar = @source.compile o, LEVEL_TOP - if (name or not @raw) and not IDENTIFIER.test svar + if (name or @own) and not IDENTIFIER.test svar defPart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n" svar = ref namePart = if @pattern @@ -1440,7 +1440,7 @@ exports.For = class For extends Base varPart = "\n#{idt1}#{namePart};" if namePart if @object forPart = "#{ivar} in #{svar}" - guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw + guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" if @own defPart += @pluckDirectCall o, body, name, index unless @pattern body = body.compile merge(o, indent: idt1), LEVEL_TOP body = '\n' + body + '\n' if body diff --git a/src/rewriter.coffee b/src/rewriter.coffee index 92c29340..59776a50 100644 --- a/src/rewriter.coffee +++ b/src/rewriter.coffee @@ -217,7 +217,7 @@ class exports.Rewriter openLine[open] = token[2] if levels[open]++ is 0 else if tag is close and --levels[open] < 0 throw Error "too many #{token[1]} on line #{token[2] + 1}" - for all open, level of levels when level > 0 + for open, level of levels when level > 0 throw Error "unclosed #{ open } on line #{openLine[open] + 1}" this @@ -240,7 +240,7 @@ class exports.Rewriter rewriteClosingParens: -> stack = [] debt = {} - debt[key] = 0 for all key of INVERSES + debt[key] = 0 for key of INVERSES @scanTokens (token, i, tokens) -> if (tag = token[0]) in EXPRESSION_START stack.push token diff --git a/test/test_compilation.coffee b/test/test_compilation.coffee index b8669f1f..8b327df4 100644 --- a/test/test_compilation.coffee +++ b/test/test_compilation.coffee @@ -12,7 +12,7 @@ ok 'passed' is CoffeeScript.eval '"passed"', bare: on, fileName: 'test' try ok not CoffeeScript.nodes 'f(->' catch e then eq e.message, 'unclosed CALL_START on line 1' -eq CoffeeScript.compile('for all k of o then', bare: on, globals: on), +eq CoffeeScript.compile('for k of o then', bare: on, globals: on), 'for (k in o) {}' #875: %d and %s in strings causes node.js to apply formatting diff --git a/test/test_comprehensions.coffee b/test/test_comprehensions.coffee index 08b58dc5..86dff3ff 100644 --- a/test/test_comprehensions.coffee +++ b/test/test_comprehensions.coffee @@ -171,8 +171,8 @@ class Cat hair: 'cream' whiskers = new Cat -own = (value for key, value of whiskers) -all = (value for all key, value of whiskers) +own = (value for own key, value of whiskers) +all = (value for key, value of whiskers) ok own.join(' ') is 'Whiskers' ok all.sort().join(' ') is 'Whiskers cream tabby'