mirror of https://github.com/vuejs/core.git
Merge 63f96a2ace
into 56be3dd4db
This commit is contained in:
commit
148afd352b
|
@ -3848,6 +3848,380 @@ exports[`compiler: parse > Errors > UNEXPECTED_SOLIDUS_IN_TAG > <template><div a
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`compiler: parse > Errors > X_DIRECTIVE_SHORTHAND_NO_ARGUMENT > <div #="obj" /> 1`] = `
|
||||
{
|
||||
"cached": 0,
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"codegenNode": undefined,
|
||||
"isSelfClosing": true,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div #="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"ns": 0,
|
||||
"props": [
|
||||
{
|
||||
"arg": undefined,
|
||||
"exp": {
|
||||
"constType": 0,
|
||||
"content": "obj",
|
||||
"isStatic": false,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 12,
|
||||
"line": 1,
|
||||
"offset": 11,
|
||||
},
|
||||
"source": "obj",
|
||||
"start": {
|
||||
"column": 9,
|
||||
"line": 1,
|
||||
"offset": 8,
|
||||
},
|
||||
},
|
||||
"type": 4,
|
||||
},
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 13,
|
||||
"line": 1,
|
||||
"offset": 12,
|
||||
},
|
||||
"source": "#="obj"",
|
||||
"start": {
|
||||
"column": 6,
|
||||
"line": 1,
|
||||
"offset": 5,
|
||||
},
|
||||
},
|
||||
"modifiers": [],
|
||||
"name": "slot",
|
||||
"rawName": "#",
|
||||
"type": 7,
|
||||
},
|
||||
],
|
||||
"tag": "div",
|
||||
"tagType": 0,
|
||||
"type": 1,
|
||||
},
|
||||
],
|
||||
"codegenNode": undefined,
|
||||
"components": [],
|
||||
"directives": [],
|
||||
"helpers": Set {},
|
||||
"hoists": [],
|
||||
"imports": [],
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div #="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"source": "<div #="obj" />",
|
||||
"temps": 0,
|
||||
"type": 0,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`compiler: parse > Errors > X_DIRECTIVE_SHORTHAND_NO_ARGUMENT > <div .="obj" /> 1`] = `
|
||||
{
|
||||
"cached": 0,
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"codegenNode": undefined,
|
||||
"isSelfClosing": true,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div .="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"ns": 0,
|
||||
"props": [
|
||||
{
|
||||
"arg": undefined,
|
||||
"exp": {
|
||||
"constType": 0,
|
||||
"content": "obj",
|
||||
"isStatic": false,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 12,
|
||||
"line": 1,
|
||||
"offset": 11,
|
||||
},
|
||||
"source": "obj",
|
||||
"start": {
|
||||
"column": 9,
|
||||
"line": 1,
|
||||
"offset": 8,
|
||||
},
|
||||
},
|
||||
"type": 4,
|
||||
},
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 13,
|
||||
"line": 1,
|
||||
"offset": 12,
|
||||
},
|
||||
"source": ".="obj"",
|
||||
"start": {
|
||||
"column": 6,
|
||||
"line": 1,
|
||||
"offset": 5,
|
||||
},
|
||||
},
|
||||
"modifiers": [
|
||||
"prop",
|
||||
],
|
||||
"name": "bind",
|
||||
"rawName": ".",
|
||||
"type": 7,
|
||||
},
|
||||
],
|
||||
"tag": "div",
|
||||
"tagType": 0,
|
||||
"type": 1,
|
||||
},
|
||||
],
|
||||
"codegenNode": undefined,
|
||||
"components": [],
|
||||
"directives": [],
|
||||
"helpers": Set {},
|
||||
"hoists": [],
|
||||
"imports": [],
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div .="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"source": "<div .="obj" />",
|
||||
"temps": 0,
|
||||
"type": 0,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`compiler: parse > Errors > X_DIRECTIVE_SHORTHAND_NO_ARGUMENT > <div :="obj" /> 1`] = `
|
||||
{
|
||||
"cached": 0,
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"codegenNode": undefined,
|
||||
"isSelfClosing": true,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div :="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"ns": 0,
|
||||
"props": [
|
||||
{
|
||||
"arg": undefined,
|
||||
"exp": {
|
||||
"constType": 0,
|
||||
"content": "obj",
|
||||
"isStatic": false,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 12,
|
||||
"line": 1,
|
||||
"offset": 11,
|
||||
},
|
||||
"source": "obj",
|
||||
"start": {
|
||||
"column": 9,
|
||||
"line": 1,
|
||||
"offset": 8,
|
||||
},
|
||||
},
|
||||
"type": 4,
|
||||
},
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 13,
|
||||
"line": 1,
|
||||
"offset": 12,
|
||||
},
|
||||
"source": ":="obj"",
|
||||
"start": {
|
||||
"column": 6,
|
||||
"line": 1,
|
||||
"offset": 5,
|
||||
},
|
||||
},
|
||||
"modifiers": [],
|
||||
"name": "bind",
|
||||
"rawName": ":",
|
||||
"type": 7,
|
||||
},
|
||||
],
|
||||
"tag": "div",
|
||||
"tagType": 0,
|
||||
"type": 1,
|
||||
},
|
||||
],
|
||||
"codegenNode": undefined,
|
||||
"components": [],
|
||||
"directives": [],
|
||||
"helpers": Set {},
|
||||
"hoists": [],
|
||||
"imports": [],
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div :="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"source": "<div :="obj" />",
|
||||
"temps": 0,
|
||||
"type": 0,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`compiler: parse > Errors > X_DIRECTIVE_SHORTHAND_NO_ARGUMENT > <div @="obj" /> 1`] = `
|
||||
{
|
||||
"cached": 0,
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"codegenNode": undefined,
|
||||
"isSelfClosing": true,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div @="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"ns": 0,
|
||||
"props": [
|
||||
{
|
||||
"arg": undefined,
|
||||
"exp": {
|
||||
"constType": 0,
|
||||
"content": "obj",
|
||||
"isStatic": false,
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 12,
|
||||
"line": 1,
|
||||
"offset": 11,
|
||||
},
|
||||
"source": "obj",
|
||||
"start": {
|
||||
"column": 9,
|
||||
"line": 1,
|
||||
"offset": 8,
|
||||
},
|
||||
},
|
||||
"type": 4,
|
||||
},
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 13,
|
||||
"line": 1,
|
||||
"offset": 12,
|
||||
},
|
||||
"source": "@="obj"",
|
||||
"start": {
|
||||
"column": 6,
|
||||
"line": 1,
|
||||
"offset": 5,
|
||||
},
|
||||
},
|
||||
"modifiers": [],
|
||||
"name": "on",
|
||||
"rawName": "@",
|
||||
"type": 7,
|
||||
},
|
||||
],
|
||||
"tag": "div",
|
||||
"tagType": 0,
|
||||
"type": 1,
|
||||
},
|
||||
],
|
||||
"codegenNode": undefined,
|
||||
"components": [],
|
||||
"directives": [],
|
||||
"helpers": Set {},
|
||||
"hoists": [],
|
||||
"imports": [],
|
||||
"loc": {
|
||||
"end": {
|
||||
"column": 16,
|
||||
"line": 1,
|
||||
"offset": 15,
|
||||
},
|
||||
"source": "<div @="obj" />",
|
||||
"start": {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"offset": 0,
|
||||
},
|
||||
},
|
||||
"source": "<div @="obj" />",
|
||||
"temps": 0,
|
||||
"type": 0,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`compiler: parse > Errors > X_INVALID_END_TAG > <svg><![CDATA[</div>]]></svg> 1`] = `
|
||||
{
|
||||
"cached": [],
|
||||
|
|
|
@ -2254,6 +2254,9 @@ describe('compiler: parse', () => {
|
|||
exp: undefined,
|
||||
arg: undefined,
|
||||
})
|
||||
expect(
|
||||
`the directive shorthand '#' cannot be used without an argument`,
|
||||
).toHaveBeenWarned()
|
||||
})
|
||||
|
||||
// edge case found in vue-macros where the input is TS or JSX
|
||||
|
@ -2550,7 +2553,8 @@ describe('compiler: parse', () => {
|
|||
const patterns: {
|
||||
[key: string]: Array<{
|
||||
code: string
|
||||
errors: Array<{ type: ErrorCodes; loc: Position }>
|
||||
errors?: Array<{ type: ErrorCodes; loc: Position }>
|
||||
warnings?: Array<{ type: ErrorCodes; loc: Position }>
|
||||
options?: Partial<ParserOptions>
|
||||
}>
|
||||
} = {
|
||||
|
@ -3420,32 +3424,80 @@ describe('compiler: parse', () => {
|
|||
],
|
||||
},
|
||||
],
|
||||
X_DIRECTIVE_SHORTHAND_NO_ARGUMENT: [
|
||||
{
|
||||
code: `<div :="obj" />`,
|
||||
warnings: [
|
||||
{
|
||||
type: ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
loc: { offset: 5, line: 1, column: 6 },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `<div .="obj" />`,
|
||||
warnings: [
|
||||
{
|
||||
type: ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
loc: { offset: 5, line: 1, column: 6 },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `<div @="obj" />`,
|
||||
warnings: [
|
||||
{
|
||||
type: ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
loc: { offset: 5, line: 1, column: 6 },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `<div #="obj" />`,
|
||||
warnings: [
|
||||
{
|
||||
type: ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
loc: { offset: 5, line: 1, column: 6 },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
for (const key of Object.keys(patterns)) {
|
||||
describe(key, () => {
|
||||
for (const { code, errors, options } of patterns[key]) {
|
||||
for (const { code, errors = [], warnings = [], options } of patterns[
|
||||
key
|
||||
]) {
|
||||
test(
|
||||
code.replace(
|
||||
/[\r\n]/g,
|
||||
c => `\\x0${c.codePointAt(0)!.toString(16)};`,
|
||||
),
|
||||
() => {
|
||||
const spy = vi.fn()
|
||||
const errorSpy = vi.fn()
|
||||
const warnSpy = vi.fn()
|
||||
const ast = baseParse(code, {
|
||||
parseMode: 'html',
|
||||
getNamespace: tag =>
|
||||
tag === 'svg' ? Namespaces.SVG : Namespaces.HTML,
|
||||
...options,
|
||||
onError: spy,
|
||||
onError: errorSpy,
|
||||
onWarn: warnSpy,
|
||||
})
|
||||
|
||||
expect(
|
||||
spy.mock.calls.map(([err]) => ({
|
||||
errorSpy.mock.calls.map(([err]) => ({
|
||||
type: err.code,
|
||||
loc: err.loc.start,
|
||||
})),
|
||||
).toMatchObject(errors)
|
||||
expect(
|
||||
warnSpy.mock.calls.map(([err]) => ({
|
||||
type: err.code,
|
||||
loc: err.loc.start,
|
||||
})),
|
||||
).toMatchObject(warnings)
|
||||
expect(ast).toMatchSnapshot()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -90,6 +90,7 @@ export enum ErrorCodes {
|
|||
X_V_MODEL_ON_PROPS,
|
||||
X_INVALID_EXPRESSION,
|
||||
X_KEEP_ALIVE_INVALID_CHILDREN,
|
||||
X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
|
||||
// generic errors
|
||||
X_PREFIX_ID_NOT_SUPPORTED,
|
||||
|
@ -179,6 +180,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
|
|||
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
|
||||
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
|
||||
[ErrorCodes.X_VNODE_HOOKS]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
|
||||
[ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT]: `Directive shorthand without an argument: `,
|
||||
|
||||
// generic errors
|
||||
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
|
||||
|
|
|
@ -244,7 +244,21 @@ const tokenizer = new Tokenizer(stack, {
|
|||
},
|
||||
|
||||
ondirarg(start, end) {
|
||||
if (start === end) return
|
||||
if (start === end) {
|
||||
if (__DEV__) {
|
||||
const currentDir = currentProp as DirectiveNode
|
||||
|
||||
if (currentDir.rawName?.length === 1) {
|
||||
emitWarning(
|
||||
ErrorCodes.X_DIRECTIVE_SHORTHAND_NO_ARGUMENT,
|
||||
start - 1,
|
||||
`the directive shorthand '${currentDir.rawName}' cannot be used without an argument. ` +
|
||||
`Use v-${currentDir.name} instead or provide an argument.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
const arg = getSlice(start, end)
|
||||
if (inVPre) {
|
||||
;(currentProp as AttributeNode).name += arg
|
||||
|
@ -1025,6 +1039,12 @@ function emitError(code: ErrorCodes, index: number, message?: string) {
|
|||
)
|
||||
}
|
||||
|
||||
function emitWarning(code: ErrorCodes, index: number, message?: string) {
|
||||
currentOptions.onWarn(
|
||||
createCompilerError(code, getLoc(index, index), undefined, message),
|
||||
)
|
||||
}
|
||||
|
||||
function reset() {
|
||||
tokenizer.reset()
|
||||
currentOpenTag = null
|
||||
|
|
|
@ -21,7 +21,7 @@ export function createDOMCompilerError(
|
|||
}
|
||||
|
||||
export enum DOMErrorCodes {
|
||||
X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
|
||||
X_V_HTML_NO_EXPRESSION = 54 /* ErrorCodes.__EXTEND_POINT__ */,
|
||||
X_V_HTML_WITH_CHILDREN,
|
||||
X_V_TEXT_NO_EXPRESSION,
|
||||
X_V_TEXT_WITH_CHILDREN,
|
||||
|
|
|
@ -17,7 +17,7 @@ export function createSSRCompilerError(
|
|||
}
|
||||
|
||||
export enum SSRErrorCodes {
|
||||
X_SSR_UNSAFE_ATTR_NAME = 65 /* DOMErrorCodes.__EXTEND_POINT__ */,
|
||||
X_SSR_UNSAFE_ATTR_NAME = 66 /* DOMErrorCodes.__EXTEND_POINT__ */,
|
||||
X_SSR_NO_TELEPORT_TARGET,
|
||||
X_SSR_INVALID_AST_NODE,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue