From 25c6001a6c2bc553acdc234bd2ba3665563175ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20H=C3=A4fner?= Date: Fri, 21 Jun 2013 02:47:29 +0200 Subject: [PATCH] Speed up `updateLocationDataIfMissing`. * Avoid excessive search for missing `locationData` * Fix `locationData` for `ELSE IF`. --- lib/coffee-script/grammar.js | 4 ++-- lib/coffee-script/nodes.js | 6 +++++- lib/coffee-script/parser.js | 4 ++-- src/grammar.coffee | 2 +- src/nodes.coffee | 4 +++- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/coffee-script/grammar.js b/lib/coffee-script/grammar.js index a11b9748..666042de 100644 --- a/lib/coffee-script/grammar.js +++ b/lib/coffee-script/grammar.js @@ -514,9 +514,9 @@ type: $1 }); }), o('IfBlock ELSE IF Expression Block', function() { - return $1.addElse(new If($4, $5, { + return $1.addElse(LOC(3, 5)(new If($4, $5, { type: $3 - })); + }))); }) ], If: [ diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 45b3873c..1de96e11 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -229,7 +229,10 @@ Base.prototype.assigns = NO; Base.prototype.updateLocationDataIfMissing = function(locationData) { - this.locationData || (this.locationData = locationData); + if (this.locationData) { + return this; + } + this.locationData = locationData; return this.eachChild(function(child) { return child.updateLocationDataIfMissing(locationData); }); @@ -2852,6 +2855,7 @@ } else { this.isChain = elseBody instanceof If; this.elseBody = this.ensureBlock(elseBody); + this.elseBody.updateLocationDataIfMissing(elseBody.locationData); } return this; }; diff --git a/lib/coffee-script/parser.js b/lib/coffee-script/parser.js index f051e286..3bb55947 100755 --- a/lib/coffee-script/parser.js +++ b/lib/coffee-script/parser.js @@ -486,9 +486,9 @@ case 180:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[ type: $$[$0-2] })); break; -case 181:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], { +case 181:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { type: $$[$0-2] - }))); + })))); break; case 182:this.$ = $$[$0]; break; diff --git a/src/grammar.coffee b/src/grammar.coffee index b372a52d..0cd5b4d8 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -511,7 +511,7 @@ grammar = # ambiguity. IfBlock: [ o 'IF Expression Block', -> new If $2, $3, type: $1 - o 'IfBlock ELSE IF Expression Block', -> $1.addElse new If $4, $5, type: $3 + o 'IfBlock ELSE IF Expression Block', -> $1.addElse LOC(3,5) new If $4, $5, type: $3 ] # The full complement of *if* expressions, including postfix one-liner diff --git a/src/nodes.coffee b/src/nodes.coffee index 03b87e56..1fd748d0 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -176,7 +176,8 @@ exports.Base = class Base # For this node and all descendents, set the location data to `locationData` # if the location data is not already set. updateLocationDataIfMissing: (locationData) -> - @locationData or= locationData + return this if @locationData + @locationData = locationData @eachChild (child) -> child.updateLocationDataIfMissing locationData @@ -2006,6 +2007,7 @@ exports.If = class If extends Base else @isChain = elseBody instanceof If @elseBody = @ensureBlock elseBody + @elseBody.updateLocationDataIfMissing elseBody.locationData this # The **If** only compiles into a statement if either of its bodies needs