From ead9b1041c55a9d2518ab6ec2d6d30b028c74efa Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sat, 14 Aug 2010 11:29:10 -0400 Subject: [PATCH] tweaking existential compilation. --- lib/nodes.js | 18 ++---------------- src/nodes.coffee | 16 +++++----------- test/test_existence.coffee | 5 +++++ 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 007a8c9a..61f5ec65 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -322,7 +322,6 @@ return this; }; __extends(ValueNode, BaseNode); - ValueNode.prototype.SOAK = " == undefined ? undefined : "; ValueNode.prototype["class"] = 'ValueNode'; ValueNode.prototype.children = ['base', 'properties']; ValueNode.prototype.push = function(prop) { @@ -353,17 +352,6 @@ ValueNode.prototype.isNumber = function() { return this.base instanceof LiteralNode && this.base.value.match(NUMBER); }; - ValueNode.prototype.isStart = function(o) { - var node; - if (this === o.chainRoot && this.properties[0] instanceof AccessorNode) { - return true; - } - node = o.chainRoot.base || o.chainRoot.variable; - while (node instanceof CallNode) { - node = node.variable; - } - return node === this; - }; ValueNode.prototype.cacheIndexes = function(o) { var _b, _c, _d, copy, i; copy = new ValueNode(this.base, this.properties.slice(0)); @@ -414,10 +402,8 @@ temp = o.scope.freeVariable(); complete = ("(" + (baseline = temp) + " = (" + (complete) + "))"); } - if (i === 0 && this.isStart(o)) { - complete = ("typeof " + (complete) + " === \"undefined\" || " + (baseline)); - } - return complete += this.SOAK + (baseline += prop.compile(o)); + complete = i === 0 ? ("(typeof " + (complete) + " === \"undefined\" || " + (baseline) + " === null) ? undefined : ") : ("" + (complete) + " == undefined ? undefined : "); + return complete += (baseline += prop.compile(o)); } else { part = prop.compile(o); baseline += part; diff --git a/src/nodes.coffee b/src/nodes.coffee index 29bb40c2..deba0ee9 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -288,8 +288,6 @@ exports.ReturnNode = class ReturnNode extends BaseNode # or vanilla. exports.ValueNode = class ValueNode extends BaseNode - SOAK: " == undefined ? undefined : " - class: 'ValueNode' children: ['base', 'properties'] @@ -331,13 +329,6 @@ exports.ValueNode = class ValueNode extends BaseNode isNumber: -> @base instanceof LiteralNode and @base.value.match NUMBER - # Works out if the value is the start of a chain. - isStart: (o) -> - return true if this is o.chainRoot and @properties[0] instanceof AccessorNode - node = o.chainRoot.base or o.chainRoot.variable - while node instanceof CallNode then node = node.variable - node is this - # 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 # the value of the indexes. @@ -373,8 +364,11 @@ exports.ValueNode = class ValueNode extends BaseNode if @base instanceof CallNode or @base.contains((n) -> n instanceof CallNode) and i is 0 temp = o.scope.freeVariable() complete = "(#{ baseline = temp } = (#{complete}))" - complete = "typeof #{complete} === \"undefined\" || #{baseline}" if i is 0 and @isStart(o) - complete += @SOAK + (baseline += prop.compile(o)) + complete = if i is 0 + "(typeof #{complete} === \"undefined\" || #{baseline} === null) ? undefined : " + else + "#{complete} == undefined ? undefined : " + complete += (baseline += prop.compile(o)) else part = prop.compile(o) baseline += part diff --git a/test/test_existence.coffee b/test/test_existence.coffee index 85c1cf86..c54d7f5e 100644 --- a/test/test_existence.coffee +++ b/test/test_existence.coffee @@ -70,6 +70,11 @@ result = value?.toString().toLowerCase() ok result is '10' +# Soaks inner values. +ident = (obj) -> obj +ok ident(non?.existent().method()) is undefined + + # Soaks constructor invocations. a = 0 class Foo