@@ -16,7 +16,6 @@ import {
16
16
CompoundExpressionNode ,
17
17
createCompoundExpression
18
18
} from '../ast'
19
- import { Node , Function , Identifier , Property } from 'estree'
20
19
import {
21
20
advancePositionWithClone ,
22
21
isSimpleIdentifier ,
@@ -25,6 +24,7 @@ import {
25
24
} from '../utils'
26
25
import { isGloballyWhitelisted , makeMap } from '@vue/shared'
27
26
import { createCompilerError , ErrorCodes } from '../errors'
27
+ import { Node , Function , Identifier , ObjectProperty } from '@babel/types'
28
28
29
29
const isLiteralWhitelisted = /*#__PURE__*/ makeMap ( 'true,false,null,this' )
30
30
@@ -117,22 +117,39 @@ export function processExpression(
117
117
? ` ${ rawExp } `
118
118
: `(${ rawExp } )${ asParams ? `=>{}` : `` } `
119
119
try {
120
- ast = parseJS ( source , { ranges : true } )
120
+ ast = parseJS ( source , {
121
+ plugins : [
122
+ ...context . expressionPlugins ,
123
+ // by default we enable proposals slated for ES2020.
124
+ // full list at https://babeljs.io/docs/en/next/babel-parser#plugins
125
+ // this will need to be updated as the spec moves forward.
126
+ 'bigInt' ,
127
+ 'optionalChaining' ,
128
+ 'nullishCoalescingOperator'
129
+ ]
130
+ } ) . program
121
131
} catch ( e ) {
122
132
context . onError (
123
- createCompilerError ( ErrorCodes . X_INVALID_EXPRESSION , node . loc )
133
+ createCompilerError (
134
+ ErrorCodes . X_INVALID_EXPRESSION ,
135
+ node . loc ,
136
+ undefined ,
137
+ e . message
138
+ )
124
139
)
125
140
return node
126
141
}
127
142
128
143
const ids : ( Identifier & PrefixMeta ) [ ] = [ ]
129
144
const knownIds = Object . create ( context . identifiers )
145
+ const isDuplicate = ( node : Node & PrefixMeta ) : boolean =>
146
+ ids . some ( id => id . start === node . start )
130
147
131
148
// walk the AST and look for identifiers that need to be prefixed with `_ctx.`.
132
149
walkJS ( ast , {
133
150
enter ( node : Node & PrefixMeta , parent ) {
134
151
if ( node . type === 'Identifier' ) {
135
- if ( ! ids . includes ( node ) ) {
152
+ if ( ! isDuplicate ( node ) ) {
136
153
const needPrefix = shouldPrefix ( node , parent )
137
154
if ( ! knownIds [ node . name ] && needPrefix ) {
138
155
if ( isPropertyShorthand ( node , parent ) ) {
@@ -246,17 +263,20 @@ export function processExpression(
246
263
const isFunction = ( node : Node ) : node is Function =>
247
264
/ F u n c t i o n ( E x p r e s s i o n | D e c l a r a t i o n ) $ / . test ( node . type )
248
265
249
- const isPropertyKey = ( node : Node , parent : Node ) =>
250
- parent &&
251
- parent . type === 'Property' &&
252
- parent . key === node &&
253
- ! parent . computed
266
+ const isStaticProperty = ( node : Node ) : node is ObjectProperty =>
267
+ node && node . type === 'ObjectProperty' && ! node . computed
254
268
255
- const isPropertyShorthand = ( node : Node , parent : Node ) =>
256
- isPropertyKey ( node , parent ) && ( parent as Property ) . value === node
269
+ const isPropertyShorthand = ( node : Node , parent : Node ) => {
270
+ return (
271
+ isStaticProperty ( parent ) &&
272
+ parent . value === node &&
273
+ parent . key . type === 'Identifier' &&
274
+ parent . key . name === ( node as Identifier ) . name
275
+ )
276
+ }
257
277
258
278
const isStaticPropertyKey = ( node : Node , parent : Node ) =>
259
- isPropertyKey ( node , parent ) && ( parent as Property ) . value ! == node
279
+ isStaticProperty ( parent ) && parent . key = == node
260
280
261
281
function shouldPrefix ( identifier : Identifier , parent : Node ) {
262
282
if (
@@ -271,7 +291,8 @@ function shouldPrefix(identifier: Identifier, parent: Node) {
271
291
! isStaticPropertyKey ( identifier , parent ) &&
272
292
// not a property of a MemberExpression
273
293
! (
274
- parent . type === 'MemberExpression' &&
294
+ ( parent . type === 'MemberExpression' ||
295
+ parent . type === 'OptionalMemberExpression' ) &&
275
296
parent . property === identifier &&
276
297
! parent . computed
277
298
) &&
0 commit comments