First draft of fixing shorthand objects mixed with regulars within arrays.

This commit is contained in:
Jeremy Ashkenas
2011-01-19 22:36:30 -05:00
parent 7625d900d3
commit 3924c2f2bd
3 changed files with 81 additions and 50 deletions

View File

@@ -631,37 +631,41 @@
}
return ifn;
};
Call.prototype.filterImplicitObjects = function(list) {
var node, nodes, obj, prop, properties, _i, _j, _len, _len2, _ref;
nodes = [];
for (_i = 0, _len = list.length; _i < _len; _i++) {
node = list[_i];
if (!((typeof node.isObject == "function" ? node.isObject() : void 0) && node.base.generated)) {
nodes.push(node);
continue;
}
obj = null;
_ref = node.base.properties;
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
prop = _ref[_j];
if (prop instanceof Assign) {
if (!obj) {
nodes.push(obj = new Obj(properties = [], true));
}
properties.push(prop);
} else {
nodes.push(prop);
obj = null;
}
}
}
return nodes;
};
Call.prototype.compileNode = function(o) {
var arg, args, code, obj, prop, properties, _i, _j, _len, _len2, _ref, _ref2, _ref3;
var arg, args, code, _ref;
if ((_ref = this.variable) != null) {
_ref.front = this.front;
}
if (code = Splat.compileSplattedArray(o, this.args, true)) {
return this.compileSplat(o, code);
}
args = [];
_ref2 = this.args;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
arg = _ref2[_i];
if (!((typeof arg.isObject == "function" ? arg.isObject() : void 0) && arg.base.generated)) {
args.push(arg);
continue;
}
obj = null;
_ref3 = arg.base.properties;
for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
prop = _ref3[_j];
if (prop instanceof Assign) {
if (!obj) {
args.push(obj = new Obj(properties = [], true));
}
properties.push(prop);
} else {
args.push(prop);
obj = null;
}
}
}
args = this.filterImplicitObjects(this.args);
args = ((function() {
var _i, _len, _results;
_results = [];
@@ -931,25 +935,26 @@
this.objects = objs || [];
}
Arr.prototype.children = ['objects'];
Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects;
Arr.prototype.compileNode = function(o) {
var code, obj;
var code, obj, objs;
if (!this.objects.length) {
return '[]';
}
o.indent += TAB;
if (code = Splat.compileSplattedArray(o, this.objects)) {
objs = this.filterImplicitObjects(this.objects);
if (code = Splat.compileSplattedArray(o, objs)) {
return code;
}
code = ((function() {
var _i, _len, _ref, _results;
_ref = this.objects;
var _i, _len, _results;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
obj = _ref[_i];
for (_i = 0, _len = objs.length; _i < _len; _i++) {
obj = objs[_i];
_results.push(obj.compile(o, LEVEL_LIST));
}
return _results;
}).call(this)).join(', ');
})()).join(', ');
if (code.indexOf('\n') >= 0) {
return "[\n" + o.indent + code + "\n" + this.tab + "]";
} else {

View File

@@ -499,28 +499,30 @@ exports.Call = class Call extends Base
ifn = unfoldSoak o, call, 'variable'
ifn
# Walk through the objects in the arguments, moving over simple values.
# This allows syntax like `call a: b, c` into `call({a: b}, c);`
filterImplicitObjects: (list) ->
nodes = []
for node in list
unless node.isObject?() and node.base.generated
nodes.push node
continue
obj = null
for prop in node.base.properties
if prop instanceof Assign
nodes.push obj = new Obj properties = [], true if not obj
properties.push prop
else
nodes.push prop
obj = null
nodes
# Compile a vanilla function call.
compileNode: (o) ->
@variable?.front = @front
if code = Splat.compileSplattedArray o, @args, true
return @compileSplat o, code
# Walk through the objects in the arguments, moving over simple values.
# This allows syntax like `call a: b, c` into `call({a: b}, c);`
args = []
for arg in @args
unless arg.isObject?() and arg.base.generated
args.push arg
continue
obj = null
for prop in arg.base.properties
if prop instanceof Assign
args.push obj = new Obj properties = [], true if not obj
properties.push prop
else
args.push prop
obj = null
args = @filterImplicitObjects @args
args = (arg.compile o, LEVEL_LIST for arg in args).join ', '
if @isSuper
@superReference(o) + ".call(this#{ args and ', ' + args })"
@@ -755,11 +757,14 @@ exports.Arr = class Arr extends Base
children: ['objects']
filterImplicitObjects: Call::filterImplicitObjects
compileNode: (o) ->
return '[]' unless @objects.length
o.indent += TAB
return code if code = Splat.compileSplattedArray o, @objects
code = (obj.compile o, LEVEL_LIST for obj in @objects).join ', '
objs = @filterImplicitObjects @objects
return code if code = Splat.compileSplattedArray o, objs
code = (obj.compile o, LEVEL_LIST for obj in objs).join ', '
if code.indexOf('\n') >= 0
"[\n#{o.indent}#{code}\n#{@tab}]"
else

View File

@@ -35,3 +35,24 @@ test "array splat expansions with assignments", ->
eq 0, a
eq 4, b
arrayEq [0,1,2,3,4], list
test "mixed shorthand objects in array lists", ->
arr = [
a:1
'b'
c:1
]
ok arr.length is 3
ok arr[2].c is 1
arr = [b: 1, a: 2, 100]
eq arr[1], 100
arr = [a:0, b:1, (1 + 1)]
eq arr[1], 2
arr = [a:1, 'a', b:1, 'b']
eq arr.length, 4
eq arr[2].b, 1
eq arr[3], 'b'