@vue-vine/eslint-parser 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +2129 -2078
  2. package/dist/index.mjs +2130 -2079
  3. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -24,20 +24,34 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  mod
25
25
  ));
26
26
 
27
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseFindIndex.js
28
- var require_baseFindIndex = __commonJS({
29
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseFindIndex.js"(exports, module) {
27
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/head.js
28
+ var require_head = __commonJS({
29
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/head.js"(exports, module) {
30
30
  "use strict";
31
- function baseFindIndex(array, predicate, fromIndex, fromRight) {
32
- var length = array.length, index = fromIndex + (fromRight ? 1 : -1);
33
- while (fromRight ? index-- : ++index < length) {
34
- if (predicate(array[index], index, array)) {
35
- return index;
36
- }
37
- }
38
- return -1;
31
+ function head(array) {
32
+ return array && array.length ? array[0] : void 0;
39
33
  }
40
- module.exports = baseFindIndex;
34
+ module.exports = head;
35
+ }
36
+ });
37
+
38
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/first.js
39
+ var require_first = __commonJS({
40
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/first.js"(exports, module) {
41
+ "use strict";
42
+ module.exports = require_head();
43
+ }
44
+ });
45
+
46
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/last.js
47
+ var require_last = __commonJS({
48
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/last.js"(exports, module) {
49
+ "use strict";
50
+ function last4(array) {
51
+ var length = array == null ? 0 : array.length;
52
+ return length ? array[length - 1] : void 0;
53
+ }
54
+ module.exports = last4;
41
55
  }
42
56
  });
43
57
 
@@ -2123,6 +2137,79 @@ var require_baseIteratee = __commonJS({
2123
2137
  }
2124
2138
  });
2125
2139
 
2140
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndexBy.js
2141
+ var require_baseSortedIndexBy = __commonJS({
2142
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndexBy.js"(exports, module) {
2143
+ "use strict";
2144
+ var isSymbol = require_isSymbol();
2145
+ var MAX_ARRAY_LENGTH = 4294967295;
2146
+ var MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
2147
+ var nativeFloor = Math.floor;
2148
+ var nativeMin = Math.min;
2149
+ function baseSortedIndexBy(array, value, iteratee, retHighest) {
2150
+ var low = 0, high = array == null ? 0 : array.length;
2151
+ if (high === 0) {
2152
+ return 0;
2153
+ }
2154
+ value = iteratee(value);
2155
+ var valIsNaN = value !== value, valIsNull = value === null, valIsSymbol = isSymbol(value), valIsUndefined = value === void 0;
2156
+ while (low < high) {
2157
+ var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), othIsDefined = computed !== void 0, othIsNull = computed === null, othIsReflexive = computed === computed, othIsSymbol = isSymbol(computed);
2158
+ if (valIsNaN) {
2159
+ var setLow = retHighest || othIsReflexive;
2160
+ } else if (valIsUndefined) {
2161
+ setLow = othIsReflexive && (retHighest || othIsDefined);
2162
+ } else if (valIsNull) {
2163
+ setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
2164
+ } else if (valIsSymbol) {
2165
+ setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
2166
+ } else if (othIsNull || othIsSymbol) {
2167
+ setLow = false;
2168
+ } else {
2169
+ setLow = retHighest ? computed <= value : computed < value;
2170
+ }
2171
+ if (setLow) {
2172
+ low = mid + 1;
2173
+ } else {
2174
+ high = mid;
2175
+ }
2176
+ }
2177
+ return nativeMin(high, MAX_ARRAY_INDEX);
2178
+ }
2179
+ module.exports = baseSortedIndexBy;
2180
+ }
2181
+ });
2182
+
2183
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/sortedIndexBy.js
2184
+ var require_sortedIndexBy = __commonJS({
2185
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/sortedIndexBy.js"(exports, module) {
2186
+ "use strict";
2187
+ var baseIteratee = require_baseIteratee();
2188
+ var baseSortedIndexBy = require_baseSortedIndexBy();
2189
+ function sortedIndexBy2(array, value, iteratee) {
2190
+ return baseSortedIndexBy(array, value, baseIteratee(iteratee, 2));
2191
+ }
2192
+ module.exports = sortedIndexBy2;
2193
+ }
2194
+ });
2195
+
2196
+ // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseFindIndex.js
2197
+ var require_baseFindIndex = __commonJS({
2198
+ "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseFindIndex.js"(exports, module) {
2199
+ "use strict";
2200
+ function baseFindIndex(array, predicate, fromIndex, fromRight) {
2201
+ var length = array.length, index = fromIndex + (fromRight ? 1 : -1);
2202
+ while (fromRight ? index-- : ++index < length) {
2203
+ if (predicate(array[index], index, array)) {
2204
+ return index;
2205
+ }
2206
+ }
2207
+ return -1;
2208
+ }
2209
+ module.exports = baseFindIndex;
2210
+ }
2211
+ });
2212
+
2126
2213
  // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_trimmedEndIndex.js
2127
2214
  var require_trimmedEndIndex = __commonJS({
2128
2215
  "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_trimmedEndIndex.js"(exports, module) {
@@ -2245,61 +2332,6 @@ var require_findLastIndex = __commonJS({
2245
2332
  }
2246
2333
  });
2247
2334
 
2248
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/last.js
2249
- var require_last = __commonJS({
2250
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/last.js"(exports, module) {
2251
- "use strict";
2252
- function last4(array) {
2253
- var length = array == null ? 0 : array.length;
2254
- return length ? array[length - 1] : void 0;
2255
- }
2256
- module.exports = last4;
2257
- }
2258
- });
2259
-
2260
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndexBy.js
2261
- var require_baseSortedIndexBy = __commonJS({
2262
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndexBy.js"(exports, module) {
2263
- "use strict";
2264
- var isSymbol = require_isSymbol();
2265
- var MAX_ARRAY_LENGTH = 4294967295;
2266
- var MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
2267
- var nativeFloor = Math.floor;
2268
- var nativeMin = Math.min;
2269
- function baseSortedIndexBy(array, value, iteratee, retHighest) {
2270
- var low = 0, high = array == null ? 0 : array.length;
2271
- if (high === 0) {
2272
- return 0;
2273
- }
2274
- value = iteratee(value);
2275
- var valIsNaN = value !== value, valIsNull = value === null, valIsSymbol = isSymbol(value), valIsUndefined = value === void 0;
2276
- while (low < high) {
2277
- var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), othIsDefined = computed !== void 0, othIsNull = computed === null, othIsReflexive = computed === computed, othIsSymbol = isSymbol(computed);
2278
- if (valIsNaN) {
2279
- var setLow = retHighest || othIsReflexive;
2280
- } else if (valIsUndefined) {
2281
- setLow = othIsReflexive && (retHighest || othIsDefined);
2282
- } else if (valIsNull) {
2283
- setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
2284
- } else if (valIsSymbol) {
2285
- setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
2286
- } else if (othIsNull || othIsSymbol) {
2287
- setLow = false;
2288
- } else {
2289
- setLow = retHighest ? computed <= value : computed < value;
2290
- }
2291
- if (setLow) {
2292
- low = mid + 1;
2293
- } else {
2294
- high = mid;
2295
- }
2296
- }
2297
- return nativeMin(high, MAX_ARRAY_INDEX);
2298
- }
2299
- module.exports = baseSortedIndexBy;
2300
- }
2301
- });
2302
-
2303
2335
  // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndex.js
2304
2336
  var require_baseSortedIndex = __commonJS({
2305
2337
  "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/_baseSortedIndex.js"(exports, module) {
@@ -2340,38 +2372,6 @@ var require_sortedLastIndex = __commonJS({
2340
2372
  }
2341
2373
  });
2342
2374
 
2343
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/head.js
2344
- var require_head = __commonJS({
2345
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/head.js"(exports, module) {
2346
- "use strict";
2347
- function head(array) {
2348
- return array && array.length ? array[0] : void 0;
2349
- }
2350
- module.exports = head;
2351
- }
2352
- });
2353
-
2354
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/first.js
2355
- var require_first = __commonJS({
2356
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/first.js"(exports, module) {
2357
- "use strict";
2358
- module.exports = require_head();
2359
- }
2360
- });
2361
-
2362
- // ../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/sortedIndexBy.js
2363
- var require_sortedIndexBy = __commonJS({
2364
- "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/sortedIndexBy.js"(exports, module) {
2365
- "use strict";
2366
- var baseIteratee = require_baseIteratee();
2367
- var baseSortedIndexBy = require_baseSortedIndexBy();
2368
- function sortedIndexBy2(array, value, iteratee) {
2369
- return baseSortedIndexBy(array, value, baseIteratee(iteratee, 2));
2370
- }
2371
- module.exports = sortedIndexBy2;
2372
- }
2373
- });
2374
-
2375
2375
  // src/parse.ts
2376
2376
  var _parser = require('@typescript-eslint/parser');
2377
2377
 
