mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
refactoring Scope.
This commit is contained in:
parent
3eac6aeb99
commit
2fb269a938
4 changed files with 30 additions and 71 deletions
12
lib/nodes.js
12
lib/nodes.js
|
@ -281,11 +281,13 @@
|
|||
}
|
||||
post = this.compileNode(o);
|
||||
scope = o.scope;
|
||||
if (!o.globals && o.scope.hasDeclarations(this)) {
|
||||
code += "" + this.tab + "var " + (scope.compiledDeclarations()) + ";\n";
|
||||
}
|
||||
if (scope.hasAssignments(this)) {
|
||||
code += "" + this.tab + "var " + (multident(scope.compiledAssignments(), this.tab)) + ";\n";
|
||||
if (scope.expressions === this) {
|
||||
if (!o.globals && o.scope.hasDeclarations) {
|
||||
code += "" + this.tab + "var " + (scope.declaredVariables().join(', ')) + ";\n";
|
||||
}
|
||||
if (scope.hasAssignments) {
|
||||
code += "" + this.tab + "var " + (multident(scope.assignedVariables().join(', '), this.tab)) + ";\n";
|
||||
}
|
||||
}
|
||||
return code + post;
|
||||
};
|
||||
|
|
42
lib/scope.js
42
lib/scope.js
|
@ -34,17 +34,7 @@
|
|||
return true;
|
||||
}
|
||||
this.add(name, 'var');
|
||||
return false;
|
||||
};
|
||||
Scope.prototype.any = function(fn) {
|
||||
var v, _i, _len, _ref;
|
||||
_ref = this.variables;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
v = _ref[_i];
|
||||
if (fn(v)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.hasDeclarations = true;
|
||||
return false;
|
||||
};
|
||||
Scope.prototype.parameter = function(name) {
|
||||
|
@ -86,36 +76,28 @@
|
|||
index++;
|
||||
}
|
||||
this.add(temp, 'var');
|
||||
this.hasDeclarations = true;
|
||||
return temp;
|
||||
};
|
||||
Scope.prototype.assign = function(name, value) {
|
||||
return this.add(name, {
|
||||
this.add(name, {
|
||||
value: value,
|
||||
assigned: true
|
||||
});
|
||||
};
|
||||
Scope.prototype.hasDeclarations = function(body) {
|
||||
return body === this.expressions && this.any(function(v) {
|
||||
return v.type === 'var';
|
||||
});
|
||||
};
|
||||
Scope.prototype.hasAssignments = function(body) {
|
||||
return body === this.expressions && this.any(function(v) {
|
||||
return v.type.assigned;
|
||||
});
|
||||
return this.hasAssignments = true;
|
||||
};
|
||||
Scope.prototype.declaredVariables = function() {
|
||||
var tmp, usr, v, _i, _len, _ref;
|
||||
usr = [];
|
||||
tmp = [];
|
||||
var realVars, tempVars, v, _i, _len, _ref;
|
||||
realVars = [];
|
||||
tempVars = [];
|
||||
_ref = this.variables;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
v = _ref[_i];
|
||||
if (v.type === 'var') {
|
||||
(v.name.charAt(0) === '_' ? tmp : usr).push(v.name);
|
||||
(v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
|
||||
}
|
||||
}
|
||||
return usr.sort().concat(tmp.sort());
|
||||
return realVars.sort().concat(tempVars.sort());
|
||||
};
|
||||
Scope.prototype.assignedVariables = function() {
|
||||
var v, _i, _len, _ref, _results;
|
||||
|
@ -129,12 +111,6 @@
|
|||
}
|
||||
return _results;
|
||||
};
|
||||
Scope.prototype.compiledDeclarations = function() {
|
||||
return this.declaredVariables().join(', ');
|
||||
};
|
||||
Scope.prototype.compiledAssignments = function() {
|
||||
return this.assignedVariables().join(', ');
|
||||
};
|
||||
return Scope;
|
||||
}();
|
||||
}).call(this);
|
||||
|
|
|
@ -244,10 +244,11 @@ exports.Expressions = class Expressions extends Base
|
|||
@expressions = rest
|
||||
post = @compileNode o
|
||||
{scope} = o
|
||||
if not o.globals and o.scope.hasDeclarations this
|
||||
code += "#{@tab}var #{ scope.compiledDeclarations() };\n"
|
||||
if scope.hasAssignments this
|
||||
code += "#{@tab}var #{ multident scope.compiledAssignments(), @tab };\n"
|
||||
if scope.expressions is this
|
||||
if not o.globals and o.scope.hasDeclarations
|
||||
code += "#{@tab}var #{ scope.declaredVariables().join(', ') };\n"
|
||||
if scope.hasAssignments
|
||||
code += "#{@tab}var #{ multident scope.assignedVariables().join(', '), @tab };\n"
|
||||
code + post
|
||||
|
||||
# Wrap up the given nodes as an **Expressions**, unless it already happens
|
||||
|
|
|
@ -32,13 +32,9 @@ exports.Scope = class Scope
|
|||
# Look up a variable name in lexical scope, and declare it if it does not
|
||||
# already exist.
|
||||
find: (name, options) ->
|
||||
return true if @check name, options
|
||||
return yes if @check name, options
|
||||
@add name, 'var'
|
||||
false
|
||||
|
||||
# Test variables and return `true` the first time `fn(v)` returns `true`
|
||||
any: (fn) ->
|
||||
return yes for v in @variables when fn v
|
||||
@hasDeclarations = yes
|
||||
no
|
||||
|
||||
# Reserve a variable name as originating from a function parameter for this
|
||||
|
@ -72,40 +68,24 @@ exports.Scope = class Scope
|
|||
index = 0
|
||||
index++ while @check((temp = @temporary type, index), true)
|
||||
@add temp, 'var'
|
||||
@hasDeclarations = yes
|
||||
temp
|
||||
|
||||
# Ensure that an assignment is made at the top of this scope
|
||||
# (or at the top-level scope, if requested).
|
||||
assign: (name, value) ->
|
||||
@add name, value: value, assigned: true
|
||||
|
||||
# Does this scope reference any variables that need to be declared in the
|
||||
# given function body?
|
||||
hasDeclarations: (body) ->
|
||||
body is @expressions and @any (v) -> v.type is 'var'
|
||||
|
||||
# Does this scope reference any assignments that need to be declared at the
|
||||
# top of the given function body?
|
||||
hasAssignments: (body) ->
|
||||
body is @expressions and @any (v) -> v.type.assigned
|
||||
@hasAssignments = yes
|
||||
|
||||
# Return the list of variables first declared in this scope.
|
||||
declaredVariables: ->
|
||||
usr = []
|
||||
tmp = []
|
||||
realVars = []
|
||||
tempVars = []
|
||||
for v in @variables when v.type is 'var'
|
||||
(if v.name.charAt(0) is '_' then tmp else usr).push v.name
|
||||
usr.sort().concat tmp.sort()
|
||||
(if v.name.charAt(0) is '_' then tempVars else realVars).push v.name
|
||||
realVars.sort().concat tempVars.sort()
|
||||
|
||||
# Return the list of assignments that are supposed to be made at the top
|
||||
# of this scope.
|
||||
assignedVariables: ->
|
||||
("#{v.name} = #{v.type.value}" for v in @variables when v.type.assigned)
|
||||
|
||||
# Compile the JavaScript for all of the variable declarations in this scope.
|
||||
compiledDeclarations: ->
|
||||
@declaredVariables().join ', '
|
||||
|
||||
# Compile the JavaScript for all of the variable assignments in this scope.
|
||||
compiledAssignments: ->
|
||||
@assignedVariables().join ', '
|
||||
"#{v.name} = #{v.type.value}" for v in @variables when v.type.assigned
|
||||
|
|
Loading…
Add table
Reference in a new issue