nodes: made ExistenceNode omit `typeof` for known variables
This commit is contained in:
parent
9bc613e4a7
commit
b5261abb6b
|
@ -547,14 +547,14 @@
|
||||||
if (!(tok = last(this.tokens, index))) {
|
if (!(tok = last(this.tokens, index))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (tok[0] = (typeof newTag !== "undefined" && newTag !== null) ? newTag : tok[0]);
|
return (tok[0] = (newTag != null) ? newTag : tok[0]);
|
||||||
};
|
};
|
||||||
Lexer.prototype.value = function(index, val) {
|
Lexer.prototype.value = function(index, val) {
|
||||||
var tok;
|
var tok;
|
||||||
if (!(tok = last(this.tokens, index))) {
|
if (!(tok = last(this.tokens, index))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (tok[1] = (typeof val !== "undefined" && val !== null) ? val : tok[1]);
|
return (tok[1] = (val != null) ? val : tok[1]);
|
||||||
};
|
};
|
||||||
Lexer.prototype.unfinished = function() {
|
Lexer.prototype.unfinished = function() {
|
||||||
var prev, value;
|
var prev, value;
|
||||||
|
|
34
lib/nodes.js
34
lib/nodes.js
|
@ -1,5 +1,5 @@
|
||||||
(function() {
|
(function() {
|
||||||
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NO, NUMBER, ObjectNode, OpNode, ParamNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, SwitchNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility;
|
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NO, NUMBER, ObjectNode, OpNode, ParamNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, SwitchNode, TAB, THIS, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility;
|
||||||
var __extends = function(child, parent) {
|
var __extends = function(child, parent) {
|
||||||
var ctor = function(){};
|
var ctor = function(){};
|
||||||
ctor.prototype = parent.prototype;
|
ctor.prototype = parent.prototype;
|
||||||
|
@ -16,6 +16,9 @@
|
||||||
NO = function() {
|
NO = function() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
THIS = function() {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
exports.BaseNode = (function() {
|
exports.BaseNode = (function() {
|
||||||
BaseNode = function() {
|
BaseNode = function() {
|
||||||
this.tags = {};
|
this.tags = {};
|
||||||
|
@ -148,9 +151,7 @@
|
||||||
};
|
};
|
||||||
BaseNode.prototype["class"] = 'BaseNode';
|
BaseNode.prototype["class"] = 'BaseNode';
|
||||||
BaseNode.prototype.children = [];
|
BaseNode.prototype.children = [];
|
||||||
BaseNode.prototype.unwrap = function() {
|
BaseNode.prototype.unwrap = THIS;
|
||||||
return this;
|
|
||||||
};
|
|
||||||
BaseNode.prototype.isStatement = NO;
|
BaseNode.prototype.isStatement = NO;
|
||||||
BaseNode.prototype.isPureStatement = NO;
|
BaseNode.prototype.isPureStatement = NO;
|
||||||
BaseNode.prototype.isComplex = YES;
|
BaseNode.prototype.isComplex = YES;
|
||||||
|
@ -281,9 +282,7 @@
|
||||||
ReturnNode.prototype.isStatement = YES;
|
ReturnNode.prototype.isStatement = YES;
|
||||||
ReturnNode.prototype.isPureStatement = YES;
|
ReturnNode.prototype.isPureStatement = YES;
|
||||||
ReturnNode.prototype.children = ['expression'];
|
ReturnNode.prototype.children = ['expression'];
|
||||||
ReturnNode.prototype.makeReturn = function() {
|
ReturnNode.prototype.makeReturn = THIS;
|
||||||
return this;
|
|
||||||
};
|
|
||||||
ReturnNode.prototype.compile = function(o) {
|
ReturnNode.prototype.compile = function(o) {
|
||||||
var expr;
|
var expr;
|
||||||
expr = this.expression.makeReturn();
|
expr = this.expression.makeReturn();
|
||||||
|
@ -337,10 +336,10 @@
|
||||||
return this.properties.length ? this : this.base;
|
return this.properties.length ? this : this.base;
|
||||||
};
|
};
|
||||||
ValueNode.prototype.isStatement = function(o) {
|
ValueNode.prototype.isStatement = function(o) {
|
||||||
return this.base.isStatement && this.base.isStatement(o) && !this.hasProperties();
|
return this.base.isStatement(o) && !this.properties.length;
|
||||||
};
|
};
|
||||||
ValueNode.prototype.isNumber = function() {
|
ValueNode.prototype.isNumber = function() {
|
||||||
return this.base instanceof LiteralNode && this.base.value.match(NUMBER);
|
return this.base instanceof LiteralNode && NUMBER.test(this.base.value);
|
||||||
};
|
};
|
||||||
ValueNode.prototype.cacheIndexes = function(o) {
|
ValueNode.prototype.cacheIndexes = function(o) {
|
||||||
var _len, _ref2, _ref3, copy, first, i, index, indexVar, prop;
|
var _len, _ref2, _ref3, copy, first, i, index, indexVar, prop;
|
||||||
|
@ -421,9 +420,7 @@
|
||||||
__extends(CommentNode, BaseNode);
|
__extends(CommentNode, BaseNode);
|
||||||
CommentNode.prototype["class"] = 'CommentNode';
|
CommentNode.prototype["class"] = 'CommentNode';
|
||||||
CommentNode.prototype.isStatement = YES;
|
CommentNode.prototype.isStatement = YES;
|
||||||
CommentNode.prototype.makeReturn = function() {
|
CommentNode.prototype.makeReturn = THIS;
|
||||||
return this;
|
|
||||||
};
|
|
||||||
CommentNode.prototype.compileNode = function(o) {
|
CommentNode.prototype.compileNode = function(o) {
|
||||||
return this.tab + '/*' + this.comment.replace(/\n/g, '\n' + this.tab) + '*/';
|
return this.tab + '/*' + this.comment.replace(/\n/g, '\n' + this.tab) + '*/';
|
||||||
};
|
};
|
||||||
|
@ -1207,14 +1204,14 @@
|
||||||
exports.WhileNode = (function() {
|
exports.WhileNode = (function() {
|
||||||
WhileNode = function(condition, opts) {
|
WhileNode = function(condition, opts) {
|
||||||
WhileNode.__super__.constructor.call(this);
|
WhileNode.__super__.constructor.call(this);
|
||||||
if (opts && opts.invert) {
|
if (opts == null ? undefined : opts.invert) {
|
||||||
if (condition instanceof OpNode) {
|
if (condition instanceof OpNode) {
|
||||||
condition = new ParentheticalNode(condition);
|
condition = new ParentheticalNode(condition);
|
||||||
}
|
}
|
||||||
condition = new OpNode('!', condition);
|
condition = new OpNode('!', condition);
|
||||||
}
|
}
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.guard = opts && opts.guard;
|
this.guard = opts == null ? undefined : opts.guard;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
__extends(WhileNode, BaseNode);
|
__extends(WhileNode, BaseNode);
|
||||||
|
@ -1465,9 +1462,7 @@
|
||||||
ThrowNode.prototype["class"] = 'ThrowNode';
|
ThrowNode.prototype["class"] = 'ThrowNode';
|
||||||
ThrowNode.prototype.children = ['expression'];
|
ThrowNode.prototype.children = ['expression'];
|
||||||
ThrowNode.prototype.isStatement = YES;
|
ThrowNode.prototype.isStatement = YES;
|
||||||
ThrowNode.prototype.makeReturn = function() {
|
ThrowNode.prototype.makeReturn = THIS;
|
||||||
return this;
|
|
||||||
};
|
|
||||||
ThrowNode.prototype.compileNode = function(o) {
|
ThrowNode.prototype.compileNode = function(o) {
|
||||||
return "" + (this.tab) + "throw " + (this.expression.compile(o)) + ";";
|
return "" + (this.tab) + "throw " + (this.expression.compile(o)) + ";";
|
||||||
};
|
};
|
||||||
|
@ -1485,14 +1480,15 @@
|
||||||
ExistenceNode.prototype.compileNode = function(o) {
|
ExistenceNode.prototype.compileNode = function(o) {
|
||||||
var test;
|
var test;
|
||||||
test = ExistenceNode.compileTest(o, this.expression)[0];
|
test = ExistenceNode.compileTest(o, this.expression)[0];
|
||||||
return this.parenthetical ? test.substring(1, test.length - 1) : test;
|
return this.parenthetical ? test.slice(1, -1) : test;
|
||||||
};
|
};
|
||||||
ExistenceNode.compileTest = function(o, variable) {
|
ExistenceNode.compileTest = function(o, variable) {
|
||||||
var _ref2, first, second;
|
var _ref2, first, second;
|
||||||
_ref2 = variable.compileReference(o, {
|
_ref2 = variable.compileReference(o, {
|
||||||
precompile: true
|
precompile: true
|
||||||
}), first = _ref2[0], second = _ref2[1];
|
}), first = _ref2[0], second = _ref2[1];
|
||||||
return [("(typeof " + (first) + " !== \"undefined\" && " + (second) + " !== null)"), second];
|
first = first === second && o.scope.check(first) ? ("(" + (first) + " != null)") : ("(typeof " + (first) + " !== \"undefined\" && " + (second) + " !== null)");
|
||||||
|
return [first, second];
|
||||||
};
|
};
|
||||||
return ExistenceNode;
|
return ExistenceNode;
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
@ -331,10 +331,10 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
|
|
||||||
# Values are considered to be statements if their base is a statement.
|
# Values are considered to be statements if their base is a statement.
|
||||||
isStatement: (o) ->
|
isStatement: (o) ->
|
||||||
@base.isStatement and @base.isStatement(o) and not @hasProperties()
|
@base.isStatement(o) and not @properties.length
|
||||||
|
|
||||||
isNumber: ->
|
isNumber: ->
|
||||||
@base instanceof LiteralNode and @base.value.match NUMBER
|
@base instanceof LiteralNode and NUMBER.test @base.value
|
||||||
|
|
||||||
# If the value node has indexes containing function calls, and the value node
|
# If the value node has indexes containing function calls, and the value node
|
||||||
# needs to be used twice, in compound assignment ... then we need to cache
|
# needs to be used twice, in compound assignment ... then we need to cache
|
||||||
|
@ -1071,11 +1071,11 @@ exports.WhileNode = class WhileNode extends BaseNode
|
||||||
|
|
||||||
constructor: (condition, opts) ->
|
constructor: (condition, opts) ->
|
||||||
super()
|
super()
|
||||||
if opts and opts.invert
|
if opts?.invert
|
||||||
condition = new ParentheticalNode condition if condition instanceof OpNode
|
condition = new ParentheticalNode condition if condition instanceof OpNode
|
||||||
condition = new OpNode('!', condition)
|
condition = new OpNode('!', condition)
|
||||||
@condition = condition
|
@condition = condition
|
||||||
@guard = opts and opts.guard
|
@guard = opts?.guard
|
||||||
|
|
||||||
addBody: (body) ->
|
addBody: (body) ->
|
||||||
@body = body
|
@body = body
|
||||||
|
@ -1302,14 +1302,18 @@ exports.ExistenceNode = class ExistenceNode extends BaseNode
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
test = ExistenceNode.compileTest(o, @expression)[0]
|
test = ExistenceNode.compileTest(o, @expression)[0]
|
||||||
if @parenthetical then test.substring(1, test.length - 1) else test
|
if @parenthetical then test.slice 1, -1 else test
|
||||||
|
|
||||||
# The meat of the **ExistenceNode** is in this static `compileTest` method
|
# The meat of the **ExistenceNode** is in this static `compileTest` method
|
||||||
# because other nodes like to check the existence of their variables as well.
|
# because other nodes like to check the existence of their variables as well.
|
||||||
# Be careful not to double-evaluate anything.
|
# Be careful not to double-evaluate anything.
|
||||||
@compileTest: (o, variable) ->
|
@compileTest: (o, variable) ->
|
||||||
[first, second] = variable.compileReference o, precompile: yes
|
[first, second] = variable.compileReference o, precompile: yes
|
||||||
["(typeof #{first} !== \"undefined\" && #{second} !== null)", second]
|
first = if first is second and o.scope.check first
|
||||||
|
"(#{first} != null)"
|
||||||
|
else
|
||||||
|
"(typeof #{first} !== \"undefined\" && #{second} !== null)"
|
||||||
|
[first, second]
|
||||||
|
|
||||||
#### ParentheticalNode
|
#### ParentheticalNode
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue