Fixing #600. JS statements that must be expressions but contain pure statements cause syntax errors.

This commit is contained in:
Timothy Jones 2010-10-19 20:02:21 +13:00
parent d9cd75c426
commit df46fb8c68
2 changed files with 17 additions and 9 deletions

View File

@ -31,13 +31,13 @@
this.options = o ? merge(o) : {};
this.tab = o.indent;
top = this.topSensitive() ? this.options.top : del(this.options, 'top');
closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof Comment) && !this.containsPureStatement();
closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof Comment);
code = closure ? this.compileClosure(this.options) : this.compileNode(this.options);
return code;
};
Base.prototype.compileClosure = function(o) {
o.sharedScope = o.scope;
return Closure.wrap(this).compile(o);
return Closure.wrap(this, false, true).compile(o);
};
Base.prototype.compileReference = function(o, options) {
var _len, compiled, i, node, pair, reference;
@ -484,7 +484,7 @@
var method, name;
method = o.scope.method;
if (!method) {
throw Error("cannot call super outside of a function");
throw Error("cannot call super outside of a function.");
}
name = method.name;
if (!name) {
@ -1910,8 +1910,14 @@
}
};
Closure = {
wrap: function(expressions, statement) {
wrap: function(expressions, statement, force) {
var args, call, func, mentionsArgs, meth;
if (expressions.containsPureStatement()) {
if (!force) {
return expressions;
}
throw new Error('cannot include a pure statement in an expression.');
}
if (expressions.containsPureStatement()) {
return expressions;
}

View File

@ -44,8 +44,7 @@ exports.Base = class Base
@tab = o.indent
top = if @topSensitive() then @options.top else del @options, 'top'
closure = @isStatement(o) and not @isPureStatement() and not top and
not @options.asStatement and this not instanceof Comment and
not @containsPureStatement()
not @options.asStatement and this not instanceof Comment
code = if closure then @compileClosure(@options) else @compileNode(@options)
code
@ -53,7 +52,7 @@ exports.Base = class Base
# object with their parent closure, to preserve the expected lexical scope.
compileClosure: (o) ->
o.sharedScope = o.scope
Closure.wrap(this).compile o
Closure.wrap(this, no, yes).compile o
# If the code generation wishes to use the result of a complex expression
# in multiple places, ensure that the expression is only ever evaluated once,
@ -447,7 +446,7 @@ exports.Call = class Call extends Base
# Grab the reference to the superclass' implementation of the current method.
superReference: (o) ->
{method} = o.scope
throw Error "cannot call super outside of a function" unless method
throw Error "cannot call super outside of a function." unless method
{name} = method
throw Error "cannot call super on an anonymous function." unless name
if method.klass
@ -1617,7 +1616,10 @@ Closure =
# Wrap the expressions body, unless it contains a pure statement,
# in which case, no dice. If the body mentions `this` or `arguments`,
# then make sure that the closure wrapper preserves the original values.
wrap: (expressions, statement) ->
wrap: (expressions, statement, force) ->
if expressions.containsPureStatement()
return expressions unless force
throw new Error 'cannot include a pure statement in an expression.'
return expressions if expressions.containsPureStatement()
func = new Parens new Code [], Expressions.wrap [expressions]
args = []