Issue #856. Invert

This commit is contained in:
Jeremy Ashkenas 2010-11-28 15:33:43 -08:00
parent 4afa6a2887
commit c3f1820ebc
15 changed files with 34 additions and 37 deletions

View File

@ -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...

View File

@ -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 _

View File

@ -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;
})
],

View File

@ -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;
}

View File

@ -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 === '::');

View File

@ -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;";
}
}

View File

@ -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;

View File

@ -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 ''

View File

@ -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]

View File

@ -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

View File

@ -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 : '=='

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'