fixes #1509: compile initial comments/literals outside of safety wrapper

This commit is contained in:
Michael Ficarra 2011-12-12 02:44:52 -05:00
parent 5f1314cd66
commit 26a28abcb5
2 changed files with 45 additions and 9 deletions

View File

@ -302,19 +302,41 @@
};
Block.prototype.compileRoot = function(o) {
var code, hasReturn;
o.indent = this.tab = o.bare ? '' : TAB;
var code, e, exp, hasReturn, i, prelude, preludeExps, rest;
o.indent = "";
o.scope = new Scope(null, this, null);
o.level = LEVEL_TOP;
this.spaced = true;
code = this.compileWithDeclarations(o);
prelude = "";
hasReturn = false;
this.traverseChildren(false, function(e) {
if (e instanceof Return) hasReturn = true;
return !hasReturn;
});
if ((o.bare || o.scope.variables.length <= 1) && !hasReturn) return code;
return "(function() {\n" + code + "\n}).call(this);\n";
if (hasReturn || !o.bare) {
preludeExps = (function() {
var _len, _ref2, _results;
_ref2 = this.expressions;
_results = [];
for (i = 0, _len = _ref2.length; i < _len; i++) {
exp = _ref2[i];
e = exp.unwrap();
if (!(e instanceof Comment || e instanceof Literal)) break;
_results.push(exp);
}
return _results;
}).call(this);
rest = this.expressions.slice(preludeExps.length);
this.expressions = preludeExps;
if (preludeExps.length) prelude = "" + (this.compileNode(o)) + "\n\n";
this.expressions = rest;
o.indent = TAB;
}
code = this.compileWithDeclarations(o);
if (hasReturn || (!o.bare && o.scope.variables.length > 1)) {
return "" + prelude + "(function() {\n" + code + "\n}).call(this);\n";
}
return prelude + code;
};
Block.prototype.compileWithDeclarations = function(o) {

View File

@ -243,18 +243,32 @@ exports.Block = class Block extends Base
# It would be better not to generate them in the first place, but for now,
# clean up obvious double-parentheses.
compileRoot: (o) ->
o.indent = @tab = if o.bare then '' else TAB
o.indent = ""
o.scope = new Scope null, this, null
o.level = LEVEL_TOP
@spaced = yes
code = @compileWithDeclarations o
prelude = ""
hasReturn = no
@traverseChildren no, (e) ->
hasReturn = yes if e instanceof Return
!hasReturn
if hasReturn or not o.bare
preludeExps = for exp, i in @expressions
e = exp.unwrap()
break unless e instanceof Comment or e instanceof Literal
exp
rest = @expressions[preludeExps.length...]
@expressions = preludeExps
prelude = "#{@compileNode o}\n\n" if preludeExps.length
@expressions = rest
# We assume that we will need the safety wrapper.
# This is our best guess without actually compiling.
o.indent = TAB
code = @compileWithDeclarations o
# the `1` below accounts for `arguments`, always "in scope"
return code if (o.bare or o.scope.variables.length <= 1) and not hasReturn
"(function() {\n#{code}\n}).call(this);\n"
if hasReturn or (not o.bare and o.scope.variables.length > 1)
return "#{prelude}(function() {\n#{code}\n}).call(this);\n"
prelude + code
# Compile the expressions body for the contents of a function, with
# declarations of all inner variables pushed up to the top.