2019-09-23 10:19:42 +08:00
import { SourceLocation } from './ast'
2019-09-18 07:08:47 +08:00
export interface CompilerError extends SyntaxError {
2021-04-13 07:42:09 +08:00
code : number | string
2019-09-24 01:25:18 +08:00
loc? : SourceLocation
2019-09-18 07:08:47 +08:00
}
2019-10-09 23:13:13 +08:00
export interface CoreCompilerError extends CompilerError {
code : ErrorCodes
}
2019-09-21 00:16:19 +08:00
export function defaultOnError ( error : CompilerError ) {
throw error
}
2021-04-17 00:26:17 +08:00
export function defaultOnWarn ( msg : CompilerError ) {
2021-04-18 03:55:14 +08:00
__DEV__ && console . warn ( ` [Vue warn] ${ msg . message } ` )
2021-04-13 07:42:09 +08:00
}
2021-07-19 22:32:07 +08:00
type InferCompilerError < T > = T extends ErrorCodes
? CoreCompilerError
: CompilerError
2019-10-09 23:13:13 +08:00
export function createCompilerError < T extends number > (
code : T ,
loc? : SourceLocation ,
2020-02-28 05:53:51 +08:00
messages ? : { [ code : number ] : string } ,
additionalMessage? : string
2021-07-19 22:32:07 +08:00
) : InferCompilerError < T > {
2020-02-28 05:53:51 +08:00
const msg =
__DEV__ || ! __BROWSER__
? ( messages || errorMessages ) [ code ] + ( additionalMessage || ` ` )
2023-11-28 07:38:36 +08:00
: ` https://vuejs.org/errors/#compiler- ${ code } `
2021-07-19 22:32:07 +08:00
const error = new SyntaxError ( String ( msg ) ) as InferCompilerError < T >
2019-09-18 07:08:47 +08:00
error . code = code
error . loc = loc
2021-07-19 22:32:07 +08:00
return error
2019-09-18 07:08:47 +08:00
}
export const enum ErrorCodes {
// parse errors
ABRUPT_CLOSING_OF_EMPTY_COMMENT ,
CDATA_IN_HTML_CONTENT ,
DUPLICATE_ATTRIBUTE ,
END_TAG_WITH_ATTRIBUTES ,
END_TAG_WITH_TRAILING_SOLIDUS ,
EOF_BEFORE_TAG_NAME ,
EOF_IN_CDATA ,
EOF_IN_COMMENT ,
EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT ,
EOF_IN_TAG ,
INCORRECTLY_CLOSED_COMMENT ,
INCORRECTLY_OPENED_COMMENT ,
INVALID_FIRST_CHARACTER_OF_TAG_NAME ,
MISSING_ATTRIBUTE_VALUE ,
MISSING_END_TAG_NAME ,
MISSING_WHITESPACE_BETWEEN_ATTRIBUTES ,
NESTED_COMMENT ,
UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME ,
UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE ,
UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME ,
UNEXPECTED_NULL_CHARACTER ,
UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME ,
UNEXPECTED_SOLIDUS_IN_TAG ,
2019-09-24 01:25:18 +08:00
// Vue-specific parse errors
2019-09-18 07:08:47 +08:00
X_INVALID_END_TAG ,
X_MISSING_END_TAG ,
X_MISSING_INTERPOLATION_END ,
2021-09-02 21:42:20 +08:00
X_MISSING_DIRECTIVE_NAME ,
2019-09-18 07:08:47 +08:00
X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END ,
// transform errors
2019-10-09 22:27:24 +08:00
X_V_IF_NO_EXPRESSION ,
2020-08-05 00:01:07 +08:00
X_V_IF_SAME_KEY ,
2019-10-09 22:27:24 +08:00
X_V_ELSE_NO_ADJACENT_IF ,
X_V_FOR_NO_EXPRESSION ,
X_V_FOR_MALFORMED_EXPRESSION ,
2020-08-05 00:20:32 +08:00
X_V_FOR_TEMPLATE_KEY_PLACEMENT ,
2019-09-24 01:25:18 +08:00
X_V_BIND_NO_EXPRESSION ,
2019-09-25 08:51:48 +08:00
X_V_ON_NO_EXPRESSION ,
2019-10-09 22:27:24 +08:00
X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET ,
X_V_SLOT_MIXED_SLOT_USAGE ,
X_V_SLOT_DUPLICATE_SLOT_NAMES ,
2020-01-07 04:31:21 +08:00
X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN ,
2019-10-09 22:27:24 +08:00
X_V_SLOT_MISPLACED ,
2019-10-10 22:33:58 +08:00
X_V_MODEL_NO_EXPRESSION ,
X_V_MODEL_MALFORMED_EXPRESSION ,
2019-10-17 02:05:18 +08:00
X_V_MODEL_ON_SCOPE_VARIABLE ,
2022-11-10 10:42:27 +08:00
X_V_MODEL_ON_PROPS ,
2019-10-17 04:33:23 +08:00
X_INVALID_EXPRESSION ,
2020-02-07 04:53:26 +08:00
X_KEEP_ALIVE_INVALID_CHILDREN ,
2019-09-24 01:25:18 +08:00
// generic errors
2019-09-26 10:29:37 +08:00
X_PREFIX_ID_NOT_SUPPORTED ,
2019-10-09 23:13:13 +08:00
X_MODULE_MODE_NOT_SUPPORTED ,
2019-12-18 01:30:49 +08:00
X_CACHE_HANDLER_NOT_SUPPORTED ,
X_SCOPE_ID_NOT_SUPPORTED ,
2019-10-09 23:13:13 +08:00
2023-04-21 15:20:12 +08:00
// deprecations
DEPRECATION_VNODE_HOOKS ,
2023-04-21 15:26:01 +08:00
DEPRECATION_V_IS ,
2023-04-21 15:20:12 +08:00
2019-10-18 03:01:51 +08:00
// Special value for higher-order compilers to pick up the last code
2019-10-09 23:13:13 +08:00
// to avoid collision of error codes. This should always be kept as the last
// item.
__EXTEND_POINT__
2019-09-18 07:08:47 +08:00
}
2021-04-18 03:35:44 +08:00
export const errorMessages : Record < ErrorCodes , string > = {
2019-09-18 07:08:47 +08:00
// parse errors
[ ErrorCodes . ABRUPT_CLOSING_OF_EMPTY_COMMENT ] : 'Illegal comment.' ,
[ ErrorCodes . CDATA_IN_HTML_CONTENT ] :
'CDATA section is allowed only in XML context.' ,
[ ErrorCodes . DUPLICATE_ATTRIBUTE ] : 'Duplicate attribute.' ,
[ ErrorCodes . END_TAG_WITH_ATTRIBUTES ] : 'End tag cannot have attributes.' ,
[ ErrorCodes . END_TAG_WITH_TRAILING_SOLIDUS ] : "Illegal '/' in tags." ,
[ ErrorCodes . EOF_BEFORE_TAG_NAME ] : 'Unexpected EOF in tag.' ,
[ ErrorCodes . EOF_IN_CDATA ] : 'Unexpected EOF in CDATA section.' ,
[ ErrorCodes . EOF_IN_COMMENT ] : 'Unexpected EOF in comment.' ,
[ ErrorCodes . EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT ] :
'Unexpected EOF in script.' ,
[ ErrorCodes . EOF_IN_TAG ] : 'Unexpected EOF in tag.' ,
[ ErrorCodes . INCORRECTLY_CLOSED_COMMENT ] : 'Incorrectly closed comment.' ,
[ ErrorCodes . INCORRECTLY_OPENED_COMMENT ] : 'Incorrectly opened comment.' ,
[ ErrorCodes . INVALID_FIRST_CHARACTER_OF_TAG_NAME ] :
"Illegal tag name. Use '<' to print '<'." ,
[ ErrorCodes . MISSING_ATTRIBUTE_VALUE ] : 'Attribute value was expected.' ,
[ ErrorCodes . MISSING_END_TAG_NAME ] : 'End tag name was expected.' ,
[ ErrorCodes . MISSING_WHITESPACE_BETWEEN_ATTRIBUTES ] :
'Whitespace was expected.' ,
[ ErrorCodes . NESTED_COMMENT ] : "Unexpected '<!--' in comment." ,
[ ErrorCodes . UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME ] :
'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).' ,
[ ErrorCodes . UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE ] :
'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).' ,
[ ErrorCodes . UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME ] :
"Attribute name cannot start with '='." ,
[ ErrorCodes . UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME ] :
"'<?' is allowed only in XML context." ,
2021-09-02 04:42:24 +08:00
[ ErrorCodes . UNEXPECTED_NULL_CHARACTER ] : ` Unexpected null character. ` ,
2019-09-18 07:08:47 +08:00
[ ErrorCodes . UNEXPECTED_SOLIDUS_IN_TAG ] : "Illegal '/' in tags." ,
2019-09-24 01:25:18 +08:00
// Vue-specific parse errors
2019-09-18 07:08:47 +08:00
[ ErrorCodes . X_INVALID_END_TAG ] : 'Invalid end tag.' ,
2019-12-20 05:25:05 +08:00
[ ErrorCodes . X_MISSING_END_TAG ] : 'Element is missing end tag.' ,
2019-09-18 07:08:47 +08:00
[ ErrorCodes . X_MISSING_INTERPOLATION_END ] :
'Interpolation end sign was not found.' ,
2019-09-24 01:25:18 +08:00
[ ErrorCodes . X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END ] :
2019-09-27 23:42:02 +08:00
'End bracket for dynamic directive argument was not found. ' +
2019-10-05 22:35:19 +08:00
'Note that dynamic directive argument cannot contain spaces.' ,
2021-09-02 21:42:20 +08:00
[ ErrorCodes . X_MISSING_DIRECTIVE_NAME ] : 'Legal directive name was expected.' ,
2019-09-18 07:08:47 +08:00
// transform errors
2019-10-09 22:27:24 +08:00
[ ErrorCodes . X_V_IF_NO_EXPRESSION ] : ` v-if/v-else-if is missing expression. ` ,
2020-08-05 00:01:07 +08:00
[ ErrorCodes . X_V_IF_SAME_KEY ] : ` v-if/else branches must use unique keys. ` ,
2021-09-22 00:59:38 +08:00
[ ErrorCodes . X_V_ELSE_NO_ADJACENT_IF ] : ` v-else/v-else-if has no adjacent v-if or v-else-if. ` ,
2019-10-09 22:27:24 +08:00
[ ErrorCodes . X_V_FOR_NO_EXPRESSION ] : ` v-for is missing expression. ` ,
[ ErrorCodes . X_V_FOR_MALFORMED_EXPRESSION ] : ` v-for has invalid expression. ` ,
2020-08-05 00:20:32 +08:00
[ ErrorCodes . X_V_FOR_TEMPLATE_KEY_PLACEMENT ] : ` <template v-for> key should be placed on the <template> tag. ` ,
2019-09-28 10:25:32 +08:00
[ ErrorCodes . X_V_BIND_NO_EXPRESSION ] : ` v-bind is missing expression. ` ,
[ ErrorCodes . X_V_ON_NO_EXPRESSION ] : ` v-on is missing expression. ` ,
2019-10-09 22:27:24 +08:00
[ ErrorCodes . X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET ] : ` Unexpected custom directive on <slot> outlet. ` ,
[ ErrorCodes . X_V_SLOT_MIXED_SLOT_USAGE ] :
2022-11-14 15:06:24 +08:00
` Mixed v-slot usage on both the component and nested <template>. ` +
2020-04-02 08:44:53 +08:00
` When there are multiple named slots, all slots should use <template> ` +
` syntax to avoid scope ambiguity. ` ,
2019-10-09 22:27:24 +08:00
[ ErrorCodes . X_V_SLOT_DUPLICATE_SLOT_NAMES ] : ` Duplicate slot names found. ` ,
2020-01-07 04:31:21 +08:00
[ ErrorCodes . X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN ] :
` Extraneous children found when component already has explicitly named ` +
` default slot. These children will be ignored. ` ,
2019-10-09 22:27:24 +08:00
[ ErrorCodes . X_V_SLOT_MISPLACED ] : ` v-slot can only be used on components or <template> tags. ` ,
2019-10-10 22:33:58 +08:00
[ ErrorCodes . X_V_MODEL_NO_EXPRESSION ] : ` v-model is missing expression. ` ,
2019-10-10 23:15:24 +08:00
[ ErrorCodes . X_V_MODEL_MALFORMED_EXPRESSION ] : ` v-model value must be a valid JavaScript member expression. ` ,
2019-10-17 02:05:18 +08:00
[ ErrorCodes . X_V_MODEL_ON_SCOPE_VARIABLE ] : ` v-model cannot be used on v-for or v-slot scope variables because they are not writable. ` ,
2022-11-10 10:42:27 +08:00
[ ErrorCodes . X_V_MODEL_ON_PROPS ] : ` v-model cannot be used on a prop, because local prop bindings are not writable. \ nUse a v-bind binding combined with a v-on listener that emits update:x event instead. ` ,
2020-02-28 05:53:51 +08:00
[ ErrorCodes . X_INVALID_EXPRESSION ] : ` Error parsing JavaScript expression: ` ,
2020-02-07 04:53:26 +08:00
[ ErrorCodes . X_KEEP_ALIVE_INVALID_CHILDREN ] : ` <KeepAlive> expects exactly one child component. ` ,
2019-09-29 02:05:10 +08:00
2019-09-24 01:25:18 +08:00
// generic errors
2019-09-26 10:29:37 +08:00
[ ErrorCodes . X_PREFIX_ID_NOT_SUPPORTED ] : ` "prefixIdentifiers" option is not supported in this build of compiler. ` ,
2019-12-18 01:30:49 +08:00
[ ErrorCodes . X_MODULE_MODE_NOT_SUPPORTED ] : ` ES module mode is not supported in this build of compiler. ` ,
[ ErrorCodes . X_CACHE_HANDLER_NOT_SUPPORTED ] : ` "cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled. ` ,
2021-04-18 03:35:44 +08:00
[ ErrorCodes . X_SCOPE_ID_NOT_SUPPORTED ] : ` "scopeId" option is only supported in module mode. ` ,
2023-04-21 15:20:12 +08:00
// deprecations
2023-04-21 15:26:01 +08:00
[ ErrorCodes . DEPRECATION_VNODE_HOOKS ] : ` @vnode-* hooks in templates are deprecated. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support will be removed in 3.4. ` ,
[ ErrorCodes . DEPRECATION_V_IS ] : ` v-is="component-name" has been deprecated. Use is="vue:component-name" instead. v-is support will be removed in 3.4. ` ,
2023-04-21 15:20:12 +08:00
2021-09-22 22:12:33 +08:00
// just to fulfill types
2021-04-18 03:35:44 +08:00
[ ErrorCodes . __EXTEND_POINT__ ] : ` `
2019-09-18 07:08:47 +08:00
}