mirror of https://github.com/vuejs/core.git
feat(compiler-core): parse modifiers as expression to provide location data (#11819)
This commit is contained in:
parent
7a64b6734d
commit
3f13203564
|
|
@ -1358,7 +1358,27 @@ describe('compiler: parse', () => {
|
||||||
name: 'on',
|
name: 'on',
|
||||||
rawName: 'v-on.enter',
|
rawName: 'v-on.enter',
|
||||||
arg: undefined,
|
arg: undefined,
|
||||||
modifiers: ['enter'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'enter',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 16,
|
||||||
|
line: 1,
|
||||||
|
offset: 15,
|
||||||
|
},
|
||||||
|
source: 'enter',
|
||||||
|
start: {
|
||||||
|
column: 11,
|
||||||
|
line: 1,
|
||||||
|
offset: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: undefined,
|
exp: undefined,
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 5, line: 1, column: 6 },
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
|
@ -1377,7 +1397,46 @@ describe('compiler: parse', () => {
|
||||||
name: 'on',
|
name: 'on',
|
||||||
rawName: 'v-on.enter.exact',
|
rawName: 'v-on.enter.exact',
|
||||||
arg: undefined,
|
arg: undefined,
|
||||||
modifiers: ['enter', 'exact'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'enter',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 16,
|
||||||
|
line: 1,
|
||||||
|
offset: 15,
|
||||||
|
},
|
||||||
|
source: 'enter',
|
||||||
|
start: {
|
||||||
|
column: 11,
|
||||||
|
line: 1,
|
||||||
|
offset: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'exact',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 22,
|
||||||
|
line: 1,
|
||||||
|
offset: 21,
|
||||||
|
},
|
||||||
|
source: 'exact',
|
||||||
|
start: {
|
||||||
|
column: 17,
|
||||||
|
line: 1,
|
||||||
|
offset: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: undefined,
|
exp: undefined,
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 5, line: 1, column: 6 },
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
|
@ -1406,7 +1465,46 @@ describe('compiler: parse', () => {
|
||||||
source: 'click',
|
source: 'click',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modifiers: ['enter', 'exact'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'enter',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 22,
|
||||||
|
line: 1,
|
||||||
|
offset: 21,
|
||||||
|
},
|
||||||
|
source: 'enter',
|
||||||
|
start: {
|
||||||
|
column: 17,
|
||||||
|
line: 1,
|
||||||
|
offset: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'exact',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 28,
|
||||||
|
line: 1,
|
||||||
|
offset: 27,
|
||||||
|
},
|
||||||
|
source: 'exact',
|
||||||
|
start: {
|
||||||
|
column: 23,
|
||||||
|
line: 1,
|
||||||
|
offset: 22,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: undefined,
|
exp: undefined,
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 5, line: 1, column: 6 },
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
|
@ -1435,7 +1533,27 @@ describe('compiler: parse', () => {
|
||||||
source: '[a.b]',
|
source: '[a.b]',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modifiers: ['camel'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'camel',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 22,
|
||||||
|
line: 1,
|
||||||
|
offset: 21,
|
||||||
|
},
|
||||||
|
source: 'camel',
|
||||||
|
start: {
|
||||||
|
column: 17,
|
||||||
|
line: 1,
|
||||||
|
offset: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: undefined,
|
exp: undefined,
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 5, line: 1, column: 6 },
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
|
@ -1530,7 +1648,27 @@ describe('compiler: parse', () => {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modifiers: ['prop'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 0,
|
||||||
|
content: 'prop',
|
||||||
|
isStatic: false,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 1,
|
||||||
|
line: 1,
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
source: '',
|
||||||
|
start: {
|
||||||
|
column: 1,
|
||||||
|
line: 1,
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
|
|
@ -1569,7 +1707,27 @@ describe('compiler: parse', () => {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modifiers: ['sync'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'sync',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 13,
|
||||||
|
line: 1,
|
||||||
|
offset: 12,
|
||||||
|
},
|
||||||
|
source: 'sync',
|
||||||
|
start: {
|
||||||
|
column: 9,
|
||||||
|
line: 1,
|
||||||
|
offset: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
|
|
@ -1649,7 +1807,27 @@ describe('compiler: parse', () => {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modifiers: ['enter'],
|
modifiers: [
|
||||||
|
{
|
||||||
|
constType: 3,
|
||||||
|
content: 'enter',
|
||||||
|
isStatic: true,
|
||||||
|
loc: {
|
||||||
|
end: {
|
||||||
|
column: 14,
|
||||||
|
line: 1,
|
||||||
|
offset: 13,
|
||||||
|
},
|
||||||
|
source: 'enter',
|
||||||
|
start: {
|
||||||
|
column: 9,
|
||||||
|
line: 1,
|
||||||
|
offset: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ export interface DirectiveNode extends Node {
|
||||||
rawName?: string
|
rawName?: string
|
||||||
exp: ExpressionNode | undefined
|
exp: ExpressionNode | undefined
|
||||||
arg: ExpressionNode | undefined
|
arg: ExpressionNode | undefined
|
||||||
modifiers: string[]
|
modifiers: SimpleExpressionNode[]
|
||||||
/**
|
/**
|
||||||
* optional property to cache the expression parse result for v-for
|
* optional property to cache the expression parse result for v-for
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ const tokenizer = new Tokenizer(stack, {
|
||||||
rawName: raw,
|
rawName: raw,
|
||||||
exp: undefined,
|
exp: undefined,
|
||||||
arg: undefined,
|
arg: undefined,
|
||||||
modifiers: raw === '.' ? ['prop'] : [],
|
modifiers: raw === '.' ? [createSimpleExpression('prop')] : [],
|
||||||
loc: getLoc(start),
|
loc: getLoc(start),
|
||||||
}
|
}
|
||||||
if (name === 'pre') {
|
if (name === 'pre') {
|
||||||
|
|
@ -273,7 +273,8 @@ const tokenizer = new Tokenizer(stack, {
|
||||||
setLocEnd(arg.loc, end)
|
setLocEnd(arg.loc, end)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
;(currentProp as DirectiveNode).modifiers.push(mod)
|
const exp = createSimpleExpression(mod, true, getLoc(start, end))
|
||||||
|
;(currentProp as DirectiveNode).modifiers.push(exp)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -379,7 +380,9 @@ const tokenizer = new Tokenizer(stack, {
|
||||||
if (
|
if (
|
||||||
__COMPAT__ &&
|
__COMPAT__ &&
|
||||||
currentProp.name === 'bind' &&
|
currentProp.name === 'bind' &&
|
||||||
(syncIndex = currentProp.modifiers.indexOf('sync')) > -1 &&
|
(syncIndex = currentProp.modifiers.findIndex(
|
||||||
|
mod => mod.content === 'sync',
|
||||||
|
)) > -1 &&
|
||||||
checkCompatEnabled(
|
checkCompatEnabled(
|
||||||
CompilerDeprecationTypes.COMPILER_V_BIND_SYNC,
|
CompilerDeprecationTypes.COMPILER_V_BIND_SYNC,
|
||||||
currentOptions,
|
currentOptions,
|
||||||
|
|
|
||||||
|
|
@ -665,7 +665,7 @@ export function buildProps(
|
||||||
}
|
}
|
||||||
|
|
||||||
// force hydration for v-bind with .prop modifier
|
// force hydration for v-bind with .prop modifier
|
||||||
if (isVBind && modifiers.includes('prop')) {
|
if (isVBind && modifiers.some(mod => mod.content === 'prop')) {
|
||||||
patchFlag |= PatchFlags.NEED_HYDRATION
|
patchFlag |= PatchFlags.NEED_HYDRATION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// .sync is replaced by v-model:arg
|
// .sync is replaced by v-model:arg
|
||||||
if (modifiers.includes('camel')) {
|
if (modifiers.some(mod => mod.content === 'camel')) {
|
||||||
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
if (arg.isStatic) {
|
if (arg.isStatic) {
|
||||||
arg.content = camelize(arg.content)
|
arg.content = camelize(arg.content)
|
||||||
|
|
@ -83,10 +83,10 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.inSSR) {
|
if (!context.inSSR) {
|
||||||
if (modifiers.includes('prop')) {
|
if (modifiers.some(mod => mod.content === 'prop')) {
|
||||||
injectPrefix(arg, '.')
|
injectPrefix(arg, '.')
|
||||||
}
|
}
|
||||||
if (modifiers.includes('attr')) {
|
if (modifiers.some(mod => mod.content === 'attr')) {
|
||||||
injectPrefix(arg, '^')
|
injectPrefix(arg, '^')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
|
||||||
// modelModifiers: { foo: true, "bar-baz": true }
|
// modelModifiers: { foo: true, "bar-baz": true }
|
||||||
if (dir.modifiers.length && node.tagType === ElementTypes.COMPONENT) {
|
if (dir.modifiers.length && node.tagType === ElementTypes.COMPONENT) {
|
||||||
const modifiers = dir.modifiers
|
const modifiers = dir.modifiers
|
||||||
|
.map(m => m.content)
|
||||||
.map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
|
.map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
|
||||||
.join(`, `)
|
.join(`, `)
|
||||||
const modifiersKey = arg
|
const modifiersKey = arg
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const isKeyboardEvent = /*@__PURE__*/ makeMap(
|
||||||
|
|
||||||
const resolveModifiers = (
|
const resolveModifiers = (
|
||||||
key: ExpressionNode,
|
key: ExpressionNode,
|
||||||
modifiers: string[],
|
modifiers: SimpleExpressionNode[],
|
||||||
context: TransformContext,
|
context: TransformContext,
|
||||||
loc: SourceLocation,
|
loc: SourceLocation,
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -44,7 +44,7 @@ const resolveModifiers = (
|
||||||
const eventOptionModifiers = []
|
const eventOptionModifiers = []
|
||||||
|
|
||||||
for (let i = 0; i < modifiers.length; i++) {
|
for (let i = 0; i < modifiers.length; i++) {
|
||||||
const modifier = modifiers[i]
|
const modifier = modifiers[i].content
|
||||||
|
|
||||||
if (
|
if (
|
||||||
__COMPAT__ &&
|
__COMPAT__ &&
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue