mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
nodes: reformatted
This commit is contained in:
parent
7bfb2e3a78
commit
101a044219
2 changed files with 62 additions and 106 deletions
63
lib/nodes.js
63
lib/nodes.js
|
@ -6,9 +6,6 @@
|
|||
child.prototype = new ctor;
|
||||
if (typeof parent.extended === "function") parent.extended(child);
|
||||
child.__super__ = parent.prototype;
|
||||
}, __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) if (this[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
Scope = require('./scope').Scope;
|
||||
_ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, extend = _ref.extend, merge = _ref.merge, del = _ref.del, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
|
||||
|
@ -347,13 +344,19 @@
|
|||
return !!this.properties.length;
|
||||
};
|
||||
Value.prototype.isArray = function() {
|
||||
return this.base instanceof Arr && !this.properties.length;
|
||||
return !this.properties.length && this.base instanceof Arr;
|
||||
};
|
||||
Value.prototype.isObject = function() {
|
||||
return this.base instanceof Obj && !this.properties.length;
|
||||
return !this.properties.length && this.base instanceof Obj;
|
||||
};
|
||||
Value.prototype.isComplex = function() {
|
||||
return this.base.isComplex() || this.hasProperties();
|
||||
return this.hasProperties() || this.base.isComplex();
|
||||
};
|
||||
Value.prototype.isAssignable = function() {
|
||||
return this.hasProperties() || this.base.isAssignable();
|
||||
};
|
||||
Value.prototype.isSimpleNumber = function() {
|
||||
return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
|
||||
};
|
||||
Value.prototype.isAtomic = function() {
|
||||
var _i, _len, _ref2, node;
|
||||
|
@ -366,8 +369,8 @@
|
|||
}
|
||||
return true;
|
||||
};
|
||||
Value.prototype.isAssignable = function() {
|
||||
return this.hasProperties() || this.base.isAssignable();
|
||||
Value.prototype.isStatement = function(o) {
|
||||
return !this.properties.length && this.base.isStatement(o);
|
||||
};
|
||||
Value.prototype.assigns = function(name) {
|
||||
return !this.properties.length && this.base.assigns(name);
|
||||
|
@ -378,12 +381,6 @@
|
|||
Value.prototype.unwrap = function() {
|
||||
return this.properties.length ? this : this.base;
|
||||
};
|
||||
Value.prototype.isStatement = function(o) {
|
||||
return !this.properties.length && this.base.isStatement(o);
|
||||
};
|
||||
Value.prototype.isSimpleNumber = function() {
|
||||
return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
|
||||
};
|
||||
Value.prototype.cacheReference = function(o) {
|
||||
var base, bref, name, nref;
|
||||
name = last(this.properties);
|
||||
|
@ -479,9 +476,6 @@
|
|||
})();
|
||||
__extends(Call, Base);
|
||||
Call.prototype.children = ['variable', 'args'];
|
||||
Call.prototype.compileSplatArguments = function(o) {
|
||||
return Splat.compileSplattedArray(this.args, o);
|
||||
};
|
||||
Call.prototype.newInstance = function() {
|
||||
this.isNew = true;
|
||||
return this;
|
||||
|
@ -575,7 +569,7 @@
|
|||
};
|
||||
Call.prototype.compileSplat = function(o) {
|
||||
var base, fun, idt, name, ref, splatargs;
|
||||
splatargs = this.compileSplatArguments(o);
|
||||
splatargs = Splat.compileSplattedArray(this.args, o);
|
||||
if (this.isSuper) {
|
||||
return "" + (this.superReference(o)) + ".apply(this, " + splatargs + ")";
|
||||
}
|
||||
|
@ -753,9 +747,6 @@
|
|||
})();
|
||||
__extends(Arr, Base);
|
||||
Arr.prototype.children = ['objects'];
|
||||
Arr.prototype.compileSplatLiteral = function(o) {
|
||||
return Splat.compileSplattedArray(this.objects, o);
|
||||
};
|
||||
Arr.prototype.compileNode = function(o) {
|
||||
var _i, _len, _len2, _ref2, _ref3, code, i, obj, objects;
|
||||
o.indent = this.idt(1);
|
||||
|
@ -763,7 +754,7 @@
|
|||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
obj = _ref2[_i];
|
||||
if (obj instanceof Splat) {
|
||||
return this.compileSplatLiteral(o);
|
||||
return Splat.compileSplattedArray(this.objects, o);
|
||||
}
|
||||
}
|
||||
objects = [];
|
||||
|
@ -901,7 +892,6 @@
|
|||
})();
|
||||
__extends(Assign, Base);
|
||||
Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/;
|
||||
Assign.prototype.CONDITIONAL = ['||=', '&&=', '?='];
|
||||
Assign.prototype.children = ['variable', 'value'];
|
||||
Assign.prototype.assigns = function(name) {
|
||||
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
|
||||
|
@ -915,7 +905,7 @@
|
|||
if (this.variable.isArray() || this.variable.isObject()) {
|
||||
return this.compilePatternMatch(o);
|
||||
}
|
||||
if (_ref2 = this.context, __indexOf.call(this.CONDITIONAL, _ref2) >= 0) {
|
||||
if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
|
||||
return this.compileConditional(o);
|
||||
}
|
||||
}
|
||||
|
@ -1011,12 +1001,10 @@
|
|||
})();
|
||||
exports.Code = (function() {
|
||||
Code = (function() {
|
||||
function Code(_arg, _arg2, tag) {
|
||||
this.body = _arg2;
|
||||
this.params = _arg;
|
||||
function Code(params, body, tag) {
|
||||
Code.__super__.constructor.call(this);
|
||||
this.params || (this.params = []);
|
||||
this.body || (this.body = new Expressions);
|
||||
this.params = params || [];
|
||||
this.body = body || new Expressions;
|
||||
this.bound = tag === 'boundfunc';
|
||||
if (this.bound) {
|
||||
this.context = 'this';
|
||||
|
@ -1111,12 +1099,11 @@
|
|||
})();
|
||||
exports.Param = (function() {
|
||||
Param = (function() {
|
||||
function Param(_arg, _arg2, _arg3) {
|
||||
this.splat = _arg3;
|
||||
this.attach = _arg2;
|
||||
this.name = _arg;
|
||||
function Param(name, _arg, _arg2) {
|
||||
this.splat = _arg2;
|
||||
this.attach = _arg;
|
||||
Param.__super__.constructor.call(this);
|
||||
this.value = new Literal(this.name);
|
||||
this.value = new Literal(this.name = name);
|
||||
return this;
|
||||
};
|
||||
return Param;
|
||||
|
@ -1796,11 +1783,11 @@
|
|||
return If;
|
||||
}).call(this);
|
||||
Push = {
|
||||
wrap: function(name, expressions) {
|
||||
if (expressions.isEmpty() || last(expressions.expressions).containsPureStatement()) {
|
||||
return expressions;
|
||||
wrap: function(name, exps) {
|
||||
if (exps.isEmpty() || last(exps.expressions).containsPureStatement()) {
|
||||
return exps;
|
||||
}
|
||||
return expressions.push(new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [expressions.pop()]));
|
||||
return exps.push(new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [exps.pop()]));
|
||||
}
|
||||
};
|
||||
Closure = {
|
||||
|
|
105
src/nodes.coffee
105
src/nodes.coffee
|
@ -28,8 +28,7 @@ THIS = -> this
|
|||
# scope, and indentation level.
|
||||
exports.Base = class Base
|
||||
|
||||
constructor: ->
|
||||
@tags = {}
|
||||
constructor: -> @tags = {}
|
||||
|
||||
# Common logic for determining whether to wrap this node in a closure before
|
||||
# compiling it, or to compile directly. We need to wrap if this node is a
|
||||
|
@ -81,8 +80,7 @@ exports.Base = class Base
|
|||
# Construct a node that returns the current node's result.
|
||||
# Note that this is overridden for smarter behavior for
|
||||
# many statement nodes (eg If, For)...
|
||||
makeReturn: ->
|
||||
new Return this
|
||||
makeReturn: -> new Return this
|
||||
|
||||
# Does this node, or any of its children, contain a node of a certain kind?
|
||||
# Recursively traverses down the *children* of the nodes, yielding to a block
|
||||
|
@ -178,8 +176,7 @@ exports.Expressions = class Expressions extends Base
|
|||
this
|
||||
|
||||
# Remove and return the last expression of this expression list.
|
||||
pop: ->
|
||||
@expressions.pop()
|
||||
pop: -> @expressions.pop()
|
||||
|
||||
# Add an expression at the beginning of this expression list.
|
||||
unshift: (node) ->
|
||||
|
@ -188,8 +185,7 @@ exports.Expressions = class Expressions extends Base
|
|||
|
||||
# If this Expressions consists of just a single node, unwrap it by pulling
|
||||
# it back out.
|
||||
unwrap: ->
|
||||
if @expressions.length is 1 then @expressions[0] else this
|
||||
unwrap: -> if @expressions.length is 1 then @expressions[0] else this
|
||||
|
||||
# Is this an empty block of code?
|
||||
isEmpty: -> not @expressions.length
|
||||
|
@ -319,45 +315,27 @@ exports.Value = class Value extends Base
|
|||
@properties.push prop
|
||||
this
|
||||
|
||||
hasProperties: ->
|
||||
!!@properties.length
|
||||
hasProperties: -> !!@properties.length
|
||||
|
||||
# Some boolean checks for the benefit of other nodes.
|
||||
|
||||
isArray: ->
|
||||
@base instanceof Arr and not @properties.length
|
||||
|
||||
isObject: ->
|
||||
@base instanceof Obj and not @properties.length
|
||||
|
||||
isComplex: ->
|
||||
@base.isComplex() or @hasProperties()
|
||||
|
||||
isAtomic: ->
|
||||
isArray : -> not @properties.length and @base instanceof Arr
|
||||
isObject : -> not @properties.length and @base instanceof Obj
|
||||
isComplex : -> @hasProperties() or @base.isComplex()
|
||||
isAssignable : -> @hasProperties() or @base.isAssignable()
|
||||
isSimpleNumber : -> @base instanceof Literal and SIMPLENUM.test @base.value
|
||||
isAtomic : ->
|
||||
for node in @properties.concat @base
|
||||
return no if node.soakNode or node instanceof Call
|
||||
yes
|
||||
|
||||
isAssignable: ->
|
||||
@hasProperties() or @base.isAssignable()
|
||||
isStatement : (o) -> not @properties.length and @base.isStatement o
|
||||
assigns : (name) -> not @properties.length and @base.assigns name
|
||||
|
||||
assigns: (name) ->
|
||||
not @properties.length and @base.assigns name
|
||||
|
||||
makeReturn: ->
|
||||
if @properties.length then super() else @base.makeReturn()
|
||||
makeReturn: -> if @properties.length then super() else @base.makeReturn()
|
||||
|
||||
# The value can be unwrapped as its inner node, if there are no attached
|
||||
# properties.
|
||||
unwrap: ->
|
||||
if @properties.length then this else @base
|
||||
|
||||
# Values are considered to be statements if their base is a statement.
|
||||
isStatement: (o) ->
|
||||
not @properties.length and @base.isStatement o
|
||||
|
||||
isSimpleNumber: ->
|
||||
@base instanceof Literal and SIMPLENUM.test @base.value
|
||||
unwrap: -> if @properties.length then this else @base
|
||||
|
||||
# A reference has base part (`this` value) and name part.
|
||||
# We cache them separately for compiling complex expressions.
|
||||
|
@ -434,9 +412,6 @@ exports.Call = class Call extends Base
|
|||
@variable = if @isSuper then null else variable
|
||||
@args or= []
|
||||
|
||||
compileSplatArguments: (o) ->
|
||||
Splat.compileSplattedArray @args, o
|
||||
|
||||
# Tag this invocation as creating a new instance.
|
||||
newInstance: ->
|
||||
@isNew = true
|
||||
|
@ -506,7 +481,7 @@ exports.Call = class Call extends Base
|
|||
# If it's a constructor, then things get real tricky. We have to inject an
|
||||
# inner constructor in order to be able to pass the varargs.
|
||||
compileSplat: (o) ->
|
||||
splatargs = @compileSplatArguments o
|
||||
splatargs = Splat.compileSplattedArray @args, o
|
||||
return "#{ @superReference o }.apply(this, #{splatargs})" if @isSuper
|
||||
unless @isNew
|
||||
base = new Value @variable
|
||||
|
@ -639,13 +614,10 @@ exports.Arr = class Arr extends Base
|
|||
super()
|
||||
@objects = objs or []
|
||||
|
||||
compileSplatLiteral: (o) ->
|
||||
Splat.compileSplattedArray @objects, o
|
||||
|
||||
compileNode: (o) ->
|
||||
o.indent = @idt 1
|
||||
for obj in @objects when obj instanceof Splat
|
||||
return @compileSplatLiteral o
|
||||
return Splat.compileSplattedArray @objects, o
|
||||
objects = []
|
||||
for obj, i in @objects
|
||||
code = obj.compile o, LEVEL_LIST
|
||||
|
@ -756,8 +728,6 @@ exports.Assign = class Assign extends Base
|
|||
# Matchers for detecting class/method names
|
||||
METHOD_DEF: /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/
|
||||
|
||||
CONDITIONAL: ['||=', '&&=', '?=']
|
||||
|
||||
children: ['variable', 'value']
|
||||
|
||||
constructor: (@variable, @value, @context) -> super()
|
||||
|
@ -774,7 +744,7 @@ exports.Assign = class Assign extends Base
|
|||
compileNode: (o) ->
|
||||
if isValue = @variable instanceof Value
|
||||
return @compilePatternMatch o if @variable.isArray() or @variable.isObject()
|
||||
return @compileConditional o if @context in @CONDITIONAL
|
||||
return @compileConditional o if @context in ['||=', '&&=', '?=']
|
||||
name = @variable.compile o, LEVEL_LIST
|
||||
if @value instanceof Code and match = @METHOD_DEF.exec name
|
||||
@value.name = match[2]
|
||||
|
@ -863,12 +833,12 @@ exports.Code = class Code extends Base
|
|||
|
||||
children: ['params', 'body']
|
||||
|
||||
constructor: (@params, @body, tag) ->
|
||||
constructor: (params, body, tag) ->
|
||||
super()
|
||||
@params or= []
|
||||
@body or= new Expressions
|
||||
@bound = tag is 'boundfunc'
|
||||
@context = 'this' if @bound
|
||||
@params = params or []
|
||||
@body = body or new Expressions
|
||||
@bound = tag is 'boundfunc'
|
||||
@context = 'this' if @bound
|
||||
|
||||
# Compilation creates a new scope unless explicitly asked to share with the
|
||||
# outer scope. Handles splat parameters in the parameter list by peeking at
|
||||
|
@ -945,9 +915,9 @@ exports.Param = class Param extends Base
|
|||
|
||||
children: ['name']
|
||||
|
||||
constructor: (@name, @attach, @splat) ->
|
||||
constructor: (name, @attach, @splat) ->
|
||||
super()
|
||||
@value = new Literal @name
|
||||
@value = new Literal @name = name
|
||||
|
||||
compile: (o) -> @value.compile o, LEVEL_LIST
|
||||
|
||||
|
@ -973,8 +943,7 @@ exports.Splat = class Splat extends Base
|
|||
|
||||
assigns: (name) -> @name.assigns name
|
||||
|
||||
compile: (o) ->
|
||||
if @index? then @compileParam o else @name.compile o
|
||||
compile: (o) -> if @index? then @compileParam o else @name.compile o
|
||||
|
||||
# Compiling a parameter splat means recovering the parameters that succeed
|
||||
# the splat in the parameter list, by slicing the arguments object.
|
||||
|
@ -1036,8 +1005,8 @@ exports.While = class While extends Base
|
|||
|
||||
constructor: (condition, opts) ->
|
||||
super()
|
||||
@condition = if opts?.invert then condition.invert() else condition
|
||||
@guard = opts?.guard
|
||||
@condition = if opts?.invert then condition.invert() else condition
|
||||
@guard = opts?.guard
|
||||
|
||||
addBody: (body) ->
|
||||
@body = body
|
||||
|
@ -1095,9 +1064,9 @@ exports.Op = class Op extends Base
|
|||
first = new Parens first if first instanceof Code and first.bound
|
||||
super()
|
||||
@operator = @CONVERSIONS[op] or op
|
||||
@first = first
|
||||
@second = second
|
||||
@flip = !!flip
|
||||
@first = first
|
||||
@second = second
|
||||
@flip = !!flip
|
||||
|
||||
isUnary: -> not @second
|
||||
|
||||
|
@ -1447,7 +1416,8 @@ exports.If = class If extends Base
|
|||
# The **If** only compiles into a statement if either of its bodies needs
|
||||
# to be a statement. Otherwise a conditional operator is safe.
|
||||
isStatement: (o) ->
|
||||
o?.level is LEVEL_TOP or @bodyNode().isStatement(o) or @elseBodyNode()?.isStatement(o)
|
||||
o?.level is LEVEL_TOP or
|
||||
@bodyNode().isStatement(o) or @elseBodyNode()?.isStatement(o)
|
||||
|
||||
compileNode: (o) ->
|
||||
if @isStatement o then @compileStatement o else @compileExpression o
|
||||
|
@ -1504,11 +1474,10 @@ exports.If = class If extends Base
|
|||
# The **Push** creates the tree for `array.push(value)`,
|
||||
# which is helpful for recording the result arrays from comprehensions.
|
||||
Push =
|
||||
wrap: (name, expressions) ->
|
||||
return expressions if expressions.isEmpty() or
|
||||
last(expressions.expressions).containsPureStatement()
|
||||
expressions.push new Call(new Value new Literal(name), [new Accessor new Literal 'push']
|
||||
[expressions.pop()])
|
||||
wrap: (name, exps) ->
|
||||
return exps if exps.isEmpty() or last(exps.expressions).containsPureStatement()
|
||||
exps.push new Call \
|
||||
new Value(new Literal(name), [new Accessor new Literal 'push']), [exps.pop()]
|
||||
|
||||
#### Closure
|
||||
|
||||
|
|
Loading…
Reference in a new issue