@@ -100,11 +100,10 @@ function restore (str, i) {
100
100
* `scope.` and generate getter/setter functions.
101
101
*
102
102
* @param {String } exp
103
- * @param {Boolean } needSet
104
103
* @return {Function }
105
104
*/
106
105
107
- function compileExpFns ( exp , needSet ) {
106
+ function compileGetter ( exp ) {
108
107
if ( improperKeywordsRE . test ( exp ) ) {
109
108
process . env . NODE_ENV !== 'production' && _ . warn (
110
109
'Avoid using reserved keywords in expression: ' + exp
@@ -121,44 +120,7 @@ function compileExpFns (exp, needSet) {
121
120
body = ( ' ' + body )
122
121
. replace ( pathReplaceRE , rewrite )
123
122
. replace ( restoreRE , restore )
124
- var getter = makeGetter ( body )
125
- if ( getter ) {
126
- return {
127
- get : getter ,
128
- body : body ,
129
- set : needSet
130
- ? makeSetter ( body )
131
- : null
132
- }
133
- }
134
- }
135
-
136
- /**
137
- * Compile getter setters for a simple path.
138
- *
139
- * @param {String } exp
140
- * @return {Function }
141
- */
142
-
143
- function compilePathFns ( exp ) {
144
- var getter , path
145
- if ( exp . indexOf ( '[' ) < 0 ) {
146
- // really simple path
147
- path = exp . split ( '.' )
148
- path . raw = exp
149
- getter = Path . compileGetter ( path )
150
- } else {
151
- // do the real parsing
152
- path = Path . parse ( exp )
153
- getter = path . get
154
- }
155
- return {
156
- get : getter ,
157
- // always generate setter for simple paths
158
- set : function ( obj , val ) {
159
- Path . set ( obj , path , val )
160
- }
161
- }
123
+ return makeGetterFn ( body )
162
124
}
163
125
164
126
/**
@@ -171,7 +133,7 @@ function compilePathFns (exp) {
171
133
* @return {Function|undefined }
172
134
*/
173
135
174
- function makeGetter ( body ) {
136
+ function makeGetterFn ( body ) {
175
137
try {
176
138
return new Function ( 'scope' , 'return ' + body + ';' )
177
139
} catch ( e ) {
@@ -183,41 +145,25 @@ function makeGetter (body) {
183
145
}
184
146
185
147
/**
186
- * Build a setter function.
187
- *
188
- * This is only needed in rare situations like "a[b]" where
189
- * a settable path requires dynamic evaluation.
148
+ * Compile a setter function for the expression.
190
149
*
191
- * This setter function may throw error when called if the
192
- * expression body is not a valid left-hand expression in
193
- * assignment.
194
- *
195
- * @param {String } body
150
+ * @param {String } exp
196
151
* @return {Function|undefined }
197
152
*/
198
153
199
- function makeSetter ( body ) {
200
- try {
201
- return new Function ( 'scope' , 'value' , body + '=value;' )
202
- } catch ( e ) {
154
+ function compileSetter ( exp ) {
155
+ var path = Path . parse ( exp )
156
+ if ( path ) {
157
+ return function ( scope , val ) {
158
+ Path . set ( scope , path , val )
159
+ }
160
+ } else {
203
161
process . env . NODE_ENV !== 'production' && _ . warn (
204
- 'Invalid setter function body : ' + body
162
+ 'Invalid setter expression : ' + exp
205
163
)
206
164
}
207
165
}
208
166
209
- /**
210
- * Check for setter existence on a cache hit.
211
- *
212
- * @param {Function } hit
213
- */
214
-
215
- function checkSetter ( hit ) {
216
- if ( ! hit . set ) {
217
- hit . set = makeSetter ( hit . body )
218
- }
219
- }
220
-
221
167
/**
222
168
* Parse an expression into re-written getter/setters.
223
169
*
@@ -231,19 +177,20 @@ exports.parse = function (exp, needSet) {
231
177
// try cache
232
178
var hit = expressionCache . get ( exp )
233
179
if ( hit ) {
234
- if ( needSet ) {
235
- checkSetter ( hit )
180
+ if ( needSet && ! hit . set ) {
181
+ hit . set = compileSetter ( hit . exp )
236
182
}
237
183
return hit
238
184
}
239
- // we do a simple path check to optimize for them.
240
- // the check fails valid paths with unusal whitespaces,
241
- // but that's too rare and we don't care.
242
- // also skip boolean literals and paths that start with
243
- // global "Math"
244
- var res = exports . isSimplePath ( exp )
245
- ? compilePathFns ( exp )
246
- : compileExpFns ( exp , needSet )
185
+ var res = { exp : exp }
186
+ res . get = exports . isSimplePath ( exp ) && exp . indexOf ( '[' ) < 0
187
+ // optimized super simple getter
188
+ ? makeGetterFn ( 'scope.' + exp )
189
+ // dynamic getter
190
+ : compileGetter ( exp )
191
+ if ( needSet ) {
192
+ res . set = compileSetter ( exp )
193
+ }
247
194
expressionCache . put ( exp , res )
248
195
return res
249
196
}
0 commit comments