destructuring assignment no longer uses a temporary variable for simple LHS

This commit is contained in:
satyr
2010-10-11 09:17:31 +09:00
parent 2642fde0f8
commit e5fe145f80
3 changed files with 102 additions and 48 deletions

View File

@@ -154,6 +154,7 @@
Base.prototype.isPureStatement = NO;
Base.prototype.isComplex = YES;
Base.prototype.topSensitive = NO;
Base.prototype.assigns = NO;
return Base;
})();
exports.Expressions = (function() {
@@ -266,6 +267,9 @@
Literal.prototype.isReserved = function() {
return !!this.value.reserved;
};
Literal.prototype.assigns = function(name) {
return name === this.value;
};
Literal.prototype.compileNode = function(o) {
var end, idt, val;
idt = this.isStatement(o) ? this.idt() : '';
@@ -348,6 +352,9 @@
Value.prototype.isComplex = function() {
return this.base.isComplex() || this.hasProperties();
};
Value.prototype.assigns = function(name) {
return !this.properties.length && this.base.assigns(name);
};
Value.prototype.makeReturn = function() {
return this.properties.length ? Value.__super__.makeReturn.call(this) : this.base.makeReturn();
};
@@ -817,13 +824,7 @@
for (i = 0, _len = (_ref2 = this.properties).length; i < _len; i++) {
prop = _ref2[i];
_result.push((function() {
join = ",\n";
if ((prop === lastNoncom) || (prop instanceof Comment)) {
join = "\n";
}
if (i === this.properties.length - 1) {
join = '';
}
join = i === this.properties.length - 1 ? '' : (prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n');
indent = prop instanceof Comment ? '' : this.idt(1);
if (prop instanceof Value && prop.tags["this"]) {
prop = new Assign(prop.properties[0].name, prop, 'object');
@@ -836,9 +837,19 @@
return _result;
}).call(this);
props = props.join('');
obj = '{' + (props ? '\n' + props + '\n' + this.idt() : '') + '}';
obj = ("{" + (props ? '\n' + props + '\n' + this.idt() : '') + "}");
return top ? ("(" + obj + ")") : obj;
};
ObjectLiteral.prototype.assigns = function(name) {
var _i, _len, _ref2, prop;
for (_i = 0, _len = (_ref2 = this.properties).length; _i < _len; _i++) {
prop = _ref2[_i];
if (prop.assigns(name)) {
return true;
}
}
return false;
};
return ObjectLiteral;
})();
exports.ArrayLiteral = (function() {
@@ -874,6 +885,16 @@
objects = objects.join('');
return 0 < objects.indexOf('\n') ? ("[\n" + (o.indent) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]");
};
ArrayLiteral.prototype.assigns = function(name) {
var _i, _len, _ref2, obj;
for (_i = 0, _len = (_ref2 = this.objects).length; _i < _len; _i++) {
obj = _ref2[_i];
if (obj.assigns(name)) {
return true;
}
}
return false;
};
return ArrayLiteral;
})();
exports.Class = (function() {
@@ -1024,7 +1045,7 @@
return top || this.parenthetical ? val : ("(" + val + ")");
};
Assign.prototype.compilePatternMatch = function(o) {
var _len, _ref2, _ref3, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, splat, top, val, valVar, value;
var _len, _ref2, _ref3, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, ref, splat, top, val, valVar, value;
if ((value = this.value).isStatement(o)) {
value = Closure.wrap(value);
}
@@ -1050,15 +1071,19 @@
otop = merge(o, {
top: true
});
valVar = o.scope.freeVariable('ref');
assigns = [("" + valVar + " = " + (value.compile(o)))];
valVar = value.compile(o);
assigns = [];
splat = false;
if (!IDENTIFIER.test(valVar) || this.variable.assigns(valVar)) {
assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + valVar);
valVar = ref;
}
for (i = 0, _len = objects.length; i < _len; i++) {
obj = objects[i];
idx = i;
if (isObject) {
if (obj instanceof Assign) {
_ref3 = [obj.value, obj.variable.base], obj = _ref3[0], idx = _ref3[1];
_ref3 = obj, idx = _ref3.variable.base, obj = _ref3.value;
} else {
idx = obj.tags["this"] ? obj.properties[0].name : obj;
}
@@ -1095,6 +1120,9 @@
val = this.value.compile(o);
return "([].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + ref + " = " + val + ")), " + ref + ")";
};
Assign.prototype.assigns = function(name) {
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
};
return Assign;
})();
exports.Code = (function() {
@@ -1221,16 +1249,16 @@
Splat = (function() {
function Splat(name) {
Splat.__super__.constructor.call(this);
if (!name.compile) {
name = new Literal(name);
}
this.name = name;
this.name = name.compile ? name : new Literal(name);
return this;
};
return Splat;
})();
__extends(Splat, Base);
Splat.prototype.children = ['name'];
Splat.prototype.assigns = function(name) {
return this.name.assigns(name);
};
Splat.prototype.compileNode = function(o) {
return (this.index != null) ? this.compileParam(o) : this.name.compile(o);
};
@@ -1611,16 +1639,16 @@
exports.For = (function() {
For = (function() {
function For(_arg, source, _arg2, _arg3) {
var _ref2, _ref3;
var _ref2;
this.index = _arg3;
this.name = _arg2;
this.body = _arg;
For.__super__.constructor.call(this);
_ref2 = source, this.source = _ref2.source, this.guard = _ref2.guard, this.step = _ref2.step;
this.source = source.source, this.guard = source.guard, this.step = source.step;
this.raw = !!source.raw;
this.object = !!source.object;
if (this.object) {
_ref3 = [this.index, this.name], this.name = _ref3[0], this.index = _ref3[1];
_ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
}
this.pattern = this.name instanceof Value;
if (this.index instanceof Value) {
@@ -1772,16 +1800,16 @@
return this;
};
Switch.prototype.compileNode = function(o) {
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, block, code, condition, conditions, exprs, idt, pair;
var _i, _j, _len, _len2, _ref2, _ref3, block, code, condition, conditions, exprs, idt, pair;
idt = (o.indent = this.idt(2));
o.top = true;
code = ("" + (this.tab) + "switch (" + (this.subject.compile(o)) + ") {");
for (_i = 0, _len = (_ref2 = this.cases).length; _i < _len; _i++) {
pair = _ref2[_i];
_ref3 = pair, conditions = _ref3[0], block = _ref3[1];
conditions = pair[0], block = pair[1];
exprs = block.expressions;
for (_j = 0, _len2 = (_ref4 = flatten([conditions])).length; _j < _len2; _j++) {
condition = _ref4[_j];
for (_j = 0, _len2 = (_ref3 = flatten([conditions])).length; _j < _len2; _j++) {
condition = _ref3[_j];
if (this.tags.subjectless) {
condition = new Op('!!', new Parens(condition));
}