UNPKG

803 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.js.map","sources":[".temp/ast/src/ast/errors.ts",".temp/ast/src/ast/nodes.ts",".temp/ast/src/ast/traverse.ts",".temp/common/src/common/lines-and-columns.ts",".temp/common/src/common/location-calculator.ts",".temp/common/src/common/debug.ts",".temp/common/src/common/ast-utils.ts",".temp/common/src/common/parser-object.ts",".temp/common/src/common/parser-options.ts",".temp/common/src/common/create-require.ts",".temp/common/src/common/linter-require.ts",".temp/common/src/common/eslint-scope.ts",".temp/common/src/common/espree.ts",".temp/script/src/script/scope-analyzer.ts",".temp/common/src/common/fix-locations.ts",".temp/script-setup/src/script-setup/parser-options.ts",".temp/script/src/script/generic.ts",".temp/script/src/script/index.ts",".temp/common/src/common/token-utils.ts",".temp/common/src/common/error-utils.ts",".temp/utils/src/utils/utils.ts",".temp/template/src/template/index.ts",".temp/html/util/src/html/util/attribute-names.ts",".temp/html/util/src/html/util/tag-names.ts",".temp/html/src/html/intermediate-tokenizer.ts",".temp/html/src/html/parser.ts",".temp/html/util/src/html/util/alternative-cr.ts",".temp/html/util/src/html/util/entities.ts",".temp/html/util/src/html/util/unicode.ts",".temp/html/src/html/tokenizer.ts",".temp/external/src/external/node-event-generator.ts",".temp/external/token-store/src/external/token-store/utils.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/backward-token-comment-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/backward-token-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/decorative-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/filter-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/forward-token-comment-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/forward-token-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/limit-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/skip-cursor.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/index.ts",".temp/external/token-store/cursors/src/external/token-store/cursors/padded-token-cursor.ts",".temp/external/token-store/src/external/token-store/index.ts",".temp/sfc/custom-block/src/sfc/custom-block/index.ts",".temp/src/parser-services.ts",".temp/script-setup/src/script-setup/index.ts",".temp/style/src/style/tokenizer.ts",".temp/style/src/style/index.ts",".temp/script-setup/src/script-setup/scope-analyzer.ts",".temp/src/index.ts"],"sourcesContent":["/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport type { Location } from \"./locations\"\n\n/**\n * Check whether the given value has acorn style location information.\n * @param x The value to check.\n * @returns `true` if the value has acorn style location information.\n */\nfunction isAcornStyleParseError(\n x: any,\n): x is { message: string; pos: number; loc: Location } {\n return (\n typeof x.message === \"string\" &&\n typeof x.pos === \"number\" &&\n typeof x.loc === \"object\" &&\n x.loc !== null &&\n typeof x.loc.line === \"number\" &&\n typeof x.loc.column === \"number\"\n )\n}\n\n/**\n * Check whether the given value is probably a TSError.\n * @param x The value to check.\n * @returns `true` if the given value is probably a TSError.\n */\nfunction isTSError(\n x: any,\n): x is { message: string; index: number; lineNumber: number; column: number } {\n return (\n !(x instanceof ParseError) &&\n typeof x.message === \"string\" &&\n typeof x.index === \"number\" &&\n typeof x.lineNumber === \"number\" &&\n typeof x.column === \"number\" &&\n x.name === \"TSError\"\n )\n}\n\n/**\n * HTML parse errors.\n */\nexport class ParseError extends SyntaxError {\n public code?: ErrorCode\n public index: number\n public lineNumber: number\n public column: number\n\n /**\n * Create new parser error object.\n * @param code The error code. See also: https://html.spec.whatwg.org/multipage/parsing.html#parse-errors\n * @param offset The offset number of this error.\n * @param line The line number of this error.\n * @param column The column number of this error.\n */\n public static fromCode(\n code: ErrorCode,\n offset: number,\n line: number,\n column: number,\n ): ParseError {\n return new ParseError(code, code, offset, line, column)\n }\n\n /**\n * Normalize the error object.\n * @param x The error object to normalize.\n */\n public static normalize(x: any): ParseError | null {\n if (isTSError(x)) {\n return new ParseError(\n x.message,\n undefined,\n x.index,\n x.lineNumber,\n x.column,\n )\n }\n if (ParseError.isParseError(x)) {\n return x\n }\n if (isAcornStyleParseError(x)) {\n return new ParseError(\n x.message,\n undefined,\n x.pos,\n x.loc.line,\n x.loc.column,\n )\n }\n return null\n }\n\n /**\n * Initialize this ParseError instance.\n * @param message The error message.\n * @param code The error code. See also: https://html.spec.whatwg.org/multipage/parsing.html#parse-errors\n * @param offset The offset number of this error.\n * @param line The line number of this error.\n * @param column The column number of this error.\n */\n public constructor(\n message: string,\n code: ErrorCode | undefined,\n offset: number,\n line: number,\n column: number,\n ) {\n super(message)\n this.code = code\n this.index = offset\n this.lineNumber = line\n this.column = column\n }\n\n /**\n * Type guard for ParseError.\n * @param x The value to check.\n * @returns `true` if the value has `message`, `pos`, `loc` properties.\n */\n public static isParseError(x: any): x is ParseError {\n return (\n x instanceof ParseError ||\n (typeof x.message === \"string\" &&\n typeof x.index === \"number\" &&\n typeof x.lineNumber === \"number\" &&\n typeof x.column === \"number\")\n )\n }\n}\n\n/**\n * The error codes of HTML syntax errors.\n * https://html.spec.whatwg.org/multipage/parsing.html#parse-errors\n */\nexport type ErrorCode =\n | \"abrupt-closing-of-empty-comment\"\n | \"absence-of-digits-in-numeric-character-reference\"\n | \"cdata-in-html-content\"\n | \"character-reference-outside-unicode-range\"\n | \"control-character-in-input-stream\"\n | \"control-character-reference\"\n | \"eof-before-tag-name\"\n | \"eof-in-cdata\"\n | \"eof-in-comment\"\n | \"eof-in-tag\"\n | \"incorrectly-closed-comment\"\n | \"incorrectly-opened-comment\"\n | \"invalid-first-character-of-tag-name\"\n | \"missing-attribute-value\"\n | \"missing-end-tag-name\"\n | \"missing-semicolon-after-character-reference\"\n | \"missing-whitespace-between-attributes\"\n | \"nested-comment\"\n | \"noncharacter-character-reference\"\n | \"noncharacter-in-input-stream\"\n | \"null-character-reference\"\n | \"surrogate-character-reference\"\n | \"surrogate-in-input-stream\"\n | \"unexpected-character-in-attribute-name\"\n | \"unexpected-character-in-unquoted-attribute-value\"\n | \"unexpected-equals-sign-before-attribute-name\"\n | \"unexpected-null-character\"\n | \"unexpected-question-mark-instead-of-tag-name\"\n | \"unexpected-solidus-in-tag\"\n | \"unknown-named-character-reference\"\n | \"end-tag-with-attributes\"\n | \"duplicate-attribute\"\n | \"end-tag-with-trailing-solidus\"\n | \"non-void-html-element-start-tag-with-trailing-solidus\"\n | \"x-invalid-end-tag\"\n | \"x-invalid-namespace\"\n | \"x-missing-interpolation-end\"\n// ---- Use RAWTEXT state for <script> elements instead ----\n// \"eof-in-script-html-comment-like-text\" |\n// ---- Use BOGUS_COMMENT state for DOCTYPEs instead ----\n// \"abrupt-doctype-public-identifier\" |\n// \"abrupt-doctype-system-identifier\" |\n// \"eof-in-doctype\" |\n// \"invalid-character-sequence-after-doctype-name\" |\n// \"missing-doctype-name\" |\n// \"missing-doctype-public-identifier\" |\n// \"missing-doctype-system-identifier\" |\n// \"missing-quote-before-doctype-public-identifier\" |\n// \"missing-quote-before-doctype-system-identifier\" |\n// \"missing-whitespace-after-doctype-public-keyword\" |\n// \"missing-whitespace-after-doctype-system-keyword\" |\n// \"missing-whitespace-before-doctype-name\" |\n// \"missing-whitespace-between-doctype-public-and-system-identifiers\" |\n// \"unexpected-character-after-doctype-system-identifier\" |\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport type { ScopeManager } from \"eslint-scope\"\nimport type { ParseError } from \"./errors\"\nimport type { HasLocation } from \"./locations\"\nimport type { Token } from \"./tokens\"\n// eslint-disable-next-line node/no-extraneous-import -- ignore\nimport type { TSESTree } from \"@typescript-eslint/utils\"\n\n//------------------------------------------------------------------------------\n// Common\n//------------------------------------------------------------------------------\n\n/**\n * Objects which have their parent.\n */\nexport interface HasParent {\n parent?: Node | null\n}\n\n/**\n * The union type for all nodes.\n */\nexport type Node =\n | ESLintNode\n | VNode\n | VForExpression\n | VOnExpression\n | VSlotScopeExpression\n | VGenericExpression\n | VFilterSequenceExpression\n | VFilter\n\n//------------------------------------------------------------------------------\n// Script\n//------------------------------------------------------------------------------\n\n/**\n * The union type for ESLint nodes.\n */\nexport type ESLintNode =\n | ESLintIdentifier\n | ESLintLiteral\n | ESLintProgram\n | ESLintSwitchCase\n | ESLintCatchClause\n | ESLintVariableDeclarator\n | ESLintStatement\n | ESLintExpression\n | ESLintProperty\n | ESLintAssignmentProperty\n | ESLintSuper\n | ESLintTemplateElement\n | ESLintSpreadElement\n | ESLintPattern\n | ESLintClassBody\n | ESLintMethodDefinition\n | ESLintPropertyDefinition\n | ESLintStaticBlock\n | ESLintPrivateIdentifier\n | ESLintModuleDeclaration\n | ESLintModuleSpecifier\n | ESLintImportExpression\n | ESLintLegacyRestProperty\n\n/**\n * The parsing result of ESLint custom parsers.\n */\nexport interface ESLintExtendedProgram {\n ast: ESLintProgram\n services?: {}\n visitorKeys?: { [type: string]: string[] }\n scopeManager?: ScopeManager\n}\n\nexport interface ESLintProgram extends HasLocation, HasParent {\n type: \"Program\"\n sourceType: \"script\" | \"module\"\n body: (ESLintStatement | ESLintModuleDeclaration)[]\n templateBody?: VElement & HasConcreteInfo\n tokens?: Token[]\n comments?: Token[]\n errors?: ParseError[]\n}\n\nexport type ESLintStatement =\n | ESLintExpressionStatement\n | ESLintBlockStatement\n | ESLintEmptyStatement\n | ESLintDebuggerStatement\n | ESLintWithStatement\n | ESLintReturnStatement\n | ESLintLabeledStatement\n | ESLintBreakStatement\n | ESLintContinueStatement\n | ESLintIfStatement\n | ESLintSwitchStatement\n | ESLintThrowStatement\n | ESLintTryStatement\n | ESLintWhileStatement\n | ESLintDoWhileStatement\n | ESLintForStatement\n | ESLintForInStatement\n | ESLintForOfStatement\n | ESLintDeclaration\n\nexport interface ESLintEmptyStatement extends HasLocation, HasParent {\n type: \"EmptyStatement\"\n}\n\nexport interface ESLintBlockStatement extends HasLocation, HasParent {\n type: \"BlockStatement\"\n body: ESLintStatement[]\n}\n\nexport interface ESLintExpressionStatement extends HasLocation, HasParent {\n type: \"ExpressionStatement\"\n expression: ESLintExpression\n}\n\nexport interface ESLintIfStatement extends HasLocation, HasParent {\n type: \"IfStatement\"\n test: ESLintExpression\n consequent: ESLintStatement\n alternate: ESLintStatement | null\n}\n\nexport interface ESLintSwitchStatement extends HasLocation, HasParent {\n type: \"SwitchStatement\"\n discriminant: ESLintExpression\n cases: ESLintSwitchCase[]\n}\n\nexport interface ESLintSwitchCase extends HasLocation, HasParent {\n type: \"SwitchCase\"\n test: ESLintExpression | null\n consequent: ESLintStatement[]\n}\n\nexport interface ESLintWhileStatement extends HasLocation, HasParent {\n type: \"WhileStatement\"\n test: ESLintExpression\n body: ESLintStatement\n}\n\nexport interface ESLintDoWhileStatement extends HasLocation, HasParent {\n type: \"DoWhileStatement\"\n body: ESLintStatement\n test: ESLintExpression\n}\n\nexport interface ESLintForStatement extends HasLocation, HasParent {\n type: \"ForStatement\"\n init: ESLintVariableDeclaration | ESLintExpression | null\n test: ESLintExpression | null\n update: ESLintExpression | null\n body: ESLintStatement\n}\n\nexport interface ESLintForInStatement extends HasLocation, HasParent {\n type: \"ForInStatement\"\n left: ESLintVariableDeclaration | ESLintPattern\n right: ESLintExpression\n body: ESLintStatement\n}\n\nexport interface ESLintForOfStatement extends HasLocation, HasParent {\n type: \"ForOfStatement\"\n left: ESLintVariableDeclaration | ESLintPattern\n right: ESLintExpression\n body: ESLintStatement\n await: boolean\n}\n\nexport interface ESLintLabeledStatement extends HasLocation, HasParent {\n type: \"LabeledStatement\"\n label: ESLintIdentifier\n body: ESLintStatement\n}\n\nexport interface ESLintBreakStatement extends HasLocation, HasParent {\n type: \"BreakStatement\"\n label: ESLintIdentifier | null\n}\n\nexport interface ESLintContinueStatement extends HasLocation, HasParent {\n type: \"ContinueStatement\"\n label: ESLintIdentifier | null\n}\n\nexport interface ESLintReturnStatement extends HasLocation, HasParent {\n type: \"ReturnStatement\"\n argument: ESLintExpression | null\n}\n\nexport interface ESLintThrowStatement extends HasLocation, HasParent {\n type: \"ThrowStatement\"\n argument: ESLintExpression\n}\n\nexport interface ESLintTryStatement extends HasLocation, HasParent {\n type: \"TryStatement\"\n block: ESLintBlockStatement\n handler: ESLintCatchClause | null\n finalizer: ESLintBlockStatement | null\n}\n\nexport interface ESLintCatchClause extends HasLocation, HasParent {\n type: \"CatchClause\"\n param: ESLintPattern | null\n body: ESLintBlockStatement\n}\n\nexport interface ESLintWithStatement extends HasLocation, HasParent {\n type: \"WithStatement\"\n object: ESLintExpression\n body: ESLintStatement\n}\n\nexport interface ESLintDebuggerStatement extends HasLocation, HasParent {\n type: \"DebuggerStatement\"\n}\n\nexport type ESLintDeclaration =\n | ESLintFunctionDeclaration\n | ESLintVariableDeclaration\n | ESLintClassDeclaration\n\nexport interface ESLintFunctionDeclaration extends HasLocation, HasParent {\n type: \"FunctionDeclaration\"\n async: boolean\n generator: boolean\n id: ESLintIdentifier | null\n params: ESLintPattern[]\n body: ESLintBlockStatement\n}\n\nexport interface ESLintVariableDeclaration extends HasLocation, HasParent {\n type: \"VariableDeclaration\"\n kind: \"var\" | \"let\" | \"const\"\n declarations: ESLintVariableDeclarator[]\n}\n\nexport interface ESLintVariableDeclarator extends HasLocation, HasParent {\n type: \"VariableDeclarator\"\n id: ESLintPattern\n init: ESLintExpression | null\n}\n\nexport interface ESLintClassDeclaration extends HasLocation, HasParent {\n type: \"ClassDeclaration\"\n id: ESLintIdentifier | null\n superClass: ESLintExpression | null\n body: ESLintClassBody\n}\n\nexport interface ESLintClassBody extends HasLocation, HasParent {\n type: \"ClassBody\"\n body: (\n | ESLintMethodDefinition\n | ESLintPropertyDefinition\n | ESLintStaticBlock\n )[]\n}\n\nexport interface ESLintMethodDefinition extends HasLocation, HasParent {\n type: \"MethodDefinition\"\n kind: \"constructor\" | \"method\" | \"get\" | \"set\"\n computed: boolean\n static: boolean\n key: ESLintExpression | ESLintPrivateIdentifier\n value: ESLintFunctionExpression\n}\nexport interface ESLintPropertyDefinition extends HasLocation, HasParent {\n type: \"PropertyDefinition\"\n computed: boolean\n static: boolean\n key: ESLintExpression | ESLintPrivateIdentifier\n value: ESLintExpression | null\n}\n\nexport interface ESLintStaticBlock\n extends HasLocation,\n HasParent,\n Omit<ESLintBlockStatement, \"type\"> {\n type: \"StaticBlock\"\n body: ESLintStatement[]\n}\n\nexport interface ESLintPrivateIdentifier extends HasLocation, HasParent {\n type: \"PrivateIdentifier\"\n name: string\n}\n\nexport type ESLintModuleDeclaration =\n | ESLintImportDeclaration\n | ESLintExportNamedDeclaration\n | ESLintExportDefaultDeclaration\n | ESLintExportAllDeclaration\n\nexport type ESLintModuleSpecifier =\n | ESLintImportSpecifier\n | ESLintImportDefaultSpecifier\n | ESLintImportNamespaceSpecifier\n | ESLintExportSpecifier\n\nexport interface ESLintImportDeclaration extends HasLocation, HasParent {\n type: \"ImportDeclaration\"\n specifiers: (\n | ESLintImportSpecifier\n | ESLintImportDefaultSpecifier\n | ESLintImportNamespaceSpecifier\n )[]\n source: ESLintLiteral\n}\n\nexport interface ESLintImportSpecifier extends HasLocation, HasParent {\n type: \"ImportSpecifier\"\n imported: ESLintIdentifier | ESLintStringLiteral\n local: ESLintIdentifier\n}\n\nexport interface ESLintImportDefaultSpecifier extends HasLocation, HasParent {\n type: \"ImportDefaultSpecifier\"\n local: ESLintIdentifier\n}\n\nexport interface ESLintImportNamespaceSpecifier extends HasLocation, HasParent {\n type: \"ImportNamespaceSpecifier\"\n local: ESLintIdentifier\n}\n\nexport interface ESLintImportExpression extends HasLocation, HasParent {\n type: \"ImportExpression\"\n source: ESLintExpression\n}\n\nexport interface ESLintExportNamedDeclaration extends HasLocation, HasParent {\n type: \"ExportNamedDeclaration\"\n declaration?: ESLintDeclaration | null\n specifiers: ESLintExportSpecifier[]\n source?: ESLintLiteral | null\n}\n\nexport interface ESLintExportSpecifier extends HasLocation, HasParent {\n type: \"ExportSpecifier\"\n local: ESLintIdentifier | ESLintStringLiteral\n exported: ESLintIdentifier | ESLintStringLiteral\n}\n\nexport interface ESLintExportDefaultDeclaration extends HasLocation, HasParent {\n type: \"ExportDefaultDeclaration\"\n declaration: ESLintDeclaration | ESLintExpression\n}\n\nexport interface ESLintExportAllDeclaration extends HasLocation, HasParent {\n type: \"ExportAllDeclaration\"\n exported: ESLintIdentifier | ESLintStringLiteral | null\n source: ESLintLiteral\n}\n\nexport type ESLintExpression =\n | ESLintThisExpression\n | ESLintArrayExpression\n | ESLintObjectExpression\n | ESLintFunctionExpression\n | ESLintArrowFunctionExpression\n | ESLintYieldExpression\n | ESLintLiteral\n | ESLintUnaryExpression\n | ESLintUpdateExpression\n | ESLintBinaryExpression\n | ESLintAssignmentExpression\n | ESLintLogicalExpression\n | ESLintMemberExpression\n | ESLintConditionalExpression\n | ESLintCallExpression\n | ESLintNewExpression\n | ESLintSequenceExpression\n | ESLintTemplateLiteral\n | ESLintTaggedTemplateExpression\n | ESLintClassExpression\n | ESLintMetaProperty\n | ESLintIdentifier\n | ESLintAwaitExpression\n | ESLintChainExpression\n\nexport interface ESLintIdentifier extends HasLocation, HasParent {\n type: \"Identifier\"\n name: string\n}\ninterface ESLintLiteralBase extends HasLocation, HasParent {\n type: \"Literal\"\n value: string | boolean | null | number | RegExp | bigint\n raw: string\n regex?: {\n pattern: string\n flags: string\n }\n bigint?: string\n}\nexport interface ESLintStringLiteral extends ESLintLiteralBase {\n value: string\n regex?: undefined\n bigint?: undefined\n}\nexport interface ESLintBooleanLiteral extends ESLintLiteralBase {\n value: boolean\n regex?: undefined\n bigint?: undefined\n}\nexport interface ESLintNullLiteral extends ESLintLiteralBase {\n value: null\n regex?: undefined\n bigint?: undefined\n}\nexport interface ESLintNumberLiteral extends ESLintLiteralBase {\n value: number\n regex?: undefined\n bigint?: undefined\n}\nexport interface ESLintRegExpLiteral extends ESLintLiteralBase {\n value: null | RegExp\n regex: {\n pattern: string\n flags: string\n }\n bigint?: undefined\n}\nexport interface ESLintBigIntLiteral extends ESLintLiteralBase {\n value: null | bigint\n regex?: undefined\n bigint: string\n}\nexport type ESLintLiteral =\n | ESLintStringLiteral\n | ESLintBooleanLiteral\n | ESLintNullLiteral\n | ESLintNumberLiteral\n | ESLintRegExpLiteral\n | ESLintBigIntLiteral\n\nexport interface ESLintThisExpression extends HasLocation, HasParent {\n type: \"ThisExpression\"\n}\n\nexport interface ESLintArrayExpression extends HasLocation, HasParent {\n type: \"ArrayExpression\"\n elements: (ESLintExpression | ESLintSpreadElement)[]\n}\n\nexport interface ESLintObjectExpression extends HasLocation, HasParent {\n type: \"ObjectExpression\"\n properties: (\n | ESLintProperty\n | ESLintSpreadElement\n | ESLintLegacySpreadProperty\n )[]\n}\n\nexport interface ESLintProperty extends HasLocation, HasParent {\n type: \"Property\"\n kind: \"init\" | \"get\" | \"set\"\n method: boolean\n shorthand: boolean\n computed: boolean\n key: ESLintExpression\n value: ESLintExpression | ESLintPattern\n}\n\nexport interface ESLintFunctionExpression extends HasLocation, HasParent {\n type: \"FunctionExpression\"\n async: boolean\n generator: boolean\n id: ESLintIdentifier | null\n params: ESLintPattern[]\n body: ESLintBlockStatement\n}\n\nexport interface ESLintArrowFunctionExpression extends HasLocation, HasParent {\n type: \"ArrowFunctionExpression\"\n async: boolean\n generator: boolean\n id: ESLintIdentifier | null\n params: ESLintPattern[]\n body: ESLintBlockStatement | ESLintExpression\n}\n\nexport interface ESLintSequenceExpression extends HasLocation, HasParent {\n type: \"SequenceExpression\"\n expressions: ESLintExpression[]\n}\n\nexport interface ESLintUnaryExpression extends HasLocation, HasParent {\n type: \"UnaryExpression\"\n operator: \"-\" | \"+\" | \"!\" | \"~\" | \"typeof\" | \"void\" | \"delete\"\n prefix: boolean\n argument: ESLintExpression\n}\n\nexport interface ESLintBinaryExpression extends HasLocation, HasParent {\n type: \"BinaryExpression\"\n operator:\n | \"==\"\n | \"!=\"\n | \"===\"\n | \"!==\"\n | \"<\"\n | \"<=\"\n | \">\"\n | \">=\"\n | \"<<\"\n | \">>\"\n | \">>>\"\n | \"+\"\n | \"-\"\n | \"*\"\n | \"/\"\n | \"%\"\n | \"**\"\n | \"|\"\n | \"^\"\n | \"&\"\n | \"in\"\n | \"instanceof\"\n left: ESLintExpression | ESLintPrivateIdentifier\n right: ESLintExpression\n}\n\nexport interface ESLintAssignmentExpression extends HasLocation, HasParent {\n type: \"AssignmentExpression\"\n operator:\n | \"=\"\n | \"+=\"\n | \"-=\"\n | \"*=\"\n | \"/=\"\n | \"%=\"\n | \"**=\"\n | \"<<=\"\n | \">>=\"\n | \">>>=\"\n | \"|=\"\n | \"^=\"\n | \"&=\"\n | \"||=\"\n | \"&&=\"\n | \"??=\"\n left: ESLintPattern\n right: ESLintExpression\n}\n\nexport interface ESLintUpdateExpression extends HasLocation, HasParent {\n type: \"UpdateExpression\"\n operator: \"++\" | \"--\"\n argument: ESLintExpression\n prefix: boolean\n}\n\nexport interface ESLintLogicalExpression extends HasLocation, HasParent {\n type: \"LogicalExpression\"\n operator: \"||\" | \"&&\" | \"??\"\n left: ESLintExpression\n right: ESLintExpression\n}\n\nexport interface ESLintConditionalExpression extends HasLocation, HasParent {\n type: \"ConditionalExpression\"\n test: ESLintExpression\n alternate: ESLintExpression\n consequent: ESLintExpression\n}\n\nexport interface ESLintCallExpression extends HasLocation, HasParent {\n type: \"CallExpression\"\n optional: boolean\n callee: ESLintExpression | ESLintSuper\n arguments: (ESLintExpression | ESLintSpreadElement)[]\n}\n\nexport interface ESLintSuper extends HasLocation, HasParent {\n type: \"Super\"\n}\n\nexport interface ESLintNewExpression extends HasLocation, HasParent {\n type: \"NewExpression\"\n callee: ESLintExpression\n arguments: (ESLintExpression | ESLintSpreadElement)[]\n}\n\nexport interface ESLintMemberExpression extends HasLocation, HasParent {\n type: \"MemberExpression\"\n optional: boolean\n computed: boolean\n object: ESLintExpression | ESLintSuper\n property: ESLintExpression | ESLintPrivateIdentifier\n}\n\nexport interface ESLintYieldExpression extends HasLocation, HasParent {\n type: \"YieldExpression\"\n delegate: boolean\n argument: ESLintExpression | null\n}\n\nexport interface ESLintAwaitExpression extends HasLocation, HasParent {\n type: \"AwaitExpression\"\n argument: ESLintExpression\n}\n\nexport interface ESLintTemplateLiteral extends HasLocation, HasParent {\n type: \"TemplateLiteral\"\n quasis: ESLintTemplateElement[]\n expressions: ESLintExpression[]\n}\n\nexport interface ESLintTaggedTemplateExpression extends HasLocation, HasParent {\n type: \"TaggedTemplateExpression\"\n tag: ESLintExpression\n quasi: ESLintTemplateLiteral\n}\n\nexport interface ESLintTemplateElement extends HasLocation, HasParent {\n type: \"TemplateElement\"\n tail: boolean\n value: {\n cooked: string | null\n raw: string\n }\n}\n\nexport interface ESLintClassExpression extends HasLocation, HasParent {\n type: \"ClassExpression\"\n id: ESLintIdentifier | null\n superClass: ESLintExpression | null\n body: ESLintClassBody\n}\n\nexport interface ESLintMetaProperty extends HasLocation, HasParent {\n type: \"MetaProperty\"\n meta: ESLintIdentifier\n property: ESLintIdentifier\n}\n\nexport type ESLintPattern =\n | ESLintIdentifier\n | ESLintObjectPattern\n | ESLintArrayPattern\n | ESLintRestElement\n | ESLintAssignmentPattern\n | ESLintMemberExpression\n | ESLintLegacyRestProperty\n\nexport interface ESLintObjectPattern extends HasLocation, HasParent {\n type: \"ObjectPattern\"\n properties: (\n | ESLintAssignmentProperty\n | ESLintRestElement\n | ESLintLegacyRestProperty\n )[]\n}\n\nexport interface ESLintAssignmentProperty extends ESLintProperty {\n value: ESLintPattern\n kind: \"init\"\n method: false\n}\n\nexport interface ESLintArrayPattern extends HasLocation, HasParent {\n type: \"ArrayPattern\"\n elements: ESLintPattern[]\n}\n\nexport interface ESLintRestElement extends HasLocation, HasParent {\n type: \"RestElement\"\n argument: ESLintPattern\n}\n\nexport interface ESLintSpreadElement extends HasLocation, HasParent {\n type: \"SpreadElement\"\n argument: ESLintExpression\n}\n\nexport interface ESLintAssignmentPattern extends HasLocation, HasParent {\n type: \"AssignmentPattern\"\n left: ESLintPattern\n right: ESLintExpression\n}\n\nexport type ESLintChainElement = ESLintCallExpression | ESLintMemberExpression\n\nexport interface ESLintChainExpression extends HasLocation, HasParent {\n type: \"ChainExpression\"\n expression: ESLintChainElement\n}\n\n/**\n * Legacy for babel-eslint and espree.\n */\nexport interface ESLintLegacyRestProperty extends HasLocation, HasParent {\n type: \"RestProperty\" | \"ExperimentalRestProperty\"\n argument: ESLintPattern\n}\n\n/**\n * Legacy for babel-eslint and espree.\n */\nexport interface ESLintLegacySpreadProperty extends HasLocation, HasParent {\n type: \"SpreadProperty\" | \"ExperimentalSpreadProperty\"\n argument: ESLintExpression\n}\n\n//------------------------------------------------------------------------------\n// Template\n//------------------------------------------------------------------------------\n\n/**\n * Constants of namespaces.\n * @see https://infra.spec.whatwg.org/#namespaces\n */\nexport const NS = Object.freeze({\n HTML: \"http://www.w3.org/1999/xhtml\" as \"http://www.w3.org/1999/xhtml\",\n MathML: \"http://www.w3.org/1998/Math/MathML\" as \"http://www.w3.org/1998/Math/MathML\",\n SVG: \"http://www.w3.org/2000/svg\" as \"http://www.w3.org/2000/svg\",\n XLink: \"http://www.w3.org/1999/xlink\" as \"http://www.w3.org/1999/xlink\",\n XML: \"http://www.w3.org/XML/1998/namespace\" as \"http://www.w3.org/XML/1998/namespace\",\n XMLNS: \"http://www.w3.org/2000/xmlns/\" as \"http://www.w3.org/2000/xmlns/\",\n})\n\n/**\n * Type of namespaces.\n */\nexport type Namespace =\n | typeof NS.HTML\n | typeof NS.MathML\n | typeof NS.SVG\n | typeof NS.XLink\n | typeof NS.XML\n | typeof NS.XMLNS\n\n/**\n * Type of variable definitions.\n */\nexport interface Variable {\n id: ESLintIdentifier\n kind: \"v-for\" | \"scope\" | \"generic\"\n references: Reference[]\n}\n\n/**\n * Type of variable references.\n */\nexport interface Reference {\n id: ESLintIdentifier\n mode: \"rw\" | \"r\" | \"w\"\n variable: Variable | null\n\n // For typescript-eslint\n isValueReference?: boolean\n isTypeReference?: boolean\n}\n\n/**\n * The node of `v-for` directives.\n */\nexport interface VForExpression extends HasLocation, HasParent {\n type: \"VForExpression\"\n parent: VExpressionContainer\n left: ESLintPattern[]\n right: ESLintExpression\n}\n\n/**\n * The node of `v-on` directives.\n */\nexport interface VOnExpression extends HasLocation, HasParent {\n type: \"VOnExpression\"\n parent: VExpressionContainer\n body: ESLintStatement[]\n}\n\n/**\n * The node of `slot-scope` directives.\n */\nexport interface VSlotScopeExpression extends HasLocation, HasParent {\n type: \"VSlotScopeExpression\"\n parent: VExpressionContainer\n params: ESLintPattern[]\n}\n\n/**\n * The node of `generic` directives.\n */\nexport interface VGenericExpression extends HasLocation, HasParent {\n type: \"VGenericExpression\"\n parent: VExpressionContainer\n params: TSESTree.TSTypeParameterDeclaration[\"params\"]\n rawParams: string[]\n}\n\n/**\n * The node of a filter sequence which is separated by `|`.\n */\nexport interface VFilterSequenceExpression extends HasLocation, HasParent {\n type: \"VFilterSequenceExpression\"\n parent: VExpressionContainer\n expression: ESLintExpression\n filters: VFilter[]\n}\n\n/**\n * The node of a filter sequence which is separated by `|`.\n */\nexport interface VFilter extends HasLocation, HasParent {\n type: \"VFilter\"\n parent: VFilterSequenceExpression\n callee: ESLintIdentifier\n arguments: (ESLintExpression | ESLintSpreadElement)[]\n}\n\n/**\n * The union type of any nodes.\n */\nexport type VNode =\n | VAttribute\n | VDirective\n | VDirectiveKey\n | VDocumentFragment\n | VElement\n | VEndTag\n | VExpressionContainer\n | VIdentifier\n | VLiteral\n | VStartTag\n | VText\n\n/**\n * Text nodes.\n */\nexport interface VText extends HasLocation, HasParent {\n type: \"VText\"\n parent: VDocumentFragment | VElement\n value: string\n}\n\n/**\n * The node of JavaScript expression in text.\n * e.g. `{{ name }}`\n */\nexport interface VExpressionContainer extends HasLocation, HasParent {\n type: \"VExpressionContainer\"\n parent: VDocumentFragment | VElement | VDirective | VDirectiveKey\n expression:\n | ESLintExpression\n | VFilterSequenceExpression\n | VForExpression\n | VOnExpression\n | VSlotScopeExpression\n | VGenericExpression\n | null\n references: Reference[]\n}\n\n/**\n * Attribute name nodes.\n */\nexport interface VIdentifier extends HasLocation, HasParent {\n type: \"VIdentifier\"\n parent: VAttribute | VDirectiveKey\n name: string\n rawName: string\n}\n\n/**\n * Attribute name nodes.\n */\nexport interface VDirectiveKey extends HasLocation, HasParent {\n type: \"VDirectiveKey\"\n parent: VDirective\n name: VIdentifier\n argument: VExpressionContainer | VIdentifier | null\n modifiers: VIdentifier[]\n}\n\n/**\n * Attribute value nodes.\n */\nexport interface VLiteral extends HasLocation, HasParent {\n type: \"VLiteral\"\n parent: VAttribute\n value: string\n}\n\n/**\n * Static attribute nodes.\n */\nexport interface VAttribute extends HasLocation, HasParent {\n type: \"VAttribute\"\n parent: VStartTag\n directive: false\n key: VIdentifier\n value: VLiteral | null\n}\n\n/**\n * Directive nodes.\n */\nexport interface VDirective extends HasLocation, HasParent {\n type: \"VAttribute\"\n parent: VStartTag\n directive: true\n key: VDirectiveKey\n value: VExpressionContainer | null\n}\n\n/**\n * Start tag nodes.\n */\nexport interface VStartTag extends HasLocation, HasParent {\n type: \"VStartTag\"\n parent: VElement\n selfClosing: boolean\n attributes: (VAttribute | VDirective)[]\n}\n\n/**\n * End tag nodes.\n */\nexport interface VEndTag extends HasLocation, HasParent {\n type: \"VEndTag\"\n parent: VElement\n}\n\n/**\n * The property which has concrete information.\n */\nexport interface HasConcreteInfo {\n tokens: Token[]\n comments: Token[]\n errors: ParseError[]\n}\n\n/**\n * Element nodes.\n */\nexport interface VElement extends HasLocation, HasParent {\n type: \"VElement\"\n parent: VDocumentFragment | VElement\n namespace: Namespace\n name: string\n rawName: string\n startTag: VStartTag\n children: (VElement | VText | VExpressionContainer)[]\n endTag: VEndTag | null\n variables: Variable[]\n}\n\n/**\n * Root nodes.\n */\nexport interface VDocumentFragment\n extends HasLocation,\n HasParent,\n HasConcreteInfo {\n type: \"VDocumentFragment\"\n parent: null\n children: (VElement | VText | VExpressionContainer | VStyleElement)[]\n}\n\n/**\n * Style element nodes.\n */\nexport interface VStyleElement extends VElement {\n type: \"VElement\"\n name: \"style\"\n style: true\n children: (VText | VExpressionContainer)[]\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport type { VisitorKeys } from \"eslint-visitor-keys\"\nimport * as Evk from \"eslint-visitor-keys\"\nimport type { Node } from \"./nodes\"\n\n//------------------------------------------------------------------------------\n// Helpers\n//------------------------------------------------------------------------------\n\nexport const KEYS = Evk.unionWith({\n VAttribute: [\"key\", \"value\"],\n VDirectiveKey: [\"name\", \"argument\", \"modifiers\"],\n VDocumentFragment: [\"children\"],\n VElement: [\"startTag\", \"children\", \"endTag\"],\n VEndTag: [],\n VExpressionContainer: [\"expression\"],\n VFilter: [\"callee\", \"arguments\"],\n VFilterSequenceExpression: [\"expression\", \"filters\"],\n VForExpression: [\"left\", \"right\"],\n VIdentifier: [],\n VLiteral: [],\n VOnExpression: [\"body\"],\n VSlotScopeExpression: [\"params\"],\n VStartTag: [\"attributes\"],\n VText: [],\n})\n\n/**\n * Check that the given key should be traversed or not.\n * @this {Traversable}\n * @param key The key to check.\n * @returns `true` if the key should be traversed.\n */\nfunction fallbackKeysFilter(this: any, key: string): boolean {\n let value = null\n return (\n key !== \"comments\" &&\n key !== \"leadingComments\" &&\n key !== \"loc\" &&\n key !== \"parent\" &&\n key !== \"range\" &&\n key !== \"tokens\" &&\n key !== \"trailingComments\" &&\n (value = this[key]) !== null &&\n typeof value === \"object\" &&\n (typeof value.type === \"string\" || Array.isArray(value))\n )\n}\n\n/**\n * Get the keys of the given node to traverse it.\n * @param node The node to get.\n * @returns The keys to traverse.\n */\nfunction getFallbackKeys(node: Node): string[] {\n return Object.keys(node).filter(fallbackKeysFilter, node)\n}\n\n/**\n * Check wheather a given value is a node.\n * @param x The value to check.\n * @returns `true` if the value is a node.\n */\nfunction isNode(x: any): x is Node {\n return x !== null && typeof x === \"object\" && typeof x.type === \"string\"\n}\n\n/**\n * Traverse the given node.\n * @param node The node to traverse.\n * @param parent The parent node.\n * @param visitor The node visitor.\n */\nfunction traverse(node: Node, parent: Node | null, visitor: Visitor): void {\n let i = 0\n let j = 0\n\n visitor.enterNode(node, parent)\n\n const keys =\n (visitor.visitorKeys || KEYS)[node.type] || getFallbackKeys(node)\n for (i = 0; i < keys.length; ++i) {\n const child = (node as any)[keys[i]]\n\n if (Array.isArray(child)) {\n for (j = 0; j < child.length; ++j) {\n if (isNode(child[j])) {\n traverse(child[j], node, visitor)\n }\n }\n } else if (isNode(child)) {\n traverse(child, node, visitor)\n }\n }\n\n visitor.leaveNode(node, parent)\n}\n\n//------------------------------------------------------------------------------\n// Exports\n//------------------------------------------------------------------------------\n\nexport interface Visitor {\n visitorKeys?: VisitorKeys\n enterNode(node: Node, parent: Node | null): void\n leaveNode(node: Node, parent: Node | null): void\n}\n\n/**\n * Traverse the given AST tree.\n * @param node Root node to traverse.\n * @param visitor Visitor.\n */\nexport function traverseNodes(node: Node, visitor: Visitor): void {\n traverse(node, null, visitor)\n}\n\nexport { getFallbackKeys }\n","import sortedLastIndex from \"lodash/sortedLastIndex\"\nimport type { Location } from \"../ast\"\nimport type { LocationCalculator } from \"./location-calculator\"\n/**\n * A class for getting lines and columns location.\n */\nexport class LinesAndColumns {\n protected ltOffsets: number[]\n\n /**\n * Initialize.\n * @param ltOffsets The list of the offset of line terminators.\n */\n public constructor(ltOffsets: number[]) {\n this.ltOffsets = ltOffsets\n }\n\n /**\n * Calculate the location of the given index.\n * @param index The index to calculate their location.\n * @returns The location of the index.\n */\n public getLocFromIndex(index: number): Location {\n const line = sortedLastIndex(this.ltOffsets, index) + 1\n const column = index - (line === 1 ? 0 : this.ltOffsets[line - 2])\n return { line, column }\n }\n\n public createOffsetLocationCalculator(offset: number): LocationCalculator {\n return {\n getFixOffset() {\n return offset\n },\n getLocFromIndex: this.getLocFromIndex.bind(this),\n }\n }\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport sortedLastIndex from \"lodash/sortedLastIndex\"\nimport type { Location } from \"../ast\"\nimport { LinesAndColumns } from \"./lines-and-columns\"\n\n/**\n * Location calculators.\n */\nexport interface LocationCalculator {\n /**\n * Gets the fix location offset of the given offset with using the base offset of this calculator.\n * @param offset The offset to modify.\n */\n getFixOffset(offset: number, kind: \"start\" | \"end\"): number\n\n /**\n * Calculate the location of the given index.\n * @param index The index to calculate their location.\n * @returns The location of the index.\n */\n getLocFromIndex(index: number): Location\n}\n\n/**\n * Location calculators.\n *\n * HTML tokenizers remove several characters to handle HTML entities and line terminators.\n * Tokens have the processed text as their value, but tokens have offsets and locations in the original text.\n * This calculator calculates the original locations from the processed texts.\n *\n * This calculator will be used for:\n *\n * - Adjusts the locations of script ASTs.\n * - Creates expression containers in postprocess.\n */\nexport class LocationCalculatorForHtml\n extends LinesAndColumns\n implements LocationCalculator\n{\n private gapOffsets: number[]\n private baseOffset: number\n private baseIndexOfGap: number\n private shiftOffset: number\n\n /**\n * Initialize this calculator.\n * @param gapOffsets The list of the offset of removed characters in tokenization phase.\n * @param ltOffsets The list of the offset of line terminators.\n * @param baseOffset The base offset to calculate locations.\n * @param shiftOffset The shift offset to calculate locations.\n */\n public constructor(\n gapOffsets: number[],\n ltOffsets: number[],\n baseOffset?: number,\n shiftOffset = 0,\n ) {\n super(ltOffsets)\n this.gapOffsets = gapOffsets\n this.ltOffsets = ltOffsets\n this.baseOffset = baseOffset || 0\n this.baseIndexOfGap =\n this.baseOffset === 0\n ? 0\n : sortedLastIndex(gapOffsets, this.baseOffset)\n this.shiftOffset = shiftOffset\n }\n\n /**\n * Get sub calculator which have the given base offset.\n * @param offset The base offset of new sub calculator.\n * @returns Sub calculator.\n */\n public getSubCalculatorAfter(offset: number): LocationCalculatorForHtml {\n return new LocationCalculatorForHtml(\n this.gapOffsets,\n this.ltOffsets,\n this.baseOffset + offset,\n this.shiftOffset,\n )\n }\n\n /**\n * Get sub calculator that shifts the given offset.\n * @param offset The shift of new sub calculator.\n * @returns Sub calculator.\n */\n public getSubCalculatorShift(offset: number): LocationCalculatorForHtml {\n return new LocationCalculatorForHtml(\n this.gapOffsets,\n this.ltOffsets,\n this.baseOffset,\n this.shiftOffset + offset,\n )\n }\n\n /**\n * Calculate gap at the given index.\n * @param index The index to calculate gap.\n */\n private _getGap(index: number): number {\n const offsets = this.gapOffsets\n let g0 = sortedLastIndex(offsets, index + this.baseOffset)\n let pos = index + this.baseOffset + g0 - this.baseIndexOfGap\n\n while (g0 < offsets.length && offsets[g0] <= pos) {\n g0 += 1\n pos += 1\n }\n\n return g0 - this.baseIndexOfGap\n }\n\n /**\n * Calculate the location of the given index.\n * @param index The index to calculate their location.\n * @returns The location of the index.\n */\n public getLocation(index: number): Location {\n return this.getLocFromIndex(this.getOffsetWithGap(index))\n }\n\n /**\n * Calculate the offset of the given index.\n * @param index The index to calculate their location.\n * @returns The offset of the index.\n */\n public getOffsetWithGap(index: number): number {\n return index + this.getFixOffset(index)\n }\n\n /**\n * Gets the fix location offset of the given offset with using the base offset of this calculator.\n * @param offset The offset to modify.\n */\n public getFixOffset(offset: number): number {\n const shiftOffset = this.shiftOffset\n const gap = this._getGap(offset + shiftOffset)\n return this.baseOffset + gap + shiftOffset\n }\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport debugFactory from \"debug\"\nexport const debug = debugFactory(\"vue-eslint-parser\")\n","import type {\n VAttribute,\n VDirective,\n VDocumentFragment,\n VElement,\n VExpressionContainer,\n VGenericExpression,\n VNode,\n} from \"../ast\"\n\n/**\n * Check whether the node is a `<script>` element.\n * @param node The node to check.\n * @returns `true` if the node is a `<script>` element.\n */\nexport function isScriptElement(node: VNode): node is VElement {\n return node.type === \"VElement\" && node.name === \"script\"\n}\n\n/**\n * Checks whether the given script element is `<script setup>`.\n */\nexport function isScriptSetupElement(script: VElement): boolean {\n return (\n isScriptElement(script) &&\n script.startTag.attributes.some(\n (attr) => !attr.directive && attr.key.name === \"setup\",\n )\n )\n}\n\n/**\n * Check whether the node is a `<template>` element.\n * @param node The node to check.\n * @returns `true` if the node is a `<template>` element.\n */\nexport function isTemplateElement(node: VNode): node is VElement {\n return node.type === \"VElement\" && node.name === \"template\"\n}\n\n/**\n * Check whether the node is a `<style>` element.\n * @param node The node to check.\n * @returns `true` if the node is a `<style>` element.\n */\nexport function isStyleElement(node: VNode): node is VElement {\n return node.type === \"VElement\" && node.name === \"style\"\n}\n\n/**\n * Get the belonging document of the given node.\n * @param leafNode The node to get.\n * @returns The belonging document.\n */\nexport function getOwnerDocument(leafNode: VNode): VDocumentFragment | null {\n let node: VNode | null = leafNode\n while (node != null && node.type !== \"VDocumentFragment\") {\n node = node.parent\n }\n return node\n}\n\n/**\n * Check whether the attribute node is a `lang` attribute.\n * @param attribute The attribute node to check.\n * @returns `true` if the attribute node is a `lang` attribute.\n */\nexport function isLang(\n attribute: VAttribute | VDirective,\n): attribute is VAttribute {\n return attribute.directive === false && attribute.key.name === \"lang\"\n}\n\n/**\n * Get the `lang` attribute value from a given element.\n * @param element The element to get.\n * @param defaultLang The default value of the `lang` attribute.\n * @returns The `lang` attribute value.\n */\nexport function getLang(element: VElement | undefined): string | null {\n const langAttr = element && element.startTag.attributes.find(isLang)\n const lang = langAttr && langAttr.value && langAttr.value.value\n return lang || null\n}\n/**\n * Check whether the given script element has `lang=\"ts\"`.\n * @param element The element to check.\n * @returns The given script element has `lang=\"ts\"`.\n */\nexport function isTSLang(element: VElement | undefined): boolean {\n const lang = getLang(element)\n // See https://github.com/vuejs/core/blob/28e30c819df5e4fc301c98f7be938fa13e8be3bc/packages/compiler-sfc/src/compileScript.ts#L179\n return lang === \"ts\" || lang === \"tsx\"\n}\n\nexport type GenericDirective = VDirective & {\n value: VExpressionContainer & {\n expression: VGenericExpression\n }\n}\n\n/**\n * Find `generic` directive from given `<script>` element\n */\nexport function findGenericDirective(\n element: VElement,\n): GenericDirective | null {\n return (\n element.startTag.attributes.find(\n (attr): attr is GenericDirective =>\n attr.directive &&\n attr.value?.expression?.type === \"VGenericExpression\",\n ) || null\n )\n}\n","import type { ESLintExtendedProgram, ESLintProgram } from \"../ast\"\n\n/**\n * The type of basic ESLint custom parser.\n * e.g. espree\n */\nexport type BasicParserObject<R = ESLintProgram> = {\n parse(code: string, options: any): R\n parseForESLint: undefined\n}\n/**\n * The type of ESLint custom parser enhanced for ESLint.\n * e.g. @babel/eslint-parser, @typescript-eslint/parser\n */\nexport type EnhancedParserObject<R = ESLintExtendedProgram> = {\n parseForESLint(code: string, options: any): R\n parse: undefined\n}\n\n/**\n * The type of ESLint (custom) parsers.\n */\nexport type ParserObject<R1 = ESLintExtendedProgram, R2 = ESLintProgram> =\n | EnhancedParserObject<R1>\n | BasicParserObject<R2>\n\nexport function isParserObject<R1, R2>(\n value: ParserObject<R1, R2> | {} | undefined | null,\n): value is ParserObject<R1, R2> {\n return isEnhancedParserObject(value) || isBasicParserObject(value)\n}\nexport function isEnhancedParserObject<R>(\n value: EnhancedParserObject<R> | {} | undefined | null,\n): value is EnhancedParserObject<R> {\n return Boolean(value && typeof (value as any).parseForESLint === \"function\")\n}\nexport function isBasicParserObject<R>(\n value: BasicParserObject<R> | {} | undefined | null,\n): value is BasicParserObject<R> {\n return Boolean(value && typeof (value as any).parse === \"function\")\n}\n","import * as path from \"path\"\nimport type { VDocumentFragment } from \"../ast\"\nimport type { CustomTemplateTokenizerConstructor } from \"../html/custom-tokenizer\"\nimport { getLang, isScriptElement, isScriptSetupElement } from \"./ast-utils\"\nimport type { ParserObject } from \"./parser-object\"\nimport { isParserObject } from \"./parser-object\"\n\nexport interface ParserOptions {\n // vue-eslint-parser options\n parser?:\n | boolean\n | string\n | ParserObject\n | Record<string, string | ParserObject | undefined>\n vueFeatures?: {\n interpolationAsNonHTML?: boolean // default true\n filter?: boolean // default true\n styleCSSVariableInjection?: boolean // default true\n customMacros?: string[]\n }\n\n // espree options\n ecmaVersion?: number | \"latest\"\n sourceType?: \"script\" | \"module\"\n ecmaFeatures?: { [key: string]: any }\n\n // @typescript-eslint/parser options\n jsxPragma?: string\n jsxFragmentName?: string | null\n lib?: string[]\n\n project?: string | string[]\n projectFolderIgnoreList?: string[]\n tsconfigRootDir?: string\n extraFileExtensions?: string[]\n warnOnUnsupportedTypeScriptVersion?: boolean\n\n // set by eslint\n filePath?: string\n // enables by eslint\n comment?: boolean\n loc?: boolean\n range?: boolean\n tokens?: boolean\n\n // From ESLint\n eslintScopeManager?: boolean\n\n // others\n // [key: string]: any\n\n templateTokenizer?: Record<\n string,\n string | CustomTemplateTokenizerConstructor | undefined\n >\n}\n\nexport function isSFCFile(parserOptions: ParserOptions) {\n if (parserOptions.filePath === \"<input>\") {\n return true\n }\n return path.extname(parserOptions.filePath || \"unknown.vue\") === \".vue\"\n}\n\n/**\n * Gets the script parser name from the given parser lang.\n */\nexport function getScriptParser(\n parser:\n | boolean\n | string\n | ParserObject\n | Record<string, string | ParserObject | undefined>\n | undefined,\n getParserLang: () => string | null | Iterable<string | null>,\n): string | ParserObject | undefined {\n if (isParserObject(parser)) {\n return parser\n }\n if (parser && typeof parser === \"object\") {\n const parserLang = getParserLang()\n const parserLangs =\n parserLang == null\n ? []\n : typeof parserLang === \"string\"\n ? [parserLang]\n : parserLang\n for (const lang of parserLangs) {\n const parserForLang = lang && parser[lang]\n if (\n typeof parserForLang === \"string\" ||\n isParserObject(parserForLang)\n ) {\n return parserForLang\n }\n }\n return parser.js\n }\n return typeof parser === \"string\" ? parser : undefined\n}\n\nexport function getParserLangFromSFC(doc: VDocumentFragment): string | null {\n if (doc) {\n const scripts = doc.children.filter(isScriptElement)\n const script =\n (scripts.length === 2 && scripts.find(isScriptSetupElement)) ||\n scripts[0]\n if (script) {\n return getLang(script)\n }\n }\n return null\n}\n","import Module from \"module\"\nimport path from \"path\"\nexport const createRequire: (filename: string) => (modname: string) => any =\n // Added in v12.2.0\n (Module as any).createRequire ||\n // Added in v10.12.0, but deprecated in v12.2.0.\n (Module as any).createRequireFromPath ||\n // Polyfill - This is not executed on the tests on node@>=10.\n /* istanbul ignore next */\n ((modname) => {\n const mod = new Module(modname)\n\n mod.filename = modname\n mod.paths = (Module as any)._nodeModulePaths(path.dirname(modname))\n ;(mod as any)._compile(\"module.exports = require;\", modname)\n return mod.exports\n })\n","import path from \"path\"\nimport { createRequire } from \"./create-require\"\n\nfunction isLinterPath(p: string): boolean {\n return (\n // ESLint 6 and above\n p.includes(\n `eslint${path.sep}lib${path.sep}linter${path.sep}linter.js`,\n ) ||\n // ESLint 5\n p.includes(`eslint${path.sep}lib${path.sep}linter.js`)\n )\n}\n\nexport function getLinterRequire() {\n // Lookup the loaded eslint\n const linterPath = Object.keys(require.cache).find(isLinterPath)\n if (linterPath) {\n try {\n return createRequire(linterPath)\n } catch {\n // ignore\n }\n }\n return null\n}\n","import * as escope from \"eslint-scope\"\nimport { getLinterRequire } from \"./linter-require\"\nimport { lte } from \"semver\"\n\nlet escopeCache: typeof escope | null = null\n\n/**\n * Load the newest `eslint-scope` from the loaded ESLint or dependency.\n */\nexport function getEslintScope(): typeof escope & {\n version: string\n} {\n if (!escopeCache) {\n escopeCache = getLinterRequire()?.(\"eslint-scope\")\n if (\n !escopeCache ||\n escopeCache.version == null ||\n lte(escopeCache.version, escope.version)\n ) {\n escopeCache = escope\n }\n }\n\n return escopeCache\n}\n","import type { ParserOptions } from \"../common/parser-options\"\nimport { getLinterRequire } from \"./linter-require\"\n// @ts-expect-error -- ignore\nimport * as dependencyEspree from \"espree\"\nimport { lte, lt } from \"semver\"\nimport { createRequire } from \"./create-require\"\nimport path from \"path\"\nimport type { BasicParserObject } from \"./parser-object\"\n\ntype Espree = BasicParserObject & {\n latestEcmaVersion?: number\n version: string\n}\nlet espreeCache: Espree | null = null\n\n/**\n * Gets the espree that the given ecmaVersion can parse.\n */\nexport function getEspreeFromEcmaVersion(\n ecmaVersion: ParserOptions[\"ecmaVersion\"],\n): Espree {\n const linterEspree = getEspreeFromLinter()\n if (ecmaVersion == null) {\n return linterEspree\n }\n if (ecmaVersion === \"latest\") {\n return getNewestEspree()\n }\n if (\n normalizeEcmaVersion(ecmaVersion) <= getLatestEcmaVersion(linterEspree)\n ) {\n return linterEspree\n }\n const userEspree = getEspreeFromUser()\n if (normalizeEcmaVersion(ecmaVersion) <= getLatestEcmaVersion(userEspree)) {\n return userEspree\n }\n return linterEspree\n}\n\n/**\n * Load `espree` from the user dir.\n */\nexport function getEspreeFromUser(): Espree {\n try {\n const cwd = process.cwd()\n const relativeTo = path.join(cwd, \"__placeholder__.js\")\n return createRequire(relativeTo)(\"espree\")\n } catch {\n return getEspreeFromLinter()\n }\n}\n\n/**\n * Load `espree` from the loaded ESLint.\n * If the loaded ESLint was not found, just returns `require(\"espree\")`.\n */\nexport function getEspreeFromLinter(): Espree {\n if (!espreeCache) {\n espreeCache = getLinterRequire()?.(\"espree\")\n if (!espreeCache) {\n espreeCache = dependencyEspree\n }\n }\n\n return espreeCache!\n}\n\n/**\n * Load the newest `espree` from the loaded ESLint or dependency.\n */\nfunction getNewestEspree(): Espree {\n let newest = dependencyEspree\n const linterEspree = getEspreeFromLinter()\n if (\n linterEspree.version != null &&\n lte(newest.version, linterEspree.version)\n ) {\n newest = linterEspree\n }\n const userEspree = getEspreeFromUser()\n if (userEspree.version != null && lte(newest.version, userEspree.version)) {\n newest = userEspree\n }\n return newest\n}\n\nexport function getEcmaVersionIfUseEspree(\n parserOptions: ParserOptions,\n getDefault?: (defaultVer: number) => number,\n): number | undefined {\n if (parserOptions.parser != null && parserOptions.parser !== \"espree\") {\n return undefined\n }\n\n if (parserOptions.ecmaVersion === \"latest\") {\n return normalizeEcmaVersion(getLatestEcmaVersion(getNewestEspree()))\n }\n if (parserOptions.ecmaVersion == null) {\n const defVer = getDefaultEcmaVersion()\n return getDefault?.(defVer) ?? defVer\n }\n return normalizeEcmaVersion(parserOptions.ecmaVersion)\n}\n\nfunction getDefaultEcmaVersion(): number {\n if (lt(getEspreeFromLinter().version, \"9.0.0\")) {\n return 5\n }\n // Perhaps the version 9 will change the default to \"latest\".\n return normalizeEcmaVersion(getLatestEcmaVersion(getNewestEspree()))\n}\n\n/**\n * Normalize ECMAScript version\n */\nfunction normalizeEcmaVersion(version: number) {\n if (version > 5 && version < 2015) {\n return version + 2009\n }\n return version\n}\n\nfunction getLatestEcmaVersion(espree: Espree) {\n if (espree.latestEcmaVersion == null) {\n for (const { v, latest } of [\n { v: \"6.1.0\", latest: 2020 },\n { v: \"4.0.0\", latest: 2019 },\n ]) {\n if (lte(v, espree.version)) {\n return latest\n }\n }\n return 2018\n }\n return normalizeEcmaVersion(espree.latestEcmaVersion)\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport type * as escopeTypes from \"eslint-scope\"\nimport type { ParserOptions } from \"../common/parser-options\"\nimport type {\n ESLintIdentifier,\n ESLintProgram,\n Reference,\n Variable,\n} from \"../ast\"\nimport { getFallbackKeys } from \"../ast\"\nimport { getEslintScope } from \"../common/eslint-scope\"\nimport { getEcmaVersionIfUseEspree } from \"../common/espree\"\n\ntype ParserResult = {\n ast: ESLintProgram\n scopeManager?: escopeTypes.ScopeManager\n}\n\n/**\n * Check whether the given reference is unique in the belonging array.\n * @param reference The current reference to check.\n * @param index The index of the reference.\n * @param references The belonging array of the reference.\n */\nfunction isUnique(\n reference: escopeTypes.Reference,\n index: number,\n references: escopeTypes.Reference[],\n): boolean {\n return (\n index === 0 || reference.identifier !== references[index - 1].identifier\n )\n}\n\n/**\n * Check whether a given variable has that definition.\n * @param variable The variable to check.\n * @returns `true` if the variable has that definition.\n */\nfunction hasDefinition(variable: escopeTypes.Variable): boolean {\n return variable.defs.length >= 1\n}\n\n/**\n * Transform the given reference object.\n * @param reference The source reference object.\n * @returns The transformed reference object.\n */\nfunction transformReference(reference: escopeTypes.Reference): Reference {\n const ret: Reference = {\n id: reference.identifier as ESLintIdentifier,\n mode: reference.isReadOnly()\n ? \"r\"\n : reference.isWriteOnly()\n ? \"w\"\n : /* otherwise */ \"rw\",\n variable: null,\n isValueReference: reference.isValueReference,\n isTypeReference: reference.isTypeReference,\n }\n Object.defineProperty(ret, \"variable\", { enumerable: false })\n\n return ret\n}\n\n/**\n * Transform the given variable object.\n * @param variable The source variable object.\n * @returns The transformed variable object.\n */\nfunction transformVariable(\n variable: escopeTypes.Variable,\n kind: Variable[\"kind\"],\n): Variable {\n const ret: Variable = {\n id: variable.defs[0].name as ESLintIdentifier,\n kind,\n references: [],\n }\n Object.defineProperty(ret, \"references\", { enumerable: false })\n\n return ret\n}\n\n/**\n * Get the `for` statement scope.\n * @param scope The global scope.\n * @returns The `for` statement scope.\n */\nfunction getForScope(scope: escopeTypes.Scope): escopeTypes.Scope {\n const child = scope.childScopes[0]\n return child.block === scope.block ? child.childScopes[0] : child\n}\n\nexport function analyzeScope(\n ast: ESLintProgram,\n parserOptions: ParserOptions,\n): escopeTypes.ScopeManager {\n const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions) || 2022\n const ecmaFeatures = parserOptions.ecmaFeatures || {}\n const sourceType = parserOptions.sourceType || \"script\"\n const result = getEslintScope().analyze(ast, {\n ignoreEval: true,\n nodejsScope: false,\n impliedStrict: ecmaFeatures.impliedStrict,\n ecmaVersion,\n sourceType,\n fallback: getFallbackKeys,\n })\n\n return result\n}\n\n/**\n * Analyze the scope of the given AST.\n * @param {ParserResult} parserResult The parser result to analyze.\n * @param parserOptions\n */\nfunction analyze(\n parserResult: ParserResult,\n parserOptions: ParserOptions,\n): escopeTypes.Scope {\n const scopeManager =\n parserResult.scopeManager ||\n analyzeScope(parserResult.ast, parserOptions)\n return scopeManager.globalScope\n}\n\n/**\n * Analyze the external references of the given AST.\n * @param {ParserResult} parserResult The parser result to analyze.\n * @returns {Reference[]} The reference objects of external references.\n */\nexport function analyzeExternalReferences(\n parserResult: ParserResult,\n parserOptions: ParserOptions,\n): Reference[] {\n const scope = analyze(parserResult, parserOptions)\n return scope.through.filter(isUnique).map(transformReference)\n}\n\n/**\n * Analyze the external references of the given AST.\n * @param {ParserResult} parserResult The parser result to analyze.\n * @returns {Reference[]} The reference objects of external references.\n */\nexport function analyzeVariablesAndExternalReferences(\n parserResult: ParserResult,\n kind: Variable[\"kind\"],\n parserOptions: ParserOptions,\n): { variables: Variable[]; references: Reference[] } {\n const scope = analyze(parserResult, parserOptions)\n return {\n variables: getForScope(scope)\n .variables.filter(hasDefinition)\n .map((v) => transformVariable(v, kind)),\n references: scope.through.filter(isUnique).map(transformReference),\n }\n}\n","import type {\n ESLintExtendedProgram,\n ESLintNode,\n HasLocation,\n LocationRange,\n Node,\n ParseError,\n} from \"../ast\"\nimport { traverseNodes } from \"../ast\"\nimport type { LocationCalculator } from \"./location-calculator\"\n\n/**\n * Do post-process of parsing an expression.\n *\n * 1. Set `node.parent`.\n * 2. Fix `node.range` and `node.loc` for HTML entities.\n *\n * @param result The parsing result to modify.\n * @param locationCalculator The location calculator to modify.\n */\nexport function fixLocations(\n result: ESLintExtendedProgram,\n locationCalculator: LocationCalculator,\n): void {\n fixNodeLocations(result.ast, result.visitorKeys, locationCalculator)\n\n for (const token of result.ast.tokens || []) {\n fixLocation(token, locationCalculator)\n }\n for (const comment of result.ast.comments || []) {\n fixLocation(comment, locationCalculator)\n }\n}\n\nexport function fixNodeLocations(\n rootNode: ESLintNode,\n visitorKeys: ESLintExtendedProgram[\"visitorKeys\"],\n locationCalculator: LocationCalculator,\n): void {\n // There are cases which the same node instance appears twice in the tree.\n // E.g. `let {a} = {}` // This `a` appears twice at `Property#key` and `Property#value`.\n const traversed = new Map<Node | number[] | LocationRange, Node>()\n\n traverseNodes(rootNode, {\n visitorKeys,\n\n enterNode(node, parent) {\n if (!traversed.has(node)) {\n traversed.set(node, node)\n node.parent = parent\n\n // `babel-eslint@8` has shared `Node#range` with multiple nodes.\n // See also: https://github.com/vuejs/eslint-plugin-vue/issues/208\n if (traversed.has(node.range)) {\n if (!traversed.has(node.loc)) {\n // However, `Node#loc` may not be shared.\n // See also: https://github.com/vuejs/vue-eslint-parser/issues/84\n node.loc.start = locationCalculator.getLocFromIndex(\n node.range[0],\n )\n node.loc.end = locationCalculator.getLocFromIndex(\n node.range[1],\n )\n traversed.set(node.loc, node)\n } else if (node.start != null || node.end != null) {\n const traversedNode = traversed.get(node.range)!\n if (traversedNode.type === node.type) {\n node.start = traversedNode.start\n node.end = traversedNode.end\n }\n }\n } else {\n fixLocation(node, locationCalculator)\n traversed.set(node.range, node)\n traversed.set(node.loc, node)\n }\n }\n },\n\n leaveNode() {\n // Do nothing.\n },\n })\n}\n\n/**\n * Modify the location information of the given node with using the base offset and gaps of this calculator.\n * @param node The node to modify their location.\n */\nexport function fixLocation<T extends HasLocation>(\n node: T,\n locationCalculator: LocationCalculator,\n): T {\n const range = node.range\n const loc = node.loc\n const d0 = locationCalculator.getFixOffset(range[0], \"start\")\n const d1 = locationCalculator.getFixOffset(range[1], \"end\")\n\n if (d0 !== 0) {\n range[0] += d0\n if (node.start != null) {\n node.start += d0\n }\n loc.start = locationCalculator.getLocFromIndex(range[0])\n }\n if (d1 !== 0) {\n range[1] += d1\n if (node.end != null) {\n node.end += d0\n }\n loc.end = locationCalculator.getLocFromIndex(range[1])\n }\n\n return node\n}\n\n/**\n * Modify the location information of the given error with using the base offset and gaps of this calculator.\n * @param error The error to modify their location.\n */\nexport function fixErrorLocation(\n error: ParseError,\n locationCalculator: LocationCalculator,\n) {\n const diff = locationCalculator.getFixOffset(error.index, \"start\")\n\n error.index += diff\n\n const loc = locationCalculator.getLocFromIndex(error.index)\n error.lineNumber = loc.line\n error.column = loc.column\n}\n","import { lte } from \"semver\"\nimport { getEcmaVersionIfUseEspree, getEspreeFromUser } from \"../common/espree\"\nimport type { ParserOptions } from \"../common/parser-options\"\n\nexport const DEFAULT_ECMA_VERSION = 2017\n\n/**\n * Get parser options for <script setup>\n */\nexport function getScriptSetupParserOptions(\n parserOptions: ParserOptions,\n): ParserOptions {\n const espreeEcmaVersion = getEcmaVersionIfUseEspree(\n parserOptions,\n getDefaultEcmaVersion,\n )\n\n return {\n ...parserOptions,\n ecmaVersion: espreeEcmaVersion,\n }\n}\n\nfunction getDefaultEcmaVersion(def: number) {\n if (lte(\"8.0.0\", getEspreeFromUser().version)) {\n // Script setup requires top level await support, so default the ecma version to 2022.\n return getEspreeFromUser().latestEcmaVersion!\n }\n return Math.max(def, DEFAULT_ECMA_VERSION)\n}\n","import type {\n ESLintExtendedProgram,\n ESLintProgram,\n HasLocation,\n Token,\n VElement,\n VGenericExpression,\n} from \"../ast\"\n// eslint-disable-next-line node/no-extraneous-import -- ignore\nimport type { TSESTree } from \"@typescript-eslint/utils\"\nimport type {\n Reference,\n Scope,\n Variable,\n ScopeManager,\n VariableDefinition,\n} from \"eslint-scope\"\nimport { findGenericDirective } from \"../common/ast-utils\"\n\nexport type GenericProcessInfo = {\n node: VGenericExpression\n defineTypes: {\n node: VGenericExpression[\"params\"][number]\n define: string\n }[]\n postprocess: (context: GenericPostprocessContext) => void\n}\nexport type GenericPostprocessContext = {\n result: ESLintExtendedProgram\n getTypeBlock?: (node: ESLintProgram) => {\n body: ESLintProgram[\"body\"]\n }\n isRemoveTarget: (nodeOrToken: HasLocation) => boolean\n getTypeDefScope: (scopeManager: ScopeManager) => Scope\n}\nexport function extractGeneric(element: VElement): GenericProcessInfo | null {\n const genericAttr = findGenericDirective(element)\n if (!genericAttr) {\n return null\n }\n const genericNode = genericAttr.value.expression\n const defineTypes = genericNode.params.map((t, i) => ({\n node: t,\n define: `type ${t.name.name} = ${getConstraint(\n t,\n genericNode.rawParams[i],\n )}`,\n }))\n\n return {\n node: genericNode,\n defineTypes,\n postprocess({ result, getTypeBlock, isRemoveTarget, getTypeDefScope }) {\n const node = getTypeBlock?.(result.ast) ?? result.ast\n removeTypeDeclarations(node, isRemoveTarget)\n if (result.ast.tokens) {\n removeTypeDeclarationTokens(result.ast.tokens, isRemoveTarget)\n }\n if (result.ast.comments) {\n removeTypeDeclarationTokens(result.ast.comments, isRemoveTarget)\n }\n if (result.scopeManager) {\n const typeDefScope = getTypeDefScope(result.scopeManager)\n restoreScope(result.scopeManager, typeDefScope, isRemoveTarget)\n }\n },\n }\n\n function removeTypeDeclarations(\n node: {\n body: ESLintProgram[\"body\"]\n },\n isRemoveTarget: (nodeOrToken: HasLocation) => boolean,\n ) {\n for (let index = node.body.length - 1; index >= 0; index--) {\n if (isRemoveTarget(node.body[index])) {\n node.body.splice(index, 1)\n }\n }\n }\n\n function removeTypeDeclarationTokens(\n tokens: Token[],\n isRemoveTarget: (nodeOrToken: HasLocation) => boolean,\n ) {\n for (let index = tokens.length - 1; index >= 0; index--) {\n if (isRemoveTarget(tokens[index])) {\n tokens.splice(index, 1)\n }\n }\n }\n\n function restoreScope(\n scopeManager: ScopeManager,\n typeDefScope: Scope,\n isRemoveTarget: (nodeOrToken: HasLocation) => boolean,\n ) {\n for (const variable of [...typeDefScope.variables]) {\n let def = variable.defs.find((d) =>\n isRemoveTarget(d.name as HasLocation),\n )\n while (def) {\n removeVariableDef(variable, def, typeDefScope)\n def = variable.defs.find((d) =>\n isRemoveTarget(d.name as HasLocation),\n )\n }\n }\n for (const reference of [...typeDefScope.references]) {\n if (isRemoveTarget(reference.identifier as HasLocation)) {\n removeReference(reference, typeDefScope)\n }\n }\n\n for (const scope of [...scopeManager.scopes]) {\n if (isRemoveTarget(scope.block as HasLocation)) {\n removeScope(scopeManager, scope)\n }\n }\n }\n}\n\nfunction getConstraint(node: TSESTree.TSTypeParameter, rawParam: string) {\n if (!node.constraint) {\n return \"unknown\"\n }\n let index = rawParam.indexOf(node.name.name) + node.name.name.length\n let startIndex: number | null = null\n while (index < rawParam.length) {\n if (startIndex == null) {\n if (rawParam.startsWith(\"extends\", index)) {\n startIndex = index = index + 7\n continue\n }\n } else if (rawParam[index] === \"=\") {\n if (rawParam[index + 1] === \">\") {\n // Arrow function type\n index += 2\n continue\n }\n return rawParam.slice(startIndex, index)\n }\n if (rawParam.startsWith(\"//\", index)) {\n // Skip line comment\n const lfIndex = rawParam.indexOf(\"\\n\", index)\n if (lfIndex >= 0) {\n index = lfIndex + 1\n continue\n }\n return \"unknown\"\n }\n if (rawParam.startsWith(\"/*\", index)) {\n // Skip block comment\n const endIndex = rawParam.indexOf(\"*/\", index)\n if (endIndex >= 0) {\n index = endIndex + 2\n continue\n }\n return \"unknown\"\n }\n index++\n }\n if (startIndex == null) {\n return \"unknown\"\n }\n\n return rawParam.slice(startIndex)\n}\n\n/** Remove variable def */\nfunction removeVariableDef(\n variable: Variable,\n def: VariableDefinition,\n scope: Scope,\n): void {\n const defIndex = variable.defs.indexOf(def)\n if (defIndex < 0) {\n return\n }\n variable.defs.splice(defIndex, 1)\n if (variable.defs.length === 0) {\n // Remove variable\n referencesToThrough(variable.references, scope)\n variable.references.forEach((r) => {\n if ((r as any).init) {\n ;(r as any).init = false\n }\n r.resolved = null\n })\n scope.variables.splice(scope.variables.indexOf(variable), 1)\n const name = variable.name\n if (variable === scope.set.get(name)) {\n scope.set.delete(name)\n }\n } else {\n const idIndex = variable.identifiers.indexOf(def.name)\n if (idIndex >= 0) {\n variable.identifiers.splice(idIndex, 1)\n }\n }\n}\n\n/** Move reference to through */\nfunction referencesToThrough(references: Reference[], baseScope: Scope) {\n let scope: Scope | null = baseScope\n while (scope) {\n addAllReferences(scope.through, references)\n scope = scope.upper\n }\n}\n\n/**\n * Add all references to array\n */\nfunction addAllReferences(list: Reference[], elements: Reference[]): void {\n list.push(...elements)\n list.sort((a, b) => a.identifier.range![0] - b.identifier.range![0])\n}\n\n/** Remove reference */\nfunction removeReference(reference: Reference, baseScope: Scope): void {\n if (reference.resolved) {\n if (\n reference.resolved.defs.some((d) => d.name === reference.identifier)\n ) {\n // remove var\n const varIndex = baseScope.variables.indexOf(reference.resolved)\n if (varIndex >= 0) {\n baseScope.variables.splice(varIndex, 1)\n }\n const name = reference.identifier.name\n if (reference.resolved === baseScope.set.get(name)) {\n baseScope.set.delete(name)\n }\n } else {\n const refIndex = reference.resolved.references.indexOf(reference)\n if (refIndex >= 0) {\n reference.resolved.references.splice(refIndex, 1)\n }\n }\n }\n\n let scope: Scope | null = baseScope\n while (scope) {\n const refIndex = scope.references.indexOf(reference)\n if (refIndex >= 0) {\n scope.references.splice(refIndex, 1)\n }\n const throughIndex = scope.through.indexOf(reference)\n if (throughIndex >= 0) {\n scope.through.splice(throughIndex, 1)\n }\n scope = scope.upper\n }\n}\n\n/** Remove scope */\nfunction removeScope(scopeManager: ScopeManager, scope: Scope): void {\n for (const childScope of scope.childScopes) {\n removeScope(scopeManager, childScope)\n }\n\n while (scope.references[0]) {\n removeReference(scope.references[0], scope)\n }\n const upper = scope.upper\n if (upper) {\n const index = upper.childScopes.indexOf(scope)\n if (index >= 0) {\n upper.childScopes.splice(index, 1)\n }\n }\n const index = scopeManager.scopes.indexOf(scope)\n if (index >= 0) {\n scopeManager.scopes.splice(index, 1)\n }\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport first from \"lodash/first\"\nimport last from \"lodash/last\"\nimport sortedIndexBy from \"lodash/sortedIndexBy\"\nimport type {\n ESLintArrayExpression,\n ESLintArrayPattern,\n ESLintCallExpression,\n ESLintExpression,\n ESLintExpressionStatement,\n ESLintExtendedProgram,\n ESLintForInStatement,\n ESLintForOfStatement,\n ESLintFunctionExpression,\n ESLintIdentifier,\n ESLintUnaryExpression,\n ESLintVariableDeclaration,\n HasLocation,\n Node,\n Reference,\n Token,\n Variable,\n VElement,\n VFilter,\n VFilterSequenceExpression,\n VForExpression,\n VOnExpression,\n VSlotScopeExpression,\n OffsetRange,\n VGenericExpression,\n} from \"../ast\"\nimport { ParseError } from \"../ast\"\nimport { debug } from \"../common/debug\"\nimport type {\n LocationCalculator,\n LocationCalculatorForHtml,\n} from \"../common/location-calculator\"\nimport {\n analyzeExternalReferences,\n analyzeVariablesAndExternalReferences,\n} from \"./scope-analyzer\"\nimport {\n getEcmaVersionIfUseEspree,\n getEspreeFromUser,\n getEspreeFromEcmaVersion,\n} from \"../common/espree\"\nimport type { ParserOptions } from \"../common/parser-options\"\nimport {\n fixErrorLocation,\n fixLocation,\n fixLocations,\n} from \"../common/fix-locations\"\nimport {\n DEFAULT_ECMA_VERSION,\n getScriptSetupParserOptions,\n} from \"../script-setup/parser-options\"\nimport { isScriptSetupElement } from \"../common/ast-utils\"\nimport type { LinesAndColumns } from \"../common/lines-and-columns\"\nimport type { ParserObject } from \"../common/parser-object\"\nimport { isEnhancedParserObject, isParserObject } from \"../common/parser-object\"\n// eslint-disable-next-line node/no-extraneous-import -- ignore\nimport type { TSESTree } from \"@typescript-eslint/utils\"\nimport type { GenericProcessInfo } from \"./generic\"\nimport { extractGeneric } from \"./generic\"\n\n// [1] = aliases.\n// [2] = delimiter.\n// [3] = iterator.\nconst ALIAS_ITERATOR = /^([\\s\\S]*?(?:\\s|\\)))(\\bin\\b|\\bof\\b)([\\s\\S]*)$/u\nconst PARENS = /^(\\s*\\()([\\s\\S]*?)(\\)\\s*)$/u\nconst DUMMY_PARENT: any = {}\n\n// Like Vue, it judges whether it is a function expression or not.\n// https://github.com/vuejs/core/blob/fef2acb2049fce3407dff17fe8af1836b97dfd73/packages/compiler-core/src/transforms/vOn.ts#L19\nconst IS_FUNCTION_EXPRESSION =\n /^\\s*([\\w$_]+|(async\\s*)?\\([^)]*?\\))\\s*(:[^=]+)?=>|^\\s*(async\\s+)?function(?:\\s+[\\w$]+)?\\s*\\(/u\n// ^^^^^^^ omit paren argument ^^^^^^^^ function keyword\n// ^^^^^ <--- async keyword (optional) ---> ^^^^^\n// ^^------^^ arguments with parens ^^^^^^ named function (optional)\n// ^^^^^^^^^ return types (optional)\n// ^^ arrow ^^ opening paren\n\nconst IS_SIMPLE_PATH =\n /^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*|\\['[^']*?'\\]|\\[\"[^\"]*?\"\\]|\\[\\d+\\]|\\[[A-Za-z_$][\\w$]*\\])*$/u\n\n/**\n * Parse the alias and iterator of 'v-for' directive values.\n * @param code The code to parse.\n * @returns The parsed result.\n */\nfunction processVForAliasAndIterator(code: string): {\n aliases: string\n hasParens: boolean\n delimiter: string\n iterator: string\n aliasesWithBrackets: string\n} {\n const match = ALIAS_ITERATOR.exec(code)\n if (match != null) {\n const aliases = match[1]\n const parenMatch = PARENS.exec(aliases)\n return {\n aliases,\n hasParens: Boolean(parenMatch),\n aliasesWithBrackets: parenMatch\n ? `${parenMatch[1].slice(0, -1)}[${\n parenMatch[2]\n }]${parenMatch[3].slice(1)}`\n : `[${aliases.slice(0, -1)}]`,\n delimiter: match[2] || \"\",\n iterator: match[3],\n }\n }\n return {\n aliases: \"\",\n hasParens: false,\n aliasesWithBrackets: \"\",\n delimiter: \"\",\n iterator: code,\n }\n}\n\n/**\n * Get the comma token before a given node.\n * @param tokens The token list.\n * @param node The node to get the comma before this node.\n * @returns The comma token.\n */\nfunction getCommaTokenBeforeNode(tokens: Token[], node: Node): Token | null {\n let tokenIndex = sortedIndexBy(\n tokens as { range: OffsetRange }[],\n { range: node.range },\n (t) => t.range[0],\n )\n\n while (tokenIndex >= 0) {\n const token = tokens[tokenIndex]\n if (token.type === \"Punctuator\" && token.value === \",\") {\n return token\n }\n tokenIndex -= 1\n }\n\n return null\n}\n\n/**\n * Throw syntax error for empty.\n * @param locationCalculator The location calculator to get line/column.\n */\nfunction throwEmptyError(\n locationCalculator: LocationCalculatorForHtml,\n expected: string,\n): never {\n const loc = locationCalculator.getLocation(0)\n const err = new ParseError(\n `Expected to be ${expected}, but got empty.`,\n undefined,\n 0,\n loc.line,\n loc.column,\n )\n fixErrorLocation(err, locationCalculator)\n\n throw err\n}\n\n/**\n * Throw syntax error for unexpected token.\n * @param locationCalculator The location calculator to get line/column.\n * @param name The token name.\n * @param token The token object to get that location.\n */\nfunction throwUnexpectedTokenError(name: string, token: HasLocation): never {\n const err = new ParseError(\n `Unexpected token '${name}'.`,\n undefined,\n token.range[0],\n token.loc.start.line,\n token.loc.start.column,\n )\n\n throw err\n}\n\n/**\n * Throw syntax error of outside of code.\n * @param locationCalculator The location calculator to get line/column.\n */\nfunction throwErrorAsAdjustingOutsideOfCode(\n err: any,\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n): never {\n if (ParseError.isParseError(err)) {\n const endOffset = locationCalculator.getOffsetWithGap(code.length)\n if (err.index >= endOffset) {\n err.message = \"Unexpected end of expression.\"\n }\n }\n\n throw err\n}\n\n/**\n * Parse the given source code.\n *\n * @param code The source code to parse.\n * @param locationCalculator The location calculator for fixLocations.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseScriptFragment(\n code: string,\n locationCalculator: LocationCalculator,\n parserOptions: ParserOptions,\n): ESLintExtendedProgram {\n return parseScriptFragmentWithOption(\n code,\n locationCalculator,\n parserOptions,\n )\n}\n\n/**\n * Parse the given source code.\n *\n * @param code The source code to parse.\n * @param locationCalculator The location calculator for fixLocations.\n * @param parserOptions The parser options.\n * @param processOptions The process options.\n * @returns The result of parsing.\n */\nfunction parseScriptFragmentWithOption(\n code: string,\n locationCalculator: LocationCalculator,\n parserOptions: ParserOptions,\n processOptions?: {\n preFixLocationProcess?: (result: ESLintExtendedProgram) => void\n },\n): ESLintExtendedProgram {\n try {\n const result = parseScript(code, parserOptions)\n processOptions?.preFixLocationProcess?.(result)\n fixLocations(result, locationCalculator)\n return result\n } catch (err) {\n const perr = ParseError.normalize(err)\n if (perr) {\n fixErrorLocation(perr, locationCalculator)\n throw perr\n }\n throw err\n }\n}\n\nconst validDivisionCharRE = /[\\w).+\\-_$\\]]/u\n\n/**\n * This is a fork of https://github.com/vuejs/vue/blob/2686818beb5728e3b7aa22f47a3b3f0d39d90c8e/src/compiler/parser/filter-parser.js\n * @param exp the expression to process filters.\n */\n//eslint-disable-next-line complexity\nfunction splitFilters(exp: string): string[] {\n const result: string[] = []\n let inSingle = false\n let inDouble = false\n let inTemplateString = false\n let inRegex = false\n let curly = 0\n let square = 0\n let paren = 0\n let lastFilterIndex = 0\n let c = 0\n let prev = 0\n\n for (let i = 0; i < exp.length; i++) {\n prev = c\n c = exp.charCodeAt(i)\n if (inSingle) {\n if (c === 0x27 && prev !== 0x5c) {\n inSingle = false\n }\n } else if (inDouble) {\n if (c === 0x22 && prev !== 0x5c) {\n inDouble = false\n }\n } else if (inTemplateString) {\n if (c === 0x60 && prev !== 0x5c) {\n inTemplateString = false\n }\n } else if (inRegex) {\n if (c === 0x2f && prev !== 0x5c) {\n inRegex = false\n }\n } else if (\n c === 0x7c && // pipe\n exp.charCodeAt(i + 1) !== 0x7c &&\n exp.charCodeAt(i - 1) !== 0x7c &&\n !curly &&\n !square &&\n !paren\n ) {\n result.push(exp.slice(lastFilterIndex, i))\n lastFilterIndex = i + 1\n } else {\n switch (c) {\n case 0x22: // \"\n inDouble = true\n break\n case 0x27: // '\n inSingle = true\n break\n case 0x60: // `\n inTemplateString = true\n break\n case 0x28: // (\n paren++\n break\n case 0x29: // )\n paren--\n break\n case 0x5b: // [\n square++\n break\n case 0x5d: // ]\n square--\n break\n case 0x7b: // {\n curly++\n break\n case 0x7d: // }\n curly--\n break\n // no default\n }\n if (c === 0x2f) {\n // /\n let j = i - 1\n let p\n // find first non-whitespace prev char\n for (; j >= 0; j--) {\n p = exp.charAt(j)\n if (p !== \" \") {\n break\n }\n }\n if (!p || !validDivisionCharRE.test(p)) {\n inRegex = true\n }\n }\n }\n }\n\n result.push(exp.slice(lastFilterIndex))\n\n return result\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nfunction parseExpressionBody(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n allowEmpty = false,\n): ExpressionParseResult<ESLintExpression> {\n debug('[script] parse expression: \"0(%s)\"', code)\n\n try {\n const result = parseScriptFragment(\n `0(${code})`,\n locationCalculator.getSubCalculatorShift(-2),\n parserOptions,\n )\n const { ast } = result\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const references = analyzeExternalReferences(result, parserOptions)\n const statement = ast.body[0] as ESLintExpressionStatement\n const callExpression = statement.expression as ESLintCallExpression\n const expression = callExpression.arguments[0]\n\n if (!allowEmpty && !expression) {\n return throwEmptyError(locationCalculator, \"an expression\")\n }\n if (expression && expression.type === \"SpreadElement\") {\n return throwUnexpectedTokenError(\"...\", expression)\n }\n if (callExpression.arguments[1]) {\n const node = callExpression.arguments[1]\n return throwUnexpectedTokenError(\n \",\",\n getCommaTokenBeforeNode(tokens, node) || node,\n )\n }\n\n // Remove parens.\n tokens.shift()\n tokens.shift()\n tokens.pop()\n\n return { expression, tokens, comments, references, variables: [] }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nfunction parseFilter(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VFilter> | null {\n debug('[script] parse filter: \"%s\"', code)\n\n try {\n const expression: VFilter = {\n type: \"VFilter\",\n parent: null as any,\n range: [0, 0],\n loc: {} as any,\n callee: null as any,\n arguments: [],\n }\n const tokens: Token[] = []\n const comments: Token[] = []\n const references: Reference[] = []\n\n // Parse the callee.\n const paren = code.indexOf(\"(\")\n const calleeCode = paren === -1 ? code : code.slice(0, paren)\n const argsCode = paren === -1 ? null : code.slice(paren)\n\n // Parse the callee.\n if (calleeCode.trim()) {\n const spaces = /^\\s*/u.exec(calleeCode)![0]\n const subCalculator = locationCalculator.getSubCalculatorShift(\n spaces.length,\n )\n const { ast } = parseScriptFragment(\n `\"${calleeCode.trim()}\"`,\n subCalculator,\n parserOptions,\n )\n const statement = ast.body[0] as ESLintExpressionStatement\n const callee = statement.expression\n if (callee.type !== \"Literal\") {\n const { loc, range } = ast.tokens![0]\n return throwUnexpectedTokenError('\"', {\n range: [range[1] - 1, range[1]],\n loc: {\n start: {\n line: loc.end.line,\n column: loc.end.column - 1,\n },\n end: loc.end,\n },\n })\n }\n\n expression.callee = {\n type: \"Identifier\",\n parent: expression,\n range: [\n callee.range[0],\n subCalculator.getOffsetWithGap(calleeCode.trim().length),\n ],\n loc: {\n start: callee.loc.start,\n end: subCalculator.getLocation(calleeCode.trim().length),\n },\n name: String(callee.value),\n }\n tokens.push({\n type: \"Identifier\",\n value: calleeCode.trim(),\n range: expression.callee.range,\n loc: expression.callee.loc,\n })\n } else {\n return throwEmptyError(locationCalculator, \"a filter name\")\n }\n\n // Parse the arguments.\n if (argsCode != null) {\n const result = parseScriptFragment(\n `0${argsCode}`,\n locationCalculator\n .getSubCalculatorAfter(paren)\n .getSubCalculatorShift(-1),\n parserOptions,\n )\n const { ast } = result\n const statement = ast.body[0] as ESLintExpressionStatement\n const callExpression = statement.expression\n\n ast.tokens!.shift()\n\n if (\n callExpression.type !== \"CallExpression\" ||\n callExpression.callee.type !== \"Literal\"\n ) {\n // Report the next token of `)`.\n let nestCount = 1\n for (const token of ast.tokens!.slice(1)) {\n if (nestCount === 0) {\n return throwUnexpectedTokenError(token.value, token)\n }\n if (token.type === \"Punctuator\" && token.value === \"(\") {\n nestCount += 1\n }\n if (token.type === \"Punctuator\" && token.value === \")\") {\n nestCount -= 1\n }\n }\n\n const token = last(ast.tokens)!\n return throwUnexpectedTokenError(token.value, token)\n }\n\n for (const argument of callExpression.arguments) {\n argument.parent = expression\n expression.arguments.push(argument)\n }\n tokens.push(...ast.tokens!)\n comments.push(...ast.comments!)\n references.push(...analyzeExternalReferences(result, parserOptions))\n }\n\n // Update range.\n const firstToken = tokens[0]\n const lastToken = last(tokens)!\n expression.range = [firstToken.range[0], lastToken.range[1]]\n expression.loc = { start: firstToken.loc.start, end: lastToken.loc.end }\n\n return { expression, tokens, comments, references, variables: [] }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\n/**\n * The result of parsing expressions.\n */\nexport interface ExpressionParseResult<T extends Node> {\n expression: T | null\n tokens: Token[]\n comments: Token[]\n references: Reference[]\n variables: Variable[]\n}\n\nfunction loadParser(parser: string) {\n if (parser !== \"espree\") {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return require(parser)\n }\n return getEspreeFromUser()\n}\n\n/**\n * Parse the given source code.\n *\n * @param code The source code to parse.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseScript(\n code: string,\n parserOptions: ParserOptions,\n): ESLintExtendedProgram {\n const parser: ParserObject =\n typeof parserOptions.parser === \"string\"\n ? loadParser(parserOptions.parser)\n : isParserObject(parserOptions.parser)\n ? parserOptions.parser\n : getEspreeFromEcmaVersion(parserOptions.ecmaVersion)\n\n const result: any = isEnhancedParserObject(parser)\n ? parser.parseForESLint(code, parserOptions)\n : parser.parse(code, parserOptions)\n\n if (result.ast != null) {\n return result\n }\n return { ast: result }\n}\n\n/**\n * Parse the source code of the given `<script>` element.\n * @param node The `<script>` element to parse.\n * @param sfcCode The source code of SFC.\n * @param linesAndColumns The lines and columns location calculator.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseScriptElement(\n node: VElement,\n sfcCode: string,\n linesAndColumns: LinesAndColumns,\n originalParserOptions: ParserOptions,\n): ESLintExtendedProgram {\n const parserOptions: ParserOptions = isScriptSetupElement(node)\n ? getScriptSetupParserOptions(originalParserOptions)\n : {\n ...originalParserOptions,\n ecmaVersion:\n originalParserOptions.ecmaVersion || DEFAULT_ECMA_VERSION,\n }\n\n let generic: GenericProcessInfo | null = null\n let code: string\n let offset: number\n const textNode = node.children[0]\n if (textNode != null && textNode.type === \"VText\") {\n const [scriptStartOffset, scriptEndOffset] = textNode.range\n code = sfcCode.slice(scriptStartOffset, scriptEndOffset)\n offset = scriptStartOffset\n generic = extractGeneric(node)\n if (generic) {\n const defineTypesCode = `${generic.defineTypes\n .map((e) => e.define)\n .join(\";\")};\\n`\n code = defineTypesCode + code\n offset -= defineTypesCode.length\n }\n } else {\n code = \"\"\n offset = node.startTag.range[1]\n }\n const locationCalculator =\n linesAndColumns.createOffsetLocationCalculator(offset)\n const result = parseScriptFragment(code, locationCalculator, parserOptions)\n if (generic) {\n generic.postprocess({\n result,\n isRemoveTarget(nodeOrToken) {\n return nodeOrToken.range[1] <= textNode.range[0]\n },\n getTypeDefScope(scopeManager) {\n return (\n scopeManager.globalScope.childScopes.find(\n (s) => s.type === \"module\",\n ) ?? scopeManager.globalScope\n )\n },\n })\n const startToken = [\n result.ast.body[0],\n result.ast.tokens?.[0],\n result.ast.comments?.[0],\n ]\n .filter((e): e is NonNullable<typeof e> => Boolean(e))\n .sort((a, b) => a.range[0] - b.range[0])\n .find((t) => Boolean(t))\n\n // Restore Program node location\n if (startToken && result.ast.range[0] !== startToken.range[0]) {\n result.ast.range[0] = startToken.range[0]\n if (result.ast.start != null) {\n result.ast.start = startToken.start\n }\n result.ast.loc.start = { ...startToken.loc.start }\n }\n }\n // Needs the tokens of start/end tags for `lines-around-*` rules to work\n // correctly.\n if (result.ast.tokens != null) {\n const startTag = node.startTag\n const endTag = node.endTag\n\n result.ast.tokens.unshift({\n type: \"Punctuator\",\n range: startTag.range,\n loc: startTag.loc,\n value: \"<script>\",\n })\n if (endTag != null) {\n result.ast.tokens.push({\n type: \"Punctuator\",\n range: endTag.range,\n loc: endTag.loc,\n value: \"</script>\",\n })\n }\n }\n\n return result\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseExpression(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n { allowEmpty = false, allowFilters = false } = {},\n): ExpressionParseResult<ESLintExpression | VFilterSequenceExpression> {\n debug('[script] parse expression: \"%s\"', code)\n\n const [mainCode, ...filterCodes] =\n allowFilters && (parserOptions.vueFeatures?.filter ?? true)\n ? splitFilters(code)\n : [code]\n if (filterCodes.length === 0) {\n return parseExpressionBody(\n code,\n locationCalculator,\n parserOptions,\n allowEmpty,\n )\n }\n\n // Parse expression\n const retB = parseExpressionBody(\n mainCode,\n locationCalculator,\n parserOptions,\n )\n if (!retB.expression) {\n return retB\n }\n const ret =\n retB as unknown as ExpressionParseResult<VFilterSequenceExpression>\n\n ret.expression = {\n type: \"VFilterSequenceExpression\",\n parent: null as any,\n expression: retB.expression,\n filters: [],\n range: retB.expression.range.slice(0) as [number, number],\n loc: Object.assign({}, retB.expression.loc),\n }\n ret.expression.expression.parent = ret.expression\n\n // Parse filters\n let prevLoc = mainCode.length\n for (const filterCode of filterCodes) {\n // Pipe token.\n ret.tokens.push(\n fixLocation(\n {\n type: \"Punctuator\",\n value: \"|\",\n range: [prevLoc, prevLoc + 1],\n loc: {} as any,\n },\n locationCalculator,\n ),\n )\n\n // Parse a filter\n const retF = parseFilter(\n filterCode,\n locationCalculator.getSubCalculatorShift(prevLoc + 1),\n parserOptions,\n )\n if (retF) {\n if (retF.expression) {\n ret.expression.filters.push(retF.expression)\n retF.expression.parent = ret.expression\n }\n ret.tokens.push(...retF.tokens)\n ret.comments.push(...retF.comments)\n ret.references.push(...retF.references)\n }\n\n prevLoc += 1 + filterCode.length\n }\n\n // Update range.\n const lastToken = last(ret.tokens)!\n ret.expression.range[1] = lastToken.range[1]\n ret.expression.loc.end = lastToken.loc.end\n\n return ret\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\n// eslint-disable-next-line complexity\nexport function parseVForExpression(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VForExpression> {\n if (code.trim() === \"\") {\n throwEmptyError(locationCalculator, \"'<alias> in <expression>'\")\n }\n\n if (isEcmaVersion5(parserOptions)) {\n return parseVForExpressionForEcmaVersion5(\n code,\n locationCalculator,\n parserOptions,\n )\n }\n const processed = processVForAliasAndIterator(code)\n\n if (!processed.aliases.trim()) {\n return throwEmptyError(locationCalculator, \"an alias\")\n }\n try {\n debug(\n '[script] parse v-for expression: \"for(%s%s%s);\"',\n processed.aliasesWithBrackets,\n processed.delimiter,\n processed.iterator,\n )\n\n const result = parseScriptFragment(\n `for(let ${processed.aliasesWithBrackets}${processed.delimiter}${processed.iterator});`,\n locationCalculator.getSubCalculatorShift(\n processed.hasParens ? -8 : -9,\n ),\n parserOptions,\n )\n const { ast } = result\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const scope = analyzeVariablesAndExternalReferences(\n result,\n \"v-for\",\n parserOptions,\n )\n const references = scope.references\n const variables = scope.variables\n const statement = ast.body[0] as\n | ESLintForInStatement\n | ESLintForOfStatement\n const varDecl = statement.left as ESLintVariableDeclaration\n const id = varDecl.declarations[0].id as ESLintArrayPattern\n const left = id.elements\n const right = statement.right\n\n if (!processed.hasParens && !left.length) {\n return throwEmptyError(locationCalculator, \"an alias\")\n }\n // Remove `for` `(` `let` `)` `;`.\n tokens.shift()\n tokens.shift()\n tokens.shift()\n tokens.pop()\n tokens.pop()\n\n const closeOffset = statement.left.range[1] - 1\n const closeIndex = tokens.findIndex((t) => t.range[0] === closeOffset)\n\n if (processed.hasParens) {\n // Restore parentheses from array brackets.\n const open = tokens[0]\n if (open != null) {\n open.value = \"(\"\n }\n const close = tokens[closeIndex]\n if (close != null) {\n close.value = \")\"\n }\n } else {\n // Remove array brackets.\n tokens.splice(closeIndex, 1)\n tokens.shift()\n }\n const firstToken = tokens[0] || statement.left\n const lastToken = tokens[tokens.length - 1] || statement.right\n const expression: VForExpression = {\n type: \"VForExpression\",\n range: [firstToken.range[0], lastToken.range[1]],\n loc: { start: firstToken.loc.start, end: lastToken.loc.end },\n parent: DUMMY_PARENT,\n left,\n right,\n }\n\n // Modify parent.\n for (const l of left) {\n if (l != null) {\n l.parent = expression\n }\n }\n right.parent = expression\n\n return { expression, tokens, comments, references, variables }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\nfunction isEcmaVersion5(parserOptions: ParserOptions) {\n const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions)\n return ecmaVersion != null && ecmaVersion <= 5\n}\n\nfunction parseVForExpressionForEcmaVersion5(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VForExpression> {\n const processed = processVForAliasAndIterator(code)\n\n if (!processed.aliases.trim()) {\n return throwEmptyError(locationCalculator, \"an alias\")\n }\n try {\n const tokens: Token[] = []\n const comments: Token[] = []\n\n const parsedAliases = parseVForAliasesForEcmaVersion5(\n processed.aliasesWithBrackets,\n locationCalculator.getSubCalculatorShift(\n processed.hasParens ? 0 : -1,\n ),\n parserOptions,\n )\n\n if (processed.hasParens) {\n // Restore parentheses from array brackets.\n const open = parsedAliases.tokens[0]\n if (open != null) {\n open.value = \"(\"\n }\n const close = last(parsedAliases.tokens)\n if (close != null) {\n close.value = \")\"\n }\n } else {\n // Remove array brackets.\n parsedAliases.tokens.shift()\n parsedAliases.tokens.pop()\n }\n tokens.push(...parsedAliases.tokens)\n comments.push(...parsedAliases.comments)\n const { left, variables } = parsedAliases\n\n if (!processed.hasParens && !left.length) {\n return throwEmptyError(locationCalculator, \"an alias\")\n }\n\n const delimiterStart = processed.aliases.length\n const delimiterEnd = delimiterStart + processed.delimiter.length\n tokens.push(\n fixLocation(\n {\n type:\n processed.delimiter === \"in\" ? \"Keyword\" : \"Identifier\",\n value: processed.delimiter,\n start: delimiterStart,\n end: delimiterEnd,\n loc: {} as any,\n range: [delimiterStart, delimiterEnd],\n } as Token,\n locationCalculator,\n ),\n )\n\n const parsedIterator = parseVForIteratorForEcmaVersion5(\n processed.iterator,\n locationCalculator.getSubCalculatorShift(delimiterEnd),\n parserOptions,\n )\n\n tokens.push(...parsedIterator.tokens)\n comments.push(...parsedIterator.comments)\n const { right, references } = parsedIterator\n const firstToken = tokens[0]\n const lastToken = last(tokens) || firstToken\n const expression: VForExpression = {\n type: \"VForExpression\",\n range: [firstToken.range[0], lastToken.range[1]],\n loc: { start: firstToken.loc.start, end: lastToken.loc.end },\n parent: DUMMY_PARENT,\n left,\n right,\n }\n\n // Modify parent.\n for (const l of left) {\n if (l != null) {\n l.parent = expression\n }\n }\n right.parent = expression\n\n return { expression, tokens, comments, references, variables }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\nfunction parseVForAliasesForEcmaVersion5(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n) {\n const result = parseScriptFragment(\n `0(${code})`,\n locationCalculator.getSubCalculatorShift(-2),\n parserOptions,\n )\n const { ast } = result\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const variables = analyzeExternalReferences(result, parserOptions).map(\n transformVariable,\n )\n\n const statement = ast.body[0] as ESLintExpressionStatement\n const callExpression = statement.expression as ESLintCallExpression\n const expression = callExpression.arguments[0] as ESLintArrayExpression\n\n const left: ESLintIdentifier[] = expression.elements.filter(\n (e): e is ESLintIdentifier => {\n if (e == null || e.type === \"Identifier\") {\n return true\n }\n const errorToken = tokens.find(\n (t) => e.range[0] <= t.range[0] && t.range[1] <= e.range[1],\n )!\n return throwUnexpectedTokenError(errorToken.value, errorToken)\n },\n )\n // Remove parens.\n tokens.shift()\n tokens.shift()\n tokens.pop()\n\n return { left, tokens, comments, variables }\n\n function transformVariable(reference: Reference): Variable {\n const ret: Variable = {\n id: reference.id,\n kind: \"v-for\",\n references: [],\n }\n Object.defineProperty(ret, \"references\", { enumerable: false })\n\n return ret\n }\n}\n\nfunction parseVForIteratorForEcmaVersion5(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n) {\n const result = parseScriptFragment(\n `0(${code})`,\n locationCalculator.getSubCalculatorShift(-2),\n parserOptions,\n )\n const { ast } = result\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const references = analyzeExternalReferences(result, parserOptions)\n\n const statement = ast.body[0] as ESLintExpressionStatement\n const callExpression = statement.expression as ESLintCallExpression\n const expression = callExpression.arguments[0]\n\n if (!expression) {\n return throwEmptyError(locationCalculator, \"an expression\")\n }\n if (expression && expression.type === \"SpreadElement\") {\n return throwUnexpectedTokenError(\"...\", expression)\n }\n const right = expression\n\n // Remove parens.\n tokens.shift()\n tokens.shift()\n tokens.pop()\n return { right, tokens, comments, references }\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseVOnExpression(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<ESLintExpression | VOnExpression> {\n if (IS_FUNCTION_EXPRESSION.test(code) || IS_SIMPLE_PATH.test(code)) {\n return parseExpressionBody(code, locationCalculator, parserOptions)\n }\n return parseVOnExpressionBody(code, locationCalculator, parserOptions)\n}\n\n/**\n * Parse the source code of inline scripts.\n * @param code The source code of inline scripts.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nfunction parseVOnExpressionBody(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VOnExpression> {\n debug('[script] parse v-on expression: \"void function($event){%s}\"', code)\n\n if (code.trim() === \"\") {\n throwEmptyError(locationCalculator, \"statements\")\n }\n\n try {\n const result = parseScriptFragment(\n `void function($event){${code}}`,\n locationCalculator.getSubCalculatorShift(-22),\n parserOptions,\n )\n const { ast } = result\n const references = analyzeExternalReferences(result, parserOptions)\n const outermostStatement = ast.body[0] as ESLintExpressionStatement\n const functionDecl = (\n outermostStatement.expression as ESLintUnaryExpression\n ).argument as ESLintFunctionExpression\n const block = functionDecl.body\n const body = block.body\n const firstStatement = first(body)\n const lastStatement = last(body)\n const expression: VOnExpression = {\n type: \"VOnExpression\",\n range: [\n firstStatement != null\n ? firstStatement.range[0]\n : block.range[0] + 1,\n lastStatement != null\n ? lastStatement.range[1]\n : block.range[1] - 1,\n ],\n loc: {\n start:\n firstStatement != null\n ? firstStatement.loc.start\n : locationCalculator.getLocation(1),\n end:\n lastStatement != null\n ? lastStatement.loc.end\n : locationCalculator.getLocation(code.length + 1),\n },\n parent: DUMMY_PARENT,\n body,\n }\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n\n // Modify parent.\n for (const b of body) {\n b.parent = expression\n }\n\n // Remove braces.\n tokens.splice(0, 6)\n tokens.pop()\n\n return { expression, tokens, comments, references, variables: [] }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\n/**\n * Parse the source code of `slot-scope` directive.\n * @param code The source code of `slot-scope` directive.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseSlotScopeExpression(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VSlotScopeExpression> {\n debug('[script] parse slot-scope expression: \"void function(%s) {}\"', code)\n\n if (code.trim() === \"\") {\n throwEmptyError(\n locationCalculator,\n \"an identifier or an array/object pattern\",\n )\n }\n\n try {\n const result = parseScriptFragment(\n `void function(${code}) {}`,\n locationCalculator.getSubCalculatorShift(-14),\n parserOptions,\n )\n const { ast } = result\n const statement = ast.body[0] as ESLintExpressionStatement\n const rawExpression = statement.expression as ESLintUnaryExpression\n const functionDecl = rawExpression.argument as ESLintFunctionExpression\n const params = functionDecl.params\n\n if (params.length === 0) {\n return {\n expression: null,\n tokens: [],\n comments: [],\n references: [],\n variables: [],\n }\n }\n\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const scope = analyzeVariablesAndExternalReferences(\n result,\n \"scope\",\n parserOptions,\n )\n const references = scope.references\n const variables = scope.variables\n const firstParam = first(params)!\n const lastParam = last(params)!\n const expression: VSlotScopeExpression = {\n type: \"VSlotScopeExpression\",\n range: [firstParam.range[0], lastParam.range[1]],\n loc: { start: firstParam.loc.start, end: lastParam.loc.end },\n parent: DUMMY_PARENT,\n params: functionDecl.params,\n }\n\n // Modify parent.\n for (const param of params) {\n param.parent = expression\n }\n\n // Remove `void` `function` `(` `)` `{` `}`.\n tokens.shift()\n tokens.shift()\n tokens.shift()\n tokens.pop()\n tokens.pop()\n tokens.pop()\n\n return { expression, tokens, comments, references, variables }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n\n/**\n * Parse the source code of `generic` directive.\n * @param code The source code of `generic` directive.\n * @param locationCalculator The location calculator for the inline script.\n * @param parserOptions The parser options.\n * @returns The result of parsing.\n */\nexport function parseGenericExpression(\n code: string,\n locationCalculator: LocationCalculatorForHtml,\n parserOptions: ParserOptions,\n): ExpressionParseResult<VGenericExpression> {\n debug('[script] parse generic definition: \"void function<%s>() {}\"', code)\n\n if (code.trim() === \"\") {\n throwEmptyError(locationCalculator, \"a type parameter\")\n }\n\n function getParams(result: ESLintExtendedProgram) {\n const { ast } = result\n const statement = ast.body[0] as ESLintExpressionStatement\n const rawExpression = statement.expression as ESLintUnaryExpression\n const classDecl = rawExpression.argument as ESLintFunctionExpression\n const typeParameters = (classDecl as TSESTree.FunctionExpression)\n .typeParameters\n return typeParameters?.params\n }\n\n try {\n const rawParams: string[] = []\n const scriptLet = `void function<${code}>(){}`\n const result = parseScriptFragmentWithOption(\n scriptLet,\n locationCalculator.getSubCalculatorShift(-14),\n { ...parserOptions, project: undefined },\n {\n preFixLocationProcess(preResult) {\n const params = getParams(preResult)\n if (params) {\n for (const param of params) {\n rawParams.push(\n scriptLet.slice(param.range[0], param.range[1]),\n )\n }\n }\n },\n },\n )\n const { ast } = result\n const params = getParams(result)\n\n if (!params || params.length === 0) {\n return {\n expression: null,\n tokens: [],\n comments: [],\n references: [],\n variables: [],\n }\n }\n\n const tokens = ast.tokens || []\n const comments = ast.comments || []\n const scope = analyzeVariablesAndExternalReferences(\n result,\n \"generic\",\n parserOptions,\n )\n const references = scope.references\n const variables = scope.variables\n const firstParam = first(params)!\n const lastParam = last(params)!\n const expression: VGenericExpression = {\n type: \"VGenericExpression\",\n range: [firstParam.range[0], lastParam.range[1]],\n loc: { start: firstParam.loc.start, end: lastParam.loc.end },\n parent: DUMMY_PARENT,\n params,\n rawParams,\n }\n\n // Modify parent.\n for (const param of params) {\n ;(param as any).parent = expression\n }\n\n // Remove `void` `function` `<` `>` `(` `)` `{` `}`.\n tokens.shift()\n tokens.shift()\n tokens.shift()\n tokens.pop()\n tokens.pop()\n tokens.pop()\n tokens.pop()\n tokens.pop()\n\n return { expression, tokens, comments, references, variables }\n } catch (err) {\n return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator)\n }\n}\n","import sortedIndexBy from \"lodash/sortedIndexBy\"\nimport sortedLastIndexBy from \"lodash/sortedLastIndexBy\"\nimport type { LocationRange, Token, VDocumentFragment } from \"../ast\"\nimport type { LinesAndColumns } from \"./lines-and-columns\"\n\ninterface HasRange {\n range: [number, number]\n}\n/**\n * Replace the tokens in the given range.\n * @param document The document that the node is belonging to.\n * @param node The node to specify the range of replacement.\n * @param newTokens The new tokens.\n */\nexport function replaceTokens(\n document: VDocumentFragment | null,\n node: HasRange,\n newTokens: Token[],\n): void {\n if (document == null) {\n return\n }\n\n const index = sortedIndexBy(document.tokens, node, byRange0)\n const count = sortedLastIndexBy(document.tokens, node, byRange1) - index\n document.tokens.splice(index, count, ...newTokens)\n}\n\n/**\n * Replace and split the tokens in the given range.\n * @param document The document that the node is belonging to.\n * @param node The node to specify the range of replacement.\n * @param newTokens The new tokens.\n */\nexport function replaceAndSplitTokens(\n document: VDocumentFragment | null,\n node: HasRange & {\n loc: LocationRange\n },\n newTokens: Token[],\n): void {\n if (document == null) {\n return\n }\n\n const index = sortedIndexBy(document.tokens, node, byRange0)\n if (\n document.tokens.length === index ||\n node.range[0] < document.tokens[index].range[0]\n ) {\n // split\n const beforeToken = document.tokens[index - 1]\n const value = beforeToken.value\n const splitOffset = node.range[0] - beforeToken.range[0]\n const afterToken: Token = {\n type: beforeToken.type,\n range: [node.range[0], beforeToken.range[1]],\n loc: {\n start: { ...node.loc.start },\n end: { ...beforeToken.loc.end },\n },\n value: value.slice(splitOffset),\n }\n beforeToken.range[1] = node.range[0]\n beforeToken.loc.end = { ...node.loc.start }\n beforeToken.value = value.slice(0, splitOffset)\n document.tokens.splice(index, 0, afterToken)\n }\n let lastIndex = sortedLastIndexBy(document.tokens, node, byRange1)\n if (\n lastIndex === 0 ||\n node.range[1] < document.tokens[lastIndex].range[1]\n ) {\n // split\n const beforeToken = document.tokens[lastIndex]\n const value = beforeToken.value\n const splitOffset =\n beforeToken.range[1] -\n beforeToken.range[0] -\n (beforeToken.range[1] - node.range[1])\n const afterToken: Token = {\n type: beforeToken.type,\n range: [node.range[1], beforeToken.range[1]],\n loc: {\n start: { ...node.loc.end },\n end: { ...beforeToken.loc.end },\n },\n value: value.slice(splitOffset),\n }\n beforeToken.range[1] = node.range[1]\n beforeToken.loc.end = { ...node.loc.end }\n beforeToken.value = value.slice(0, splitOffset)\n document.tokens.splice(lastIndex + 1, 0, afterToken)\n lastIndex++\n }\n const count = lastIndex - index\n document.tokens.splice(index, count, ...newTokens)\n}\n\n/**\n * Insert the given comment tokens.\n * @param document The document that the node is belonging to.\n * @param newComments The comments to insert.\n */\nexport function insertComments(\n document: VDocumentFragment | null,\n newComments: Token[],\n): void {\n if (document == null || newComments.length === 0) {\n return\n }\n\n const index = sortedIndexBy(document.comments, newComments[0], byRange0)\n document.comments.splice(index, 0, ...newComments)\n}\n\n/**\n * Create a simple token.\n * @param type The type of new token.\n * @param start The offset of the start position of new token.\n * @param end The offset of the end position of new token.\n * @param value The value of new token.\n * @returns The new token.\n */\nexport function createSimpleToken(\n type: string,\n start: number,\n end: number,\n value: string,\n linesAndColumns: LinesAndColumns,\n): Token {\n return {\n type,\n range: [start, end],\n loc: {\n start: linesAndColumns.getLocFromIndex(start),\n end: linesAndColumns.getLocFromIndex(end),\n },\n value,\n }\n}\n\n/**\n * Get `x.range[0]`.\n * @param x The object to get.\n * @returns `x.range[0]`.\n */\nfunction byRange0(x: HasRange): number {\n return x.range[0]\n}\n\n/**\n * Get `x.range[1]`.\n * @param x The object to get.\n * @returns `x.range[1]`.\n */\nfunction byRange1(x: HasRange): number {\n return x.range[1]\n}\n","import type { ParseError, VDocumentFragment } from \"../ast\"\nimport sortedIndexBy from \"lodash/sortedIndexBy\"\n/**\n * Insert the given error.\n * @param document The document that the node is belonging to.\n * @param error The error to insert.\n */\nexport function insertError(\n document: VDocumentFragment | null,\n error: ParseError,\n): void {\n if (document == null) {\n return\n }\n\n const index = sortedIndexBy(document.errors, error, byIndex)\n document.errors.splice(index, 0, error)\n}\n\n/**\n * Get `x.pos`.\n * @param x The object to get.\n * @returns `x.pos`.\n */\nfunction byIndex(x: ParseError): number {\n return x.index\n}\n","/**\n * @see https://github.com/vuejs/vue-next/blob/48de8a42b7fed7a03f7f1ff5d53d6a704252cafe/packages/shared/src/index.ts#L109\n */\nexport function camelize(str: string) {\n return str.replace(/-(\\w)/gu, (_, c) => (c ? c.toUpperCase() : \"\"))\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport type { ParserOptions } from \"../common/parser-options\"\nimport { isSFCFile } from \"../common/parser-options\"\nimport type {\n ESLintExpression,\n ESLintExtendedProgram,\n ESLintIdentifier,\n Reference,\n Token,\n VAttribute,\n VDirective,\n VDirectiveKey,\n VDocumentFragment,\n VElement,\n VExpressionContainer,\n VFilterSequenceExpression,\n VForExpression,\n VGenericExpression,\n VIdentifier,\n VLiteral,\n VNode,\n VOnExpression,\n VSlotScopeExpression,\n} from \"../ast\"\nimport { ParseError } from \"../ast\"\nimport { debug } from \"../common/debug\"\nimport type { LocationCalculatorForHtml } from \"../common/location-calculator\"\nimport type { ExpressionParseResult } from \"../script\"\nimport {\n parseExpression,\n parseVForExpression,\n parseVOnExpression,\n parseSlotScopeExpression,\n parseGenericExpression,\n parseScriptFragment,\n} from \"../script\"\nimport {\n createSimpleToken,\n insertComments,\n replaceTokens,\n} from \"../common/token-utils\"\nimport {\n getOwnerDocument,\n isScriptSetupElement,\n isTSLang,\n} from \"../common/ast-utils\"\nimport { insertError } from \"../common/error-utils\"\nimport { camelize } from \"../utils/utils\"\n\nconst shorthandSign = /^[.:@#]/u\nconst shorthandNameMap = { \":\": \"bind\", \".\": \"bind\", \"@\": \"on\", \"#\": \"slot\" }\nconst invalidDynamicArgumentNextChar = /^[\\s\\r\\n=/>]$/u\n\n/**\n * Gets the tag name from the given node or token.\n * For SFC, it returns the value of `rawName` to be case sensitive.\n */\nfunction getTagName(\n startTagOrElement: { name: string; rawName: string },\n isSFC: boolean,\n) {\n return isSFC ? startTagOrElement.rawName : startTagOrElement.name\n}\n\n/**\n * Parse the given attribute name as a directive key.\n * @param node The identifier node to parse.\n * @param document The document to add parsing errors.\n * @returns The directive key node.\n */\nfunction parseDirectiveKeyStatically(\n node: VIdentifier,\n document: VDocumentFragment | null,\n): VDirectiveKey {\n const {\n name: text,\n rawName: rawText,\n range: [offset],\n loc: {\n start: { column, line },\n },\n } = node\n const directiveKey: VDirectiveKey = {\n type: \"VDirectiveKey\",\n range: node.range,\n loc: node.loc,\n parent: node.parent as any,\n name: null as any,\n argument: null as VIdentifier | null,\n modifiers: [] as VIdentifier[],\n }\n let i = 0\n\n function createIdentifier(\n start: number,\n end: number,\n name?: string,\n ): VIdentifier {\n return {\n type: \"VIdentifier\",\n parent: directiveKey,\n range: [offset + start, offset + end],\n loc: {\n start: { column: column + start, line },\n end: { column: column + end, line },\n },\n name: name || text.slice(start, end),\n rawName: rawText.slice(start, end),\n }\n }\n\n // Parse.\n if (shorthandSign.test(text)) {\n const sign = text[0] as \":\" | \".\" | \"@\" | \"#\"\n directiveKey.name = createIdentifier(0, 1, shorthandNameMap[sign])\n i = 1\n } else {\n const colon = text.indexOf(\":\")\n if (colon !== -1) {\n directiveKey.name = createIdentifier(0, colon)\n i = colon + 1\n }\n }\n\n if (directiveKey.name != null && text[i] === \"[\") {\n // Dynamic argument.\n const len = text.slice(i).lastIndexOf(\"]\")\n if (len !== -1) {\n directiveKey.argument = createIdentifier(i, i + len + 1)\n i = i + len + 1 + (text[i + len + 1] === \".\" ? 1 : 0)\n }\n }\n\n const modifiers = text\n .slice(i)\n .split(\".\")\n .map((modifierName) => {\n const modifier = createIdentifier(i, i + modifierName.length)\n if (modifierName === \"\" && i < text.length) {\n insertError(\n document,\n new ParseError(\n `Unexpected token '${text[i]}'`,\n undefined,\n offset + i,\n line,\n column + i,\n ),\n )\n }\n i += modifierName.length + 1\n return modifier\n })\n\n if (directiveKey.name == null) {\n directiveKey.name = modifiers.shift()!\n } else if (directiveKey.argument == null && modifiers[0].name !== \"\") {\n directiveKey.argument = modifiers.shift() || null\n }\n directiveKey.modifiers = modifiers.filter(isNotEmptyModifier)\n\n if (directiveKey.name.name === \"v-\") {\n insertError(\n document,\n new ParseError(\n `Unexpected token '${\n text[directiveKey.name.range[1] - offset]\n }'`,\n undefined,\n directiveKey.name.range[1],\n directiveKey.name.loc.end.line,\n directiveKey.name.loc.end.column,\n ),\n )\n }\n\n // v-bind.prop shorthand\n if (\n directiveKey.name.rawName === \".\" &&\n !directiveKey.modifiers.some(isPropModifier)\n ) {\n const pos =\n (directiveKey.argument || directiveKey.name).range[1] - offset\n const propModifier = createIdentifier(pos, pos, \"prop\")\n directiveKey.modifiers.unshift(propModifier)\n }\n\n return directiveKey\n}\n\n/**\n * Check whether a given identifier node is `prop` or not.\n * @param node The identifier node to check.\n */\nfunction isPropModifier(node: VIdentifier): boolean {\n return node.name === \"prop\"\n}\n\n/**\n * Check whether a given identifier node is empty or not.\n * @param node The identifier node to check.\n */\nfunction isNotEmptyModifier(node: VIdentifier): boolean {\n return node.name !== \"\"\n}\n\n/**\n * Parse the tokens of a given key node.\n * @param node The key node to parse.\n */\nfunction parseDirectiveKeyTokens(node: VDirectiveKey): Token[] {\n const { name, argument, modifiers } = node\n const shorthand = name.range[1] - name.range[0] === 1\n const tokens: Token[] = []\n\n if (shorthand) {\n tokens.push({\n type: \"Punctuator\",\n range: name.range,\n loc: name.loc,\n value: name.rawName,\n })\n } else {\n tokens.push({\n type: \"HTMLIdentifier\",\n range: name.range,\n loc: name.loc,\n value: name.rawName,\n })\n\n if (argument) {\n tokens.push({\n type: \"Punctuator\",\n range: [name.range[1], argument.range[0]],\n loc: { start: name.loc.end, end: argument.loc.start },\n value: \":\",\n })\n }\n }\n\n if (argument) {\n tokens.push({\n type: \"HTMLIdentifier\",\n range: argument.range,\n loc: argument.loc,\n value: (argument as VIdentifier).rawName,\n })\n }\n\n let lastNode = (argument as VIdentifier | null) || name\n for (const modifier of modifiers) {\n if (modifier.rawName === \"\") {\n continue\n }\n\n tokens.push(\n {\n type: \"Punctuator\",\n range: [lastNode.range[1], modifier.range[0]],\n loc: { start: lastNode.loc.end, end: modifier.loc.start },\n value: \".\",\n },\n {\n type: \"HTMLIdentifier\",\n range: modifier.range,\n loc: modifier.loc,\n value: modifier.rawName,\n },\n )\n lastNode = modifier\n }\n\n return tokens\n}\n\n/**\n * Convert `node.argument` property to a `VExpressionContainer` node if it's a dynamic argument.\n * @param text The source code text of the directive key node.\n * @param node The directive key node to convert.\n * @param document The belonging document node.\n * @param parserOptions The parser options to parse.\n * @param locationCalculator The location calculator to parse.\n */\nfunction convertDynamicArgument(\n node: VDirectiveKey,\n document: VDocumentFragment | null,\n parserOptions: ParserOptions,\n locationCalculator: LocationCalculatorForHtml,\n): void {\n const { argument } = node\n if (\n !(\n argument != null &&\n argument.type === \"VIdentifier\" &&\n argument.name.startsWith(\"[\") &&\n argument.name.endsWith(\"]\")\n )\n ) {\n return\n }\n\n const { rawName, range, loc } = argument\n try {\n const { comments, expression, references, tokens } = parseExpression(\n rawName.slice(1, -1),\n locationCalculator.getSubCalculatorAfter(range[0] + 1),\n parserOptions,\n )\n\n node.argument = {\n type: \"VExpressionContainer\",\n range,\n loc,\n parent: node,\n expression,\n references,\n }\n\n if (expression != null) {\n expression.parent = node.argument\n }\n\n // Add tokens of `[` and `]`.\n tokens.unshift(\n createSimpleToken(\n \"Punctuator\",\n range[0],\n range[0] + 1,\n \"[\",\n locationCalculator,\n ),\n )\n tokens.push(\n createSimpleToken(\n \"Punctuator\",\n range[1] - 1,\n range[1],\n \"]\",\n locationCalculator,\n ),\n )\n\n replaceTokens(document, node.argument, tokens)\n insertComments(document, comments)\n } catch (error) {\n debug(\"[template] Parse error: %s\", error)\n\n if (ParseError.isParseError(error)) {\n node.argument = {\n type: \"VExpressionContainer\",\n range,\n loc,\n parent: node,\n expression: null,\n references: [],\n }\n insertError(document, error)\n } else {\n throw error\n }\n }\n}\n\n/**\n * Parse the given attribute name as a directive key.\n * @param node The identifier node to parse.\n * @returns The directive key node.\n */\nfunction createDirectiveKey(\n node: VIdentifier,\n document: VDocumentFragment | null,\n parserOptions: ParserOptions,\n locationCalculator: LocationCalculatorForHtml,\n): VDirectiveKey {\n // Parse node and tokens.\n const directiveKey = parseDirectiveKeyStatically(node, document)\n const tokens = parseDirectiveKeyTokens(directiveKey)\n replaceTokens(document, directiveKey, tokens)\n\n // Drop `v-` prefix.\n if (directiveKey.name.name.startsWith(\"v-\")) {\n directiveKey.name.name = directiveKey.name.name.slice(2)\n }\n if (directiveKey.name.rawName.startsWith(\"v-\")) {\n directiveKey.name.rawName = directiveKey.name.rawName.slice(2)\n }\n\n // Parse dynamic argument.\n convertDynamicArgument(\n directiveKey,\n document,\n parserOptions,\n locationCalculator,\n )\n\n return directiveKey\n}\n\n/**\n * Parse the given attribute value as an expression.\n * @param code Whole source code text.\n * @param parserOptions The parser options to parse expressions.\n * @param globalLocationCalculator The location calculator to adjust the locations of nodes.\n * @param node The attribute node to replace. This function modifies this node directly.\n * @param tagName The name of this tag.\n * @param directiveKey The key of this directive.\n */\nfunction parseAttributeValue(\n code: string,\n parserOptions: ParserOptions,\n scriptParserOptions: ParserOptions,\n globalLocationCalculator: LocationCalculatorForHtml,\n node: VLiteral,\n element: VElement,\n directiveKey: VDirectiveKey,\n): ExpressionParseResult<\n | ESLintExpression\n | VFilterSequenceExpression\n | VForExpression\n | VOnExpression\n | VSlotScopeExpression\n | VGenericExpression\n> {\n const firstChar = code[node.range[0]]\n const quoted = firstChar === '\"' || firstChar === \"'\"\n const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(\n node.range[0] + (quoted ? 1 : 0),\n )\n const directiveKind = getStandardDirectiveKind(\n parserOptions,\n element,\n directiveKey,\n )\n\n let result: ExpressionParseResult<\n | ESLintExpression\n | VFilterSequenceExpression\n | VForExpression\n | VOnExpression\n | VSlotScopeExpression\n | VGenericExpression\n >\n if (quoted && node.value === \"\") {\n result = {\n expression: null,\n tokens: [],\n comments: [],\n variables: [],\n references: [],\n }\n } else if (directiveKind === \"for\") {\n result = parseVForExpression(\n node.value,\n locationCalculator,\n parserOptions,\n )\n } else if (directiveKind === \"on\" && directiveKey.argument != null) {\n result = parseVOnExpression(\n node.value,\n locationCalculator,\n parserOptions,\n )\n } else if (directiveKind === \"slot\") {\n result = parseSlotScopeExpression(\n node.value,\n locationCalculator,\n parserOptions,\n )\n } else if (directiveKind === \"bind\") {\n result = parseExpression(\n node.value,\n locationCalculator,\n parserOptions,\n { allowFilters: true },\n )\n } else if (directiveKind === \"generic\") {\n result = parseGenericExpression(\n node.value,\n locationCalculator,\n scriptParserOptions,\n )\n } else {\n result = parseExpression(node.value, locationCalculator, parserOptions)\n }\n\n // Add the tokens of quotes.\n if (quoted) {\n result.tokens.unshift(\n createSimpleToken(\n \"Punctuator\",\n node.range[0],\n node.range[0] + 1,\n firstChar,\n globalLocationCalculator,\n ),\n )\n result.tokens.push(\n createSimpleToken(\n \"Punctuator\",\n node.range[1] - 1,\n node.range[1],\n firstChar,\n globalLocationCalculator,\n ),\n )\n }\n\n return result\n}\n\nfunction getStandardDirectiveKind(\n parserOptions: ParserOptions,\n element: VElement,\n directiveKey: VDirectiveKey,\n) {\n const directiveName = directiveKey.name.name\n\n if (directiveName === \"for\") {\n return \"for\"\n } else if (directiveName === \"on\") {\n return \"on\"\n } else if (\n directiveName === \"slot\" ||\n directiveName === \"slot-scope\" ||\n (directiveName === \"scope\" &&\n getTagName(element, isSFCFile(parserOptions)) === \"template\")\n ) {\n return \"slot\"\n } else if (directiveName === \"bind\") {\n return \"bind\"\n } else if (\n directiveName === \"generic\" &&\n element.parent.type === \"VDocumentFragment\" &&\n getTagName(element, isSFCFile(parserOptions)) === \"script\" &&\n isScriptSetupElement(element) &&\n isTSLang(element)\n ) {\n return \"generic\"\n }\n return null\n}\n\n/**\n * Resolve the variable of the given reference.\n * @param referene The reference to resolve.\n * @param element The belonging element of the reference.\n */\nfunction resolveReference(referene: Reference, element: VElement): void {\n let node: VNode | null = element\n\n // Find the variable of this reference.\n while (node != null && node.type === \"VElement\") {\n for (const variable of node.variables) {\n if (variable.id.name === referene.id.name) {\n referene.variable = variable\n variable.references.push(referene)\n return\n }\n }\n\n node = node.parent\n }\n}\n\n/**\n * Information of a mustache.\n */\nexport interface Mustache {\n value: string\n startToken: Token\n endToken: Token\n}\n\n/**\n * Replace the given attribute by a directive.\n * @param code Whole source code text.\n * @param parserOptions The parser options to parse expressions.\n * @param locationCalculator The location calculator to adjust the locations of nodes.\n * @param node The attribute node to replace. This function modifies this node directly.\n */\nexport function convertToDirective(\n code: string,\n parserOptions: ParserOptions,\n scriptParserOptions: ParserOptions,\n locationCalculator: LocationCalculatorForHtml,\n node: VAttribute,\n): void {\n debug(\n '[template] convert to directive: %s=\"%s\" %j',\n node.key.name,\n node.value && node.value.value,\n node.range,\n )\n\n const document = getOwnerDocument(node)\n const directive: VDirective = node as any\n directive.directive = true\n directive.key = createDirectiveKey(\n node.key,\n document,\n parserOptions,\n locationCalculator,\n )\n\n const { argument } = directive.key\n if (\n argument &&\n argument.type === \"VIdentifier\" &&\n argument.name.startsWith(\"[\")\n ) {\n const nextChar = code[argument.range[1]]\n if (nextChar == null || invalidDynamicArgumentNextChar.test(nextChar)) {\n const char =\n nextChar == null ? \"EOF\" : JSON.stringify(nextChar).slice(1, -1)\n insertError(\n document,\n new ParseError(\n `Dynamic argument cannot contain the '${char}' character.`,\n undefined,\n argument.range[1],\n argument.loc.end.line,\n argument.loc.end.column,\n ),\n )\n }\n }\n\n if (node.value == null) {\n if (directive.key.name.name === \"bind\") {\n // v-bind same-name shorthand (Vue 3.4+)\n convertForVBindSameNameShorthandValue(\n directive,\n parserOptions,\n locationCalculator,\n )\n }\n return\n }\n\n try {\n const ret = parseAttributeValue(\n code,\n parserOptions,\n scriptParserOptions,\n locationCalculator,\n node.value,\n node.parent.parent,\n directive.key,\n )\n\n directive.value = {\n type: \"VExpressionContainer\",\n range: node.value.range,\n loc: node.value.loc,\n parent: directive,\n expression: ret.expression,\n references: ret.references,\n }\n if (ret.expression != null) {\n ret.expression.parent = directive.value\n }\n\n for (const variable of ret.variables) {\n node.parent.parent.variables.push(variable)\n }\n\n replaceTokens(document, node.value, ret.tokens)\n insertComments(document, ret.comments)\n } catch (err) {\n debug(\"[template] Parse error: %s\", err)\n\n if (ParseError.isParseError(err)) {\n directive.value = {\n type: \"VExpressionContainer\",\n range: node.value.range,\n loc: node.value.loc,\n parent: directive,\n expression: null,\n references: [],\n }\n insertError(document, err)\n } else {\n throw err\n }\n }\n}\n\nfunction convertForVBindSameNameShorthandValue(\n directive: VDirective,\n parserOptions: ParserOptions,\n locationCalculator: LocationCalculatorForHtml,\n) {\n if (\n directive.key.name.name !== \"bind\" ||\n directive.key.argument == null ||\n directive.key.argument.type !== \"VIdentifier\"\n ) {\n return\n }\n // v-bind same-name shorthand (Vue 3.4+)\n const vId = directive.key.argument\n const camelName = camelize(vId.rawName)\n let result: ESLintExtendedProgram | null = null\n try {\n result = parseScriptFragment(\n camelName,\n locationCalculator.getSubCalculatorAfter(vId.range[0]),\n parserOptions,\n )\n } catch (err) {\n debug(\"[template] Parse error: %s\", err)\n }\n if (\n result == null ||\n result.ast.body.length !== 1 ||\n result.ast.body[0].type !== \"ExpressionStatement\" ||\n result.ast.body[0].expression.type !== \"Identifier\"\n ) {\n return\n }\n const id: ESLintIdentifier = result.ast.body[0].expression\n id.range[1] = vId.range[1]\n id.loc.end = { ...vId.loc.end }\n if (id.end != null) {\n id.end = vId.end\n }\n directive.value = {\n type: \"VExpressionContainer\",\n range: [...vId.range],\n loc: {\n start: { ...vId.loc.start },\n end: { ...vId.loc.end },\n },\n parent: directive,\n expression: id,\n references: [\n {\n id,\n mode: \"r\",\n variable: null,\n },\n ],\n }\n id.parent = directive.value\n}\n\n/**\n * Parse the content of the given mustache.\n * @param parserOptions The parser options to parse expressions.\n * @param globalLocationCalculator The location calculator to adjust the locations of nodes.\n * @param node The expression container node. This function modifies the `expression` and `references` properties of this node.\n * @param mustache The information of mustache to parse.\n */\nexport function processMustache(\n parserOptions: ParserOptions,\n globalLocationCalculator: LocationCalculatorForHtml,\n node: VExpressionContainer,\n mustache: Mustache,\n): void {\n const range: [number, number] = [\n mustache.startToken.range[1],\n mustache.endToken.range[0],\n ]\n debug(\"[template] convert mustache {{%s}} %j\", mustache.value, range)\n\n const document = getOwnerDocument(node)\n try {\n const locationCalculator =\n globalLocationCalculator.getSubCalculatorAfter(range[0])\n const ret = parseExpression(\n mustache.value,\n locationCalculator,\n parserOptions,\n { allowEmpty: true, allowFilters: true },\n )\n\n node.expression = ret.expression || null\n node.references = ret.references\n if (ret.expression != null) {\n ret.expression.parent = node\n }\n\n replaceTokens(document, { range }, ret.tokens)\n insertComments(document, ret.comments)\n } catch (err) {\n debug(\"[template] Parse error: %s\", err)\n\n if (ParseError.isParseError(err)) {\n insertError(document, err)\n } else {\n throw err\n }\n }\n}\n\n/**\n * Resolve all references of the given expression container.\n * @param container The expression container to resolve references.\n */\nexport function resolveReferences(container: VExpressionContainer): void {\n let element: VNode | null = container.parent\n\n // Get the belonging element.\n while (element != null && element.type !== \"VElement\") {\n element = element.parent\n }\n\n // Resolve.\n if (element != null) {\n for (const reference of container.references) {\n resolveReference(reference, element)\n }\n }\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nexport const SVG_ATTRIBUTE_NAME_MAP = new Map([\n [\"attributename\", \"attributeName\"],\n [\"attributetype\", \"attributeType\"],\n [\"basefrequency\", \"baseFrequency\"],\n [\"baseprofile\", \"baseProfile\"],\n [\"calcmode\", \"calcMode\"],\n [\"clippathunits\", \"clipPathUnits\"],\n [\"diffuseconstant\", \"diffuseConstant\"],\n [\"edgemode\", \"edgeMode\"],\n [\"filterunits\", \"filterUnits\"],\n [\"glyphref\", \"glyphRef\"],\n [\"gradienttransform\", \"gradientTransform\"],\n [\"gradientunits\", \"gradientUnits\"],\n [\"kernelmatrix\", \"kernelMatrix\"],\n [\"kernelunitlength\", \"kernelUnitLength\"],\n [\"keypoints\", \"keyPoints\"],\n [\"keysplines\", \"keySplines\"],\n [\"keytimes\", \"keyTimes\"],\n [\"lengthadjust\", \"lengthAdjust\"],\n [\"limitingconeangle\", \"limitingConeAngle\"],\n [\"markerheight\", \"markerHeight\"],\n [\"markerunits\", \"markerUnits\"],\n [\"markerwidth\", \"markerWidth\"],\n [\"maskcontentunits\", \"maskContentUnits\"],\n [\"maskunits\", \"maskUnits\"],\n [\"numoctaves\", \"numOctaves\"],\n [\"pathlength\", \"pathLength\"],\n [\"patterncontentunits\", \"patternContentUnits\"],\n [\"patterntransform\", \"patternTransform\"],\n [\"patternunits\", \"patternUnits\"],\n [\"pointsatx\", \"pointsAtX\"],\n [\"pointsaty\", \"pointsAtY\"],\n [\"pointsatz\", \"pointsAtZ\"],\n [\"preservealpha\", \"preserveAlpha\"],\n [\"preserveaspectratio\", \"preserveAspectRatio\"],\n [\"primitiveunits\", \"primitiveUnits\"],\n [\"refx\", \"refX\"],\n [\"refy\", \"refY\"],\n [\"repeatcount\", \"repeatCount\"],\n [\"repeatdur\", \"repeatDur\"],\n [\"requiredextensions\", \"requiredExtensions\"],\n [\"requiredfeatures\", \"requiredFeatures\"],\n [\"specularconstant\", \"specularConstant\"],\n [\"specularexponent\", \"specularExponent\"],\n [\"spreadmethod\", \"spreadMethod\"],\n [\"startoffset\", \"startOffset\"],\n [\"stddeviation\", \"stdDeviation\"],\n [\"stitchtiles\", \"stitchTiles\"],\n [\"surfacescale\", \"surfaceScale\"],\n [\"systemlanguage\", \"systemLanguage\"],\n [\"tablevalues\", \"tableValues\"],\n [\"targetx\", \"targetX\"],\n [\"targety\", \"targetY\"],\n [\"textlength\", \"textLength\"],\n [\"viewbox\", \"viewBox\"],\n [\"viewtarget\", \"viewTarget\"],\n [\"xchannelselector\", \"xChannelSelector\"],\n [\"ychannelselector\", \"yChannelSelector\"],\n [\"zoomandpan\", \"zoomAndPan\"],\n])\n\nexport const MATHML_ATTRIBUTE_NAME_MAP = new Map([\n [\"definitionurl\", \"definitionUrl\"]\n])\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\n\n/**\n * HTML tag names.\n */\nexport const HTML_TAGS = new Set([\n \"a\", \"abbr\", \"address\", \"area\", \"article\",\"aside\", \"audio\", \"b\", \"base\",\n \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\", \"canvas\", \"caption\",\n \"cite\", \"code\", \"col\", \"colgroup\", \"data\", \"datalist\", \"dd\", \"del\",\n \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"document\", \"dt\", \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\", \"h1\", \"h2\", \"h3\",\n \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hgroup\", \"hr\", \"html\", \"i\", \"iframe\",\n \"img\", \"input\", \"ins\", \"kbd\", \"label\", \"legend\", \"li\", \"link\", \"main\",\n \"map\", \"mark\", \"marquee\", \"menu\", \"meta\", \"meter\", \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\", \"p\", \"param\", \"picture\",\n \"pre\", \"progress\", \"q\", \"rp\", \"rt\", \"ruby\", \"s\", \"samp\", \"script\",\n \"section\", \"select\", \"slot\", \"small\", \"source\", \"span\", \"strong\", \"style\",\n \"sub\", \"summary\", \"sup\", \"table\", \"tbody\", \"td\", \"template\", \"textarea\",\n \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\", \"track\", \"u\", \"ul\", \"var\",\n \"video\", \"wbr\"\n])\n\n/**\n * HTML tag names of void elements.\n */\nexport const HTML_VOID_ELEMENT_TAGS = new Set([\n \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"link\", \"meta\",\n \"param\", \"source\", \"track\", \"wbr\",\n])\n\n/**\n * https://github.com/vuejs/vue/blob/e4da249ab8ef32a0b8156c840c9d2b9773090f8a/src/platforms/web/compiler/util.js#L12\n */\nexport const HTML_CAN_BE_LEFT_OPEN_TAGS = new Set([\n \"colgroup\", \"li\", \"options\", \"p\", \"td\", \"tfoot\", \"th\", \"thead\", \n \"tr\", \"source\",\n])\n\n/**\n * https://github.com/vuejs/vue/blob/e4da249ab8ef32a0b8156c840c9d2b9773090f8a/src/platforms/web/compiler/util.js#L18\n */\nexport const HTML_NON_FHRASING_TAGS = new Set([\n \"address\", \"article\", \"aside\", \"base\", \"blockquote\", \"body\", \"caption\", \n \"col\", \"colgroup\", \"dd\", \"details\", \"dialog\", \"div\", \"dl\", \"dt\", \"fieldset\", \n \"figcaption\", \"figure\", \"footer\", \"form\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \n \"h6\", \"head\", \"header\", \"hgroup\", \"hr\", \"html\", \"legend\", \"li\", \"menuitem\", \n \"meta\", \"optgroup\", \"option\", \"param\", \"rp\", \"rt\", \"source\", \"style\", \n \"summary\", \"tbody\", \"td\", \"tfoot\", \"th\", \"thead\", \"title\", \"tr\", \"track\",\n])\n\n/**\n * HTML tag names of RCDATA.\n */\nexport const HTML_RCDATA_TAGS = new Set([\n \"title\", \"textarea\",\n])\n\n/**\n * HTML tag names of RAWTEXT.\n */\nexport const HTML_RAWTEXT_TAGS = new Set([\n \"style\", \"xmp\", \"iframe\", \"noembed\", \"noframes\", \"noscript\", \"script\",\n])\n\n/**\n * SVG tag names.\n */\nexport const SVG_TAGS = new Set([\n \"a\", \"altGlyph\", \"altGlyphDef\", \"altGlyphItem\", \"animate\", \"animateColor\", \n \"animateMotion\", \"animateTransform\", \"animation\", \"audio\", \"canvas\", \n \"circle\", \"clipPath\", \"color-profile\", \"cursor\", \"defs\", \"desc\", \"discard\", \n \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\", \"feComposite\", \n \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\", \n \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \n \"feFuncG\", \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \n \"feMorphology\", \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \n \"feSpotLight\", \"feTile\", \"feTurbulence\", \"filter\", \"font\", \"font-face\", \n \"font-face-format\", \"font-face-name\", \"font-face-src\", \"font-face-uri\", \n \"foreignObject\", \"g\", \"glyph\", \"glyphRef\", \"handler\", \"hatch\", \"hatchpath\", \n \"hkern\", \"iframe\", \"image\", \"line\", \"linearGradient\", \"listener\", \"marker\", \n \"mask\", \"mesh\", \"meshgradient\", \"meshpatch\", \"meshrow\", \"metadata\", \n \"missing-glyph\", \"mpath\", \"path\", \"pattern\", \"polygon\", \"polyline\", \n \"prefetch\", \"radialGradient\", \"rect\", \"script\", \"set\", \"solidColor\", \n \"solidcolor\", \"stop\", \"style\", \"svg\", \"switch\", \"symbol\", \"tbreak\", \"text\", \n \"textArea\", \"textPath\", \"title\", \"tref\", \"tspan\", \"unknown\", \"use\", \"video\", \n \"view\", \"vkern\",\n])\n\n/**\n * The map from lowercase names to actual names in SVG.\n */\nexport const SVG_ELEMENT_NAME_MAP = new Map<string, string>()\nfor (const name of SVG_TAGS) {\n if (/[A-Z]/.test(name)) {\n SVG_ELEMENT_NAME_MAP.set(name.toLowerCase(), name)\n }\n}\n\n/**\n * MathML tag names.\n */\nexport const MATHML_TAGS = new Set([\n \"abs\", \"and\", \"annotation\", \"annotation-xml\", \"apply\", \"approx\", \"arccos\", \n \"arccosh\", \"arccot\", \"arccoth\", \"arccsc\", \"arccsch\", \"arcsec\", \"arcsech\", \n \"arcsin\", \"arcsinh\", \"arctan\", \"arctanh\", \"arg\", \"bind\", \"bvar\", \"card\", \n \"cartesianproduct\", \"cbytes\", \"ceiling\", \"cerror\", \"ci\", \"cn\", \"codomain\", \n \"complexes\", \"compose\", \"condition\", \"conjugate\", \"cos\", \"cosh\", \"cot\", \n \"coth\", \"cs\", \"csc\", \"csch\", \"csymbol\", \"curl\", \"declare\", \"degree\", \n \"determinant\", \"diff\", \"divergence\", \"divide\", \"domain\", \n \"domainofapplication\", \"emptyset\", \"encoding\", \"eq\", \"equivalent\", \n \"eulergamma\", \"exists\", \"exp\", \"exponentiale\", \"factorial\", \"factorof\", \n \"false\", \"floor\", \"fn\", \"forall\", \"function\", \"gcd\", \"geq\", \"grad\", \"gt\", \n \"ident\", \"image\", \"imaginary\", \"imaginaryi\", \"implies\", \"in\", \"infinity\", \n \"int\", \"integers\", \"intersect\", \"interval\", \"inverse\", \"lambda\", \n \"laplacian\", \"lcm\", \"leq\", \"limit\", \"list\", \"ln\", \"log\", \"logbase\", \n \"lowlimit\", \"lt\", \"m:apply\", \"m:mrow\", \"maction\", \"malign\", \"maligngroup\", \n \"malignmark\", \"malignscope\", \"math\", \"matrix\", \"matrixrow\", \"max\", \"mean\", \n \"median\", \"menclose\", \"merror\", \"mfenced\", \"mfrac\", \"mfraction\", \"mglyph\", \n \"mi\", \"mi\\\"\", \"min\", \"minus\", \"mlabeledtr\", \"mlongdiv\", \"mmultiscripts\", \n \"mn\", \"mo\", \"mode\", \"moment\", \"momentabout\", \"mover\", \"mpadded\", \"mphantom\", \n \"mprescripts\", \"mroot\", \"mrow\", \"ms\", \"mscarries\", \"mscarry\", \"msgroup\", \n \"msline\", \"mspace\", \"msqrt\", \"msrow\", \"mstack\", \"mstyle\", \"msub\", \"msubsup\", \n \"msup\", \"mtable\", \"mtd\", \"mtext\", \"mtr\", \"munder\", \"munderover\", \n \"naturalnumbers\", \"neq\", \"none\", \"not\", \"notanumber\", \"notin\", \n \"notprsubset\", \"notsubset\", \"or\", \"otherwise\", \"outerproduct\", \n \"partialdiff\", \"pi\", \"piece\", \"piecewice\", \"piecewise\", \"plus\", \"power\", \n \"primes\", \"product\", \"prsubset\", \"quotient\", \"rationals\", \"real\", \"reals\", \n \"reln\", \"rem\", \"root\", \"scalarproduct\", \"sdev\", \"sec\", \"sech\", \"select\", \n \"selector\", \"semantics\", \"sep\", \"set\", \"setdiff\", \"share\", \"sin\", \"sinh\", \n \"span\", \"subset\", \"sum\", \"tan\", \"tanh\", \"tendsto\", \"times\", \"transpose\", \n \"true\", \"union\", \"uplimit\", \"var\", \"variance\", \"vector\", \"vectorproduct\", \n \"xor\",\n])\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport assert from \"assert\"\nimport last from \"lodash/last\"\nimport type {\n ErrorCode,\n HasLocation,\n Namespace,\n Token,\n VAttribute,\n} from \"../ast\"\nimport { ParseError } from \"../ast\"\nimport { debug } from \"../common/debug\"\nimport type { Tokenizer, TokenizerState, TokenType } from \"./tokenizer\"\n\nconst DUMMY_PARENT: any = Object.freeze({})\n\n/**\n * Concatenate token values.\n * @param text Concatenated text.\n * @param token The token to concatenate.\n */\nfunction concat(text: string, token: Token): string {\n return text + token.value\n}\n\n/**\n * The type of intermediate tokens.\n */\nexport type IntermediateToken = StartTag | EndTag | Text | Mustache\n\n/**\n * The type of start tags.\n */\nexport interface StartTag extends HasLocation {\n type: \"StartTag\"\n name: string\n rawName: string\n selfClosing: boolean\n attributes: VAttribute[]\n}\n\n/**\n * The type of end tags.\n */\nexport interface EndTag extends HasLocation {\n type: \"EndTag\"\n name: string\n}\n\n/**\n * The type of text chunks.\n */\nexport interface Text extends HasLocation {\n type: \"Text\"\n value: string\n}\n\n/**\n * The type of text chunks of an expression container.\n */\nexport interface Mustache extends HasLocation {\n type: \"Mustache\"\n value: string\n startToken: Token\n endToken: Token\n}\n\n/**\n * The class to create HTML tokens from ESTree-like tokens which are created by a Tokenizer.\n */\nexport class IntermediateTokenizer {\n private tokenizer: Tokenizer\n private currentToken: IntermediateToken | null\n private attribute: VAttribute | null\n private attributeNames: Set<string>\n private expressionStartToken: Token | null\n private expressionTokens: Token[]\n\n public readonly tokens: Token[]\n public readonly comments: Token[]\n\n /**\n * The source code text.\n */\n public get text(): string {\n return this.tokenizer.text\n }\n\n /**\n * The parse errors.\n */\n public get errors(): ParseError[] {\n return this.tokenizer.errors\n }\n\n /**\n * The current state.\n */\n public get state(): TokenizerState {\n return this.tokenizer.state\n }\n public set state(value: TokenizerState) {\n this.tokenizer.state = value\n }\n\n /**\n * The current namespace.\n */\n public get namespace(): Namespace {\n return this.tokenizer.namespace\n }\n public set namespace(value: Namespace) {\n this.tokenizer.namespace = value\n }\n\n /**\n * The current flag of expression enabled.\n */\n public get expressionEnabled(): boolean {\n return this.tokenizer.expressionEnabled\n }\n public set expressionEnabled(value: boolean) {\n this.tokenizer.expressionEnabled = value\n }\n\n /**\n * Initialize this intermediate tokenizer.\n * @param tokenizer The tokenizer.\n */\n public constructor(tokenizer: Tokenizer) {\n this.tokenizer = tokenizer\n this.currentToken = null\n this.attribute = null\n this.attributeNames = new Set<string>()\n this.expressionStartToken = null\n this.expressionTokens = []\n this.tokens = []\n this.comments = []\n }\n\n /**\n * Get the next intermediate token.\n * @returns The intermediate token or null.\n */\n public nextToken(): IntermediateToken | null {\n let token: Token | null = null\n let result: IntermediateToken | null = null\n\n while (result == null && (token = this.tokenizer.nextToken()) != null) {\n result = this[token.type as TokenType](token)\n }\n\n if (result == null && token == null && this.currentToken != null) {\n result = this.commit()\n }\n\n return result\n }\n\n /**\n * Commit the current token.\n */\n private commit(): IntermediateToken {\n assert(this.currentToken != null || this.expressionStartToken != null)\n\n let token = this.currentToken\n this.currentToken = null\n this.attribute = null\n\n if (this.expressionStartToken != null) {\n // VExpressionEnd was not found.\n // Concatenate the deferred tokens to the committed token.\n const start = this.expressionStartToken\n const end = last(this.expressionTokens) || start\n const value = this.expressionTokens.reduce(concat, start.value)\n this.expressionStartToken = null\n this.expressionTokens = []\n\n if (token == null) {\n token = {\n type: \"Text\",\n range: [start.range[0], end.range[1]],\n loc: { start: start.loc.start, end: end.loc.end },\n value,\n }\n } else if (token.type === \"Text\") {\n token.range[1] = end.range[1]\n token.loc.end = end.loc.end\n token.value += value\n } else {\n throw new Error(\"unreachable\")\n }\n }\n\n return token as IntermediateToken\n }\n\n /**\n * Report an invalid character error.\n * @param code The error code.\n */\n private reportParseError(token: HasLocation, code: ErrorCode): void {\n const error = ParseError.fromCode(\n code,\n token.range[0],\n token.loc.start.line,\n token.loc.start.column,\n )\n this.errors.push(error)\n\n debug(\"[html] syntax error:\", error.message)\n }\n\n /**\n * Process the given comment token.\n * @param token The comment token to process.\n */\n private processComment(token: Token): IntermediateToken | null {\n this.comments.push(token)\n\n if (this.currentToken != null && this.currentToken.type === \"Text\") {\n return this.commit()\n }\n return null\n }\n\n /**\n * Process the given text token.\n * @param token The text token to process.\n */\n private processText(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n let result: IntermediateToken | null = null\n\n if (this.expressionStartToken != null) {\n // Defer this token until a VExpressionEnd token or a non-text token appear.\n const lastToken =\n last(this.expressionTokens) || this.expressionStartToken\n if (lastToken.range[1] === token.range[0]) {\n this.expressionTokens.push(token)\n return null\n }\n\n result = this.commit()\n } else if (this.currentToken != null) {\n // Concatenate this token to the current text token.\n if (\n this.currentToken.type === \"Text\" &&\n this.currentToken.range[1] === token.range[0]\n ) {\n this.currentToken.value += token.value\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n return null\n }\n\n result = this.commit()\n }\n assert(this.currentToken == null)\n\n this.currentToken = {\n type: \"Text\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n value: token.value,\n }\n\n return result\n }\n\n /**\n * Process a HTMLAssociation token.\n * @param token The token to process.\n */\n protected HTMLAssociation(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n if (this.attribute != null) {\n this.attribute.range[1] = token.range[1]\n this.attribute.loc.end = token.loc.end\n\n if (\n this.currentToken == null ||\n this.currentToken.type !== \"StartTag\"\n ) {\n throw new Error(\"unreachable\")\n }\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n }\n\n return null\n }\n\n /**\n * Process a HTMLBogusComment token.\n * @param token The token to process.\n */\n protected HTMLBogusComment(token: Token): IntermediateToken | null {\n return this.processComment(token)\n }\n\n /**\n * Process a HTMLCDataText token.\n * @param token The token to process.\n */\n protected HTMLCDataText(token: Token): IntermediateToken | null {\n return this.processText(token)\n }\n\n /**\n * Process a HTMLComment token.\n * @param token The token to process.\n */\n protected HTMLComment(token: Token): IntermediateToken | null {\n return this.processComment(token)\n }\n\n /**\n * Process a HTMLEndTagOpen token.\n * @param token The token to process.\n */\n protected HTMLEndTagOpen(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n let result: IntermediateToken | null = null\n\n if (this.currentToken != null || this.expressionStartToken != null) {\n result = this.commit()\n }\n\n this.currentToken = {\n type: \"EndTag\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n name: token.value,\n }\n\n return result\n }\n\n /**\n * Process a HTMLIdentifier token.\n * @param token The token to process.\n */\n protected HTMLIdentifier(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n if (\n this.currentToken == null ||\n this.currentToken.type === \"Text\" ||\n this.currentToken.type === \"Mustache\"\n ) {\n throw new Error(\"unreachable\")\n }\n if (this.currentToken.type === \"EndTag\") {\n this.reportParseError(token, \"end-tag-with-attributes\")\n return null\n }\n if (this.attributeNames.has(token.value)) {\n this.reportParseError(token, \"duplicate-attribute\")\n }\n this.attributeNames.add(token.value)\n\n this.attribute = {\n type: \"VAttribute\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n parent: DUMMY_PARENT,\n directive: false,\n key: {\n type: \"VIdentifier\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n parent: DUMMY_PARENT,\n name: token.value,\n rawName: this.text.slice(token.range[0], token.range[1]),\n },\n value: null,\n }\n this.attribute.key.parent = this.attribute\n\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n this.currentToken.attributes.push(this.attribute)\n\n return null\n }\n\n /**\n * Process a HTMLLiteral token.\n * @param token The token to process.\n */\n protected HTMLLiteral(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n if (this.attribute != null) {\n this.attribute.range[1] = token.range[1]\n this.attribute.loc.end = token.loc.end\n this.attribute.value = {\n type: \"VLiteral\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n parent: this.attribute,\n value: token.value,\n }\n\n if (\n this.currentToken == null ||\n this.currentToken.type !== \"StartTag\"\n ) {\n throw new Error(\"unreachable\")\n }\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n }\n\n return null\n }\n\n /**\n * Process a HTMLRCDataText token.\n * @param token The token to process.\n */\n protected HTMLRCDataText(token: Token): IntermediateToken | null {\n return this.processText(token)\n }\n\n /**\n * Process a HTMLRawText token.\n * @param token The token to process.\n */\n protected HTMLRawText(token: Token): IntermediateToken | null {\n return this.processText(token)\n }\n\n /**\n * Process a HTMLSelfClosingTagClose token.\n * @param token The token to process.\n */\n protected HTMLSelfClosingTagClose(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n if (this.currentToken == null || this.currentToken.type === \"Text\") {\n throw new Error(\"unreachable\")\n }\n\n if (this.currentToken.type === \"StartTag\") {\n this.currentToken.selfClosing = true\n } else {\n this.reportParseError(token, \"end-tag-with-trailing-solidus\")\n }\n\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n\n return this.commit()\n }\n\n /**\n * Process a HTMLTagClose token.\n * @param token The token to process.\n */\n protected HTMLTagClose(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n if (this.currentToken == null || this.currentToken.type === \"Text\") {\n throw new Error(\"unreachable\")\n }\n\n this.currentToken.range[1] = token.range[1]\n this.currentToken.loc.end = token.loc.end\n\n return this.commit()\n }\n\n /**\n * Process a HTMLTagOpen token.\n * @param token The token to process.\n */\n protected HTMLTagOpen(token: Token): IntermediateToken | null {\n this.tokens.push(token)\n\n let result: IntermediateToken | null = null\n\n if (this.currentToken != null || this.expressionStartToken != null) {\n result = this.commit()\n }\n\n this.currentToken = {\n type: \"StartTag\",\n range: [token.range[0], token.range[1]],\n loc: { start: token.loc.start, end: token.loc.end },\n name: token.value,\n rawName: this.text.slice(token.range[0] + 1, token.range[1]),\n selfClosing: false,\n attributes: [],\n }\n this.attribute = null\n this.attributeNames.clear()\n\n return result\n }\n\n /**\n * Process a HTMLText token.\n * @param token The token to process.\n */\n protected HTMLText(token: Token): IntermediateToken | null {\n return this.processText(token)\n }\n\n /**\n * Process a HTMLWhitespace token.\n * @param token The token to process.\n */\n protected HTMLWhitespace(token: Token): IntermediateToken | null {\n return this.processText(token)\n }\n\n /**\n * Process a VExpressionStart token.\n * @param token The token to process.\n */\n protected VExpressionStart(token: Token): IntermediateToken | null {\n if (this.expressionStartToken != null) {\n return this.processText(token)\n }\n const separated =\n this.currentToken != null &&\n this.currentToken.range[1] !== token.range[0]\n const result = separated ? this.commit() : null\n\n this.tokens.push(token)\n this.expressionStartToken = token\n\n return result\n }\n\n /**\n * Process a VExpressionEnd token.\n * @param token The token to process.\n */\n protected VExpressionEnd(token: Token): IntermediateToken | null {\n if (this.expressionStartToken == null) {\n return this.processText(token)\n }\n\n const start = this.expressionStartToken\n const end = last(this.expressionTokens) || start\n\n // If it's '{{}}', it's handled as a text.\n if (token.range[0] === start.range[1]) {\n this.tokens.pop()\n this.expressionStartToken = null\n const result = this.processText(start)\n this.processText(token)\n return result\n }\n\n // If invalid notation `</>` exists directly before this token, separate it.\n if (end.range[1] !== token.range[0]) {\n const result = this.commit()\n this.processText(token)\n return result\n }\n\n // Clear state.\n const value = this.expressionTokens.reduce(concat, \"\")\n this.tokens.push(token)\n this.expressionStartToken = null\n this.expressionTokens = []\n\n // Create token.\n const result = this.currentToken != null ? this.commit() : null\n this.currentToken = {\n type: \"Mustache\",\n range: [start.range[0], token.range[1]],\n loc: { start: start.loc.start, end: token.loc.end },\n value,\n startToken: start,\n endToken: token,\n }\n\n return result || this.commit()\n }\n}\n","/**\n * @author Toru Nagashima <https://github.com/mysticatea>\n * @copyright 2017 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\nimport assert from \"assert\"\nimport last from \"lodash/last\"\nimport findLastIndex from \"lodash/findLastIndex\"\nimport type {\n ErrorCode,\n HasLocation,\n Namespace,\n Token,\n VAttribute,\n VDocumentFragment,\n VElement,\n VExpressionContainer,\n VLiteral,\n} from \"../ast\"\nimport { NS, ParseError } from \"../ast\"\nimport { debug } from \"../common/debug\"\nimport { LocationCalculatorForHtml } from \"../common/location-calculator\"\nimport {\n convertToDirective,\n processMustache,\n resolveReferences,\n} from \"../template\"\nimport {\n MATHML_ATTRIBUTE_NAME_MAP,\n SVG_ATTRIBUTE_NAME_MAP,\n} from \"./util/attribute-names\"\nimport {\n HTML_CAN_BE_LEFT_OPEN_TAGS,\n HTML_NON_FHRASING_TAGS,\n HTML_RAWTEXT_TAGS,\n HTML_RCDATA_TAGS,\n HTML_VOID_ELEMENT_TAGS,\n SVG_ELEMENT_NAME_MAP,\n} from \"./util/tag-names\"\nimport type {\n IntermediateToken,\n EndTag,\n Mustache,\n StartTag,\n Text,\n} from \"./intermediate-tokenizer\"\nimport { IntermediateTokenizer } from \"./intermediate-tokenizer\"\nimport type { Tokenizer } from \"./tokenizer\"\nimport type { ParserOptions } from \"../common/parser-options\"\nimport {\n isSFCFile,\n getScriptParser,\n getParserLangFromSFC,\n} from \"../common/parser-options\"\nimport sortedIndexBy from \"lodash/sortedIndexBy\"\nimport sortedLastIndexBy from \"lodash/sortedLastIndexBy\"\nimport type {\n CustomTemplateTokenizer,\n CustomTemplateTokenizerConstructor,\n} from \"./custom-tokenizer\"\nimport { isScriptSetupElement, isTSLang } from \"../common/ast-utils\"\n\nconst DIRECTIVE_NAME = /^(?:v-|[.:@#]).*[^.:@#]$/u\nconst DT_DD = /^d[dt]$/u\nconst DUMMY_PARENT: any = Object.freeze({})\n\n/**\n * Gets the tag name from the given node or token.\n * For SFC, it returns the value of `rawName` to be case sensitive.\n */\nfunction getTagName(\n startTagOrElement: { name: string; rawName: string },\n isSFC: boolean,\n) {\n return isSFC ? startTagOrElement.rawName : startTagOrElement.name\n}\n\n/**\n * Check whether the element is a MathML text integration point or not.\n * @see https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher\n * @param element The current element.\n * @param isSFC For SFC, give `true`.\n * @returns `true` if the element is a MathML text integration point.\n */\nfunction isMathMLIntegrationPoint(element: VElement, isSFC: boolean): boolean {\n if (element.namespace === NS.MathML) {\n const name = getTagName(element, isSFC)\n return (\n name === \"mi\" ||\n name === \"mo\" ||\n name === \"mn\" ||\n name === \"ms\" ||\n name === \"mtext\"\n )\n }\n return false\n}\n\n/**\n * Check whether the element is a HTML integration point or not.\n * @see https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher\n * @param element The current element.\n * @param isSFC For SFC, give `true`.\n * @returns `true` if the element is a HTML integration point.\n */\nfunction isHTMLIntegrationPoint(element: VElement, isSFC: boolean): boolean {\n if (element.namespace === NS.MathML) {\n return (\n getTagName(element, isSFC) === \"annotation-xml\" &&\n element.startTag.attributes.some(\n (a) =>\n a.directive === false &&\n a.key.name === \"encoding\" &&\n a.value != null &&\n (a.value.value === \"text/html\" ||\n a.value.value === \"application/xhtml+xml\"),\n )\n )\n }\n if (element.namespace === NS.SVG) {\n const name = getTagName(element, isSFC)\n return name === \"foreignObject\" || name === \"desc\" || name === \"title\"\n }\n\n return false\n}\n\n/**\n * Adjust element names by the current namespace.\n * @param name The lowercase element name to adjust.\n * @param namespace The current namespace.\n * @returns The adjusted element name.\n */\nfunction adjustElementName(name: string, namespace: Namespace): string {\n if (namespace === NS.SVG) {\n return SVG_ELEMENT_NAME_MAP.get(name) || name\n }\n return name\n}\n\n/**\n * Adjust attribute names by the current namespace.\n * @param name The lowercase attribute name to adjust.\n * @param namespace The current namespace.\n * @returns The adjusted attribute name.\n */\nfunction adjustAttributeName(name: string, namespace: Namespace): string {\n if (namespace === NS.SVG) {\n return SVG_ATTRIBUTE_NAME_MAP.get(name) || name\n }\n if (namespace === NS.MathML) {\n return MATHML_ATTRIBUTE_NAME_MAP.get(name) || name\n }\n return name\n}\n\n/**\n * Set the location of the last child node to the end location of the given node.\n * @param node The node to commit the end location.\n */\nfunction propagateEndLocation(node: VDocumentFragment | VElement): void {\n const lastChild =\n (node.type === \"VElement\" ? node.endTag : null) || last(node.children)\n if (lastChild != null) {\n node.range[1] = lastChild.range[1]\n node.loc.end = lastChild.loc.end\n }\n}\n\n/**\n * The parser of HTML.\n * This is not following to the HTML spec completely because Vue.js template spec is pretty different to HTML.\n */\nexport class Parser {\n private tokenizer: IntermediateTokenizer | CustomTemplateTokenizer\n private locationCalculator: LocationCalculatorForHtml\n private baseParserOptions: ParserOptions\n private isSFC: boolean\n private document: VDocument