simplifying generated output for unless/is to (a isnt b) instead of not (a is b). Ticket #617

This commit is contained in:
Jeremy Ashkenas 2010-08-15 15:13:33 -04:00
parent 197f576cab
commit 027b9e9dc3
4 changed files with 37 additions and 8 deletions

View File

@ -305,7 +305,7 @@
return true;
};
Lexer.prototype.newlineToken = function(newlines) {
if (!(this.tag() === 'TERMINATOR')) {
if (this.tag() !== 'TERMINATOR') {
this.token('TERMINATOR', "\n");
}
return true;
@ -523,7 +523,7 @@
if (pi < i && pi < str.length - 1) {
tokens.push(['STRING', quote + str.substring(pi, i) + quote]);
}
if (!(tokens[0][0] === 'STRING')) {
if (tokens[0][0] !== 'STRING') {
tokens.unshift(['STRING', '""']);
}
interpolated = tokens.length > 1;

View File

@ -1242,6 +1242,10 @@
'==': '===',
'!=': '!=='
};
OpNode.prototype.INVERSIONS = {
'!==': '===',
'===': '!=='
};
OpNode.prototype.CHAINABLE = ['<', '>', '>=', '<=', '===', '!=='];
OpNode.prototype.ASSIGNMENT = ['||=', '&&=', '?='];
OpNode.prototype.PREFIX_OPERATORS = ['typeof', 'delete'];
@ -1250,13 +1254,19 @@
OpNode.prototype.isUnary = function() {
return !this.second;
};
OpNode.prototype.isMutator = function() {
OpNode.prototype.isInvertable = function() {
var _b;
return ends(this.operator, '=') && !('===' === (_b = this.operator) || '!==' === _b);
return ('===' === (_b = this.operator) || '!==' === _b);
};
OpNode.prototype.isMutator = function() {
return ends(this.operator, '=') && !this.isInvertable();
};
OpNode.prototype.isChainable = function() {
return include(this.CHAINABLE, this.operator);
};
OpNode.prototype.invert = function() {
return (this.operator = this.INVERSIONS[this.operator]);
};
OpNode.prototype.toString = function(idt) {
return OpNode.__superClass__.toString.call(this, idt, this["class"] + ' ' + this.operator);
};
@ -1637,7 +1647,11 @@
this.condition = _b;
this.tags || (this.tags = {});
if (this.tags.invert) {
this.condition = new OpNode('!', new ParentheticalNode(this.condition));
if (this.condition instanceof OpNode && this.condition.isInvertable()) {
this.condition.invert();
} else {
this.condition = new OpNode('!', new ParentheticalNode(this.condition));
}
}
this.elseBody = null;
this.isChain = false;

View File

@ -63,7 +63,7 @@
Rewriter.prototype.adjustComments = function() {
return this.scanTokens(function(token, i) {
var _c, _d, after, before, post, prev;
if (!(token[0] === 'HERECOMMENT')) {
if (token[0] !== 'HERECOMMENT') {
return 1;
}
_c = [this.tokens[i - 2], this.tokens[i - 1], this.tokens[i + 1], this.tokens[i + 2]];

View File

@ -1059,6 +1059,11 @@ exports.OpNode = class OpNode extends BaseNode
'==': '==='
'!=': '!=='
# The map of invertable operators.
INVERSIONS:
'!==': '==='
'===': '!=='
# The list of operators for which we perform
# [Python-style comparison chaining](http://docs.python.org/reference/expressions.html#notin).
CHAINABLE: ['<', '>', '>=', '<=', '===', '!==']
@ -1081,12 +1086,18 @@ exports.OpNode = class OpNode extends BaseNode
isUnary: ->
not @second
isInvertable: ->
@operator in ['===', '!==']
isMutator: ->
ends(@operator, '=') and @operator not in ['===', '!==']
ends(@operator, '=') and not @isInvertable()
isChainable: ->
include(@CHAINABLE, @operator)
invert: ->
@operator = @INVERSIONS[@operator]
toString: (idt) ->
super(idt, @class + ' ' + @operator)
@ -1369,7 +1380,11 @@ exports.IfNode = class IfNode extends BaseNode
constructor: (@condition, @body, @tags) ->
@tags or= {}
@condition = new OpNode('!', new ParentheticalNode(@condition)) if @tags.invert
if @tags.invert
if @condition instanceof OpNode and @condition.isInvertable()
@condition.invert()
else
@condition = new OpNode '!', new ParentheticalNode @condition
@elseBody = null
@isChain = false