Skip to content

Commit 212990a

Browse files
author
Evan You
committed
make exp-parser deal with cases where strings contain variable names
1 parent 20def90 commit 212990a

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

src/exp-parser.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
var utils = require('./utils'),
2-
hasOwn = Object.prototype.hasOwnProperty
2+
hasOwn = Object.prototype.hasOwnProperty,
3+
stringSaveRE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
4+
stringRestoreRE = /"(\d+)"/g
35

46
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
57

@@ -122,6 +124,8 @@ module.exports = {
122124
}
123125
vars = utils.unique(vars)
124126
var accessors = '',
127+
has = utils.hash(),
128+
strings = [],
125129
// construct a regex to extract all valid variable paths
126130
// ones that begin with "$" are particularly tricky
127131
// because we can't use \b for them
@@ -130,16 +134,35 @@ module.exports = {
130134
vars.map(escapeDollar).join('|') +
131135
")[$\\w\\.]*\\b", 'g'
132136
),
133-
body = ('return ' + exp).replace(pathRE, function (path) {
134-
// keep track of the first char
135-
var c = path.charAt(0)
136-
path = path.slice(1)
137-
var val = 'this.' + getRel(path, compiler) + path
138-
accessors += val + ';'
139-
// don't forget to put that first char back
140-
return c + val
141-
})
137+
body = ('return ' + exp)
138+
.replace(stringSaveRE, saveStrings)
139+
.replace(pathRE, replacePath)
140+
.replace(stringRestoreRE, restoreStrings)
142141
body = accessors + body
142+
143+
function saveStrings (str) {
144+
var i = strings.length
145+
strings[i] = str
146+
return '"' + i + '"'
147+
}
148+
149+
function replacePath (path) {
150+
// keep track of the first char
151+
var c = path.charAt(0)
152+
path = path.slice(1)
153+
var val = 'this.' + getRel(path, compiler) + path
154+
if (!has[path]) {
155+
accessors += val + ';'
156+
has[path] = 1
157+
}
158+
// don't forget to put that first char back
159+
return c + val
160+
}
161+
162+
function restoreStrings (str, i) {
163+
return strings[i]
164+
}
165+
143166
return makeGetter(body, exp)
144167
}
145168
}

test/unit/specs/exp-parser.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ describe('UNIT: Expression Parser', function () {
5858
exp: "'a' + 'b'",
5959
vm: {},
6060
expectedValue: 'ab'
61+
},
62+
{
63+
// values with same variable name inside strings
64+
exp: "'\"test\"' + test + \"'hi'\" + hi",
65+
vm: {
66+
test: 1,
67+
hi: 2
68+
},
69+
expectedValue: '"test"1\'hi\'2'
6170
}
6271
]
6372

0 commit comments

Comments
 (0)