diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index 191be158fd7..7a32f21a00a 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -11,7 +11,8 @@ import { Position, TextNode, InterpolationNode, - ConstantTypes + ConstantTypes, + DirectiveNode } from '../src/ast' describe('compiler: parse', () => { @@ -1164,6 +1165,34 @@ describe('compiler: parse', () => { }) }) + // #3494 + test('directive argument edge case', () => { + const ast = baseParse('
') + const directive = (ast.children[0] as ElementNode) + .props[0] as DirectiveNode + expect(directive.arg).toMatchObject({ + loc: { + start: { offset: 12, line: 1, column: 13 }, + end: { offset: 16, line: 1, column: 17 }, + source: 'slot' + } + }) + }) + + // https://github.com/vuejs/language-tools/issues/2710 + test('directive argument edge case (2)', () => { + const ast = baseParse('
') + const directive = (ast.children[0] as ElementNode) + .props[0] as DirectiveNode + expect(directive.arg).toMatchObject({ + loc: { + start: { offset: 6, line: 1, column: 7 }, + end: { offset: 15, line: 1, column: 16 }, + source: 'item.item' + } + }) + }) + test('directive with dynamic argument', () => { const ast = baseParse('
') const directive = (ast.children[0] as ElementNode).props[0] diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index 73a1953348e..b72ad028b4b 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -817,7 +817,10 @@ function parseAttribute( if (match[2]) { const isSlot = dirName === 'slot' - const startOffset = name.lastIndexOf(match[2]) + const startOffset = name.lastIndexOf( + match[2], + name.length - (match[3]?.length || 0) + ) const loc = getSelection( context, getNewPosition(context, start, startOffset),