Skip to content

Commit 4dcc4ba

Browse files
committed
fixed hoisting with new flattened selector AST
1 parent f8ce71d commit 4dcc4ba

File tree

3 files changed

+54
-8
lines changed

3 files changed

+54
-8
lines changed

Gruntfile.coffee

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ module.exports = ->
7474
@loadNpmTasks 'grunt-contrib-watch'
7575

7676
@registerTask 'build', ['coffee:src', 'peg', 'componentbuild', 'uglify']
77-
@registerTask 'test', ['build', 'coffee:spec', 'cafemocha' ]#, 'mocha_phantomjs']
77+
@registerTask 'test', ['build', 'coffee:spec', 'cafemocha', 'mocha_phantomjs']
7878
@registerTask 'default', ['build']

lib/scoper.js

+29-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ analyze = function(ast, buffer) {
2929
};
3030

3131
_analyze = function(node, buffer, bufferLengthMinus) {
32-
var currScope, i, isScope, name, parent, scope, sub, _i, _len, _ref;
32+
var currScope, i, isScope, name, parent, part, scope, sub, _i, _j, _len, _len1, _ref;
3333
if (bufferLengthMinus == null) {
3434
bufferLengthMinus = 1;
3535
}
@@ -44,17 +44,32 @@ _analyze = function(node, buffer, bufferLengthMinus) {
4444
scope._childScopes = [];
4545
scope._unscopedVars = [];
4646
buffer.push(scope);
47-
} else if (name === 'get' || name === 'virtual') {
47+
} else if (name === 'get') {
4848
currScope = buffer[buffer.length - bufferLengthMinus];
4949
if (currScope) {
5050
if (node.length === 2) {
5151
node._varKey = node.toString();
5252
currScope._unscopedVars.push(node);
5353
}
5454
}
55+
} else if (name instanceof Array) {
56+
for (_i = 0, _len = node.length; _i < _len; _i++) {
57+
part = node[_i];
58+
if (part[0] === 'virtual') {
59+
part._dontHoist = true;
60+
}
61+
}
62+
} else if (name === 'virtual') {
63+
currScope = buffer[buffer.length - bufferLengthMinus];
64+
if (currScope) {
65+
if (!node._dontHoist) {
66+
node._varKey = node.toString();
67+
currScope._unscopedVars.push(node);
68+
}
69+
}
5570
}
5671
_ref = node.slice(0, +node.length + 1 || 9e9);
57-
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
72+
for (i = _j = 0, _len1 = _ref.length; _j < _len1; i = ++_j) {
5873
sub = _ref[i];
5974
if (sub instanceof Array) {
6075
if (name === 'rule' && i === 1) {
@@ -81,7 +96,7 @@ mutate = function(buffer) {
8196
};
8297

8398
_mutate = function(node) {
84-
var child, hoistLevel, hoister, level, parent, unscoped, upper_unscoped, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _results;
99+
var child, clone, hoistLevel, hoister, level, parent, unscoped, unscopedCommand, upper_unscoped, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _results;
85100
_ref = node._childScopes;
86101
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
87102
child = _ref[_i];
@@ -112,7 +127,16 @@ _mutate = function(node) {
112127
if (hoistLevel > 1) {
113128
hoister.push(hoistLevel);
114129
}
115-
_results.push(unscoped.splice(1, 0, hoister));
130+
unscopedCommand = unscoped[0];
131+
if (unscopedCommand === 'get') {
132+
_results.push(unscoped.splice(1, 0, hoister));
133+
} else if (unscopedCommand === 'virtual') {
134+
clone = unscoped.splice(0, 2);
135+
unscoped.push(hoister);
136+
_results.push(unscoped.push(clone));
137+
} else {
138+
_results.push(void 0);
139+
}
116140
} else {
117141
_results.push(void 0);
118142
}

src/scoper.coffee

+24-2
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,25 @@ _analyze = (node, buffer, bufferLengthMinus = 1) =>
4141
scope._unscopedVars = []
4242
buffer.push scope
4343

44-
else if name is 'get' or name is 'virtual'
44+
else if name is 'get'
4545
currScope = buffer[buffer.length - bufferLengthMinus]
4646
if currScope
4747
if node.length is 2
4848
node._varKey = node.toString()
4949
currScope._unscopedVars.push node
50+
51+
# is selector chain... dangerous assumption
52+
else if name instanceof Array
53+
for part in node
54+
if part[0] is 'virtual'
55+
part._dontHoist = true
56+
57+
else if name is 'virtual'
58+
currScope = buffer[buffer.length - bufferLengthMinus]
59+
if currScope
60+
if !node._dontHoist
61+
node._varKey = node.toString()
62+
currScope._unscopedVars.push node
5063

5164
for sub, i in node[0..node.length]
5265
if sub instanceof Array # then recurse
@@ -85,4 +98,13 @@ _mutate = (node) =>
8598
if unscoped[1][0] isnt '^' # not already hoisted
8699
hoister = ['^']
87100
hoister.push(hoistLevel) if hoistLevel > 1
88-
unscoped.splice 1, 0, hoister
101+
unscopedCommand = unscoped[0]
102+
if unscopedCommand is 'get'
103+
unscoped.splice 1, 0, hoister
104+
else if unscopedCommand is 'virtual'
105+
# can't do the easy way:
106+
# `unscoped = [hoister, unscoped]`
107+
# because creates new pointer, so...
108+
clone = unscoped.splice(0,2)
109+
unscoped.push hoister
110+
unscoped.push clone

0 commit comments

Comments
 (0)