Kaynağa Gözat

fix(compiler-core): improve the isMemberExpression function (#3675)

HcySunYang 4 yıl önce
ebeveyn
işleme
9b2e894017

+ 21 - 1
packages/compiler-core/__tests__/utils.spec.ts

@@ -1,5 +1,9 @@
 import { Position } from '../src/ast'
-import { getInnerRange, advancePositionWithClone } from '../src/utils'
+import {
+  getInnerRange,
+  advancePositionWithClone,
+  isMemberExpression
+} from '../src/utils'
 
 function p(line: number, column: number, offset: number): Position {
   return { column, line, offset }
@@ -67,3 +71,19 @@ describe('getInnerRange', () => {
     expect(loc2.end.offset).toBe(7)
   })
 })
+
+test('isMemberExpression', () => {
+  // should work
+  expect(isMemberExpression('obj.foo')).toBe(true)
+  expect(isMemberExpression('obj[foo]')).toBe(true)
+  expect(isMemberExpression('obj[arr[0]]')).toBe(true)
+  expect(isMemberExpression('obj[arr[ret.bar]]')).toBe(true)
+  expect(isMemberExpression('obj[arr[ret[bar]]]')).toBe(true)
+  expect(isMemberExpression('obj[arr[ret[bar]]].baz')).toBe(true)
+  expect(isMemberExpression('obj[1 + 1]')).toBe(true)
+  // should warning
+  expect(isMemberExpression('obj[foo')).toBe(false)
+  expect(isMemberExpression('objfoo]')).toBe(false)
+  expect(isMemberExpression('obj[arr[0]')).toBe(false)
+  expect(isMemberExpression('obj[arr0]]')).toBe(false)
+})

+ 6 - 2
packages/compiler-core/src/utils.ts

@@ -56,10 +56,14 @@ const nonIdentifierRE = /^\d|[^\$\w]/
 export const isSimpleIdentifier = (name: string): boolean =>
   !nonIdentifierRE.test(name)
 
-const memberExpRE = /^[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*(?:\s*\.\s*[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*|\[[^\]]+\])*$/
+const memberExpRE = /^[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*(?:\s*\.\s*[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*|\[(.+)\])*$/
 export const isMemberExpression = (path: string): boolean => {
   if (!path) return false
-  return memberExpRE.test(path.trim())
+  const matched = memberExpRE.exec(path.trim())
+  if (!matched) return false
+  if (!matched[1]) return true
+  if (!/[\[\]]/.test(matched[1])) return true
+  return isMemberExpression(matched[1].trim())
 }
 
 export function getInnerRange(