]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): improve the isMemberExpression function (#3675)
authorHcySunYang <HcySunYang@outlook.com>
Fri, 28 May 2021 01:07:26 +0000 (09:07 +0800)
committerGitHub <noreply@github.com>
Fri, 28 May 2021 01:07:26 +0000 (21:07 -0400)
packages/compiler-core/__tests__/utils.spec.ts
packages/compiler-core/src/utils.ts

index b5d1bea04c95f2b894ea1b0768579e295337d86a..4fc4e8d16a529652d66c07541a2da6f1c749817d 100644 (file)
@@ -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)
+})
index 370a9ac615bd3988c57c8153791ee0c4631f46bd..d69446d890908d53f59c2ce10b4ee34fc2628110 100644 (file)
@@ -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(