@@ -3019,2159 +3019,2210 @@ function createVirtualVineFnPropsReference({
3019
3019
  return virtualReference;
3020
3020
  }
3021
3021
 
3022
- // src/script/scope-analyzer.ts
3023
- var BUILTIN_COMPONENTS = /* @__PURE__ */ new Set([
3024
- "template",
3025
- "slot",
3026
- "component",
3027
- "Component",
3028
- "transition",
3029
- "Transition",
3030
- "transition-group",
3031
- "TransitionGroup",
3032
- "keep-alive",
3033
- "KeepAlive",
3034
- "teleport",
3035
- "Teleport",
3036
- "suspense",
3037
- "Suspense"
3038
- ]);
3039
- var BUILTIN_DIRECTIVES = /* @__PURE__ */ new Set([
3040
- "bind",
3041
- "on",
3042
- "text",
3043
- "html",
3044
- "show",
3045
- "if",
3046
- "else",
3047
- "else-if",
3048
- "for",
3049
- "model",
3050
- "slot",
3051
- "pre",
3052
- "cloak",
3053
- "once",
3054
- "memo",
3055
- "is"
3056
- ]);
3057
- var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot";
3058
- var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view";
3059
- var NATIVE_TAGS = /* @__PURE__ */ new Set([...HTML_TAGS.split(","), ...SVG_TAGS.split(",")]);
3060
- function isUnique(reference, index, references) {
3061
- return index === 0 || reference.identifier !== references[index - 1].identifier;
3062
- }
3063
- function camelize(str) {
3064
- return str.replace(/-(\w)/gu, (_, c) => c ? c.toUpperCase() : "");
3065
- }
3066
- function capitalize(str) {
3067
- return str[0].toUpperCase() + str.slice(1);
3068
- }
3069
- function hasDefinition(variable) {
3070
- return variable.defs.length >= 1;
3022
+ // src/common/debug.ts
3023
+ var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug);
3024
+ var debug = _debug2.default.call(void 0, "vue-vine-eslint-parser");
3025
+
3026
+ // src/common/error-utils.ts
3027
+ function insertError(templateMeta, error) {
3028
+ const index = templateMeta.errors.findIndex((e) => e.index === error.index);
3029
+ templateMeta.errors.splice(index, 0, error);
3071
3030
  }
3072
- function transformReference(reference) {
3073
- const ret = {
3074
- id: reference.identifier,
3075
- mode: reference.isReadOnly() ? "r" : reference.isWriteOnly() ? "w" : (
3076
- /* otherwise */
3077
- "rw"
3078
- ),
3079
- variable: null,
3080
- isValueReference: reference.isValueReference,
3081
- isTypeReference: reference.isTypeReference
3031
+
3032
+ // src/common/token-utils.ts
3033
+ function createSimpleToken(type, start, end, value, linesAndColumns) {
3034
+ return {
3035
+ type,
3036
+ range: [start, end],
3037
+ loc: {
3038
+ start: linesAndColumns.getLocFromIndex(start),
3039
+ end: linesAndColumns.getLocFromIndex(end)
3040
+ },
3041
+ value
3082
3042
  };
3083
- Object.defineProperty(ret, "variable", { enumerable: false });
3084
- return ret;
3085
3043
  }
3086
- function transformVariable(variable, kind) {
3087
- const ret = {
3088
- id: variable.defs[0].name,
3089
- kind,
3090
- references: []
3091
- };
3092
- Object.defineProperty(ret, "references", { enumerable: false });
3093
- return ret;
3044
+ function insertComments(templateMeta, newComments) {
3045
+ if (newComments.length === 0) {
3046
+ return;
3047
+ }
3048
+ const index = templateMeta.comments.findIndex((comment) => comment.range[0] === newComments[0].range[0]);
3049
+ templateMeta.comments.splice(index, 0, ...newComments);
3094
3050
  }
3095
- function getForScope(scope) {
3096
- const child = scope.childScopes[0];
3097
- return child.block === scope.block ? child.childScopes[0] : child;
3051
+ function replaceTokens(templateMeta, node, newTokens) {
3052
+ const index = templateMeta.tokens.findIndex((token) => token.range[0] === node.range[0]);
3053
+ const count = templateMeta.tokens.findIndex((token) => token.range[1] === node.range[1]) - index + 1;
3054
+ templateMeta.tokens.splice(index, count, ...newTokens);
3098
3055
  }
3099
- function analyzeScope(ast, parserOptions) {
3100
- const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions) || 2022;
3101
- const ecmaFeatures = parserOptions.ecmaFeatures || {};
3102
- const sourceType = parserOptions.sourceType || "script";
3103
- const result = getEslintScope().analyze(ast, {
3104
- ignoreEval: true,
3105
- nodejsScope: false,
3106
- impliedStrict: ecmaFeatures.impliedStrict,
3107
- ecmaVersion,
3108
- sourceType,
3109
- fallback: getFallbackKeys
3056
+
3057
+ // src/script/index.ts
3058
+ var import_first = __toESM(require_first());
3059
+ var import_last = __toESM(require_last());
3060
+ var import_sortedIndexBy = __toESM(require_sortedIndexBy());
3061
+
3062
+
3063
+ // src/common/fix-locations.ts
3064
+ function fixLocations(result, locationCalculator) {
3065
+ fixNodeLocations(result.ast, result.visitorKeys, locationCalculator);
3066
+ for (const token of result.ast.tokens || []) {
3067
+ fixLocation(token, locationCalculator);
3068
+ }
3069
+ for (const comment of result.ast.comments || []) {
3070
+ fixLocation(comment, locationCalculator);
3071
+ }
3072
+ }
3073
+ function fixNodeLocations(rootNode, visitorKeys, locationCalculator) {
3074
+ const traversed = /* @__PURE__ */ new Map();
3075
+ traverseNodes(rootNode, {
3076
+ visitorKeys,
3077
+ enterNode(node, parent) {
3078
+ if (!traversed.has(node)) {
3079
+ traversed.set(node, node);
3080
+ node.parent = parent;
3081
+ if (traversed.has(node.range)) {
3082
+ if (!traversed.has(node.loc)) {
3083
+ node.loc.start = locationCalculator.getLocFromIndex(
3084
+ node.range[0]
3085
+ );
3086
+ node.loc.end = locationCalculator.getLocFromIndex(
3087
+ node.range[1]
3088
+ );
3089
+ traversed.set(node.loc, node);
3090
+ } else if (node.start != null || node.end != null) {
3091
+ const traversedNode = traversed.get(node.range);
3092
+ if (traversedNode.type === node.type) {
3093
+ node.start = traversedNode.start;
3094
+ node.end = traversedNode.end;
3095
+ }
3096
+ }
3097
+ } else {
3098
+ fixLocation(node, locationCalculator);
3099
+ traversed.set(node.range, node);
3100
+ traversed.set(node.loc, node);
3101
+ }
3102
+ }
3103
+ },
3104
+ leaveNode() {
3105
+ }
3110
3106
  });
3111
- return result;
3112
3107
  }
3113
- function analyze(parserResult, parserOptions) {
3114
- const scopeManager = parserResult.scopeManager || analyzeScope(parserResult.ast, parserOptions);
3115
- return scopeManager.globalScope;
3108
+ function fixLocation(node, locationCalculator) {
3109
+ const range = node.range;
3110
+ const loc = node.loc;
3111
+ const d0 = locationCalculator.getFixOffset(range[0], "start");
3112
+ const d1 = locationCalculator.getFixOffset(range[1], "end");
3113
+ if (d0 !== 0) {
3114
+ range[0] += d0;
3115
+ if (node.start != null) {
3116
+ node.start += d0;
3117
+ }
3118
+ loc.start = locationCalculator.getLocFromIndex(range[0]);
3119
+ }
3120
+ if (d1 !== 0) {
3121
+ range[1] += d1;
3122
+ if (node.end != null) {
3123
+ node.end += d0;
3124
+ }
3125
+ loc.end = locationCalculator.getLocFromIndex(range[1]);
3126
+ }
3127
+ return node;
3116
3128
  }
3117
- function analyzeExternalReferences(parserResult, parserOptions) {
3118
- const scope = analyze(parserResult, parserOptions);
3119
- return scope.through.filter(isUnique).map(transformReference);
3129
+ function fixErrorLocation(error, locationCalculator) {
3130
+ const diff = locationCalculator.getFixOffset(error.index, "start");
3131
+ error.index += diff;
3132
+ const loc = locationCalculator.getLocFromIndex(error.index);
3133
+ error.lineNumber = loc.line;
3134
+ error.column = loc.column;
3120
3135
  }
3121
- function analyzeVariablesAndExternalReferences(parserResult, kind, parserOptions) {
3122
- const scope = analyze(parserResult, parserOptions);
3136
+
3137
+ // src/common/parser-object.ts
3138
+ function isParserObject(value) {
3139
+ return isEnhancedParserObject(value) || isBasicParserObject(value);
3140
+ }
3141
+ function isEnhancedParserObject(value) {
3142
+ return Boolean(value && typeof value.parseForESLint === "function");
3143
+ }
3144
+ function isBasicParserObject(value) {
3145
+ return Boolean(value && typeof value.parse === "function");
3146
+ }
3147
+
3148
+ // src/script/index.ts
3149
+ var ALIAS_ITERATOR = /^([\s\S]*?(?:\s|\)))(\bin\b|\bof\b)([\s\S]*)$/u;
3150
+ var PARENS = /^(\s*\()([\s\S]*?)(\)\s*)$/u;
3151
+ var DUMMY_PARENT = {};
3152
+ var IS_FUNCTION_EXPRESSION = /^\s*(?:[\w$]+|\([^)]*\))\s*=>|^function\s*\(/u;
3153
+ var IS_SIMPLE_PATH = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/u;
3154
+ function processVForAliasAndIterator(code) {
3155
+ const match = ALIAS_ITERATOR.exec(code);
3156
+ if (match != null) {
3157
+ const aliases = match[1];
3158
+ const parenMatch = PARENS.exec(aliases);
3159
+ return {
3160
+ aliases,
3161
+ hasParens: Boolean(parenMatch),
3162
+ aliasesWithBrackets: parenMatch ? `${parenMatch[1].slice(0, -1)}[${parenMatch[2]}]${parenMatch[3].slice(1)}` : `[${aliases.slice(0, -1)}]`,
3163
+ delimiter: match[2] || "",
3164
+ iterator: match[3]
3165
+ };
3166
+ }
3123
3167
  return {
3124
- variables: getForScope(scope).variables.filter(hasDefinition).map((v) => transformVariable(v, kind)),
3125
- references: scope.through.filter(isUnique).map(transformReference)
3168
+ aliases: "",
3169
+ hasParens: false,
3170
+ aliasesWithBrackets: "",
3171
+ delimiter: "",
3172
+ iterator: code
3126
3173
  };
3127
3174
  }
3128
- function collectVariablesForVCF(tsFileScopeManager, templateRoot) {
3129
- const scriptVariables = /* @__PURE__ */ new Map();
3130
- const globalScope = tsFileScopeManager.globalScope;
3131
- if (!globalScope) {
3132
- return scriptVariables;
3133
- }
3134
- for (const variable of globalScope.variables) {
3135
- scriptVariables.set(variable.name, variable);
3136
- }
3137
- const moduleScope = globalScope.childScopes.find(
3138
- (scope) => scope.type === "module"
3175
+ function getCommaTokenBeforeNode(tokens, node) {
3176
+ let tokenIndex = (0, import_sortedIndexBy.default)(
3177
+ tokens,
3178
+ { range: node.range },
3179
+ (t) => t.range[0]
3139
3180
  );
3140
- for (const variable of moduleScope && moduleScope.variables || []) {
3141
- scriptVariables.set(variable.name, variable);
3142
- }
3143
- let foundVCF = templateRoot.parent;
3144
- let foundVCFScope;
3145
- if (templateRoot.parent) {
3146
- do {
3147
- foundVCF = foundVCF.parent;
3148
- } while (foundVCF && foundVCF.type !== "FunctionDeclaration" && foundVCF.type !== "FunctionExpression" && foundVCF.type !== "ArrowFunctionExpression");
3149
- if (foundVCF) {
3150
- Object.assign(
3151
- foundVCF,
3152
- { __isVine__: true }
3153
- );
3154
- const tryGetVCFScope = tsFileScopeManager.nodeToScope.get(foundVCF);
3155
- if (_optionalChain([tryGetVCFScope, 'optionalAccess', _7 => _7[0]])) {
3156
- foundVCFScope = tryGetVCFScope[0];
3157
- for (const variable of foundVCFScope.variables) {
3158
- scriptVariables.set(variable.name, variable);
3159
- }
3160
- const compFnPropsIdentifier = _optionalChain([foundVCF, 'access', _8 => _8.params, 'optionalAccess', _9 => _9[0], 'optionalAccess', _10 => _10.type]) === "Identifier" && _optionalChain([foundVCF, 'access', _11 => _11.params, 'access', _12 => _12[0], 'optionalAccess', _13 => _13.name]) === "props" ? foundVCF.params[0] : null;
3161
- const propsVar = scriptVariables.get("props");
3162
- if (compFnPropsIdentifier && propsVar) {
3163
- ;
3164
- propsVar.eslintUsed = true;
3165
- propsVar.references.push(
3166
- createVirtualVineFnPropsReference({
3167
- foundVCFScope,
3168
- compFnPropsIdentifier
3169
- })
3170
- );
3171
- }
3172
- }
3181
+ while (tokenIndex >= 0) {
3182
+ const token = tokens[tokenIndex];
3183
+ if (token.type === "Punctuator" && token.value === ",") {
3184
+ return token;
3173
3185
  }
3186
+ tokenIndex -= 1;
3174
3187
  }
3175
- return scriptVariables;
3188
+ return null;
3176
3189
  }
3177
- function analyzeUsedInTemplateVariables(scopeManager, templateRoot) {
3178
- const scriptVariables = collectVariablesForVCF(scopeManager, templateRoot);
3179
- const markedVariables = /* @__PURE__ */ new Set();
3180
- function markSetupReferenceVariableAsUsed(name) {
3181
- if (scriptVariables.has(name)) {
3182
- markVariableAsUsed(name);
3183
- return true;
3184
- }
3185
- const camelName = camelize(name);
3186
- if (scriptVariables.has(camelName)) {
3187
- markVariableAsUsed(camelName);
3188
- return true;
3189
- }
3190
- const pascalName = capitalize(camelName);
3191
- if (scriptVariables.has(pascalName)) {
3192
- markVariableAsUsed(pascalName);
3193
- return true;
3194
- }
3195
- return false;
3196
- }
3197
- function markVariableAsUsed(nameOrRef) {
3198
- let name;
3199
- let isValueReference;
3200
- let isTypeReference;
3201
- if (typeof nameOrRef === "string") {
3202
- name = nameOrRef;
3203
- } else {
3204
- name = nameOrRef.id.name;
3205
- isValueReference = nameOrRef.isValueReference;
3206
- isTypeReference = nameOrRef.isTypeReference;
3207
- }
3208
- const variable = scriptVariables.get(name);
3209
- if (!variable || variable.identifiers.length === 0) {
3210
- return;
3211
- }
3212
- if (markedVariables.has(name)) {
3213
- return;
3190
+ function throwEmptyError(locationCalculator, expected) {
3191
+ const loc = locationCalculator.getLocation(0);
3192
+ const err = new ParseError(
3193
+ `Expected to be ${expected}, but got empty.`,
3194
+ void 0,
3195
+ 0,
3196
+ loc.line,
3197
+ loc.column
3198
+ );
3199
+ fixErrorLocation(err, locationCalculator);
3200
+ throw err;
3201
+ }
3202
+ function throwUnexpectedTokenError(name, token) {
3203
+ const err = new ParseError(
3204
+ `Unexpected token '${name}'.`,
3205
+ void 0,
3206
+ token.range[0],
3207
+ token.loc.start.line,
3208
+ token.loc.start.column
3209
+ );
3210
+ throw err;
3211
+ }
3212
+ function throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator) {
3213
+ if (ParseError.isParseError(err)) {
3214
+ const endOffset = locationCalculator.getOffsetWithGap(code.length);
3215
+ if (err.index >= endOffset) {
3216
+ err.message = "Unexpected end of expression.";
3214
3217
  }
3215
- markedVariables.add(name);
3216
- const reference = new tsEscopeTypes2.Reference(
3217
- variable.identifiers[0],
3218
- variable.scope,
3219
- 1 /* Read */,
3220
- void 0,
3221
- void 0,
3222
- void 0,
3223
- isValueReference ? 1 /* Value */ : isTypeReference ? 2 /* Type */ : void 0
3218
+ }
3219
+ throw err;
3220
+ }
3221
+ function parseScriptFragment(code, locationCalculator, parserOptions) {
3222
+ try {
3223
+ const result = parseScript(
3224
+ code,
3225
+ parserOptions
3224
3226
  );
3225
- reference.vueUsedInTemplate = true;
3226
- reference.isWrite = () => false;
3227
- reference.isWriteOnly = () => false;
3228
- reference.isRead = () => true;
3229
- reference.isReadOnly = () => true;
3230
- reference.isReadWrite = () => false;
3231
- variable.references.push(reference);
3232
- reference.resolved = variable;
3233
- if (reference.isTypeReference) {
3234
- ;
3235
- variable.eslintUsed = true;
3227
+ fixLocations(result, locationCalculator);
3228
+ return result;
3229
+ } catch (err) {
3230
+ const perr = ParseError.normalize(err);
3231
+ if (perr) {
3232
+ fixErrorLocation(perr, locationCalculator);
3233
+ throw perr;
3236
3234
  }
3235
+ throw err;
3237
3236
  }
3238
- function processVExpressionContainer(node) {
3239
- for (const reference of node.references.filter(
3240
- (ref) => ref.variable == null
3241
- )) {
3242
- markVariableAsUsed(reference);
3237
+ }
3238
+ var validDivisionCharRE = /[\w).+\-$\]]/u;
3239
+ function splitFilters(exp) {
3240
+ const result = [];
3241
+ let inSingle = false;
3242
+ let inDouble = false;
3243
+ let inTemplateString = false;
3244
+ let inRegex = false;
3245
+ let curly = 0;
3246
+ let square = 0;
3247
+ let paren = 0;
3248
+ let lastFilterIndex = 0;
3249
+ let c = 0;
3250
+ let prev = 0;
3251
+ for (let i = 0; i < exp.length; i++) {
3252
+ prev = c;
3253
+ c = exp.charCodeAt(i);
3254
+ if (inSingle) {
3255
+ if (c === 39 && prev !== 92) {
3256
+ inSingle = false;
3257
+ }
3258
+ } else if (inDouble) {
3259
+ if (c === 34 && prev !== 92) {
3260
+ inDouble = false;
3261
+ }
3262
+ } else if (inTemplateString) {
3263
+ if (c === 96 && prev !== 92) {
3264
+ inTemplateString = false;
3265
+ }
3266
+ } else if (inRegex) {
3267
+ if (c === 47 && prev !== 92) {
3268
+ inRegex = false;
3269
+ }
3270
+ } else if (c === 124 && exp.charCodeAt(i + 1) !== 124 && exp.charCodeAt(i - 1) !== 124 && !curly && !square && !paren) {
3271
+ result.push(exp.slice(lastFilterIndex, i));
3272
+ lastFilterIndex = i + 1;
3273
+ } else {
3274
+ switch (c) {
3275
+ case 34:
3276
+ inDouble = true;
3277
+ break;
3278
+ case 39:
3279
+ inSingle = true;
3280
+ break;
3281
+ case 96:
3282
+ inTemplateString = true;
3283
+ break;
3284
+ case 40:
3285
+ paren++;
3286
+ break;
3287
+ case 41:
3288
+ paren--;
3289
+ break;
3290
+ case 91:
3291
+ square++;
3292
+ break;
3293
+ case 93:
3294
+ square--;
3295
+ break;
3296
+ case 123:
3297
+ curly++;
3298
+ break;
3299
+ case 125:
3300
+ curly--;
3301
+ break;
3302
+ }
3303
+ if (c === 47) {
3304
+ let j = i - 1;
3305
+ let p;
3306
+ for (; j >= 0; j--) {
3307
+ p = exp.charAt(j);
3308
+ if (p !== " ") {
3309
+ break;
3310
+ }
3311
+ }
3312
+ if (!p || !validDivisionCharRE.test(p)) {
3313
+ inRegex = true;
3314
+ }
3315
+ }
3243
3316
  }
3244
3317
  }
3245
- function processVElement(node) {
3246
- if (node.rawName === node.name && NATIVE_TAGS.has(node.rawName) || BUILTIN_COMPONENTS.has(node.rawName)) {
3247
- return;
3318
+ result.push(exp.slice(lastFilterIndex));
3319
+ return result;
3320
+ }
3321
+ function parseExpressionBody(code, locationCalculator, parserOptions, allowEmpty = false) {
3322
+ debug('[script] parse expression: "0(%s)"', code);
3323
+ try {
3324
+ const result = parseScriptFragment(
3325
+ `0(${code})`,
3326
+ locationCalculator.getSubCalculatorShift(-2),
3327
+ parserOptions
3328
+ );
3329
+ const { ast } = result;
3330
+ const tokens = ast.tokens || [];
3331
+ const comments = ast.comments || [];
3332
+ const references = analyzeExternalReferences(result, parserOptions);
3333
+ const statement = ast.body[0];
3334
+ const callExpression = statement.expression;
3335
+ const expression = callExpression.arguments[0];
3336
+ if (!allowEmpty && !expression) {
3337
+ return throwEmptyError(locationCalculator, "an expression");
3248
3338
  }
3249
- if (!markSetupReferenceVariableAsUsed(node.rawName)) {
3250
- const dotIndex = node.rawName.indexOf(".");
3251
- if (dotIndex > 0) {
3252
- markSetupReferenceVariableAsUsed(
3253
- node.rawName.slice(0, dotIndex)
3254
- );
3255
- }
3339
+ if (expression && expression.type === "SpreadElement") {
3340
+ return throwUnexpectedTokenError("...", expression);
3256
3341
  }
3257
- }
3258
- function processVAttribute(node) {
3259
- if (node.directive) {
3260
- if (BUILTIN_DIRECTIVES.has(node.key.name.name)) {
3261
- return;
3262
- }
3263
- markSetupReferenceVariableAsUsed(`v-${node.key.name.rawName}`);
3264
- } else if (node.key.name === "ref" && node.value) {
3265
- markVariableAsUsed(node.value.value);
3342
+ if (callExpression.arguments[1]) {
3343
+ const node = callExpression.arguments[1];
3344
+ return throwUnexpectedTokenError(
3345
+ ",",
3346
+ getCommaTokenBeforeNode(tokens, node) || node
3347
+ );
3266
3348
  }
3349
+ tokens.shift();
3350
+ tokens.shift();
3351
+ tokens.pop();
3352
+ return { expression, tokens, comments, references, variables: [] };
3353
+ } catch (err) {
3354
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3267
3355
  }
3268
- traverseNodes(templateRoot, {
3269
- enterNode(node) {
3270
- if (node.type === "VExpressionContainer") {
3271
- processVExpressionContainer(node);
3272
- } else if (node.type === "VElement") {
3273
- processVElement(node);
3274
- } else if (node.type === "VAttribute") {
3275
- processVAttribute(node);
3276
- }
3277
- },
3278
- leaveNode() {
3279
- }
3280
- });
3281
3356
  }
3282
-
3283
- // src/template/parser.ts
3284
- var import_findLastIndex = __toESM(require_findLastIndex());
3285
- var import_last3 = __toESM(require_last());
3286
- var _assert = require('assert'); var _assert2 = _interopRequireDefault(_assert);
3287
-
3288
- // src/common/debug.ts
3289
- var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug);
3290
- var debug = _debug2.default.call(void 0, "vue-vine-eslint-parser");
3291
-
3292
- // src/common/location-calculator.ts
3293
- var import_sortedLastIndex2 = __toESM(require_sortedLastIndex());
3294
-
3295
- // src/common/lines-and-columns.ts
3296
- var import_sortedLastIndex = __toESM(require_sortedLastIndex());
3297
- var LinesAndColumns = class {
3298
-
3299
- /**
3300
- * Initialize.
3301
- * @param ltOffsets The list of the offset of line terminators.
3302
- */
3303
- constructor(ltOffsets) {
3304
- this.ltOffsets = ltOffsets;
3305
- }
3306
- /**
3307
- * Calculate the location of the given index.
3308
- * @param index The index to calculate their location.
3309
- * @returns The location of the index.
3310
- */
3311
- getLocFromIndex(index) {
3312
- const line = (0, import_sortedLastIndex.default)(this.ltOffsets, index) + 1;
3313
- const column = index - (line === 1 ? 0 : this.ltOffsets[line - 2]);
3314
- return { line, column };
3315
- }
3316
- createOffsetLocationCalculator(offset) {
3317
- return {
3318
- getFixOffset() {
3319
- return offset;
3320
- },
3321
- getLocFromIndex: this.getLocFromIndex.bind(this)
3357
+ function parseFilter(code, locationCalculator, parserOptions) {
3358
+ debug('[script] parse filter: "%s"', code);
3359
+ try {
3360
+ const expression = {
3361
+ type: "VFilter",
3362
+ parent: null,
3363
+ range: [0, 0],
3364
+ loc: {},
3365
+ callee: null,
3366
+ arguments: []
3322
3367
  };
3368
+ const tokens = [];
3369
+ const comments = [];
3370
+ const references = [];
3371
+ const paren = code.indexOf("(");
3372
+ const calleeCode = paren === -1 ? code : code.slice(0, paren);
3373
+ const argsCode = paren === -1 ? null : code.slice(paren);
3374
+ if (calleeCode.trim()) {
3375
+ const spaces = /^\s*/u.exec(calleeCode)[0];
3376
+ const subCalculator = locationCalculator.getSubCalculatorShift(
3377
+ spaces.length
3378
+ );
3379
+ const { ast } = parseScriptFragment(
3380
+ `"${calleeCode.trim()}"`,
3381
+ subCalculator,
3382
+ parserOptions
3383
+ );
3384
+ const statement = ast.body[0];
3385
+ const callee = statement.expression;
3386
+ if (callee.type !== "Literal") {
3387
+ const { loc, range } = ast.tokens[0];
3388
+ return throwUnexpectedTokenError('"', {
3389
+ range: [range[1] - 1, range[1]],
3390
+ loc: {
3391
+ start: {
3392
+ line: loc.end.line,
3393
+ column: loc.end.column - 1
3394
+ },
3395
+ end: loc.end
3396
+ }
3397
+ });
3398
+ }
3399
+ expression.callee = {
3400
+ type: "Identifier",
3401
+ parent: expression,
3402
+ range: [
3403
+ callee.range[0],
3404
+ subCalculator.getOffsetWithGap(calleeCode.trim().length)
3405
+ ],
3406
+ loc: {
3407
+ start: callee.loc.start,
3408
+ end: subCalculator.getLocation(calleeCode.trim().length)
3409
+ },
3410
+ name: String(callee.value)
3411
+ };
3412
+ tokens.push({
3413
+ type: "Identifier",
3414
+ value: calleeCode.trim(),
3415
+ range: expression.callee.range,
3416
+ loc: expression.callee.loc
3417
+ });
3418
+ } else {
3419
+ return throwEmptyError(locationCalculator, "a filter name");
3420
+ }
3421
+ if (argsCode != null) {
3422
+ const result = parseScriptFragment(
3423
+ `0${argsCode}`,
3424
+ locationCalculator.getSubCalculatorAfter(paren).getSubCalculatorShift(-1),
3425
+ parserOptions
3426
+ );
3427
+ const { ast } = result;
3428
+ const statement = ast.body[0];
3429
+ const callExpression = statement.expression;
3430
+ ast.tokens.shift();
3431
+ if (callExpression.type !== "CallExpression" || callExpression.callee.type !== "Literal") {
3432
+ let nestCount = 1;
3433
+ for (const token2 of ast.tokens.slice(1)) {
3434
+ if (nestCount === 0) {
3435
+ return throwUnexpectedTokenError(token2.value, token2);
3436
+ }
3437
+ if (token2.type === "Punctuator" && token2.value === "(") {
3438
+ nestCount += 1;
3439
+ }
3440
+ if (token2.type === "Punctuator" && token2.value === ")") {
3441
+ nestCount -= 1;
3442
+ }
3443
+ }
3444
+ const token = (0, import_last.default)(ast.tokens);
3445
+ return throwUnexpectedTokenError(token.value, token);
3446
+ }
3447
+ for (const argument of callExpression.arguments) {
3448
+ argument.parent = expression;
3449
+ expression.arguments.push(argument);
3450
+ }
3451
+ tokens.push(...ast.tokens);
3452
+ comments.push(...ast.comments);
3453
+ references.push(...analyzeExternalReferences(result, parserOptions));
3454
+ }
3455
+ const firstToken = tokens[0];
3456
+ const lastToken = (0, import_last.default)(tokens);
3457
+ expression.range = [firstToken.range[0], lastToken.range[1]];
3458
+ expression.loc = { start: firstToken.loc.start, end: lastToken.loc.end };
3459
+ return { expression, tokens, comments, references, variables: [] };
3460
+ } catch (err) {
3461
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3323
3462
  }
3324
- };
3325
-
3326
- // src/common/location-calculator.ts
3327
- var LocationCalculatorForHtml = class _LocationCalculatorForHtml extends LinesAndColumns {
3328
-
3329
-
3330
-
3331
-
3332
- /**
3333
- * Initialize this calculator.
3334
- * @param gapOffsets The list of the offset of removed characters in tokenization phase.
3335
- * @param ltOffsets The list of the offset of line terminators.
3336
- * @param baseOffset The base offset to calculate locations.
3337
- * @param shiftOffset The shift offset to calculate locations.
3338
- */
3339
- constructor(gapOffsets, ltOffsets, baseOffset, shiftOffset = 0) {
3340
- super(ltOffsets);
3341
- this.gapOffsets = gapOffsets;
3342
- this.ltOffsets = ltOffsets;
3343
- this.baseOffset = baseOffset || 0;
3344
- this.baseIndexOfGap = this.baseOffset === 0 ? 0 : (0, import_sortedLastIndex2.default)(gapOffsets, this.baseOffset);
3345
- this.shiftOffset = shiftOffset;
3346
- }
3347
- /**
3348
- * Get sub calculator which have the given base offset.
3349
- * @param offset The base offset of new sub calculator.
3350
- * @returns Sub calculator.
3351
- */
3352
- getSubCalculatorAfter(offset) {
3353
- return new _LocationCalculatorForHtml(
3354
- this.gapOffsets,
3355
- this.ltOffsets,
3356
- this.baseOffset + offset,
3357
- this.shiftOffset
3463
+ }
3464
+ function loadParser(parser) {
3465
+ if (parser !== "espree") {
3466
+ const __require = createRequire(
3467
+ typeof __filename ? __filename : fileURLToPath2(import.meta.url)
3358
3468
  );
3469
+ return __require(parser);
3359
3470
  }
3360
- /**
3361
- * Get sub calculator that shifts the given offset.
3362
- * @param offset The shift of new sub calculator.
3363
- * @returns Sub calculator.
3364
- */
3365
- getSubCalculatorShift(offset) {
3366
- return new _LocationCalculatorForHtml(
3367
- this.gapOffsets,
3368
- this.ltOffsets,
3369
- this.baseOffset,
3370
- this.shiftOffset + offset
3471
+ return getEspreeFromUser();
3472
+ }
3473
+ function parseScript(code, parserOptions) {
3474
+ const parser = typeof parserOptions.parser === "string" ? loadParser(parserOptions.parser) : isParserObject(parserOptions.parser) ? parserOptions.parser : getEspreeFromEcmaVersion(parserOptions.ecmaVersion);
3475
+ const result = isEnhancedParserObject(parser) ? parser.parseForESLint(code, parserOptions) : parser.parse(code, parserOptions);
3476
+ if (result.ast != null) {
3477
+ return result;
3478
+ }
3479
+ return { ast: result };
3480
+ }
3481
+ function parseExpression(code, locationCalculator, parserOptions, { allowEmpty = false, allowFilters = false } = {}) {
3482
+ debug('[script] parse expression: "%s"', code);
3483
+ const [mainCode, ...filterCodes] = allowFilters ? splitFilters(code) : [code];
3484
+ if (filterCodes.length === 0) {
3485
+ return parseExpressionBody(
3486
+ code,
3487
+ locationCalculator,
3488
+ parserOptions,
3489
+ allowEmpty
3371
3490
  );
3372
3491
  }
3373
- /**
3374
- * Calculate gap at the given index.
3375
- * @param index The index to calculate gap.
3376
- */
3377
- _getGap(index) {
3378
- const offsets = this.gapOffsets;
3379
- let g0 = (0, import_sortedLastIndex2.default)(offsets, index + this.baseOffset);
3380
- let pos = index + this.baseOffset + g0 - this.baseIndexOfGap;
3381
- while (g0 < offsets.length && offsets[g0] <= pos) {
3382
- g0 += 1;
3383
- pos += 1;
3492
+ const retB = parseExpressionBody(
3493
+ mainCode,
3494
+ locationCalculator,
3495
+ parserOptions
3496
+ );
3497
+ if (!retB.expression) {
3498
+ return retB;
3499
+ }
3500
+ const ret = retB;
3501
+ ret.expression = {
3502
+ type: "VFilterSequenceExpression",
3503
+ parent: null,
3504
+ expression: retB.expression,
3505
+ filters: [],
3506
+ range: retB.expression.range.slice(0),
3507
+ loc: Object.assign({}, retB.expression.loc)
3508
+ };
3509
+ ret.expression.expression.parent = ret.expression;
3510
+ let prevLoc = mainCode.length;
3511
+ for (const filterCode of filterCodes) {
3512
+ ret.tokens.push(
3513
+ fixLocation(
3514
+ {
3515
+ type: "Punctuator",
3516
+ value: "|",
3517
+ range: [prevLoc, prevLoc + 1],
3518
+ loc: {}
3519
+ },
3520
+ locationCalculator
3521
+ )
3522
+ );
3523
+ const retF = parseFilter(
3524
+ filterCode,
3525
+ locationCalculator.getSubCalculatorShift(prevLoc + 1),
3526
+ parserOptions
3527
+ );
3528
+ if (retF) {
3529
+ if (retF.expression) {
3530
+ ret.expression.filters.push(retF.expression);
3531
+ retF.expression.parent = ret.expression;
3532
+ }
3533
+ ret.tokens.push(...retF.tokens);
3534
+ ret.comments.push(...retF.comments);
3535
+ ret.references.push(...retF.references);
3384
3536
  }
3385
- return g0 - this.baseIndexOfGap;
3537
+ prevLoc += 1 + filterCode.length;
3386
3538
  }
3387
- /**
3388
- * Calculate the location of the given index.
3389
- * @param index The index to calculate their location.
3390
- * @returns The location of the index.
3391
- */
3392
- getLocation(index) {
3393
- return this.getLocFromIndex(this.getOffsetWithGap(index));
3539
+ const lastToken = (0, import_last.default)(ret.tokens);
3540
+ ret.expression.range[1] = lastToken.range[1];
3541
+ ret.expression.loc.end = lastToken.loc.end;
3542
+ return ret;
3543
+ }
3544
+ function parseVForExpression(code, locationCalculator, parserOptions) {
3545
+ if (code.trim() === "") {
3546
+ throwEmptyError(locationCalculator, "'<alias> in <expression>'");
3394
3547
  }
3395
- /**
3396
- * Calculate the offset of the given index.
3397
- * @param index The index to calculate their location.
3398
- * @returns The offset of the index.
3399
- */
3400
- getOffsetWithGap(index) {
3401
- return index + this.getFixOffset(index);
3402
- }
3403
- /**
3404
- * Gets the fix location offset of the given offset with using the base offset of this calculator.
3405
- * @param offset The offset to modify.
3406
- */
3407
- getFixOffset(offset) {
3408
- const shiftOffset = this.shiftOffset;
3409
- const gap = this._getGap(offset + shiftOffset);
3410
- return this.baseOffset + gap + shiftOffset;
3411
- }
3412
- };
3413
-
3414
- // src/template/intermediate-tokenizer.ts
3415
- var import_last = __toESM(require_last());
3416
-
3417
- var DUMMY_PARENT = Object.freeze({});
3418
- function concat(text, token) {
3419
- return text + token.value;
3420
- }
3421
- var IntermediateTokenizer = class {
3422
-
3423
-
3424
-
3425
-
3426
-
3427
-
3428
-
3429
-
3430
-
3431
- /**
3432
- * The source code text.
3433
- */
3434
- get text() {
3435
- return this.tokenizer.text;
3436
- }
3437
- /**
3438
- * The parse errors.
3439
- */
3440
- get errors() {
3441
- return this.tokenizer.errors;
3442
- }
3443
- /**
3444
- * The current state.
3445
- */
3446
- get state() {
3447
- return this.tokenizer.state;
3448
- }
3449
- set state(value) {
3450
- this.tokenizer.state = value;
3451
- }
3452
- /**
3453
- * The current namespace.
3454
- */
3455
- get namespace() {
3456
- return this.tokenizer.namespace;
3457
- }
3458
- set namespace(value) {
3459
- this.tokenizer.namespace = value;
3460
- }
3461
- /**
3462
- * The current flag of expression enabled.
3463
- */
3464
- get expressionEnabled() {
3465
- return this.tokenizer.expressionEnabled;
3466
- }
3467
- set expressionEnabled(value) {
3468
- this.tokenizer.expressionEnabled = value;
3548
+ if (isEcmaVersion5(parserOptions)) {
3549
+ return parseVForExpressionForEcmaVersion5(
3550
+ code,
3551
+ locationCalculator,
3552
+ parserOptions
3553
+ );
3469
3554
  }
3470
- /**
3471
- * Initialize this intermediate tokenizer.
3472
- * @param tokenizer The tokenizer.
3473
- */
3474
- constructor(tokenizer, parserOptions) {
3475
- this.tokenizer = tokenizer;
3476
- this.baseParserOptions = parserOptions;
3477
- this.currentToken = null;
3478
- this.attribute = null;
3479
- this.attributeNames = /* @__PURE__ */ new Set();
3480
- this.expressionStartToken = null;
3481
- this.expressionTokens = [];
3482
- this.tokens = [];
3483
- this.comments = [];
3555
+ const processed = processVForAliasAndIterator(code);
3556
+ if (!processed.aliases.trim()) {
3557
+ return throwEmptyError(locationCalculator, "an alias");
3484
3558
  }
3485
- /**
3486
- * Get the next intermediate token.
3487
- * @returns The intermediate token or null.
3488
- */
3489
- nextToken() {
3490
- let token = null;
3491
- let result = null;
3492
- while (result == null) {
3493
- token = this.tokenizer.nextToken();
3494
- if (token == null) {
3495
- break;
3496
- }
3497
- result = this[token.type](token);
3559
+ try {
3560
+ debug(
3561
+ '[script] parse v-for expression: "for(%s%s%s);"',
3562
+ processed.aliasesWithBrackets,
3563
+ processed.delimiter,
3564
+ processed.iterator
3565
+ );
3566
+ const result = parseScriptFragment(
3567
+ `for(let ${processed.aliasesWithBrackets}${processed.delimiter}${processed.iterator});`,
3568
+ locationCalculator.getSubCalculatorShift(
3569
+ processed.hasParens ? -8 : -9
3570
+ ),
3571
+ parserOptions
3572
+ );
3573
+ const { ast } = result;
3574
+ const tokens = ast.tokens || [];
3575
+ const comments = ast.comments || [];
3576
+ const scope = analyzeVariablesAndExternalReferences(
3577
+ result,
3578
+ "v-for",
3579
+ parserOptions
3580
+ );
3581
+ const references = scope.references;
3582
+ const variables = scope.variables;
3583
+ const statement = ast.body[0];
3584
+ const varDecl = statement.left;
3585
+ const id = varDecl.declarations[0].id;
3586
+ const left = id.elements;
3587
+ const right = statement.right;
3588
+ if (!processed.hasParens && !left.length) {
3589
+ return throwEmptyError(locationCalculator, "an alias");
3498
3590
  }
3499
- if (result == null && token == null && this.currentToken != null) {
3500
- result = this.commit();
3591
+ tokens.shift();
3592
+ tokens.shift();
3593
+ tokens.shift();
3594
+ tokens.pop();
3595
+ tokens.pop();
3596
+ const closeOffset = statement.left.range[1] - 1;
3597
+ const closeIndex = tokens.findIndex((t) => t.range[0] === closeOffset);
3598
+ if (processed.hasParens) {
3599
+ const open = tokens[0];
3600
+ if (open != null) {
3601
+ open.value = "(";
3602
+ }
3603
+ const close = tokens[closeIndex];
3604
+ if (close != null) {
3605
+ close.value = ")";
3606
+ }
3607
+ } else {
3608
+ tokens.splice(closeIndex, 1);
3609
+ tokens.shift();
3501
3610
  }
3502
- return result;
3503
- }
3504
- /**
3505
- * Commit the current token.
3506
- */
3507
- commit() {
3508
- _assert2.default.call(void 0, this.currentToken != null || this.expressionStartToken != null);
3509
- let token = this.currentToken;
3510
- this.currentToken = null;
3511
- this.attribute = null;
3512
- if (this.expressionStartToken != null) {
3513
- const start = this.expressionStartToken;
3514
- const end = (0, import_last.default)(this.expressionTokens) || start;
3515
- const value = this.expressionTokens.reduce(concat, start.value);
3516
- this.expressionStartToken = null;
3517
- this.expressionTokens = [];
3518
- if (token == null) {
3519
- token = {
3520
- type: "Text",
3521
- range: [start.range[0], end.range[1]],
3522
- loc: { start: start.loc.start, end: end.loc.end },
3523
- value
3524
- };
3525
- } else if (token.type === "Text") {
3526
- token.range[1] = end.range[1];
3527
- token.loc.end = end.loc.end;
3528
- token.value += value;
3529
- } else {
3530
- throw new Error("unreachable");
3611
+ const firstToken = tokens[0] || statement.left;
3612
+ const lastToken = tokens[tokens.length - 1] || statement.right;
3613
+ const expression = {
3614
+ type: "VForExpression",
3615
+ range: [firstToken.range[0], lastToken.range[1]],
3616
+ loc: { start: firstToken.loc.start, end: lastToken.loc.end },
3617
+ parent: DUMMY_PARENT,
3618
+ left,
3619
+ right
3620
+ };
3621
+ for (const l of left) {
3622
+ if (l != null) {
3623
+ l.parent = expression;
3531
3624
  }
3532
3625
  }
3533
- return token;
3626
+ right.parent = expression;
3627
+ return { expression, tokens, comments, references, variables };
3628
+ } catch (err) {
3629
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3534
3630
  }
3535
- /**
3536
- * Report an invalid character error.
3537
- * @param token The invalid token.
3538
- * @param code The error code.
3539
- */
3540
- reportParseError(token, code) {
3541
- const error = ParseError.fromCode(
3542
- code,
3543
- token.range[0],
3544
- token.loc.start.line,
3545
- token.loc.start.column
3546
- );
3547
- this.errors.push(error);
3548
- debug("[html] syntax error:", error.message);
3631
+ }
3632
+ function isEcmaVersion5(parserOptions) {
3633
+ const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions);
3634
+ return ecmaVersion != null && ecmaVersion <= 5;
3635
+ }
3636
+ function parseVForExpressionForEcmaVersion5(code, locationCalculator, parserOptions) {
3637
+ const processed = processVForAliasAndIterator(code);
3638
+ if (!processed.aliases.trim()) {
3639
+ return throwEmptyError(locationCalculator, "an alias");
3549
3640
  }
3550
- /**
3551
- * Process the given comment token.
3552
- * @param token The comment token to process.
3553
- */
3554
- processComment(token) {
3555
- this.comments.push(token);
3556
- if (this.currentToken != null && this.currentToken.type === "Text") {
3557
- return this.commit();
3641
+ try {
3642
+ const tokens = [];
3643
+ const comments = [];
3644
+ const parsedAliases = parseVForAliasesForEcmaVersion5(
3645
+ processed.aliasesWithBrackets,
3646
+ locationCalculator.getSubCalculatorShift(
3647
+ processed.hasParens ? 0 : -1
3648
+ ),
3649
+ parserOptions
3650
+ );
3651
+ if (processed.hasParens) {
3652
+ const open = parsedAliases.tokens[0];
3653
+ if (open != null) {
3654
+ open.value = "(";
3655
+ }
3656
+ const close = (0, import_last.default)(parsedAliases.tokens);
3657
+ if (close != null) {
3658
+ close.value = ")";
3659
+ }
3660
+ } else {
3661
+ parsedAliases.tokens.shift();
3662
+ parsedAliases.tokens.pop();
3558
3663
  }
3559
- return null;
3560
- }
3561
- /**
3562
- * Process the given text token.
3563
- * @param token The text token to process.
3564
- */
3565
- processText(token) {
3566
- this.tokens.push(token);
3567
- let result = null;
3568
- if (this.expressionStartToken != null) {
3569
- const lastToken = (0, import_last.default)(this.expressionTokens) || this.expressionStartToken;
3570
- if (lastToken.range[1] === token.range[0]) {
3571
- this.expressionTokens.push(token);
3572
- return null;
3573
- }
3574
- result = this.commit();
3575
- } else if (this.currentToken != null) {
3576
- if (this.currentToken.type === "Text" && this.currentToken.range[1] === token.range[0]) {
3577
- this.currentToken.value += token.value;
3578
- this.currentToken.range[1] = token.range[1];
3579
- this.currentToken.loc.end = token.loc.end;
3580
- return null;
3581
- }
3582
- result = this.commit();
3664
+ tokens.push(...parsedAliases.tokens);
3665
+ comments.push(...parsedAliases.comments);
3666
+ const { left, variables } = parsedAliases;
3667
+ if (!processed.hasParens && !left.length) {
3668
+ return throwEmptyError(locationCalculator, "an alias");
3583
3669
  }
3584
- _assert2.default.call(void 0, this.currentToken == null);
3585
- this.currentToken = {
3586
- type: "Text",
3587
- range: [token.range[0], token.range[1]],
3588
- loc: { start: token.loc.start, end: token.loc.end },
3589
- value: token.value
3670
+ const delimiterStart = processed.aliases.length;
3671
+ const delimiterEnd = delimiterStart + processed.delimiter.length;
3672
+ tokens.push(
3673
+ fixLocation(
3674
+ {
3675
+ type: processed.delimiter === "in" ? "Keyword" : "Identifier",
3676
+ value: processed.delimiter,
3677
+ start: delimiterStart,
3678
+ end: delimiterEnd,
3679
+ loc: {},
3680
+ range: [delimiterStart, delimiterEnd]
3681
+ },
3682
+ locationCalculator
3683
+ )
3684
+ );
3685
+ const parsedIterator = parseVForIteratorForEcmaVersion5(
3686
+ processed.iterator,
3687
+ locationCalculator.getSubCalculatorShift(delimiterEnd),
3688
+ parserOptions
3689
+ );
3690
+ tokens.push(...parsedIterator.tokens);
3691
+ comments.push(...parsedIterator.comments);
3692
+ const { right, references } = parsedIterator;
3693
+ const firstToken = tokens[0];
3694
+ const lastToken = (0, import_last.default)(tokens) || firstToken;
3695
+ const expression = {
3696
+ type: "VForExpression",
3697
+ range: [firstToken.range[0], lastToken.range[1]],
3698
+ loc: { start: firstToken.loc.start, end: lastToken.loc.end },
3699
+ parent: DUMMY_PARENT,
3700
+ left,
3701
+ right
3590
3702
  };
3591
- return result;
3703
+ for (const l of left) {
3704
+ if (l != null) {
3705
+ l.parent = expression;
3706
+ }
3707
+ }
3708
+ right.parent = expression;
3709
+ return { expression, tokens, comments, references, variables };
3710
+ } catch (err) {
3711
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3592
3712
  }
3593
- /**
3594
- * Process a HTMLAssociation token.
3595
- * @param token The token to process.
3596
- */
3597
- HTMLAssociation(token) {
3598
- this.tokens.push(token);
3599
- if (this.attribute != null) {
3600
- this.attribute.range[1] = token.range[1];
3601
- this.attribute.loc.end = token.loc.end;
3602
- if (this.currentToken == null || this.currentToken.type !== "StartTag") {
3603
- throw new Error("unreachable");
3713
+ }
3714
+ function parseVForAliasesForEcmaVersion5(code, locationCalculator, parserOptions) {
3715
+ const result = parseScriptFragment(
3716
+ `0(${code})`,
3717
+ locationCalculator.getSubCalculatorShift(-2),
3718
+ parserOptions
3719
+ );
3720
+ const { ast } = result;
3721
+ const tokens = ast.tokens || [];
3722
+ const comments = ast.comments || [];
3723
+ const variables = analyzeExternalReferences(result, parserOptions).map(
3724
+ transformVariable2
3725
+ );
3726
+ const statement = ast.body[0];
3727
+ const callExpression = statement.expression;
3728
+ const expression = callExpression.arguments[0];
3729
+ const left = expression.elements.filter(
3730
+ (e) => {
3731
+ if (e == null || e.type === "Identifier") {
3732
+ return true;
3604
3733
  }
3605
- this.currentToken.range[1] = token.range[1];
3606
- this.currentToken.loc.end = token.loc.end;
3734
+ const errorToken = tokens.find(
3735
+ (t) => e.range[0] <= t.range[0] && t.range[1] <= e.range[1]
3736
+ );
3737
+ return throwUnexpectedTokenError(errorToken.value, errorToken);
3607
3738
  }
3608
- return null;
3739
+ );
3740
+ tokens.shift();
3741
+ tokens.shift();
3742
+ tokens.pop();
3743
+ return { left, tokens, comments, variables };
3744
+ function transformVariable2(reference) {
3745
+ const ret = {
3746
+ id: reference.id,
3747
+ kind: "v-for",
3748
+ references: []
3749
+ };
3750
+ Object.defineProperty(ret, "references", { enumerable: false });
3751
+ return ret;
3609
3752
  }
3610
- /**
3611
- * Process a HTMLBogusComment token.
3612
- * @param token The token to process.
3613
- */
3614
- HTMLBogusComment(token) {
3615
- return this.processComment(token);
3753
+ }
3754
+ function parseVForIteratorForEcmaVersion5(code, locationCalculator, parserOptions) {
3755
+ const result = parseScriptFragment(
3756
+ `0(${code})`,
3757
+ locationCalculator.getSubCalculatorShift(-2),
3758
+ parserOptions
3759
+ );
3760
+ const { ast } = result;
3761
+ const tokens = ast.tokens || [];
3762
+ const comments = ast.comments || [];
3763
+ const references = analyzeExternalReferences(result, parserOptions);
3764
+ const statement = ast.body[0];
3765
+ const callExpression = statement.expression;
3766
+ const expression = callExpression.arguments[0];
3767
+ if (!expression) {
3768
+ return throwEmptyError(locationCalculator, "an expression");
3616
3769
  }
3617
- /**
3618
- * Process a HTMLCDataText token.
3619
- * @param token The token to process.
3620
- */
3621
- HTMLCDataText(token) {
3622
- return this.processText(token);
3770
+ if (expression && expression.type === "SpreadElement") {
3771
+ return throwUnexpectedTokenError("...", expression);
3623
3772
  }
3624
- /**
3625
- * Process a HTMLComment token.
3626
- * @param token The token to process.
3627
- */
3628
- HTMLComment(token) {
3629
- return this.processComment(token);
3773
+ const right = expression;
3774
+ tokens.shift();
3775
+ tokens.shift();
3776
+ tokens.pop();
3777
+ return { right, tokens, comments, references };
3778
+ }
3779
+ function parseVOnExpression(code, locationCalculator, parserOptions) {
3780
+ if (IS_FUNCTION_EXPRESSION.test(code) || IS_SIMPLE_PATH.test(code)) {
3781
+ return parseExpressionBody(
3782
+ code,
3783
+ locationCalculator,
3784
+ parserOptions
3785
+ );
3630
3786
  }
3631
- /**
3632
- * Process a HTMLEndTagOpen token.
3633
- * @param token The token to process.
3634
- */
3635
- HTMLEndTagOpen(token) {
3636
- this.tokens.push(token);
3637
- let result = null;
3638
- if (this.currentToken != null || this.expressionStartToken != null) {
3639
- result = this.commit();
3640
- }
3641
- this.currentToken = {
3642
- type: "EndTag",
3643
- range: [token.range[0], token.range[1]],
3644
- loc: { start: token.loc.start, end: token.loc.end },
3645
- name: token.value
3646
- };
3647
- return result;
3787
+ return parseVOnExpressionBody(
3788
+ code,
3789
+ locationCalculator,
3790
+ parserOptions
3791
+ );
3792
+ }
3793
+ function parseVOnExpressionBody(code, locationCalculator, parserOptions) {
3794
+ debug('[script] parse v-on expression: "void function($event){%s}"', code);
3795
+ if (code.trim() === "") {
3796
+ throwEmptyError(locationCalculator, "statements");
3648
3797
  }
3649
- /**
3650
- * Process a HTMLIdentifier token.
3651
- * @param token The token to process.
3652
- */
3653
- HTMLIdentifier(token) {
3654
- this.tokens.push(token);
3655
- if (this.currentToken == null || this.currentToken.type === "Text" || this.currentToken.type === "Mustache") {
3656
- throw new Error("unreachable");
3657
- }
3658
- if (this.currentToken.type === "EndTag") {
3659
- this.reportParseError(token, "end-tag-with-attributes");
3660
- return null;
3661
- }
3662
- if (this.attributeNames.has(token.value)) {
3663
- this.reportParseError(token, "duplicate-attribute");
3664
- }
3665
- this.attributeNames.add(token.value);
3666
- this.attribute = {
3667
- type: "VAttribute",
3668
- range: [token.range[0], token.range[1]],
3669
- loc: { start: token.loc.start, end: token.loc.end },
3670
- parent: DUMMY_PARENT,
3671
- directive: false,
3672
- key: {
3673
- type: "VIdentifier",
3674
- range: [token.range[0], token.range[1]],
3675
- loc: { start: token.loc.start, end: token.loc.end },
3676
- parent: DUMMY_PARENT,
3677
- name: token.value,
3678
- rawName: this.text.slice(token.range[0], token.range[1])
3798
+ try {
3799
+ const result = parseScriptFragment(
3800
+ `void function($event){${code}}`,
3801
+ locationCalculator.getSubCalculatorShift(-22),
3802
+ parserOptions
3803
+ );
3804
+ const { ast } = result;
3805
+ const references = analyzeExternalReferences(result, parserOptions);
3806
+ const outermostStatement = ast.body[0];
3807
+ const functionDecl = outermostStatement.expression.argument;
3808
+ const block = functionDecl.body;
3809
+ const body = block.body;
3810
+ const firstStatement = (0, import_first.default)(body);
3811
+ const lastStatement = (0, import_last.default)(body);
3812
+ const expression = {
3813
+ type: "VOnExpression",
3814
+ range: [
3815
+ firstStatement != null ? firstStatement.range[0] : block.range[0] + 1,
3816
+ lastStatement != null ? lastStatement.range[1] : block.range[1] - 1
3817
+ ],
3818
+ loc: {
3819
+ start: firstStatement != null ? firstStatement.loc.start : locationCalculator.getLocation(1),
3820
+ end: lastStatement != null ? lastStatement.loc.end : locationCalculator.getLocation(code.length + 1)
3679
3821
  },
3680
- value: null
3822
+ parent: DUMMY_PARENT,
3823
+ body
3681
3824
  };
3682
- this.attribute.key.parent = this.attribute;
3683
- this.currentToken.range[1] = token.range[1];
3684
- this.currentToken.loc.end = token.loc.end;
3685
- this.currentToken.attributes.push(this.attribute);
3686
- return null;
3687
- }
3688
- /**
3689
- * Process a HTMLLiteral token.
3690
- * @param token The token to process.
3691
- */
3692
- HTMLLiteral(token) {
3693
- this.tokens.push(token);
3694
- if (this.attribute != null) {
3695
- this.attribute.range[1] = token.range[1];
3696
- this.attribute.loc.end = token.loc.end;
3697
- this.attribute.value = {
3698
- type: "VLiteral",
3699
- range: [token.range[0], token.range[1]],
3700
- loc: { start: token.loc.start, end: token.loc.end },
3701
- parent: this.attribute,
3702
- value: token.value
3703
- };
3704
- if (this.currentToken == null || this.currentToken.type !== "StartTag") {
3705
- throw new Error("unreachable");
3706
- }
3707
- this.currentToken.range[1] = token.range[1];
3708
- this.currentToken.loc.end = token.loc.end;
3825
+ const tokens = ast.tokens || [];
3826
+ const comments = ast.comments || [];
3827
+ for (const b of body) {
3828
+ b.parent = expression;
3709
3829
  }
3710
- return null;
3711
- }
3712
- /**
3713
- * Process a HTMLRCDataText token.
3714
- * @param token The token to process.
3715
- */
3716
- HTMLRCDataText(token) {
3717
- return this.processText(token);
3830
+ tokens.splice(0, 6);
3831
+ tokens.pop();
3832
+ return { expression, tokens, comments, references, variables: [] };
3833
+ } catch (err) {
3834
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3718
3835
  }
3719
- /**
3720
- * Process a HTMLRawText token.
3721
- * @param token The token to process.
3722
- */
3723
- HTMLRawText(token) {
3724
- return this.processText(token);
3836
+ }
3837
+ function parseSlotScopeExpression(code, locationCalculator, parserOptions) {
3838
+ debug('[script] parse slot-scope expression: "void function(%s) {}"', code);
3839
+ if (code.trim() === "") {
3840
+ throwEmptyError(
3841
+ locationCalculator,
3842
+ "an identifier or an array/object pattern"
3843
+ );
3725
3844
  }
3726
- /**
3727
- * Process a HTMLSelfClosingTagClose token.
3728
- * @param token The token to process.
3729
- */
3730
- HTMLSelfClosingTagClose(token) {
3731
- this.tokens.push(token);
3732
- if (this.currentToken == null || this.currentToken.type === "Text") {
3733
- throw new Error("unreachable");
3845
+ try {
3846
+ const result = parseScriptFragment(
3847
+ `void function(${code}) {}`,
3848
+ locationCalculator.getSubCalculatorShift(-14),
3849
+ parserOptions
3850
+ );
3851
+ const { ast } = result;
3852
+ const statement = ast.body[0];
3853
+ const rawExpression = statement.expression;
3854
+ const functionDecl = rawExpression.argument;
3855
+ const params = functionDecl.params;
3856
+ if (params.length === 0) {
3857
+ return {
3858
+ expression: null,
3859
+ tokens: [],
3860
+ comments: [],
3861
+ references: [],
3862
+ variables: []
3863
+ };
3734
3864
  }
3735
- if (this.currentToken.type === "StartTag") {
3736
- this.currentToken.selfClosing = true;
3737
- } else {
3738
- this.reportParseError(token, "end-tag-with-trailing-solidus");
3865
+ const tokens = ast.tokens || [];
3866
+ const comments = ast.comments || [];
3867
+ const scope = analyzeVariablesAndExternalReferences(
3868
+ result,
3869
+ "scope",
3870
+ parserOptions
3871
+ );
3872
+ const references = scope.references;
3873
+ const variables = scope.variables;
3874
+ const firstParam = (0, import_first.default)(params);
3875
+ const lastParam = (0, import_last.default)(params);
3876
+ const expression = {
3877
+ type: "VSlotScopeExpression",
3878
+ range: [firstParam.range[0], lastParam.range[1]],
3879
+ loc: { start: firstParam.loc.start, end: lastParam.loc.end },
3880
+ parent: DUMMY_PARENT,
3881
+ params: functionDecl.params
3882
+ };
3883
+ for (const param of params) {
3884
+ param.parent = expression;
3739
3885
  }
3740
- this.currentToken.range[1] = token.range[1];
3741
- this.currentToken.loc.end = token.loc.end;
3742
- return this.commit();
3886
+ tokens.shift();
3887
+ tokens.shift();
3888
+ tokens.shift();
3889
+ tokens.pop();
3890
+ tokens.pop();
3891
+ tokens.pop();
3892
+ return { expression, tokens, comments, references, variables };
3893
+ } catch (err) {
3894
+ return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
3743
3895
  }
3744
- /**
3745
- * Process a HTMLTagClose token.
3746
- * @param token The token to process.
3747
- */
3748
- HTMLTagClose(token) {
3749
- this.tokens.push(token);
3750
- if (this.currentToken == null || this.currentToken.type === "Text") {
3751
- throw new Error("unreachable");
3752
- }
3753
- this.currentToken.range[1] = token.range[1];
3754
- this.currentToken.loc.end = token.loc.end;
3755
- return this.commit();
3896
+ }
3897
+
3898
+ // src/template/utils/index.ts
3899
+ var shorthandSign = /^[.:@#]/u;
3900
+ var shorthandNameMap = { ":": "bind", ".": "bind", "@": "on", "#": "slot" };
3901
+ var invalidDynamicArgumentNextChar = /^[\s=/>]$/u;
3902
+ function camelize(str) {
3903
+ return str.replace(/-(\w)/gu, (_, c) => c ? c.toUpperCase() : "");
3904
+ }
3905
+ function isPropModifier(node) {
3906
+ return node.name === "prop";
3907
+ }
3908
+ function isNotEmptyModifier(node) {
3909
+ return node.name !== "";
3910
+ }
3911
+ function getStandardDirectiveKind(element, directiveKey) {
3912
+ const directiveName = directiveKey.name.name;
3913
+ if (directiveName === "for") {
3914
+ return "for";
3915
+ } else if (directiveName === "on") {
3916
+ return "on";
3917
+ } else if (directiveName === "slot" || directiveName === "slot-scope" || directiveName === "scope" && element.rawName === "template") {
3918
+ return "slot";
3919
+ } else if (directiveName === "bind") {
3920
+ return "bind";
3756
3921
  }
3757
- /**
3758
- * Process a HTMLTagOpen token.
3759
- * @param token The token to process.
3760
- */
3761
- HTMLTagOpen(token) {
3762
- this.tokens.push(token);
3763
- let result = null;
3764
- if (this.currentToken != null || this.expressionStartToken != null) {
3765
- result = this.commit();
3766
- }
3767
- this.currentToken = {
3768
- type: "StartTag",
3769
- range: [token.range[0], token.range[1]],
3770
- loc: { start: token.loc.start, end: token.loc.end },
3771
- name: token.value,
3772
- rawName: this.text.slice(token.range[0] + 1, token.range[1]),
3773
- selfClosing: false,
3774
- attributes: []
3922
+ return null;
3923
+ }
3924
+ function parseAttributeValue(code, parserOptions, globalLocationCalculator, node, element, directiveKey) {
3925
+ const firstChar = code[node.range[0]];
3926
+ const quoted = firstChar === '"' || firstChar === "'";
3927
+ const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(
3928
+ node.range[0] + (quoted ? 1 : 0)
3929
+ );
3930
+ const directiveKind = getStandardDirectiveKind(
3931
+ element,
3932
+ directiveKey
3933
+ );
3934
+ let result;
3935
+ if (quoted && node.value === "") {
3936
+ result = {
3937
+ expression: null,
3938
+ tokens: [],
3939
+ comments: [],
3940
+ variables: [],
3941
+ references: []
3775
3942
  };
3776
- this.attribute = null;
3777
- this.attributeNames.clear();
3778
- return result;
3779
- }
3780
- /**
3781
- * Process a HTMLText token.
3782
- * @param token The token to process.
3783
- */
3784
- HTMLText(token) {
3785
- return this.processText(token);
3786
- }
3787
- /**
3788
- * Process a HTMLWhitespace token.
3789
- * @param token The token to process.
3790
- */
3791
- HTMLWhitespace(token) {
3792
- return this.processText(token);
3793
- }
3794
- /**
3795
- * Process a VExpressionStart token.
3796
- * @param token The token to process.
3797
- */
3798
- VExpressionStart(token) {
3799
- if (this.expressionStartToken != null) {
3800
- return this.processText(token);
3801
- }
3802
- const separated = this.currentToken != null && this.currentToken.range[1] !== token.range[0];
3803
- const result = separated ? this.commit() : null;
3804
- this.tokens.push(token);
3805
- this.expressionStartToken = token;
3806
- return result;
3943
+ } else if (directiveKind === "for") {
3944
+ result = parseVForExpression(
3945
+ node.value,
3946
+ locationCalculator,
3947
+ parserOptions
3948
+ );
3949
+ } else if (directiveKind === "on" && directiveKey.argument != null) {
3950
+ result = parseVOnExpression(
3951
+ node.value,
3952
+ locationCalculator,
3953
+ parserOptions
3954
+ );
3955
+ } else if (directiveKind === "slot") {
3956
+ result = parseSlotScopeExpression(
3957
+ node.value,
3958
+ locationCalculator,
3959
+ parserOptions
3960
+ );
3961
+ } else if (directiveKind === "bind") {
3962
+ result = parseExpression(
3963
+ node.value,
3964
+ locationCalculator,
3965
+ parserOptions,
3966
+ { allowFilters: true }
3967
+ );
3968
+ } else {
3969
+ result = parseExpression(
3970
+ node.value,
3971
+ locationCalculator,
3972
+ parserOptions
3973
+ );
3807
3974
  }
3808
- /**
3809
- * Process a VExpressionEnd token.
3810
- * @param token The token to process.
3811
- */
3812
- VExpressionEnd(token) {
3813
- if (this.expressionStartToken == null) {
3814
- return this.processText(token);
3815
- }
3816
- const start = this.expressionStartToken;
3817
- const end = (0, import_last.default)(this.expressionTokens) || start;
3818
- if (token.range[0] === start.range[1]) {
3819
- this.tokens.pop();
3820
- this.expressionStartToken = null;
3821
- const result2 = this.processText(start);
3822
- this.processText(token);
3823
- return result2;
3824
- }
3825
- if (end.range[1] !== token.range[0]) {
3826
- const result2 = this.commit();
3827
- this.processText(token);
3828
- return result2;
3829
- }
3830
- const value = this.expressionTokens.reduce(concat, "");
3831
- this.tokens.push(token);
3832
- this.expressionStartToken = null;
3833
- this.expressionTokens = [];
3834
- const result = this.currentToken != null ? this.commit() : null;
3835
- this.currentToken = {
3836
- type: "Mustache",
3837
- range: [start.range[0], token.range[1]],
3838
- loc: { start: start.loc.start, end: token.loc.end },
3839
- value,
3840
- startToken: start,
3841
- endToken: token
3842
- };
3843
- return result || this.commit();
3975
+ if (quoted) {
3976
+ result.tokens.unshift(
3977
+ createSimpleToken(
3978
+ "Punctuator",
3979
+ node.range[0],
3980
+ node.range[0] + 1,
3981
+ firstChar,
3982
+ globalLocationCalculator
3983
+ )
3984
+ );
3985
+ result.tokens.push(
3986
+ createSimpleToken(
3987
+ "Punctuator",
3988
+ node.range[1] - 1,
3989
+ node.range[1],
3990
+ firstChar,
3991
+ globalLocationCalculator
3992
+ )
3993
+ );
3844
3994
  }
3845
- };
3846
-
3847
- // src/common/error-utils.ts
3848
- function insertError(templateMeta, error) {
3849
- const index = templateMeta.errors.findIndex((e) => e.index === error.index);
3850
- templateMeta.errors.splice(index, 0, error);
3995
+ return result;
3851
3996
  }
3852
-
3853
- // src/common/token-utils.ts
3854
- function createSimpleToken(type, start, end, value, linesAndColumns) {
3855
- return {
3856
- type,
3857
- range: [start, end],
3997
+ function parseDirectiveKeyStatically(node, templateMeta) {
3998
+ const {
3999
+ name: text,
4000
+ rawName: rawText,
4001
+ range: [offset],
3858
4002
  loc: {
3859
- start: linesAndColumns.getLocFromIndex(start),
3860
- end: linesAndColumns.getLocFromIndex(end)
3861
- },
3862
- value
4003
+ start: { column, line }
4004
+ }
4005
+ } = node;
4006
+ const directiveKey = {
4007
+ type: "VDirectiveKey",
4008
+ range: node.range,
4009
+ loc: node.loc,
4010
+ parent: node.parent,
4011
+ name: null,
4012
+ argument: null,
4013
+ modifiers: []
3863
4014
  };
3864
- }
3865
- function insertComments(templateMeta, newComments) {
3866
- if (newComments.length === 0) {
3867
- return;
4015
+ let i = 0;
4016
+ function createIdentifier(start, end, name) {
4017
+ const id = {
4018
+ type: "VIdentifier",
4019
+ parent: directiveKey,
4020
+ range: [offset + start, offset + end],
4021
+ loc: {
4022
+ start: { column: column + start, line },
4023
+ end: { column: column + end, line }
4024
+ },
4025
+ name: name || text.slice(start, end),
4026
+ rawName: rawText.slice(start, end)
4027
+ };
4028
+ return id;
3868
4029
  }
3869
- const index = templateMeta.comments.findIndex((comment) => comment.range[0] === newComments[0].range[0]);
3870
- templateMeta.comments.splice(index, 0, ...newComments);
3871
- }
3872
- function replaceTokens(templateMeta, node, newTokens) {
3873
- const index = templateMeta.tokens.findIndex((token) => token.range[0] === node.range[0]);
3874
- const count = templateMeta.tokens.findIndex((token) => token.range[1] === node.range[1]) - index + 1;
3875
- templateMeta.tokens.splice(index, count, ...newTokens);
3876
- }
3877
-
3878
- // src/script/index.ts
3879
- var import_first = __toESM(require_first());
3880
- var import_last2 = __toESM(require_last());
3881
- var import_sortedIndexBy = __toESM(require_sortedIndexBy());
3882
-
3883
-
3884
- // src/common/fix-locations.ts
3885
- function fixLocations(result, locationCalculator) {
3886
- fixNodeLocations(result.ast, result.visitorKeys, locationCalculator);
3887
- for (const token of result.ast.tokens || []) {
3888
- fixLocation(token, locationCalculator);
4030
+ if (shorthandSign.test(text)) {
4031
+ const sign = text[0];
4032
+ directiveKey.name = createIdentifier(0, 1, shorthandNameMap[sign]);
4033
+ i = 1;
4034
+ } else {
4035
+ const colon = text.indexOf(":");
4036
+ if (colon !== -1) {
4037
+ directiveKey.name = createIdentifier(0, colon);
4038
+ i = colon + 1;
4039
+ }
3889
4040
  }
3890
- for (const comment of result.ast.comments || []) {
3891
- fixLocation(comment, locationCalculator);
4041
+ if (directiveKey.name != null && text[i] === "[") {
4042
+ const len = text.slice(i).lastIndexOf("]");
4043
+ if (len !== -1) {
4044
+ directiveKey.argument = createIdentifier(i, i + len + 1);
4045
+ i = i + len + 1 + (text[i + len + 1] === "." ? 1 : 0);
4046
+ }
3892
4047
  }
3893
- }
3894
- function fixNodeLocations(rootNode, visitorKeys, locationCalculator) {
3895
- const traversed = /* @__PURE__ */ new Map();
3896
- traverseNodes(rootNode, {
3897
- visitorKeys,
3898
- enterNode(node, parent) {
3899
- if (!traversed.has(node)) {
3900
- traversed.set(node, node);
3901
- node.parent = parent;
3902
- if (traversed.has(node.range)) {
3903
- if (!traversed.has(node.loc)) {
3904
- node.loc.start = locationCalculator.getLocFromIndex(
3905
- node.range[0]
3906
- );
3907
- node.loc.end = locationCalculator.getLocFromIndex(
3908
- node.range[1]
3909
- );
3910
- traversed.set(node.loc, node);
3911
- } else if (node.start != null || node.end != null) {
3912
- const traversedNode = traversed.get(node.range);
3913
- if (traversedNode.type === node.type) {
3914
- node.start = traversedNode.start;
3915
- node.end = traversedNode.end;
3916
- }
3917
- }
3918
- } else {
3919
- fixLocation(node, locationCalculator);
3920
- traversed.set(node.range, node);
3921
- traversed.set(node.loc, node);
3922
- }
3923
- }
3924
- },
3925
- leaveNode() {
4048
+ const modifiers = text.slice(i).split(".").map((modifierName) => {
4049
+ const modifier = createIdentifier(i, i + modifierName.length);
4050
+ if (modifierName === "" && i < text.length) {
4051
+ insertError(
4052
+ templateMeta,
4053
+ new ParseError(
4054
+ `Unexpected token '${text[i]}'`,
4055
+ void 0,
4056
+ offset + i,
4057
+ line,
4058
+ column + i
4059
+ )
4060
+ );
3926
4061
  }
4062
+ i += modifierName.length + 1;
4063
+ return modifier;
3927
4064
  });
3928
- }
3929
- function fixLocation(node, locationCalculator) {
3930
- const range = node.range;
3931
- const loc = node.loc;
3932
- const d0 = locationCalculator.getFixOffset(range[0], "start");
3933
- const d1 = locationCalculator.getFixOffset(range[1], "end");
3934
- if (d0 !== 0) {
3935
- range[0] += d0;
3936
- if (node.start != null) {
3937
- node.start += d0;
3938
- }
3939
- loc.start = locationCalculator.getLocFromIndex(range[0]);
4065
+ if (directiveKey.name == null) {
4066
+ directiveKey.name = modifiers.shift();
4067
+ } else if (directiveKey.argument == null && modifiers[0].name !== "") {
4068
+ directiveKey.argument = modifiers.shift() || null;
3940
4069
  }
3941
- if (d1 !== 0) {
3942
- range[1] += d1;
3943
- if (node.end != null) {
3944
- node.end += d0;
3945
- }
3946
- loc.end = locationCalculator.getLocFromIndex(range[1]);
4070
+ directiveKey.modifiers = modifiers.filter(isNotEmptyModifier);
4071
+ if (directiveKey.name.name === "v-") {
4072
+ insertError(
4073
+ templateMeta,
4074
+ new ParseError(
4075
+ `Unexpected token '${text[directiveKey.name.range[1] - offset]}'`,
4076
+ void 0,
4077
+ directiveKey.name.range[1],
4078
+ directiveKey.name.loc.end.line,
4079
+ directiveKey.name.loc.end.column
4080
+ )
4081
+ );
3947
4082
  }
3948
- return node;
3949
- }
3950
- function fixErrorLocation(error, locationCalculator) {
3951
- const diff = locationCalculator.getFixOffset(error.index, "start");
3952
- error.index += diff;
3953
- const loc = locationCalculator.getLocFromIndex(error.index);
3954
- error.lineNumber = loc.line;
3955
- error.column = loc.column;
3956
- }
3957
-
3958
- // src/common/parser-object.ts
3959
- function isParserObject(value) {
3960
- return isEnhancedParserObject(value) || isBasicParserObject(value);
3961
- }
3962
- function isEnhancedParserObject(value) {
3963
- return Boolean(value && typeof value.parseForESLint === "function");
3964
- }
3965
- function isBasicParserObject(value) {
3966
- return Boolean(value && typeof value.parse === "function");
3967
- }
3968
-
3969
- // src/script/index.ts
3970
- var ALIAS_ITERATOR = /^([\s\S]*?(?:\s|\)))(\bin\b|\bof\b)([\s\S]*)$/u;
3971
- var PARENS = /^(\s*\()([\s\S]*?)(\)\s*)$/u;
3972
- var DUMMY_PARENT2 = {};
3973
- var IS_FUNCTION_EXPRESSION = /^\s*(?:[\w$]+|\([^)]*\))\s*=>|^function\s*\(/u;
3974
- var IS_SIMPLE_PATH = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/u;
3975
- function processVForAliasAndIterator(code) {
3976
- const match = ALIAS_ITERATOR.exec(code);
3977
- if (match != null) {
3978
- const aliases = match[1];
3979
- const parenMatch = PARENS.exec(aliases);
3980
- return {
3981
- aliases,
3982
- hasParens: Boolean(parenMatch),
3983
- aliasesWithBrackets: parenMatch ? `${parenMatch[1].slice(0, -1)}[${parenMatch[2]}]${parenMatch[3].slice(1)}` : `[${aliases.slice(0, -1)}]`,
3984
- delimiter: match[2] || "",
3985
- iterator: match[3]
3986
- };
4083
+ if (directiveKey.name.rawName === "." && !directiveKey.modifiers.some(isPropModifier)) {
4084
+ const pos = (directiveKey.argument || directiveKey.name).range[1] - offset;
4085
+ const propModifier = createIdentifier(pos, pos, "prop");
4086
+ directiveKey.modifiers.unshift(propModifier);
3987
4087
  }
3988
- return {
3989
- aliases: "",
3990
- hasParens: false,
3991
- aliasesWithBrackets: "",
3992
- delimiter: "",
3993
- iterator: code
3994
- };
4088
+ return directiveKey;
3995
4089
  }
3996
- function getCommaTokenBeforeNode(tokens, node) {
3997
- let tokenIndex = (0, import_sortedIndexBy.default)(
3998
- tokens,
3999
- { range: node.range },
4000
- (t) => t.range[0]
4001
- );
4002
- while (tokenIndex >= 0) {
4003
- const token = tokens[tokenIndex];
4004
- if (token.type === "Punctuator" && token.value === ",") {
4005
- return token;
4090
+ function parseDirectiveKeyTokens(node) {
4091
+ const { name, argument, modifiers } = node;
4092
+ const shorthand = name.range[1] - name.range[0] === 1;
4093
+ const tokens = [];
4094
+ if (shorthand) {
4095
+ tokens.push({
4096
+ type: "Punctuator",
4097
+ range: name.range,
4098
+ loc: name.loc,
4099
+ value: name.rawName
4100
+ });
4101
+ } else {
4102
+ tokens.push({
4103
+ type: "HTMLIdentifier",
4104
+ range: name.range,
4105
+ loc: name.loc,
4106
+ value: name.rawName
4107
+ });
4108
+ if (argument) {
4109
+ tokens.push({
4110
+ type: "Punctuator",
4111
+ range: [name.range[1], argument.range[0]],
4112
+ loc: { start: name.loc.end, end: argument.loc.start },
4113
+ value: ":"
4114
+ });
4006
4115
  }
4007
- tokenIndex -= 1;
4008
4116
  }
4009
- return null;
4010
- }
4011
- function throwEmptyError(locationCalculator, expected) {
4012
- const loc = locationCalculator.getLocation(0);
4013
- const err = new ParseError(
4014
- `Expected to be ${expected}, but got empty.`,
4015
- void 0,
4016
- 0,
4017
- loc.line,
4018
- loc.column
4019
- );
4020
- fixErrorLocation(err, locationCalculator);
4021
- throw err;
4022
- }
4023
- function throwUnexpectedTokenError(name, token) {
4024
- const err = new ParseError(
4025
- `Unexpected token '${name}'.`,
4026
- void 0,
4027
- token.range[0],
4028
- token.loc.start.line,
4029
- token.loc.start.column
4030
- );
4031
- throw err;
4032
- }
4033
- function throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator) {
4034
- if (ParseError.isParseError(err)) {
4035
- const endOffset = locationCalculator.getOffsetWithGap(code.length);
4036
- if (err.index >= endOffset) {
4037
- err.message = "Unexpected end of expression.";
4117
+ if (argument) {
4118
+ tokens.push({
4119
+ type: "HTMLIdentifier",
4120
+ range: argument.range,
4121
+ loc: argument.loc,
4122
+ value: argument.rawName
4123
+ });
4124
+ }
4125
+ let lastNode = argument || name;
4126
+ for (const modifier of modifiers) {
4127
+ if (modifier.rawName === "") {
4128
+ continue;
4038
4129
  }
4130
+ tokens.push(
4131
+ {
4132
+ type: "Punctuator",
4133
+ range: [lastNode.range[1], modifier.range[0]],
4134
+ loc: { start: lastNode.loc.end, end: modifier.loc.start },
4135
+ value: "."
4136
+ },
4137
+ {
4138
+ type: "HTMLIdentifier",
4139
+ range: modifier.range,
4140
+ loc: modifier.loc,
4141
+ value: modifier.rawName
4142
+ }
4143
+ );
4144
+ lastNode = modifier;
4039
4145
  }
4040
- throw err;
4146
+ return tokens;
4041
4147
  }
4042
- function parseScriptFragment(code, locationCalculator, parserOptions) {
4148
+ function convertDynamicArgument(node, templateMeta, parserOptions, locationCalculator) {
4149
+ const { argument } = node;
4150
+ if (!(argument != null && argument.type === "VIdentifier" && argument.name.startsWith("[") && argument.name.endsWith("]"))) {
4151
+ return;
4152
+ }
4153
+ const { rawName, range, loc } = argument;
4043
4154
  try {
4044
- const result = parseScript(
4045
- code,
4155
+ const { comments, expression, references, tokens } = parseExpression(
4156
+ rawName.slice(1, -1),
4157
+ locationCalculator.getSubCalculatorAfter(range[0] + 1),
4046
4158
  parserOptions
4047
4159
  );
4048
- fixLocations(result, locationCalculator);
4049
- return result;
4050
- } catch (err) {
4051
- const perr = ParseError.normalize(err);
4052
- if (perr) {
4053
- fixErrorLocation(perr, locationCalculator);
4054
- throw perr;
4160
+ node.argument = {
4161
+ type: "VExpressionContainer",
4162
+ range,
4163
+ loc,
4164
+ parent: node,
4165
+ expression,
4166
+ references
4167
+ };
4168
+ if (expression != null) {
4169
+ expression.parent = node.argument;
4170
+ }
4171
+ tokens.unshift(
4172
+ createSimpleToken(
4173
+ "Punctuator",
4174
+ range[0],
4175
+ range[0] + 1,
4176
+ "[",
4177
+ locationCalculator
4178
+ )
4179
+ );
4180
+ tokens.push(
4181
+ createSimpleToken(
4182
+ "Punctuator",
4183
+ range[1] - 1,
4184
+ range[1],
4185
+ "]",
4186
+ locationCalculator
4187
+ )
4188
+ );
4189
+ replaceTokens(templateMeta, node.argument, tokens);
4190
+ insertComments(templateMeta, comments);
4191
+ } catch (error) {
4192
+ debug("[template] Parse error: %s", error);
4193
+ if (ParseError.isParseError(error)) {
4194
+ node.argument = {
4195
+ type: "VExpressionContainer",
4196
+ range,
4197
+ loc,
4198
+ parent: node,
4199
+ expression: null,
4200
+ references: []
4201
+ };
4202
+ insertError(templateMeta, error);
4203
+ } else {
4204
+ throw error;
4055
4205
  }
4056
- throw err;
4057
4206
  }
4058
4207
  }
4059
- var validDivisionCharRE = /[\w).+\-$\]]/u;
4060
- function splitFilters(exp) {
4061
- const result = [];
4062
- let inSingle = false;
4063
- let inDouble = false;
4064
- let inTemplateString = false;
4065
- let inRegex = false;
4066
- let curly = 0;
4067
- let square = 0;
4068
- let paren = 0;
4069
- let lastFilterIndex = 0;
4070
- let c = 0;
4071
- let prev = 0;
4072
- for (let i = 0; i < exp.length; i++) {
4073
- prev = c;
4074
- c = exp.charCodeAt(i);
4075
- if (inSingle) {
4076
- if (c === 39 && prev !== 92) {
4077
- inSingle = false;
4078
- }
4079
- } else if (inDouble) {
4080
- if (c === 34 && prev !== 92) {
4081
- inDouble = false;
4082
- }
4083
- } else if (inTemplateString) {
4084
- if (c === 96 && prev !== 92) {
4085
- inTemplateString = false;
4086
- }
4087
- } else if (inRegex) {
4088
- if (c === 47 && prev !== 92) {
4089
- inRegex = false;
4090
- }
4091
- } else if (c === 124 && exp.charCodeAt(i + 1) !== 124 && exp.charCodeAt(i - 1) !== 124 && !curly && !square && !paren) {
4092
- result.push(exp.slice(lastFilterIndex, i));
4093
- lastFilterIndex = i + 1;
4094
- } else {
4095
- switch (c) {
4096
- case 34:
4097
- inDouble = true;
4098
- break;
4099
- case 39:
4100
- inSingle = true;
4101
- break;
4102
- case 96:
4103
- inTemplateString = true;
4104
- break;
4105
- case 40:
4106
- paren++;
4107
- break;
4108
- case 41:
4109
- paren--;
4110
- break;
4111
- case 91:
4112
- square++;
4113
- break;
4114
- case 93:
4115
- square--;
4116
- break;
4117
- case 123:
4118
- curly++;
4119
- break;
4120
- case 125:
4121
- curly--;
4122
- break;
4123
- }
4124
- if (c === 47) {
4125
- let j = i - 1;
4126
- let p;
4127
- for (; j >= 0; j--) {
4128
- p = exp.charAt(j);
4129
- if (p !== " ") {
4130
- break;
4131
- }
4132
- }
4133
- if (!p || !validDivisionCharRE.test(p)) {
4134
- inRegex = true;
4135
- }
4136
- }
4208
+ function createDirectiveKey(node, templateMeta, parserOptions, locationCalculator) {
4209
+ const directiveKey = parseDirectiveKeyStatically(node, templateMeta);
4210
+ const tokens = parseDirectiveKeyTokens(directiveKey);
4211
+ replaceTokens(templateMeta, directiveKey, tokens);
4212
+ if (directiveKey.name.name.startsWith("v-")) {
4213
+ directiveKey.name.name = directiveKey.name.name.slice(2);
4214
+ }
4215
+ if (directiveKey.name.rawName.startsWith("v-")) {
4216
+ directiveKey.name.rawName = directiveKey.name.rawName.slice(2);
4217
+ }
4218
+ convertDynamicArgument(
4219
+ directiveKey,
4220
+ templateMeta,
4221
+ parserOptions,
4222
+ locationCalculator
4223
+ );
4224
+ return directiveKey;
4225
+ }
4226
+ function convertToDirective(node, code, templateMeta, locationCalculator, vineFixLocationContext, parserOptions) {
4227
+ debug(
4228
+ '[template] convert to directive: %s="%s" %j',
4229
+ node.key.name,
4230
+ node.value && node.value.value,
4231
+ node.range
4232
+ );
4233
+ const directive = node;
4234
+ directive.directive = true;
4235
+ directive.key = createDirectiveKey(
4236
+ node.key,
4237
+ templateMeta,
4238
+ parserOptions,
4239
+ locationCalculator
4240
+ );
4241
+ const { argument } = directive.key;
4242
+ if (argument && argument.type === "VIdentifier" && argument.name.startsWith("[")) {
4243
+ const nextChar = code[argument.range[1]];
4244
+ if (nextChar == null || invalidDynamicArgumentNextChar.test(nextChar)) {
4245
+ const char = nextChar == null ? "EOF" : JSON.stringify(nextChar).slice(1, -1);
4246
+ insertError(
4247
+ templateMeta,
4248
+ new ParseError(
4249
+ `Dynamic argument cannot contain the '${char}' character.`,
4250
+ void 0,
4251
+ argument.range[1],
4252
+ argument.loc.end.line,
4253
+ argument.loc.end.column
4254
+ )
4255
+ );
4256
+ }
4257
+ }
4258
+ if (node.value == null) {
4259
+ if (directive.key.name.name === "bind") {
4260
+ convertForVBindSameNameShorthandValue(
4261
+ directive,
4262
+ parserOptions,
4263
+ locationCalculator
4264
+ );
4137
4265
  }
4266
+ return;
4138
4267
  }
4139
- result.push(exp.slice(lastFilterIndex));
4140
- return result;
4141
- }
4142
- function parseExpressionBody(code, locationCalculator, parserOptions, allowEmpty = false) {
4143
- debug('[script] parse expression: "0(%s)"', code);
4144
4268
  try {
4145
- const result = parseScriptFragment(
4146
- `0(${code})`,
4147
- locationCalculator.getSubCalculatorShift(-2),
4148
- parserOptions
4269
+ const ret = parseAttributeValue(
4270
+ code,
4271
+ parserOptions,
4272
+ locationCalculator,
4273
+ node.value,
4274
+ node.parent.parent,
4275
+ directive.key
4149
4276
  );
4150
- const { ast } = result;
4151
- const tokens = ast.tokens || [];
4152
- const comments = ast.comments || [];
4153
- const references = analyzeExternalReferences(result, parserOptions);
4154
- const statement = ast.body[0];
4155
- const callExpression = statement.expression;
4156
- const expression = callExpression.arguments[0];
4157
- if (!allowEmpty && !expression) {
4158
- return throwEmptyError(locationCalculator, "an expression");
4159
- }
4160
- if (expression && expression.type === "SpreadElement") {
4161
- return throwUnexpectedTokenError("...", expression);
4277
+ directive.value = {
4278
+ type: "VExpressionContainer",
4279
+ range: node.value.range,
4280
+ loc: node.value.loc,
4281
+ parent: directive,
4282
+ expression: ret.expression,
4283
+ references: ret.references
4284
+ };
4285
+ if (ret.expression != null) {
4286
+ ret.expression.parent = directive.value;
4162
4287
  }
4163
- if (callExpression.arguments[1]) {
4164
- const node = callExpression.arguments[1];
4165
- return throwUnexpectedTokenError(
4166
- ",",
4167
- getCommaTokenBeforeNode(tokens, node) || node
4168
- );
4288
+ for (const variable of ret.variables) {
4289
+ node.parent.parent.variables.push(variable);
4169
4290
  }
4170
- tokens.shift();
4171
- tokens.shift();
4172
- tokens.pop();
4173
- return { expression, tokens, comments, references, variables: [] };
4291
+ replaceTokens(templateMeta, node.value, ret.tokens);
4292
+ insertComments(templateMeta, ret.comments);
4174
4293
  } catch (err) {
4175
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4176
- }
4177
- }
4178
- function parseFilter(code, locationCalculator, parserOptions) {
4179
- debug('[script] parse filter: "%s"', code);
4180
- try {
4181
- const expression = {
4182
- type: "VFilter",
4183
- parent: null,
4184
- range: [0, 0],
4185
- loc: {},
4186
- callee: null,
4187
- arguments: []
4188
- };
4189
- const tokens = [];
4190
- const comments = [];
4191
- const references = [];
4192
- const paren = code.indexOf("(");
4193
- const calleeCode = paren === -1 ? code : code.slice(0, paren);
4194
- const argsCode = paren === -1 ? null : code.slice(paren);
4195
- if (calleeCode.trim()) {
4196
- const spaces = /^\s*/u.exec(calleeCode)[0];
4197
- const subCalculator = locationCalculator.getSubCalculatorShift(
4198
- spaces.length
4199
- );
4200
- const { ast } = parseScriptFragment(
4201
- `"${calleeCode.trim()}"`,
4202
- subCalculator,
4203
- parserOptions
4204
- );
4205
- const statement = ast.body[0];
4206
- const callee = statement.expression;
4207
- if (callee.type !== "Literal") {
4208
- const { loc, range } = ast.tokens[0];
4209
- return throwUnexpectedTokenError('"', {
4210
- range: [range[1] - 1, range[1]],
4211
- loc: {
4212
- start: {
4213
- line: loc.end.line,
4214
- column: loc.end.column - 1
4215
- },
4216
- end: loc.end
4217
- }
4218
- });
4219
- }
4220
- expression.callee = {
4221
- type: "Identifier",
4222
- parent: expression,
4223
- range: [
4224
- callee.range[0],
4225
- subCalculator.getOffsetWithGap(calleeCode.trim().length)
4226
- ],
4227
- loc: {
4228
- start: callee.loc.start,
4229
- end: subCalculator.getLocation(calleeCode.trim().length)
4230
- },
4231
- name: String(callee.value)
4294
+ debug("[template] Parse error: %s", err);
4295
+ if (ParseError.isParseError(err)) {
4296
+ directive.value = {
4297
+ type: "VExpressionContainer",
4298
+ range: node.value.range,
4299
+ loc: node.value.loc,
4300
+ parent: directive,
4301
+ expression: null,
4302
+ references: []
4232
4303
  };
4233
- tokens.push({
4234
- type: "Identifier",
4235
- value: calleeCode.trim(),
4236
- range: expression.callee.range,
4237
- loc: expression.callee.loc
4238
- });
4304
+ insertError(templateMeta, err);
4239
4305
  } else {
4240
- return throwEmptyError(locationCalculator, "a filter name");
4241
- }
4242
- if (argsCode != null) {
4243
- const result = parseScriptFragment(
4244
- `0${argsCode}`,
4245
- locationCalculator.getSubCalculatorAfter(paren).getSubCalculatorShift(-1),
4246
- parserOptions
4247
- );
4248
- const { ast } = result;
4249
- const statement = ast.body[0];
4250
- const callExpression = statement.expression;
4251
- ast.tokens.shift();
4252
- if (callExpression.type !== "CallExpression" || callExpression.callee.type !== "Literal") {
4253
- let nestCount = 1;
4254
- for (const token2 of ast.tokens.slice(1)) {
4255
- if (nestCount === 0) {
4256
- return throwUnexpectedTokenError(token2.value, token2);
4257
- }
4258
- if (token2.type === "Punctuator" && token2.value === "(") {
4259
- nestCount += 1;
4260
- }
4261
- if (token2.type === "Punctuator" && token2.value === ")") {
4262
- nestCount -= 1;
4263
- }
4264
- }
4265
- const token = (0, import_last2.default)(ast.tokens);
4266
- return throwUnexpectedTokenError(token.value, token);
4267
- }
4268
- for (const argument of callExpression.arguments) {
4269
- argument.parent = expression;
4270
- expression.arguments.push(argument);
4271
- }
4272
- tokens.push(...ast.tokens);
4273
- comments.push(...ast.comments);
4274
- references.push(...analyzeExternalReferences(result, parserOptions));
4306
+ throw err;
4275
4307
  }
4276
- const firstToken = tokens[0];
4277
- const lastToken = (0, import_last2.default)(tokens);
4278
- expression.range = [firstToken.range[0], lastToken.range[1]];
4279
- expression.loc = { start: firstToken.loc.start, end: lastToken.loc.end };
4280
- return { expression, tokens, comments, references, variables: [] };
4281
- } catch (err) {
4282
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4283
- }
4284
- }
4285
- function loadParser(parser) {
4286
- if (parser !== "espree") {
4287
- const __require = createRequire(
4288
- typeof __filename ? __filename : fileURLToPath2(import.meta.url)
4289
- );
4290
- return __require(parser);
4291
- }
4292
- return getEspreeFromUser();
4293
- }
4294
- function parseScript(code, parserOptions) {
4295
- const parser = typeof parserOptions.parser === "string" ? loadParser(parserOptions.parser) : isParserObject(parserOptions.parser) ? parserOptions.parser : getEspreeFromEcmaVersion(parserOptions.ecmaVersion);
4296
- const result = isEnhancedParserObject(parser) ? parser.parseForESLint(code, parserOptions) : parser.parse(code, parserOptions);
4297
- if (result.ast != null) {
4298
- return result;
4299
4308
  }
4300
- return { ast: result };
4301
4309
  }
4302
- function parseExpression(code, locationCalculator, parserOptions, { allowEmpty = false, allowFilters = false } = {}) {
4303
- debug('[script] parse expression: "%s"', code);
4304
- const [mainCode, ...filterCodes] = allowFilters ? splitFilters(code) : [code];
4305
- if (filterCodes.length === 0) {
4306
- return parseExpressionBody(
4307
- code,
4310
+ function processMustache(parserOptions, globalLocationCalculator, vineFixLocationContext, templateMeta, node, mustache) {
4311
+ const range = [
4312
+ mustache.startToken.range[1],
4313
+ mustache.endToken.range[0]
4314
+ ];
4315
+ debug("[template] convert mustache {{%s}} %j", mustache.value, range);
4316
+ try {
4317
+ const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(range[0]);
4318
+ const ret = parseExpression(
4319
+ mustache.value,
4308
4320
  locationCalculator,
4309
4321
  parserOptions,
4310
- allowEmpty
4311
- );
4312
- }
4313
- const retB = parseExpressionBody(
4314
- mainCode,
4315
- locationCalculator,
4316
- parserOptions
4317
- );
4318
- if (!retB.expression) {
4319
- return retB;
4320
- }
4321
- const ret = retB;
4322
- ret.expression = {
4323
- type: "VFilterSequenceExpression",
4324
- parent: null,
4325
- expression: retB.expression,
4326
- filters: [],
4327
- range: retB.expression.range.slice(0),
4328
- loc: Object.assign({}, retB.expression.loc)
4329
- };
4330
- ret.expression.expression.parent = ret.expression;
4331
- let prevLoc = mainCode.length;
4332
- for (const filterCode of filterCodes) {
4333
- ret.tokens.push(
4334
- fixLocation(
4335
- {
4336
- type: "Punctuator",
4337
- value: "|",
4338
- range: [prevLoc, prevLoc + 1],
4339
- loc: {}
4340
- },
4341
- locationCalculator
4342
- )
4343
- );
4344
- const retF = parseFilter(
4345
- filterCode,
4346
- locationCalculator.getSubCalculatorShift(prevLoc + 1),
4347
- parserOptions
4322
+ { allowEmpty: true, allowFilters: true }
4348
4323
  );
4349
- if (retF) {
4350
- if (retF.expression) {
4351
- ret.expression.filters.push(retF.expression);
4352
- retF.expression.parent = ret.expression;
4324
+ node.expression = ret.expression || null;
4325
+ node.references = ret.references;
4326
+ if (ret.expression != null) {
4327
+ ret.expression.parent = node;
4328
+ }
4329
+ replaceTokens(templateMeta, { range }, ret.tokens);
4330
+ insertComments(templateMeta, ret.comments);
4331
+ } catch (err) {
4332
+ debug("[template] Parse error: %s", err);
4333
+ if (ParseError.isParseError(err)) {
4334
+ insertError(templateMeta, err);
4335
+ } else {
4336
+ throw err;
4337
+ }
4338
+ }
4339
+ }
4340
+ function resolveReference(referene, element) {
4341
+ let node = element;
4342
+ while (node != null && node.type === "VElement") {
4343
+ for (const variable of node.variables) {
4344
+ if (variable.id.name === referene.id.name) {
4345
+ referene.variable = variable;
4346
+ variable.references.push(referene);
4347
+ return;
4353
4348
  }
4354
- ret.tokens.push(...retF.tokens);
4355
- ret.comments.push(...retF.comments);
4356
- ret.references.push(...retF.references);
4357
4349
  }
4358
- prevLoc += 1 + filterCode.length;
4350
+ node = node.parent;
4359
4351
  }
4360
- const lastToken = (0, import_last2.default)(ret.tokens);
4361
- ret.expression.range[1] = lastToken.range[1];
4362
- ret.expression.loc.end = lastToken.loc.end;
4363
- return ret;
4364
4352
  }
4365
- function parseVForExpression(code, locationCalculator, parserOptions) {
4366
- if (code.trim() === "") {
4367
- throwEmptyError(locationCalculator, "'<alias> in <expression>'");
4353
+ function resolveReferences(container) {
4354
+ let element = container.parent;
4355
+ while (element != null && element.type !== "VElement") {
4356
+ element = element.parent;
4368
4357
  }
4369
- if (isEcmaVersion5(parserOptions)) {
4370
- return parseVForExpressionForEcmaVersion5(
4371
- code,
4372
- locationCalculator,
4373
- parserOptions
4374
- );
4358
+ if (element != null) {
4359
+ for (const reference of container.references) {
4360
+ resolveReference(reference, element);
4361
+ }
4375
4362
  }
4376
- const processed = processVForAliasAndIterator(code);
4377
- if (!processed.aliases.trim()) {
4378
- return throwEmptyError(locationCalculator, "an alias");
4363
+ }
4364
+ function convertForVBindSameNameShorthandValue(directive, parserOptions, locationCalculator) {
4365
+ if (directive.key.name.name !== "bind" || directive.key.argument == null || directive.key.argument.type !== "VIdentifier") {
4366
+ return;
4379
4367
  }
4368
+ const vId = directive.key.argument;
4369
+ const camelName = camelize(vId.name);
4370
+ let result = null;
4380
4371
  try {
4381
- debug(
4382
- '[script] parse v-for expression: "for(%s%s%s);"',
4383
- processed.aliasesWithBrackets,
4384
- processed.delimiter,
4385
- processed.iterator
4386
- );
4387
- const result = parseScriptFragment(
4388
- `for(let ${processed.aliasesWithBrackets}${processed.delimiter}${processed.iterator});`,
4389
- locationCalculator.getSubCalculatorShift(
4390
- processed.hasParens ? -8 : -9
4391
- ),
4392
- parserOptions
4393
- );
4394
- const { ast } = result;
4395
- const tokens = ast.tokens || [];
4396
- const comments = ast.comments || [];
4397
- const scope = analyzeVariablesAndExternalReferences(
4398
- result,
4399
- "v-for",
4372
+ result = parseScriptFragment(
4373
+ camelName,
4374
+ locationCalculator.getSubCalculatorAfter(vId.range[0]),
4400
4375
  parserOptions
4401
4376
  );
4402
- const references = scope.references;
4403
- const variables = scope.variables;
4404
- const statement = ast.body[0];
4405
- const varDecl = statement.left;
4406
- const id = varDecl.declarations[0].id;
4407
- const left = id.elements;
4408
- const right = statement.right;
4409
- if (!processed.hasParens && !left.length) {
4410
- return throwEmptyError(locationCalculator, "an alias");
4411
- }
4412
- tokens.shift();
4413
- tokens.shift();
4414
- tokens.shift();
4415
- tokens.pop();
4416
- tokens.pop();
4417
- const closeOffset = statement.left.range[1] - 1;
4418
- const closeIndex = tokens.findIndex((t) => t.range[0] === closeOffset);
4419
- if (processed.hasParens) {
4420
- const open = tokens[0];
4421
- if (open != null) {
4422
- open.value = "(";
4423
- }
4424
- const close = tokens[closeIndex];
4425
- if (close != null) {
4426
- close.value = ")";
4377
+ } catch (err) {
4378
+ debug("[template] Parse error: %s", err);
4379
+ }
4380
+ if (result == null || result.ast.body.length !== 1 || result.ast.body[0].type !== "ExpressionStatement" || result.ast.body[0].expression.type !== "Identifier") {
4381
+ return;
4382
+ }
4383
+ const id = result.ast.body[0].expression;
4384
+ id.range[1] = vId.range[1];
4385
+ id.loc.end = { ...vId.loc.end };
4386
+ if (id.end != null) {
4387
+ id.end = vId.end;
4388
+ }
4389
+ directive.value = {
4390
+ type: "VExpressionContainer",
4391
+ range: [...vId.range],
4392
+ loc: {
4393
+ start: { ...vId.loc.start },
4394
+ end: { ...vId.loc.end }
4395
+ },
4396
+ parent: directive,
4397
+ expression: id,
4398
+ references: [
4399
+ {
4400
+ id,
4401
+ mode: "r",
4402
+ variable: null
4427
4403
  }
4428
- } else {
4429
- tokens.splice(closeIndex, 1);
4430
- tokens.shift();
4431
- }
4432
- const firstToken = tokens[0] || statement.left;
4433
- const lastToken = tokens[tokens.length - 1] || statement.right;
4434
- const expression = {
4435
- type: "VForExpression",
4436
- range: [firstToken.range[0], lastToken.range[1]],
4437
- loc: { start: firstToken.loc.start, end: lastToken.loc.end },
4438
- parent: DUMMY_PARENT2,
4439
- left,
4440
- right
4441
- };
4442
- for (const l of left) {
4443
- if (l != null) {
4444
- l.parent = expression;
4404
+ ]
4405
+ };
4406
+ id.parent = directive.value;
4407
+ }
4408
+
4409
+ // src/script/scope-analyzer.ts
4410
+ var BUILTIN_COMPONENTS = /* @__PURE__ */ new Set([
4411
+ "template",
4412
+ "slot",
4413
+ "component",
4414
+ "Component",
4415
+ "transition",
4416
+ "Transition",
4417
+ "transition-group",
4418
+ "TransitionGroup",
4419
+ "keep-alive",
4420
+ "KeepAlive",
4421
+ "teleport",
4422
+ "Teleport",
4423
+ "suspense",
4424
+ "Suspense"
4425
+ ]);
4426
+ var BUILTIN_DIRECTIVES = /* @__PURE__ */ new Set([
4427
+ "bind",
4428
+ "on",
4429
+ "text",
4430
+ "html",
4431
+ "show",
4432
+ "if",
4433
+ "else",
4434
+ "else-if",
4435
+ "for",
4436
+ "model",
4437
+ "slot",
4438
+ "pre",
4439
+ "cloak",
4440
+ "once",
4441
+ "memo",
4442
+ "is"
4443
+ ]);
4444
+ var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot";
4445
+ var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view";
4446
+ var NATIVE_TAGS = /* @__PURE__ */ new Set([...HTML_TAGS.split(","), ...SVG_TAGS.split(",")]);
4447
+ function isUnique(reference, index, references) {
4448
+ return index === 0 || reference.identifier !== references[index - 1].identifier;
4449
+ }
4450
+ function capitalize(str) {
4451
+ return str[0].toUpperCase() + str.slice(1);
4452
+ }
4453
+ function hasDefinition(variable) {
4454
+ return variable.defs.length >= 1;
4455
+ }
4456
+ function transformReference(reference) {
4457
+ const ret = {
4458
+ id: reference.identifier,
4459
+ mode: reference.isReadOnly() ? "r" : reference.isWriteOnly() ? "w" : (
4460
+ /* otherwise */
4461
+ "rw"
4462
+ ),
4463
+ variable: null,
4464
+ isValueReference: reference.isValueReference,
4465
+ isTypeReference: reference.isTypeReference
4466
+ };
4467
+ Object.defineProperty(ret, "variable", { enumerable: false });
4468
+ return ret;
4469
+ }
4470
+ function transformVariable(variable, kind) {
4471
+ const ret = {
4472
+ id: variable.defs[0].name,
4473
+ kind,
4474
+ references: []
4475
+ };
4476
+ Object.defineProperty(ret, "references", { enumerable: false });
4477
+ return ret;
4478
+ }
4479
+ function getForScope(scope) {
4480
+ const child = scope.childScopes[0];
4481
+ return child.block === scope.block ? child.childScopes[0] : child;
4482
+ }
4483
+ function analyzeScope(ast, parserOptions) {
4484
+ const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions) || 2022;
4485
+ const ecmaFeatures = parserOptions.ecmaFeatures || {};
4486
+ const sourceType = parserOptions.sourceType || "script";
4487
+ const result = getEslintScope().analyze(ast, {
4488
+ ignoreEval: true,
4489
+ nodejsScope: false,
4490
+ impliedStrict: ecmaFeatures.impliedStrict,
4491
+ ecmaVersion,
4492
+ sourceType,
4493
+ fallback: getFallbackKeys
4494
+ });
4495
+ return result;
4496
+ }
4497
+ function analyze(parserResult, parserOptions) {
4498
+ const scopeManager = parserResult.scopeManager || analyzeScope(parserResult.ast, parserOptions);
4499
+ return scopeManager.globalScope;
4500
+ }
4501
+ function analyzeExternalReferences(parserResult, parserOptions) {
4502
+ const scope = analyze(parserResult, parserOptions);
4503
+ return scope.through.filter(isUnique).map(transformReference);
4504
+ }
4505
+ function analyzeVariablesAndExternalReferences(parserResult, kind, parserOptions) {
4506
+ const scope = analyze(parserResult, parserOptions);
4507
+ return {
4508
+ variables: getForScope(scope).variables.filter(hasDefinition).map((v) => transformVariable(v, kind)),
4509
+ references: scope.through.filter(isUnique).map(transformReference)
4510
+ };
4511
+ }
4512
+ function collectVariablesForVCF(tsFileScopeManager, templateRoot) {
4513
+ const scriptVariables = /* @__PURE__ */ new Map();
4514
+ const globalScope = tsFileScopeManager.globalScope;
4515
+ if (!globalScope) {
4516
+ return scriptVariables;
4517
+ }
4518
+ for (const variable of globalScope.variables) {
4519
+ scriptVariables.set(variable.name, variable);
4520
+ }
4521
+ const moduleScope = globalScope.childScopes.find(
4522
+ (scope) => scope.type === "module"
4523
+ );
4524
+ for (const variable of moduleScope && moduleScope.variables || []) {
4525
+ scriptVariables.set(variable.name, variable);
4526
+ }
4527
+ let foundVCF = templateRoot.parent;
4528
+ let foundVCFScope;
4529
+ if (templateRoot.parent) {
4530
+ do {
4531
+ foundVCF = foundVCF.parent;
4532
+ } while (foundVCF && foundVCF.type !== "FunctionDeclaration" && foundVCF.type !== "FunctionExpression" && foundVCF.type !== "ArrowFunctionExpression");
4533
+ if (foundVCF) {
4534
+ Object.assign(
4535
+ foundVCF,
4536
+ { __isVine__: true }
4537
+ );
4538
+ const tryGetVCFScope = tsFileScopeManager.nodeToScope.get(foundVCF);
4539
+ if (_optionalChain([tryGetVCFScope, 'optionalAccess', _7 => _7[0]])) {
4540
+ foundVCFScope = tryGetVCFScope[0];
4541
+ for (const variable of foundVCFScope.variables) {
4542
+ scriptVariables.set(variable.name, variable);
4543
+ }
4544
+ const compFnPropsIdentifier = _optionalChain([foundVCF, 'access', _8 => _8.params, 'optionalAccess', _9 => _9[0], 'optionalAccess', _10 => _10.type]) === "Identifier" && _optionalChain([foundVCF, 'access', _11 => _11.params, 'access', _12 => _12[0], 'optionalAccess', _13 => _13.name]) === "props" ? foundVCF.params[0] : null;
4545
+ const propsVar = scriptVariables.get("props");
4546
+ if (compFnPropsIdentifier && propsVar) {
4547
+ ;
4548
+ propsVar.eslintUsed = true;
4549
+ propsVar.references.push(
4550
+ createVirtualVineFnPropsReference({
4551
+ foundVCFScope,
4552
+ compFnPropsIdentifier
4553
+ })
4554
+ );
4555
+ }
4445
4556
  }
4446
4557
  }
4447
- right.parent = expression;
4448
- return { expression, tokens, comments, references, variables };
4449
- } catch (err) {
4450
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4451
4558
  }
4559
+ return scriptVariables;
4452
4560
  }
4453
- function isEcmaVersion5(parserOptions) {
4454
- const ecmaVersion = getEcmaVersionIfUseEspree(parserOptions);
4455
- return ecmaVersion != null && ecmaVersion <= 5;
4456
- }
4457
- function parseVForExpressionForEcmaVersion5(code, locationCalculator, parserOptions) {
4458
- const processed = processVForAliasAndIterator(code);
4459
- if (!processed.aliases.trim()) {
4460
- return throwEmptyError(locationCalculator, "an alias");
4461
- }
4462
- try {
4463
- const tokens = [];
4464
- const comments = [];
4465
- const parsedAliases = parseVForAliasesForEcmaVersion5(
4466
- processed.aliasesWithBrackets,
4467
- locationCalculator.getSubCalculatorShift(
4468
- processed.hasParens ? 0 : -1
4469
- ),
4470
- parserOptions
4471
- );
4472
- if (processed.hasParens) {
4473
- const open = parsedAliases.tokens[0];
4474
- if (open != null) {
4475
- open.value = "(";
4476
- }
4477
- const close = (0, import_last2.default)(parsedAliases.tokens);
4478
- if (close != null) {
4479
- close.value = ")";
4480
- }
4481
- } else {
4482
- parsedAliases.tokens.shift();
4483
- parsedAliases.tokens.pop();
4561
+ function analyzeUsedInTemplateVariables(scopeManager, templateRoot) {
4562
+ const scriptVariables = collectVariablesForVCF(scopeManager, templateRoot);
4563
+ const markedVariables = /* @__PURE__ */ new Set();
4564
+ function markSetupReferenceVariableAsUsed(name) {
4565
+ if (scriptVariables.has(name)) {
4566
+ markVariableAsUsed(name);
4567
+ return true;
4484
4568
  }
4485
- tokens.push(...parsedAliases.tokens);
4486
- comments.push(...parsedAliases.comments);
4487
- const { left, variables } = parsedAliases;
4488
- if (!processed.hasParens && !left.length) {
4489
- return throwEmptyError(locationCalculator, "an alias");
4569
+ const camelName = camelize(name);
4570
+ if (scriptVariables.has(camelName)) {
4571
+ markVariableAsUsed(camelName);
4572
+ return true;
4490
4573
  }
4491
- const delimiterStart = processed.aliases.length;
4492
- const delimiterEnd = delimiterStart + processed.delimiter.length;
4493
- tokens.push(
4494
- fixLocation(
4495
- {
4496
- type: processed.delimiter === "in" ? "Keyword" : "Identifier",
4497
- value: processed.delimiter,
4498
- start: delimiterStart,
4499
- end: delimiterEnd,
4500
- loc: {},
4501
- range: [delimiterStart, delimiterEnd]
4502
- },
4503
- locationCalculator
4504
- )
4505
- );
4506
- const parsedIterator = parseVForIteratorForEcmaVersion5(
4507
- processed.iterator,
4508
- locationCalculator.getSubCalculatorShift(delimiterEnd),
4509
- parserOptions
4510
- );
4511
- tokens.push(...parsedIterator.tokens);
4512
- comments.push(...parsedIterator.comments);
4513
- const { right, references } = parsedIterator;
4514
- const firstToken = tokens[0];
4515
- const lastToken = (0, import_last2.default)(tokens) || firstToken;
4516
- const expression = {
4517
- type: "VForExpression",
4518
- range: [firstToken.range[0], lastToken.range[1]],
4519
- loc: { start: firstToken.loc.start, end: lastToken.loc.end },
4520
- parent: DUMMY_PARENT2,
4521
- left,
4522
- right
4523
- };
4524
- for (const l of left) {
4525
- if (l != null) {
4526
- l.parent = expression;
4527
- }
4574
+ const pascalName = capitalize(camelName);
4575
+ if (scriptVariables.has(pascalName)) {
4576
+ markVariableAsUsed(pascalName);
4577
+ return true;
4528
4578
  }
4529
- right.parent = expression;
4530
- return { expression, tokens, comments, references, variables };
4531
- } catch (err) {
4532
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4579
+ return false;
4533
4580
  }
4534
- }
4535
- function parseVForAliasesForEcmaVersion5(code, locationCalculator, parserOptions) {
4536
- const result = parseScriptFragment(
4537
- `0(${code})`,
4538
- locationCalculator.getSubCalculatorShift(-2),
4539
- parserOptions
4540
- );
4541
- const { ast } = result;
4542
- const tokens = ast.tokens || [];
4543
- const comments = ast.comments || [];
4544
- const variables = analyzeExternalReferences(result, parserOptions).map(
4545
- transformVariable2
4546
- );
4547
- const statement = ast.body[0];
4548
- const callExpression = statement.expression;
4549
- const expression = callExpression.arguments[0];
4550
- const left = expression.elements.filter(
4551
- (e) => {
4552
- if (e == null || e.type === "Identifier") {
4553
- return true;
4554
- }
4555
- const errorToken = tokens.find(
4556
- (t) => e.range[0] <= t.range[0] && t.range[1] <= e.range[1]
4557
- );
4558
- return throwUnexpectedTokenError(errorToken.value, errorToken);
4581
+ function markVariableAsUsed(nameOrRef) {
4582
+ let name;
4583
+ let isValueReference;
4584
+ let isTypeReference;
4585
+ if (typeof nameOrRef === "string") {
4586
+ name = nameOrRef;
4587
+ } else {
4588
+ name = nameOrRef.id.name;
4589
+ isValueReference = nameOrRef.isValueReference;
4590
+ isTypeReference = nameOrRef.isTypeReference;
4559
4591
  }
4560
- );
4561
- tokens.shift();
4562
- tokens.shift();
4563
- tokens.pop();
4564
- return { left, tokens, comments, variables };
4565
- function transformVariable2(reference) {
4566
- const ret = {
4567
- id: reference.id,
4568
- kind: "v-for",
4569
- references: []
4570
- };
4571
- Object.defineProperty(ret, "references", { enumerable: false });
4572
- return ret;
4573
- }
4574
- }
4575
- function parseVForIteratorForEcmaVersion5(code, locationCalculator, parserOptions) {
4576
- const result = parseScriptFragment(
4577
- `0(${code})`,
4578
- locationCalculator.getSubCalculatorShift(-2),
4579
- parserOptions
4580
- );
4581
- const { ast } = result;
4582
- const tokens = ast.tokens || [];
4583
- const comments = ast.comments || [];
4584
- const references = analyzeExternalReferences(result, parserOptions);
4585
- const statement = ast.body[0];
4586
- const callExpression = statement.expression;
4587
- const expression = callExpression.arguments[0];
4588
- if (!expression) {
4589
- return throwEmptyError(locationCalculator, "an expression");
4590
- }
4591
- if (expression && expression.type === "SpreadElement") {
4592
- return throwUnexpectedTokenError("...", expression);
4593
- }
4594
- const right = expression;
4595
- tokens.shift();
4596
- tokens.shift();
4597
- tokens.pop();
4598
- return { right, tokens, comments, references };
4599
- }
4600
- function parseVOnExpression(code, locationCalculator, parserOptions) {
4601
- if (IS_FUNCTION_EXPRESSION.test(code) || IS_SIMPLE_PATH.test(code)) {
4602
- return parseExpressionBody(
4603
- code,
4604
- locationCalculator,
4605
- parserOptions
4606
- );
4607
- }
4608
- return parseVOnExpressionBody(
4609
- code,
4610
- locationCalculator,
4611
- parserOptions
4612
- );
4613
- }
4614
- function parseVOnExpressionBody(code, locationCalculator, parserOptions) {
4615
- debug('[script] parse v-on expression: "void function($event){%s}"', code);
4616
- if (code.trim() === "") {
4617
- throwEmptyError(locationCalculator, "statements");
4618
- }
4619
- try {
4620
- const result = parseScriptFragment(
4621
- `void function($event){${code}}`,
4622
- locationCalculator.getSubCalculatorShift(-22),
4623
- parserOptions
4624
- );
4625
- const { ast } = result;
4626
- const references = analyzeExternalReferences(result, parserOptions);
4627
- const outermostStatement = ast.body[0];
4628
- const functionDecl = outermostStatement.expression.argument;
4629
- const block = functionDecl.body;
4630
- const body = block.body;
4631
- const firstStatement = (0, import_first.default)(body);
4632
- const lastStatement = (0, import_last2.default)(body);
4633
- const expression = {
4634
- type: "VOnExpression",
4635
- range: [
4636
- firstStatement != null ? firstStatement.range[0] : block.range[0] + 1,
4637
- lastStatement != null ? lastStatement.range[1] : block.range[1] - 1
4638
- ],
4639
- loc: {
4640
- start: firstStatement != null ? firstStatement.loc.start : locationCalculator.getLocation(1),
4641
- end: lastStatement != null ? lastStatement.loc.end : locationCalculator.getLocation(code.length + 1)
4642
- },
4643
- parent: DUMMY_PARENT2,
4644
- body
4645
- };
4646
- const tokens = ast.tokens || [];
4647
- const comments = ast.comments || [];
4648
- for (const b of body) {
4649
- b.parent = expression;
4592
+ const variable = scriptVariables.get(name);
4593
+ if (!variable || variable.identifiers.length === 0) {
4594
+ return;
4595
+ }
4596
+ if (markedVariables.has(name)) {
4597
+ return;
4598
+ }
4599
+ markedVariables.add(name);
4600
+ const reference = new tsEscopeTypes2.Reference(
4601
+ variable.identifiers[0],
4602
+ variable.scope,
4603
+ 1 /* Read */,
4604
+ void 0,
4605
+ void 0,
4606
+ void 0,
4607
+ isValueReference ? 1 /* Value */ : isTypeReference ? 2 /* Type */ : void 0
4608
+ );
4609
+ reference.vueUsedInTemplate = true;
4610
+ reference.isWrite = () => false;
4611
+ reference.isWriteOnly = () => false;
4612
+ reference.isRead = () => true;
4613
+ reference.isReadOnly = () => true;
4614
+ reference.isReadWrite = () => false;
4615
+ variable.references.push(reference);
4616
+ reference.resolved = variable;
4617
+ if (reference.isTypeReference) {
4618
+ ;
4619
+ variable.eslintUsed = true;
4650
4620
  }
4651
- tokens.splice(0, 6);
4652
- tokens.pop();
4653
- return { expression, tokens, comments, references, variables: [] };
4654
- } catch (err) {
4655
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4656
4621
  }
4657
- }
4658
- function parseSlotScopeExpression(code, locationCalculator, parserOptions) {
4659
- debug('[script] parse slot-scope expression: "void function(%s) {}"', code);
4660
- if (code.trim() === "") {
4661
- throwEmptyError(
4662
- locationCalculator,
4663
- "an identifier or an array/object pattern"
4664
- );
4622
+ function processVExpressionContainer(node) {
4623
+ for (const reference of node.references.filter(
4624
+ (ref) => ref.variable == null
4625
+ )) {
4626
+ markVariableAsUsed(reference);
4627
+ }
4665
4628
  }
4666
- try {
4667
- const result = parseScriptFragment(
4668
- `void function(${code}) {}`,
4669
- locationCalculator.getSubCalculatorShift(-14),
4670
- parserOptions
4671
- );
4672
- const { ast } = result;
4673
- const statement = ast.body[0];
4674
- const rawExpression = statement.expression;
4675
- const functionDecl = rawExpression.argument;
4676
- const params = functionDecl.params;
4677
- if (params.length === 0) {
4678
- return {
4679
- expression: null,
4680
- tokens: [],
4681
- comments: [],
4682
- references: [],
4683
- variables: []
4684
- };
4629
+ function processVElement(node) {
4630
+ if (node.rawName === node.name && NATIVE_TAGS.has(node.rawName) || BUILTIN_COMPONENTS.has(node.rawName)) {
4631
+ return;
4685
4632
  }
4686
- const tokens = ast.tokens || [];
4687
- const comments = ast.comments || [];
4688
- const scope = analyzeVariablesAndExternalReferences(
4689
- result,
4690
- "scope",
4691
- parserOptions
4692
- );
4693
- const references = scope.references;
4694
- const variables = scope.variables;
4695
- const firstParam = (0, import_first.default)(params);
4696
- const lastParam = (0, import_last2.default)(params);
4697
- const expression = {
4698
- type: "VSlotScopeExpression",
4699
- range: [firstParam.range[0], lastParam.range[1]],
4700
- loc: { start: firstParam.loc.start, end: lastParam.loc.end },
4701
- parent: DUMMY_PARENT2,
4702
- params: functionDecl.params
4703
- };
4704
- for (const param of params) {
4705
- param.parent = expression;
4633
+ if (!markSetupReferenceVariableAsUsed(node.rawName)) {
4634
+ const dotIndex = node.rawName.indexOf(".");
4635
+ if (dotIndex > 0) {
4636
+ markSetupReferenceVariableAsUsed(
4637
+ node.rawName.slice(0, dotIndex)
4638
+ );
4639
+ }
4640
+ }
4641
+ }
4642
+ function processVAttribute(node) {
4643
+ if (node.directive) {
4644
+ if (BUILTIN_DIRECTIVES.has(node.key.name.name)) {
4645
+ return;
4646
+ }
4647
+ markSetupReferenceVariableAsUsed(`v-${node.key.name.rawName}`);
4648
+ } else if (node.key.name === "ref" && node.value) {
4649
+ markVariableAsUsed(node.value.value);
4706
4650
  }
4707
- tokens.shift();
4708
- tokens.shift();
4709
- tokens.shift();
4710
- tokens.pop();
4711
- tokens.pop();
4712
- tokens.pop();
4713
- return { expression, tokens, comments, references, variables };
4714
- } catch (err) {
4715
- return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
4716
4651
  }
4652
+ traverseNodes(templateRoot, {
4653
+ enterNode(node) {
4654
+ if (node.type === "VExpressionContainer") {
4655
+ processVExpressionContainer(node);
4656
+ } else if (node.type === "VElement") {
4657
+ processVElement(node);
4658
+ } else if (node.type === "VAttribute") {
4659
+ processVAttribute(node);
4660
+ }
4661
+ },
4662
+ leaveNode() {
4663
+ }
4664
+ });
4717
4665
  }
4718
4666
 
4719
- // src/template/utils/index.ts
4720
- var shorthandSign = /^[.:@#]/u;
4721
- var shorthandNameMap = { ":": "bind", ".": "bind", "@": "on", "#": "slot" };
4722
- var invalidDynamicArgumentNextChar = /^[\s=/>]$/u;
4723
- function isPropModifier(node) {
4724
- return node.name === "prop";
4725
- }
4726
- function isNotEmptyModifier(node) {
4727
- return node.name !== "";
4728
- }
4729
- function getStandardDirectiveKind(element, directiveKey) {
4730
- const directiveName = directiveKey.name.name;
4731
- if (directiveName === "for") {
4732
- return "for";
4733
- } else if (directiveName === "on") {
4734
- return "on";
4735
- } else if (directiveName === "slot" || directiveName === "slot-scope" || directiveName === "scope" && element.rawName === "template") {
4736
- return "slot";
4737
- } else if (directiveName === "bind") {
4738
- return "bind";
4667
+ // src/template/parser.ts
4668
+ var import_findLastIndex = __toESM(require_findLastIndex());
4669
+ var import_last3 = __toESM(require_last());
4670
+ var _assert = require('assert'); var _assert2 = _interopRequireDefault(_assert);
4671
+
4672
+ // src/common/location-calculator.ts
4673
+ var import_sortedLastIndex2 = __toESM(require_sortedLastIndex());
4674
+
4675
+ // src/common/lines-and-columns.ts
4676
+ var import_sortedLastIndex = __toESM(require_sortedLastIndex());
4677
+ var LinesAndColumns = class {
4678
+
4679
+ /**
4680
+ * Initialize.
4681
+ * @param ltOffsets The list of the offset of line terminators.
4682
+ */
4683
+ constructor(ltOffsets) {
4684
+ this.ltOffsets = ltOffsets;
4739
4685
  }
4740
- return null;
4741
- }
4742
- function parseAttributeValue(code, parserOptions, globalLocationCalculator, node, element, directiveKey) {
4743
- const firstChar = code[node.range[0]];
4744
- const quoted = firstChar === '"' || firstChar === "'";
4745
- const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(
4746
- node.range[0] + (quoted ? 1 : 0)
4747
- );
4748
- const directiveKind = getStandardDirectiveKind(
4749
- element,
4750
- directiveKey
4751
- );
4752
- let result;
4753
- if (quoted && node.value === "") {
4754
- result = {
4755
- expression: null,
4756
- tokens: [],
4757
- comments: [],
4758
- variables: [],
4759
- references: []
4686
+ /**
4687
+ * Calculate the location of the given index.
4688
+ * @param index The index to calculate their location.
4689
+ * @returns The location of the index.
4690
+ */
4691
+ getLocFromIndex(index) {
4692
+ const line = (0, import_sortedLastIndex.default)(this.ltOffsets, index) + 1;
4693
+ const column = index - (line === 1 ? 0 : this.ltOffsets[line - 2]);
4694
+ return { line, column };
4695
+ }
4696
+ createOffsetLocationCalculator(offset) {
4697
+ return {
4698
+ getFixOffset() {
4699
+ return offset;
4700
+ },
4701
+ getLocFromIndex: this.getLocFromIndex.bind(this)
4760
4702
  };
4761
- } else if (directiveKind === "for") {
4762
- result = parseVForExpression(
4763
- node.value,
4764
- locationCalculator,
4765
- parserOptions
4766
- );
4767
- } else if (directiveKind === "on" && directiveKey.argument != null) {
4768
- result = parseVOnExpression(
4769
- node.value,
4770
- locationCalculator,
4771
- parserOptions
4772
- );
4773
- } else if (directiveKind === "slot") {
4774
- result = parseSlotScopeExpression(
4775
- node.value,
4776
- locationCalculator,
4777
- parserOptions
4778
- );
4779
- } else if (directiveKind === "bind") {
4780
- result = parseExpression(
4781
- node.value,
4782
- locationCalculator,
4783
- parserOptions,
4784
- { allowFilters: true }
4785
- );
4786
- } else {
4787
- result = parseExpression(
4788
- node.value,
4789
- locationCalculator,
4790
- parserOptions
4791
- );
4792
4703
  }
4793
- if (quoted) {
4794
- result.tokens.unshift(
4795
- createSimpleToken(
4796
- "Punctuator",
4797
- node.range[0],
4798
- node.range[0] + 1,
4799
- firstChar,
4800
- globalLocationCalculator
4801
- )
4704
+ };
4705
+
4706
+ // src/common/location-calculator.ts
4707
+ var LocationCalculatorForHtml = class _LocationCalculatorForHtml extends LinesAndColumns {
4708
+
4709
+
4710
+
4711
+
4712
+ /**
4713
+ * Initialize this calculator.
4714
+ * @param gapOffsets The list of the offset of removed characters in tokenization phase.
4715
+ * @param ltOffsets The list of the offset of line terminators.
4716
+ * @param baseOffset The base offset to calculate locations.
4717
+ * @param shiftOffset The shift offset to calculate locations.
4718
+ */
4719
+ constructor(gapOffsets, ltOffsets, baseOffset, shiftOffset = 0) {
4720
+ super(ltOffsets);
4721
+ this.gapOffsets = gapOffsets;
4722
+ this.ltOffsets = ltOffsets;
4723
+ this.baseOffset = baseOffset || 0;
4724
+ this.baseIndexOfGap = this.baseOffset === 0 ? 0 : (0, import_sortedLastIndex2.default)(gapOffsets, this.baseOffset);
4725
+ this.shiftOffset = shiftOffset;
4726
+ }
4727
+ /**
4728
+ * Get sub calculator which have the given base offset.
4729
+ * @param offset The base offset of new sub calculator.
4730
+ * @returns Sub calculator.
4731
+ */
4732
+ getSubCalculatorAfter(offset) {
4733
+ return new _LocationCalculatorForHtml(
4734
+ this.gapOffsets,
4735
+ this.ltOffsets,
4736
+ this.baseOffset + offset,
4737
+ this.shiftOffset
4802
4738
  );
4803
- result.tokens.push(
4804
- createSimpleToken(
4805
- "Punctuator",
4806
- node.range[1] - 1,
4807
- node.range[1],
4808
- firstChar,
4809
- globalLocationCalculator
4810
- )
4739
+ }
4740
+ /**
4741
+ * Get sub calculator that shifts the given offset.
4742
+ * @param offset The shift of new sub calculator.
4743
+ * @returns Sub calculator.
4744
+ */
4745
+ getSubCalculatorShift(offset) {
4746
+ return new _LocationCalculatorForHtml(
4747
+ this.gapOffsets,
4748
+ this.ltOffsets,
4749
+ this.baseOffset,
4750
+ this.shiftOffset + offset
4811
4751
  );
4812
4752
  }
4813
- return result;
4814
- }
4815
- function parseDirectiveKeyStatically(node, templateMeta) {
4816
- const {
4817
- name: text,
4818
- rawName: rawText,
4819
- range: [offset],
4820
- loc: {
4821
- start: { column, line }
4753
+ /**
4754
+ * Calculate gap at the given index.
4755
+ * @param index The index to calculate gap.
4756
+ */
4757
+ _getGap(index) {
4758
+ const offsets = this.gapOffsets;
4759
+ let g0 = (0, import_sortedLastIndex2.default)(offsets, index + this.baseOffset);
4760
+ let pos = index + this.baseOffset + g0 - this.baseIndexOfGap;
4761
+ while (g0 < offsets.length && offsets[g0] <= pos) {
4762
+ g0 += 1;
4763
+ pos += 1;
4822
4764
  }
4823
- } = node;
4824
- const directiveKey = {
4825
- type: "VDirectiveKey",
4826
- range: node.range,
4827
- loc: node.loc,
4828
- parent: node.parent,
4829
- name: null,
4830
- argument: null,
4831
- modifiers: []
4832
- };
4833
- let i = 0;
4834
- function createIdentifier(start, end, name) {
4835
- const id = {
4836
- type: "VIdentifier",
4837
- parent: directiveKey,
4838
- range: [offset + start, offset + end],
4839
- loc: {
4840
- start: { column: column + start, line },
4841
- end: { column: column + end, line }
4842
- },
4843
- name: name || text.slice(start, end),
4844
- rawName: rawText.slice(start, end)
4845
- };
4846
- return id;
4765
+ return g0 - this.baseIndexOfGap;
4847
4766
  }
4848
- if (shorthandSign.test(text)) {
4849
- const sign = text[0];
4850
- directiveKey.name = createIdentifier(0, 1, shorthandNameMap[sign]);
4851
- i = 1;
4852
- } else {
4853
- const colon = text.indexOf(":");
4854
- if (colon !== -1) {
4855
- directiveKey.name = createIdentifier(0, colon);
4856
- i = colon + 1;
4857
- }
4767
+ /**
4768
+ * Calculate the location of the given index.
4769
+ * @param index The index to calculate their location.
4770
+ * @returns The location of the index.
4771
+ */
4772
+ getLocation(index) {
4773
+ return this.getLocFromIndex(this.getOffsetWithGap(index));
4858
4774
  }
4859
- if (directiveKey.name != null && text[i] === "[") {
4860
- const len = text.slice(i).lastIndexOf("]");
4861
- if (len !== -1) {
4862
- directiveKey.argument = createIdentifier(i, i + len + 1);
4863
- i = i + len + 1 + (text[i + len + 1] === "." ? 1 : 0);
4864
- }
4775
+ /**
4776
+ * Calculate the offset of the given index.
4777
+ * @param index The index to calculate their location.
4778
+ * @returns The offset of the index.
4779
+ */
4780
+ getOffsetWithGap(index) {
4781
+ return index + this.getFixOffset(index);
4865
4782
  }
4866
- const modifiers = text.slice(i).split(".").map((modifierName) => {
4867
- const modifier = createIdentifier(i, i + modifierName.length);
4868
- if (modifierName === "" && i < text.length) {
4869
- insertError(
4870
- templateMeta,
4871
- new ParseError(
4872
- `Unexpected token '${text[i]}'`,
4873
- void 0,
4874
- offset + i,
4875
- line,
4876
- column + i
4877
- )
4878
- );
4879
- }
4880
- i += modifierName.length + 1;
4881
- return modifier;
4882
- });
4883
- if (directiveKey.name == null) {
4884
- directiveKey.name = modifiers.shift();
4885
- } else if (directiveKey.argument == null && modifiers[0].name !== "") {
4886
- directiveKey.argument = modifiers.shift() || null;
4783
+ /**
4784
+ * Gets the fix location offset of the given offset with using the base offset of this calculator.
4785
+ * @param offset The offset to modify.
4786
+ */
4787
+ getFixOffset(offset) {
4788
+ const shiftOffset = this.shiftOffset;
4789
+ const gap = this._getGap(offset + shiftOffset);
4790
+ return this.baseOffset + gap + shiftOffset;
4887
4791
  }
4888
- directiveKey.modifiers = modifiers.filter(isNotEmptyModifier);
4889
- if (directiveKey.name.name === "v-") {
4890
- insertError(
4891
- templateMeta,
4892
- new ParseError(
4893
- `Unexpected token '${text[directiveKey.name.range[1] - offset]}'`,
4894
- void 0,
4895
- directiveKey.name.range[1],
4896
- directiveKey.name.loc.end.line,
4897
- directiveKey.name.loc.end.column
4898
- )
4899
- );
4792
+ };
4793
+
4794
+ // src/template/intermediate-tokenizer.ts
4795
+ var import_last2 = __toESM(require_last());
4796
+
4797
+ var DUMMY_PARENT2 = Object.freeze({});
4798
+ function concat(text, token) {
4799
+ return text + token.value;
4800
+ }
4801
+ var IntermediateTokenizer = class {
4802
+
4803
+
4804
+
4805
+
4806
+
4807
+
4808
+
4809
+
4810
+
4811
+ /**
4812
+ * The source code text.
4813
+ */
4814
+ get text() {
4815
+ return this.tokenizer.text;
4900
4816
  }
4901
- if (directiveKey.name.rawName === "." && !directiveKey.modifiers.some(isPropModifier)) {
4902
- const pos = (directiveKey.argument || directiveKey.name).range[1] - offset;
4903
- const propModifier = createIdentifier(pos, pos, "prop");
4904
- directiveKey.modifiers.unshift(propModifier);
4817
+ /**
4818
+ * The parse errors.
4819
+ */
4820
+ get errors() {
4821
+ return this.tokenizer.errors;
4905
4822
  }
4906
- return directiveKey;
4907
- }
4908
- function parseDirectiveKeyTokens(node) {
4909
- const { name, argument, modifiers } = node;
4910
- const shorthand = name.range[1] - name.range[0] === 1;
4911
- const tokens = [];
4912
- if (shorthand) {
4913
- tokens.push({
4914
- type: "Punctuator",
4915
- range: name.range,
4916
- loc: name.loc,
4917
- value: name.rawName
4918
- });
4919
- } else {
4920
- tokens.push({
4921
- type: "HTMLIdentifier",
4922
- range: name.range,
4923
- loc: name.loc,
4924
- value: name.rawName
4925
- });
4926
- if (argument) {
4927
- tokens.push({
4928
- type: "Punctuator",
4929
- range: [name.range[1], argument.range[0]],
4930
- loc: { start: name.loc.end, end: argument.loc.start },
4931
- value: ":"
4932
- });
4933
- }
4823
+ /**
4824
+ * The current state.
4825
+ */
4826
+ get state() {
4827
+ return this.tokenizer.state;
4934
4828
  }
4935
- if (argument) {
4936
- tokens.push({
4937
- type: "HTMLIdentifier",
4938
- range: argument.range,
4939
- loc: argument.loc,
4940
- value: argument.rawName
4941
- });
4829
+ set state(value) {
4830
+ this.tokenizer.state = value;
4942
4831
  }
4943
- let lastNode = argument || name;
4944
- for (const modifier of modifiers) {
4945
- if (modifier.rawName === "") {
4946
- continue;
4947
- }
4948
- tokens.push(
4949
- {
4950
- type: "Punctuator",
4951
- range: [lastNode.range[1], modifier.range[0]],
4952
- loc: { start: lastNode.loc.end, end: modifier.loc.start },
4953
- value: "."
4954
- },
4955
- {
4956
- type: "HTMLIdentifier",
4957
- range: modifier.range,
4958
- loc: modifier.loc,
4959
- value: modifier.rawName
4832
+ /**
4833
+ * The current namespace.
4834
+ */
4835
+ get namespace() {
4836
+ return this.tokenizer.namespace;
4837
+ }
4838
+ set namespace(value) {
4839
+ this.tokenizer.namespace = value;
4840
+ }
4841
+ /**
4842
+ * The current flag of expression enabled.
4843
+ */
4844
+ get expressionEnabled() {
4845
+ return this.tokenizer.expressionEnabled;
4846
+ }
4847
+ set expressionEnabled(value) {
4848
+ this.tokenizer.expressionEnabled = value;
4849
+ }
4850
+ /**
4851
+ * Initialize this intermediate tokenizer.
4852
+ * @param tokenizer The tokenizer.
4853
+ */
4854
+ constructor(tokenizer, parserOptions) {
4855
+ this.tokenizer = tokenizer;
4856
+ this.baseParserOptions = parserOptions;
4857
+ this.currentToken = null;
4858
+ this.attribute = null;
4859
+ this.attributeNames = /* @__PURE__ */ new Set();
4860
+ this.expressionStartToken = null;
4861
+ this.expressionTokens = [];
4862
+ this.tokens = [];
4863
+ this.comments = [];
4864
+ }
4865
+ /**
4866
+ * Get the next intermediate token.
4867
+ * @returns The intermediate token or null.
4868
+ */
4869
+ nextToken() {
4870
+ let token = null;
4871
+ let result = null;
4872
+ while (result == null) {
4873
+ token = this.tokenizer.nextToken();
4874
+ if (token == null) {
4875
+ break;
4960
4876
  }
4961
- );
4962
- lastNode = modifier;
4877
+ result = this[token.type](token);
4878
+ }
4879
+ if (result == null && token == null && this.currentToken != null) {
4880
+ result = this.commit();
4881
+ }
4882
+ return result;
4963
4883
  }
4964
- return tokens;
4965
- }
4966
- function convertDynamicArgument(node, templateMeta, parserOptions, locationCalculator) {
4967
- const { argument } = node;
4968
- if (!(argument != null && argument.type === "VIdentifier" && argument.name.startsWith("[") && argument.name.endsWith("]"))) {
4969
- return;
4884
+ /**
4885
+ * Commit the current token.
4886
+ */
4887
+ commit() {
4888
+ _assert2.default.call(void 0, this.currentToken != null || this.expressionStartToken != null);
4889
+ let token = this.currentToken;
4890
+ this.currentToken = null;
4891
+ this.attribute = null;
4892
+ if (this.expressionStartToken != null) {
4893
+ const start = this.expressionStartToken;
4894
+ const end = (0, import_last2.default)(this.expressionTokens) || start;
4895
+ const value = this.expressionTokens.reduce(concat, start.value);
4896
+ this.expressionStartToken = null;
4897
+ this.expressionTokens = [];
4898
+ if (token == null) {
4899
+ token = {
4900
+ type: "Text",
4901
+ range: [start.range[0], end.range[1]],
4902
+ loc: { start: start.loc.start, end: end.loc.end },
4903
+ value
4904
+ };
4905
+ } else if (token.type === "Text") {
4906
+ token.range[1] = end.range[1];
4907
+ token.loc.end = end.loc.end;
4908
+ token.value += value;
4909
+ } else {
4910
+ throw new Error("unreachable");
4911
+ }
4912
+ }
4913
+ return token;
4970
4914
  }
4971
- const { rawName, range, loc } = argument;
4972
- try {
4973
- const { comments, expression, references, tokens } = parseExpression(
4974
- rawName.slice(1, -1),
4975
- locationCalculator.getSubCalculatorAfter(range[0] + 1),
4976
- parserOptions
4915
+ /**
4916
+ * Report an invalid character error.
4917
+ * @param token The invalid token.
4918
+ * @param code The error code.
4919
+ */
4920
+ reportParseError(token, code) {
4921
+ const error = ParseError.fromCode(
4922
+ code,
4923
+ token.range[0],
4924
+ token.loc.start.line,
4925
+ token.loc.start.column
4977
4926
  );
4978
- node.argument = {
4979
- type: "VExpressionContainer",
4980
- range,
4981
- loc,
4982
- parent: node,
4983
- expression,
4984
- references
4985
- };
4986
- if (expression != null) {
4987
- expression.parent = node.argument;
4927
+ this.errors.push(error);
4928
+ debug("[html] syntax error:", error.message);
4929
+ }
4930
+ /**
4931
+ * Process the given comment token.
4932
+ * @param token The comment token to process.
4933
+ */
4934
+ processComment(token) {
4935
+ this.comments.push(token);
4936
+ if (this.currentToken != null && this.currentToken.type === "Text") {
4937
+ return this.commit();
4988
4938
  }
4989
- tokens.unshift(
4990
- createSimpleToken(
4991
- "Punctuator",
4992
- range[0],
4993
- range[0] + 1,
4994
- "[",
4995
- locationCalculator
4996
- )
4997
- );
4998
- tokens.push(
4999
- createSimpleToken(
5000
- "Punctuator",
5001
- range[1] - 1,
5002
- range[1],
5003
- "]",
5004
- locationCalculator
5005
- )
5006
- );
5007
- replaceTokens(templateMeta, node.argument, tokens);
5008
- insertComments(templateMeta, comments);
5009
- } catch (error) {
5010
- debug("[template] Parse error: %s", error);
5011
- if (ParseError.isParseError(error)) {
5012
- node.argument = {
5013
- type: "VExpressionContainer",
5014
- range,
5015
- loc,
5016
- parent: node,
5017
- expression: null,
5018
- references: []
5019
- };
5020
- insertError(templateMeta, error);
5021
- } else {
5022
- throw error;
4939
+ return null;
4940
+ }
4941
+ /**
4942
+ * Process the given text token.
4943
+ * @param token The text token to process.
4944
+ */
4945
+ processText(token) {
4946
+ this.tokens.push(token);
4947
+ let result = null;
4948
+ if (this.expressionStartToken != null) {
4949
+ const lastToken = (0, import_last2.default)(this.expressionTokens) || this.expressionStartToken;
4950
+ if (lastToken.range[1] === token.range[0]) {
4951
+ this.expressionTokens.push(token);
4952
+ return null;
4953
+ }
4954
+ result = this.commit();
4955
+ } else if (this.currentToken != null) {
4956
+ if (this.currentToken.type === "Text" && this.currentToken.range[1] === token.range[0]) {
4957
+ this.currentToken.value += token.value;
4958
+ this.currentToken.range[1] = token.range[1];
4959
+ this.currentToken.loc.end = token.loc.end;
4960
+ return null;
4961
+ }
4962
+ result = this.commit();
5023
4963
  }
4964
+ _assert2.default.call(void 0, this.currentToken == null);
4965
+ this.currentToken = {
4966
+ type: "Text",
4967
+ range: [token.range[0], token.range[1]],
4968
+ loc: { start: token.loc.start, end: token.loc.end },
4969
+ value: token.value
4970
+ };
4971
+ return result;
5024
4972
  }
5025
- }
5026
- function createDirectiveKey(node, templateMeta, parserOptions, locationCalculator) {
5027
- const directiveKey = parseDirectiveKeyStatically(node, templateMeta);
5028
- const tokens = parseDirectiveKeyTokens(directiveKey);
5029
- replaceTokens(templateMeta, directiveKey, tokens);
5030
- if (directiveKey.name.name.startsWith("v-")) {
5031
- directiveKey.name.name = directiveKey.name.name.slice(2);
4973
+ /**
4974
+ * Process a HTMLAssociation token.
4975
+ * @param token The token to process.
4976
+ */
4977
+ HTMLAssociation(token) {
4978
+ this.tokens.push(token);
4979
+ if (this.attribute != null) {
4980
+ this.attribute.range[1] = token.range[1];
4981
+ this.attribute.loc.end = token.loc.end;
4982
+ if (this.currentToken == null || this.currentToken.type !== "StartTag") {
4983
+ throw new Error("unreachable");
4984
+ }
4985
+ this.currentToken.range[1] = token.range[1];
4986
+ this.currentToken.loc.end = token.loc.end;
4987
+ }
4988
+ return null;
5032
4989
  }
5033
- if (directiveKey.name.rawName.startsWith("v-")) {
5034
- directiveKey.name.rawName = directiveKey.name.rawName.slice(2);
4990
+ /**
4991
+ * Process a HTMLBogusComment token.
4992
+ * @param token The token to process.
4993
+ */
4994
+ HTMLBogusComment(token) {
4995
+ return this.processComment(token);
5035
4996
  }
5036
- convertDynamicArgument(
5037
- directiveKey,
5038
- templateMeta,
5039
- parserOptions,
5040
- locationCalculator
5041
- );
5042
- return directiveKey;
5043
- }
5044
- function convertToDirective(node, code, templateMeta, locationCalculator, vineFixLocationContext, parserOptions) {
5045
- debug(
5046
- '[template] convert to directive: %s="%s" %j',
5047
- node.key.name,
5048
- node.value && node.value.value,
5049
- node.range
5050
- );
5051
- const directive = node;
5052
- directive.directive = true;
5053
- directive.key = createDirectiveKey(
5054
- node.key,
5055
- templateMeta,
5056
- parserOptions,
5057
- locationCalculator
5058
- );
5059
- const { argument } = directive.key;
5060
- if (argument && argument.type === "VIdentifier" && argument.name.startsWith("[")) {
5061
- const nextChar = code[argument.range[1]];
5062
- if (nextChar == null || invalidDynamicArgumentNextChar.test(nextChar)) {
5063
- const char = nextChar == null ? "EOF" : JSON.stringify(nextChar).slice(1, -1);
5064
- insertError(
5065
- templateMeta,
5066
- new ParseError(
5067
- `Dynamic argument cannot contain the '${char}' character.`,
5068
- void 0,
5069
- argument.range[1],
5070
- argument.loc.end.line,
5071
- argument.loc.end.column
5072
- )
5073
- );
5074
- }
4997
+ /**
4998
+ * Process a HTMLCDataText token.
4999
+ * @param token The token to process.
5000
+ */
5001
+ HTMLCDataText(token) {
5002
+ return this.processText(token);
5075
5003
  }
5076
- if (node.value == null) {
5077
- return;
5004
+ /**
5005
+ * Process a HTMLComment token.
5006
+ * @param token The token to process.
5007
+ */
5008
+ HTMLComment(token) {
5009
+ return this.processComment(token);
5078
5010
  }
5079
- try {
5080
- const ret = parseAttributeValue(
5081
- code,
5082
- parserOptions,
5083
- locationCalculator,
5084
- node.value,
5085
- node.parent.parent,
5086
- directive.key
5087
- );
5088
- directive.value = {
5089
- type: "VExpressionContainer",
5090
- range: node.value.range,
5091
- loc: node.value.loc,
5092
- parent: directive,
5093
- expression: ret.expression,
5094
- references: ret.references
5011
+ /**
5012
+ * Process a HTMLEndTagOpen token.
5013
+ * @param token The token to process.
5014
+ */
5015
+ HTMLEndTagOpen(token) {
5016
+ this.tokens.push(token);
5017
+ let result = null;
5018
+ if (this.currentToken != null || this.expressionStartToken != null) {
5019
+ result = this.commit();
5020
+ }
5021
+ this.currentToken = {
5022
+ type: "EndTag",
5023
+ range: [token.range[0], token.range[1]],
5024
+ loc: { start: token.loc.start, end: token.loc.end },
5025
+ name: token.value
5095
5026
  };
5096
- if (ret.expression != null) {
5097
- ret.expression.parent = directive.value;
5027
+ return result;
5028
+ }
5029
+ /**
5030
+ * Process a HTMLIdentifier token.
5031
+ * @param token The token to process.
5032
+ */
5033
+ HTMLIdentifier(token) {
5034
+ this.tokens.push(token);
5035
+ if (this.currentToken == null || this.currentToken.type === "Text" || this.currentToken.type === "Mustache") {
5036
+ throw new Error("unreachable");
5098
5037
  }
5099
- for (const variable of ret.variables) {
5100
- node.parent.parent.variables.push(variable);
5038
+ if (this.currentToken.type === "EndTag") {
5039
+ this.reportParseError(token, "end-tag-with-attributes");
5040
+ return null;
5101
5041
  }
5102
- replaceTokens(templateMeta, node.value, ret.tokens);
5103
- insertComments(templateMeta, ret.comments);
5104
- } catch (err) {
5105
- debug("[template] Parse error: %s", err);
5106
- if (ParseError.isParseError(err)) {
5107
- directive.value = {
5108
- type: "VExpressionContainer",
5109
- range: node.value.range,
5110
- loc: node.value.loc,
5111
- parent: directive,
5112
- expression: null,
5113
- references: []
5042
+ if (this.attributeNames.has(token.value)) {
5043
+ this.reportParseError(token, "duplicate-attribute");
5044
+ }
5045
+ this.attributeNames.add(token.value);
5046
+ this.attribute = {
5047
+ type: "VAttribute",
5048
+ range: [token.range[0], token.range[1]],
5049
+ loc: { start: token.loc.start, end: token.loc.end },
5050
+ parent: DUMMY_PARENT2,
5051
+ directive: false,
5052
+ key: {
5053
+ type: "VIdentifier",
5054
+ range: [token.range[0], token.range[1]],
5055
+ loc: { start: token.loc.start, end: token.loc.end },
5056
+ parent: DUMMY_PARENT2,
5057
+ name: token.value,
5058
+ rawName: this.text.slice(token.range[0], token.range[1])
5059
+ },
5060
+ value: null
5061
+ };
5062
+ this.attribute.key.parent = this.attribute;
5063
+ this.currentToken.range[1] = token.range[1];
5064
+ this.currentToken.loc.end = token.loc.end;
5065
+ this.currentToken.attributes.push(this.attribute);
5066
+ return null;
5067
+ }
5068
+ /**
5069
+ * Process a HTMLLiteral token.
5070
+ * @param token The token to process.
5071
+ */
5072
+ HTMLLiteral(token) {
5073
+ this.tokens.push(token);
5074
+ if (this.attribute != null) {
5075
+ this.attribute.range[1] = token.range[1];
5076
+ this.attribute.loc.end = token.loc.end;
5077
+ this.attribute.value = {
5078
+ type: "VLiteral",
5079
+ range: [token.range[0], token.range[1]],
5080
+ loc: { start: token.loc.start, end: token.loc.end },
5081
+ parent: this.attribute,
5082
+ value: token.value
5114
5083
  };
5115
- insertError(templateMeta, err);
5116
- } else {
5117
- throw err;
5084
+ if (this.currentToken == null || this.currentToken.type !== "StartTag") {
5085
+ throw new Error("unreachable");
5086
+ }
5087
+ this.currentToken.range[1] = token.range[1];
5088
+ this.currentToken.loc.end = token.loc.end;
5118
5089
  }
5090
+ return null;
5119
5091
  }
5120
- }
5121
- function processMustache(parserOptions, globalLocationCalculator, vineFixLocationContext, templateMeta, node, mustache) {
5122
- const range = [
5123
- mustache.startToken.range[1],
5124
- mustache.endToken.range[0]
5125
- ];
5126
- debug("[template] convert mustache {{%s}} %j", mustache.value, range);
5127
- try {
5128
- const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(range[0]);
5129
- const ret = parseExpression(
5130
- mustache.value,
5131
- locationCalculator,
5132
- parserOptions,
5133
- { allowEmpty: true, allowFilters: true }
5134
- );
5135
- node.expression = ret.expression || null;
5136
- node.references = ret.references;
5137
- if (ret.expression != null) {
5138
- ret.expression.parent = node;
5092
+ /**
5093
+ * Process a HTMLRCDataText token.
5094
+ * @param token The token to process.
5095
+ */
5096
+ HTMLRCDataText(token) {
5097
+ return this.processText(token);
5098
+ }
5099
+ /**
5100
+ * Process a HTMLRawText token.
5101
+ * @param token The token to process.
5102
+ */
5103
+ HTMLRawText(token) {
5104
+ return this.processText(token);
5105
+ }
5106
+ /**
5107
+ * Process a HTMLSelfClosingTagClose token.
5108
+ * @param token The token to process.
5109
+ */
5110
+ HTMLSelfClosingTagClose(token) {
5111
+ this.tokens.push(token);
5112
+ if (this.currentToken == null || this.currentToken.type === "Text") {
5113
+ throw new Error("unreachable");
5139
5114
  }
5140
- replaceTokens(templateMeta, { range }, ret.tokens);
5141
- insertComments(templateMeta, ret.comments);
5142
- } catch (err) {
5143
- debug("[template] Parse error: %s", err);
5144
- if (ParseError.isParseError(err)) {
5145
- insertError(templateMeta, err);
5115
+ if (this.currentToken.type === "StartTag") {
5116
+ this.currentToken.selfClosing = true;
5146
5117
  } else {
5147
- throw err;
5118
+ this.reportParseError(token, "end-tag-with-trailing-solidus");
5148
5119
  }
5120
+ this.currentToken.range[1] = token.range[1];
5121
+ this.currentToken.loc.end = token.loc.end;
5122
+ return this.commit();
5149
5123
  }
5150
- }
5151
- function resolveReference(referene, element) {
5152
- let node = element;
5153
- while (node != null && node.type === "VElement") {
5154
- for (const variable of node.variables) {
5155
- if (variable.id.name === referene.id.name) {
5156
- referene.variable = variable;
5157
- variable.references.push(referene);
5158
- return;
5159
- }
5124
+ /**
5125
+ * Process a HTMLTagClose token.
5126
+ * @param token The token to process.
5127
+ */
5128
+ HTMLTagClose(token) {
5129
+ this.tokens.push(token);
5130
+ if (this.currentToken == null || this.currentToken.type === "Text") {
5131
+ throw new Error("unreachable");
5160
5132
  }
5161
- node = node.parent;
5133
+ this.currentToken.range[1] = token.range[1];
5134
+ this.currentToken.loc.end = token.loc.end;
5135
+ return this.commit();
5162
5136
  }
5163
- }
5164
- function resolveReferences(container) {
5165
- let element = container.parent;
5166
- while (element != null && element.type !== "VElement") {
5167
- element = element.parent;
5137
+ /**
5138
+ * Process a HTMLTagOpen token.
5139
+ * @param token The token to process.
5140
+ */
5141
+ HTMLTagOpen(token) {
5142
+ this.tokens.push(token);
5143
+ let result = null;
5144
+ if (this.currentToken != null || this.expressionStartToken != null) {
5145
+ result = this.commit();
5146
+ }
5147
+ this.currentToken = {
5148
+ type: "StartTag",
5149
+ range: [token.range[0], token.range[1]],
5150
+ loc: { start: token.loc.start, end: token.loc.end },
5151
+ name: token.value,
5152
+ rawName: this.text.slice(token.range[0] + 1, token.range[1]),
5153
+ selfClosing: false,
5154
+ attributes: []
5155
+ };
5156
+ this.attribute = null;
5157
+ this.attributeNames.clear();
5158
+ return result;
5168
5159
  }
5169
- if (element != null) {
5170
- for (const reference of container.references) {
5171
- resolveReference(reference, element);
5160
+ /**
5161
+ * Process a HTMLText token.
5162
+ * @param token The token to process.
5163
+ */
5164
+ HTMLText(token) {
5165
+ return this.processText(token);
5166
+ }
5167
+ /**
5168
+ * Process a HTMLWhitespace token.
5169
+ * @param token The token to process.
5170
+ */
5171
+ HTMLWhitespace(token) {
5172
+ return this.processText(token);
5173
+ }
5174
+ /**
5175
+ * Process a VExpressionStart token.
5176
+ * @param token The token to process.
5177
+ */
5178
+ VExpressionStart(token) {
5179
+ if (this.expressionStartToken != null) {
5180
+ return this.processText(token);
5172
5181
  }
5182
+ const separated = this.currentToken != null && this.currentToken.range[1] !== token.range[0];
5183
+ const result = separated ? this.commit() : null;
5184
+ this.tokens.push(token);
5185
+ this.expressionStartToken = token;
5186
+ return result;
5173
5187
  }
5174
- }
5188
+ /**
5189
+ * Process a VExpressionEnd token.
5190
+ * @param token The token to process.
5191
+ */
5192
+ VExpressionEnd(token) {
5193
+ if (this.expressionStartToken == null) {
5194
+ return this.processText(token);
5195
+ }
5196
+ const start = this.expressionStartToken;
5197
+ const end = (0, import_last2.default)(this.expressionTokens) || start;
5198
+ if (token.range[0] === start.range[1]) {
5199
+ this.tokens.pop();
5200
+ this.expressionStartToken = null;
5201
+ const result2 = this.processText(start);
5202
+ this.processText(token);
5203
+ return result2;
5204
+ }
5205
+ if (end.range[1] !== token.range[0]) {
5206
+ const result2 = this.commit();
5207
+ this.processText(token);
5208
+ return result2;
5209
+ }
5210
+ const value = this.expressionTokens.reduce(concat, "");
5211
+ this.tokens.push(token);
5212
+ this.expressionStartToken = null;
5213
+ this.expressionTokens = [];
5214
+ const result = this.currentToken != null ? this.commit() : null;
5215
+ this.currentToken = {
5216
+ type: "Mustache",
5217
+ range: [start.range[0], token.range[1]],
5218
+ loc: { start: start.loc.start, end: token.loc.end },
5219
+ value,
5220
+ startToken: start,
5221
+ endToken: token
5222
+ };
5223
+ return result || this.commit();
5224
+ }
5225
+ };
5175
5226
 
5176
5227
  // src/template/utils/attribute-names.ts
5177
5228
  var SVG_ATTRIBUTE_NAME_MAP = /* @__PURE__ */ new Map([