From 0e75cc2d052bc932af975e0cae70029d1680a177 Mon Sep 17 00:00:00 2001 From: d4tocchini Date: Thu, 11 Dec 2014 23:12:37 -0800 Subject: [PATCH] fixed potential double hoisting edge case --- lib/scoper.js | 16 +++++++++++----- spec/compiler.coffee | 21 +++++++++++++++++++++ spec/scoper.coffee | 40 ++++++++++++++++++++++++++++++++++++++++ src/scoper.coffee | 9 +++++---- 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/lib/scoper.js b/lib/scoper.js index ef055f0..e63a120 100644 --- a/lib/scoper.js +++ b/lib/scoper.js @@ -81,7 +81,7 @@ mutate = function(buffer) { }; _mutate = function(node) { - var child, hoistLevel, level, parent, unscoped, upper_unscoped, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _results; + var child, hoistLevel, hoister, level, parent, unscoped, upper_unscoped, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _results; _ref = node._childScopes; for (_i = 0, _len = _ref.length; _i < _len; _i++) { child = _ref[_i]; @@ -106,10 +106,16 @@ _mutate = function(node) { } parent = parent._parentScope; } - if (hoistLevel === 1) { - _results.push(unscoped.splice(1, 0, ['^'])); - } else if (hoistLevel > 1) { - _results.push(unscoped.splice(1, 0, ['^', hoistLevel])); + if (hoistLevel > 0) { + if (unscoped[1][0] !== '^') { + hoister = ['^']; + if (hoistLevel > 1) { + hoister.push(hoistLevel); + } + _results.push(unscoped.splice(1, 0, hoister)); + } else { + _results.push(void 0); + } } else { _results.push(void 0); } diff --git a/spec/compiler.coffee b/spec/compiler.coffee index bc514ad..cd8737b 100644 --- a/spec/compiler.coffee +++ b/spec/compiler.coffee @@ -2460,3 +2460,24 @@ describe 'CCSS-to-AST', -> """ + + #describe 'PRINT', -> + # it 'PRINT', -> + # console.log(JSON.stringify(parser.parse(""" + # .wrap { + # my-size == 100; + # "target" { + # width: == &height == my-size; + # center-y: == ::window[center-y]; + # center-x: == ^[center-x]; + # } + # .thing { + # width: == &height == my-size; + # center: == "target"[center]; + # .other { + # width: == &height == my-size / 2; + # center: == "target"[center]; + # } + # } + # } + # """),1,1)) diff --git a/spec/scoper.coffee b/spec/scoper.coffee index 11dbad1..2ab5648 100644 --- a/spec/scoper.coffee +++ b/spec/scoper.coffee @@ -440,6 +440,46 @@ describe "Scoper", -> } """ + equivalent "3 level with virtuals", + """ + .wrap { + my-size == 100; + width: == &height == my-size; + "target" { + width: == &height == my-size; + center-y: == ::window[center-y]; + center-x: == ^[center-x]; + } + .thing { + width: == &height == my-size; + center: == "target"[center]; + .other { + width: == &height == my-size / 2; + center: == "target"[center]; + } + } + } + """, + """ + .wrap { + my-size == 100; + width: == &height == my-size; + "target" { + width: == &height == ^my-size; + center-y: == ::window[center-y]; + center-x: == ^[center-x]; + } + .thing { + width: == &height == ^my-size; + center: == ^"target"[center]; + .other { + width: == &height == ^^my-size / 2; + center: == ^^"target"[center]; + } + } + } + """ + equivalent "3 level moderate", """ diff --git a/src/scoper.coffee b/src/scoper.coffee index e8b30d6..73d454a 100644 --- a/src/scoper.coffee +++ b/src/scoper.coffee @@ -81,7 +81,8 @@ _mutate = (node) => parent = parent._parentScope # Hoist unscoped get commands by injecting parent scope operators, `^` - if hoistLevel is 1 - unscoped.splice 1, 0, ['^'] - else if hoistLevel > 1 - unscoped.splice 1, 0, ['^', hoistLevel] + if hoistLevel > 0 + if unscoped[1][0] isnt '^' # not already hoisted + hoister = ['^'] + hoister.push(hoistLevel) if hoistLevel > 1 + unscoped.splice 1, 0, hoister