Improving soaks to avoid uncessesary parentheses.
This commit is contained in:
parent
a93229b14d
commit
0f2a2ee11e
18
lib/nodes.js
18
lib/nodes.js
|
@ -99,6 +99,9 @@
|
|||
var closure, top;
|
||||
this.options = merge(o || {});
|
||||
this.indent = o.indent;
|
||||
if (!(this.operation_sensitive())) {
|
||||
del(this.options, 'operation');
|
||||
}
|
||||
top = this.top_sensitive() ? this.options.top : del(this.options, 'top');
|
||||
closure = this.is_statement() && !this.is_statement_only() && !top && !this.options.returns && !(this instanceof CommentNode) && !this.contains(function(node) {
|
||||
return node.is_statement_only();
|
||||
|
@ -164,6 +167,9 @@
|
|||
Node.prototype.top_sensitive = function top_sensitive() {
|
||||
return false;
|
||||
};
|
||||
Node.prototype.operation_sensitive = function operation_sensitive() {
|
||||
return false;
|
||||
};
|
||||
// A collection of nodes, each one representing an expression.
|
||||
Expressions = (exports.Expressions = inherit(Node, {
|
||||
type: 'Expressions',
|
||||
|
@ -326,6 +332,9 @@
|
|||
this.children.push(prop);
|
||||
return this;
|
||||
},
|
||||
operation_sensitive: function operation_sensitive() {
|
||||
return true;
|
||||
},
|
||||
has_properties: function has_properties() {
|
||||
return !!this.properties.length;
|
||||
},
|
||||
|
@ -349,9 +358,10 @@
|
|||
return this.base.is_statement && this.base.is_statement() && !this.has_properties();
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
var _a, _b, baseline, code, only, part, parts, prop, props, soaked, temp;
|
||||
var _a, _b, baseline, code, only, op, part, parts, prop, props, soaked, temp;
|
||||
soaked = false;
|
||||
only = del(o, 'only_first');
|
||||
op = del(o, 'operation');
|
||||
props = only ? this.properties.slice(0, this.properties.length - 1) : this.properties;
|
||||
baseline = this.base.compile(o);
|
||||
if (this.base instanceof ObjectNode && this.has_properties()) {
|
||||
|
@ -378,10 +388,7 @@
|
|||
this.last = parts[parts.length - 1];
|
||||
this.source = parts.length > 1 ? parts.slice(0, (parts.length - 1)).join('') : null;
|
||||
code = parts.join('').replace(/\)\(\)\)/, '()))');
|
||||
if (!(soaked)) {
|
||||
return code;
|
||||
}
|
||||
return '(' + code + ')';
|
||||
return op && soaked ? '(' + code + ')' : code;
|
||||
}
|
||||
}));
|
||||
// Pass through CoffeeScript comments into JavaScript comments at the
|
||||
|
@ -943,6 +950,7 @@
|
|||
return this.CHAINABLE.indexOf(this.operator) >= 0;
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
o.operation = true;
|
||||
if (this.is_chainable() && this.first.unwrap() instanceof OpNode && this.first.unwrap().is_chainable()) {
|
||||
return this.compile_chain(o);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ Node: exports.Node: ->
|
|||
Node::compile: (o) ->
|
||||
@options: merge o or {}
|
||||
@indent: o.indent
|
||||
del @options, 'operation' unless @operation_sensitive()
|
||||
top: if @top_sensitive() then @options.top else del @options, 'top'
|
||||
closure: @is_statement() and not @is_statement_only() and not top and
|
||||
not @options.returns and not (this instanceof CommentNode) and
|
||||
|
@ -95,11 +96,12 @@ Node::toString: (idt) ->
|
|||
'\n' + idt + @type + (child.toString(idt + TAB) for child in @children).join('')
|
||||
|
||||
# Default implementations of the common node methods.
|
||||
Node::unwrap: -> this
|
||||
Node::children: []
|
||||
Node::is_statement: -> false
|
||||
Node::is_statement_only: -> false
|
||||
Node::top_sensitive: -> false
|
||||
Node::unwrap: -> this
|
||||
Node::children: []
|
||||
Node::is_statement: -> false
|
||||
Node::is_statement_only: -> false
|
||||
Node::top_sensitive: -> false
|
||||
Node::operation_sensitive: -> false
|
||||
|
||||
# A collection of nodes, each one representing an expression.
|
||||
Expressions: exports.Expressions: inherit Node, {
|
||||
|
@ -239,6 +241,9 @@ ValueNode: exports.ValueNode: inherit Node, {
|
|||
@children.push(prop)
|
||||
this
|
||||
|
||||
operation_sensitive: ->
|
||||
true
|
||||
|
||||
has_properties: ->
|
||||
!!@properties.length
|
||||
|
||||
|
@ -264,6 +269,7 @@ ValueNode: exports.ValueNode: inherit Node, {
|
|||
compile_node: (o) ->
|
||||
soaked: false
|
||||
only: del(o, 'only_first')
|
||||
op: del(o, 'operation')
|
||||
props: if only then @properties[0...@properties.length - 1] else @properties
|
||||
baseline: @base.compile o
|
||||
baseline: '(' + baseline + ')' if @base instanceof ObjectNode and @has_properties()
|
||||
|
@ -285,8 +291,7 @@ ValueNode: exports.ValueNode: inherit Node, {
|
|||
@last: parts[parts.length - 1]
|
||||
@source: if parts.length > 1 then parts[0...(parts.length - 1)].join('') else null
|
||||
code: parts.join('').replace(/\)\(\)\)/, '()))')
|
||||
return code unless soaked
|
||||
'(' + code + ')'
|
||||
if op and soaked then '(' + code + ')' else code
|
||||
|
||||
}
|
||||
|
||||
|
@ -757,6 +762,7 @@ OpNode: exports.OpNode: inherit Node, {
|
|||
@CHAINABLE.indexOf(@operator) >= 0
|
||||
|
||||
compile_node: (o) ->
|
||||
o.operation: true
|
||||
return @compile_chain(o) if @is_chainable() and @first.unwrap() instanceof OpNode and @first.unwrap().is_chainable()
|
||||
return @compile_assignment(o) if @ASSIGNMENT.indexOf(@operator) >= 0
|
||||
return @compile_unary(o) if @is_unary()
|
||||
|
|
|
@ -55,3 +55,16 @@ ok arr.pop()?.length is 2
|
|||
ok arr.pop()?.length is undefined
|
||||
ok arr[0]?.length is undefined
|
||||
ok arr.pop()?.length?.non?.existent()?.property is undefined
|
||||
|
||||
|
||||
# Soaks method calls safely.
|
||||
value: undefined
|
||||
result: value?.toString().toLowerCase()
|
||||
|
||||
ok result is undefined
|
||||
|
||||
value: 10
|
||||
result: value?.toString().toLowerCase()
|
||||
|
||||
ok result is '10'
|
||||
|
||||
|
|
Loading…
Reference in New Issue