@vue/compiler-sfc 3.3.0-alpha.7 → 3.3.0-alpha.9

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.
@@ -3396,6 +3396,13 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3396
3396
  rootScope[local] = true;
3397
3397
  propsLocalToPublicMap[local] = key;
3398
3398
  }
3399
+ function pushScope() {
3400
+ scopeStack.push(currentScope = Object.create(currentScope));
3401
+ }
3402
+ function popScope() {
3403
+ scopeStack.pop();
3404
+ currentScope = scopeStack[scopeStack.length - 1] || null;
3405
+ }
3399
3406
  function registerLocalBinding(id) {
3400
3407
  excludedIds.add(id);
3401
3408
  if (currentScope) {
@@ -3439,36 +3446,29 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3439
3446
  }
3440
3447
  }
3441
3448
  }
3442
- function rewriteId(scope, id, parent, parentStack2) {
3443
- if (shared.hasOwn(scope, id.name)) {
3444
- const binding = scope[id.name];
3445
- if (binding) {
3446
- if (parent.type === "AssignmentExpression" && id === parent.left || parent.type === "UpdateExpression") {
3447
- error(`Cannot assign to destructured props as they are readonly.`, id);
3448
- }
3449
- if (compilerCore.isStaticProperty(parent) && parent.shorthand) {
3450
- if (!parent.inPattern || compilerCore.isInDestructureAssignment(parent, parentStack2)) {
3451
- s.appendLeft(
3452
- id.end + offset,
3453
- `: ${shared.genPropsAccessExp(propsLocalToPublicMap[id.name])}`
3454
- );
3455
- }
3456
- } else {
3457
- s.overwrite(
3458
- id.start + offset,
3459
- id.end + offset,
3460
- shared.genPropsAccessExp(propsLocalToPublicMap[id.name])
3461
- );
3462
- }
3449
+ function rewriteId(id, parent, parentStack2) {
3450
+ if (parent.type === "AssignmentExpression" && id === parent.left || parent.type === "UpdateExpression") {
3451
+ error(`Cannot assign to destructured props as they are readonly.`, id);
3452
+ }
3453
+ if (compilerCore.isStaticProperty(parent) && parent.shorthand) {
3454
+ if (!parent.inPattern || compilerCore.isInDestructureAssignment(parent, parentStack2)) {
3455
+ s.appendLeft(
3456
+ id.end + offset,
3457
+ `: ${shared.genPropsAccessExp(propsLocalToPublicMap[id.name])}`
3458
+ );
3463
3459
  }
3464
- return true;
3460
+ } else {
3461
+ s.overwrite(
3462
+ id.start + offset,
3463
+ id.end + offset,
3464
+ shared.genPropsAccessExp(propsLocalToPublicMap[id.name])
3465
+ );
3465
3466
  }
3466
- return false;
3467
3467
  }
3468
3468
  function checkUsage(node, method, alias = method) {
3469
3469
  if (compilerCore.isCallOf(node, alias)) {
3470
3470
  const arg = compilerCore.unwrapTSNode(node.arguments[0]);
3471
- if (arg.type === "Identifier") {
3471
+ if (arg.type === "Identifier" && currentScope[arg.name]) {
3472
3472
  error(
3473
3473
  `"${arg.name}" is a destructured prop and should not be passed directly to ${method}(). Pass a getter () => ${arg.name} instead.`,
3474
3474
  arg
@@ -3486,7 +3486,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3486
3486
  checkUsage(node, "watch", vueImportAliases.watch);
3487
3487
  checkUsage(node, "toRef", vueImportAliases.toRef);
3488
3488
  if (compilerCore.isFunctionType(node)) {
3489
- scopeStack.push(currentScope = {});
3489
+ pushScope();
3490
3490
  compilerCore.walkFunctionParams(node, registerLocalBinding);
3491
3491
  if (node.body.type === "BlockStatement") {
3492
3492
  walkScope(node.body);
@@ -3494,7 +3494,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3494
3494
  return;
3495
3495
  }
3496
3496
  if (node.type === "CatchClause") {
3497
- scopeStack.push(currentScope = {});
3497
+ pushScope();
3498
3498
  if (node.param && node.param.type === "Identifier") {
3499
3499
  registerLocalBinding(node.param);
3500
3500
  }
@@ -3502,17 +3502,14 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3502
3502
  return;
3503
3503
  }
3504
3504
  if (node.type === "BlockStatement" && !compilerCore.isFunctionType(parent)) {
3505
- scopeStack.push(currentScope = {});
3505
+ pushScope();
3506
3506
  walkScope(node);
3507
3507
  return;
3508
3508
  }
3509
3509
  if (node.type === "Identifier") {
3510
3510
  if (compilerCore.isReferencedIdentifier(node, parent, parentStack) && !excludedIds.has(node)) {
3511
- let i = scopeStack.length;
3512
- while (i--) {
3513
- if (rewriteId(scopeStack[i], node, parent, parentStack)) {
3514
- return;
3515
- }
3511
+ if (currentScope[node.name]) {
3512
+ rewriteId(node, parent, parentStack);
3516
3513
  }
3517
3514
  }
3518
3515
  }
@@ -3520,8 +3517,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
3520
3517
  leave(node, parent) {
3521
3518
  parent && parentStack.pop();
3522
3519
  if (node.type === "BlockStatement" && !compilerCore.isFunctionType(parent) || compilerCore.isFunctionType(node)) {
3523
- scopeStack.pop();
3524
- currentScope = scopeStack[scopeStack.length - 1] || null;
3520
+ popScope();
3525
3521
  }
3526
3522
  }
3527
3523
  });
@@ -3533,6 +3529,7 @@ const DEFINE_EXPOSE = "defineExpose";
3533
3529
  const WITH_DEFAULTS = "withDefaults";
3534
3530
  const DEFINE_OPTIONS = "defineOptions";
3535
3531
  const DEFINE_SLOTS = "defineSlots";
3532
+ const DEFINE_MODEL = "defineModel";
3536
3533
  const isBuiltInDir = shared.makeMap(
3537
3534
  `once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`
3538
3535
  );
@@ -3540,6 +3537,7 @@ function compileScript(sfc, options) {
3540
3537
  var _a;
3541
3538
  let { script, scriptSetup, source, filename } = sfc;
3542
3539
  const enableReactivityTransform = !!options.reactivityTransform;
3540
+ const enableDefineModel = !!options.defineModel;
3543
3541
  const isProd = !!options.isProd;
3544
3542
  const genSourceMap = options.sourceMap !== false;
3545
3543
  const hoistStatic = options.hoistStatic !== false && !script;
@@ -3663,6 +3661,7 @@ export default ${defaultVar}`;
3663
3661
  let hasDefaultExportRender = false;
3664
3662
  let hasDefineOptionsCall = false;
3665
3663
  let hasDefineSlotsCall = false;
3664
+ let hasDefineModelCall = false;
3666
3665
  let propsRuntimeDecl;
3667
3666
  let propsRuntimeDefaults;
3668
3667
  let propsDestructureDecl;
@@ -3674,6 +3673,7 @@ export default ${defaultVar}`;
3674
3673
  let emitsTypeDecl;
3675
3674
  let emitIdentifier;
3676
3675
  let optionsRuntimeDecl;
3676
+ let modelDecls = {};
3677
3677
  let hasAwait = false;
3678
3678
  let hasInlinedSsrRenderFn = false;
3679
3679
  const typeDeclaredProps = {};
@@ -3896,6 +3896,61 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
3896
3896
  }
3897
3897
  return true;
3898
3898
  }
3899
+ function processDefineModel(node, declId) {
3900
+ if (!enableDefineModel || !CompilerDOM.isCallOf(node, DEFINE_MODEL)) {
3901
+ return false;
3902
+ }
3903
+ hasDefineModelCall = true;
3904
+ const type = node.typeParameters && node.typeParameters.params[0] || void 0;
3905
+ let modelName;
3906
+ let options2;
3907
+ const arg0 = node.arguments[0] && CompilerDOM.unwrapTSNode(node.arguments[0]);
3908
+ if (arg0 && arg0.type === "StringLiteral") {
3909
+ modelName = arg0.value;
3910
+ options2 = node.arguments[1];
3911
+ } else {
3912
+ modelName = "modelValue";
3913
+ options2 = arg0;
3914
+ }
3915
+ if (modelDecls[modelName]) {
3916
+ error(`duplicate model name ${JSON.stringify(modelName)}`, node);
3917
+ }
3918
+ const optionsString = options2 ? s.slice(startOffset + options2.start, startOffset + options2.end) : void 0;
3919
+ modelDecls[modelName] = {
3920
+ type,
3921
+ options: optionsString,
3922
+ identifier: declId && declId.type === "Identifier" ? declId.name : void 0
3923
+ };
3924
+ let runtimeOptions2 = "";
3925
+ if (options2) {
3926
+ if (options2.type === "ObjectExpression") {
3927
+ const local = options2.properties.find(
3928
+ (p) => p.type === "ObjectProperty" && (p.key.type === "Identifier" && p.key.name === "local" || p.key.type === "StringLiteral" && p.key.value === "local")
3929
+ );
3930
+ if (local) {
3931
+ runtimeOptions2 = `{ ${s.slice(
3932
+ startOffset + local.start,
3933
+ startOffset + local.end
3934
+ )} }`;
3935
+ } else {
3936
+ for (const p of options2.properties) {
3937
+ if (p.type === "SpreadElement" || p.computed) {
3938
+ runtimeOptions2 = optionsString;
3939
+ break;
3940
+ }
3941
+ }
3942
+ }
3943
+ } else {
3944
+ runtimeOptions2 = optionsString;
3945
+ }
3946
+ }
3947
+ s.overwrite(
3948
+ startOffset + node.start,
3949
+ startOffset + node.end,
3950
+ `${helper("useModel")}(__props, ${JSON.stringify(modelName)}${runtimeOptions2 ? `, ${runtimeOptions2}` : ``})`
3951
+ );
3952
+ return true;
3953
+ }
3899
3954
  function getAstBody() {
3900
3955
  return scriptAst ? [...scriptSetupAst.body, ...scriptAst.body] : scriptSetupAst.body;
3901
3956
  }
@@ -3955,8 +4010,10 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
3955
4010
  if (node.typeParameters) {
3956
4011
  error(`${DEFINE_OPTIONS}() cannot accept type arguments`, node);
3957
4012
  }
4013
+ if (!node.arguments[0])
4014
+ return true;
3958
4015
  hasDefineOptionsCall = true;
3959
- optionsRuntimeDecl = node.arguments[0];
4016
+ optionsRuntimeDecl = CompilerDOM.unwrapTSNode(node.arguments[0]);
3960
4017
  let propsOption = void 0;
3961
4018
  let emitsOption = void 0;
3962
4019
  let exposeOption = void 0;
@@ -4043,7 +4100,7 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
4043
4100
  return;
4044
4101
  CompilerDOM.walkIdentifiers(node, (id) => {
4045
4102
  const binding = setupBindings[id.name];
4046
- if (binding && (binding !== "literal-const" || !hoistStatic)) {
4103
+ if (binding && binding !== "literal-const") {
4047
4104
  error(
4048
4105
  `\`${method}()\` in <script setup> cannot reference locally declared variables because it will be hoisted outside of the setup() function. If your component options require initialization in the module scope, use a separate normal <script> to export the options instead.`,
4049
4106
  id
@@ -4080,61 +4137,135 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
4080
4137
  (node) => node.type !== "SpreadElement" && (!node.computed || node.key.type.endsWith("Literal"))
4081
4138
  );
4082
4139
  }
4083
- function genRuntimeProps(props) {
4084
- const keys = Object.keys(props);
4085
- if (!keys.length) {
4086
- return ``;
4087
- }
4088
- const hasStaticDefaults = hasStaticWithDefaults();
4089
- const scriptSetupSource = scriptSetup.content;
4090
- let propsDecls = `{
4140
+ function concatStrings(strs) {
4141
+ return strs.filter((s2) => !!s2).join(", ");
4142
+ }
4143
+ function genRuntimeProps() {
4144
+ function genPropsFromTS() {
4145
+ const keys = Object.keys(typeDeclaredProps);
4146
+ if (!keys.length)
4147
+ return;
4148
+ const hasStaticDefaults = hasStaticWithDefaults();
4149
+ const scriptSetupSource = scriptSetup.content;
4150
+ let propsDecls2 = `{
4091
4151
  ${keys.map((key) => {
4092
- let defaultString;
4093
- const destructured = genDestructuredDefaultValue(key, props[key].type);
4094
- if (destructured) {
4095
- defaultString = `default: ${destructured.valueString}${destructured.needSkipFactory ? `, skipFactory: true` : ``}`;
4096
- } else if (hasStaticDefaults) {
4097
- const prop = propsRuntimeDefaults.properties.find((node) => {
4098
- if (node.type === "SpreadElement")
4099
- return false;
4100
- return resolveObjectKey(node.key, node.computed) === key;
4101
- });
4102
- if (prop) {
4103
- if (prop.type === "ObjectProperty") {
4104
- defaultString = `default: ${scriptSetupSource.slice(
4105
- prop.value.start,
4106
- prop.value.end
4107
- )}`;
4108
- } else {
4109
- defaultString = `${prop.async ? "async " : ""}${prop.kind !== "method" ? `${prop.kind} ` : ""}default() ${scriptSetupSource.slice(
4110
- prop.body.start,
4111
- prop.body.end
4112
- )}`;
4152
+ let defaultString;
4153
+ const destructured = genDestructuredDefaultValue(
4154
+ key,
4155
+ typeDeclaredProps[key].type
4156
+ );
4157
+ if (destructured) {
4158
+ defaultString = `default: ${destructured.valueString}${destructured.needSkipFactory ? `, skipFactory: true` : ``}`;
4159
+ } else if (hasStaticDefaults) {
4160
+ const prop = propsRuntimeDefaults.properties.find((node) => {
4161
+ if (node.type === "SpreadElement")
4162
+ return false;
4163
+ return resolveObjectKey(node.key, node.computed) === key;
4164
+ });
4165
+ if (prop) {
4166
+ if (prop.type === "ObjectProperty") {
4167
+ defaultString = `default: ${scriptSetupSource.slice(
4168
+ prop.value.start,
4169
+ prop.value.end
4170
+ )}`;
4171
+ } else {
4172
+ defaultString = `${prop.async ? "async " : ""}${prop.kind !== "method" ? `${prop.kind} ` : ""}default() ${scriptSetupSource.slice(
4173
+ prop.body.start,
4174
+ prop.body.end
4175
+ )}`;
4176
+ }
4113
4177
  }
4114
4178
  }
4179
+ const { type, required, skipCheck } = typeDeclaredProps[key];
4180
+ if (!isProd) {
4181
+ return `${key}: { ${concatStrings([
4182
+ `type: ${toRuntimeTypeString(type)}`,
4183
+ `required: ${required}`,
4184
+ skipCheck && "skipCheck: true",
4185
+ defaultString
4186
+ ])} }`;
4187
+ } else if (type.some(
4188
+ (el) => el === "Boolean" || (!hasStaticDefaults || defaultString) && el === "Function"
4189
+ )) {
4190
+ return `${key}: { ${concatStrings([
4191
+ `type: ${toRuntimeTypeString(type)}`,
4192
+ defaultString
4193
+ ])} }`;
4194
+ } else {
4195
+ return `${key}: ${defaultString ? `{ ${defaultString} }` : `{}`}`;
4196
+ }
4197
+ }).join(",\n ")}
4198
+ }`;
4199
+ if (propsRuntimeDefaults && !hasStaticDefaults) {
4200
+ propsDecls2 = `${helper("mergeDefaults")}(${propsDecls2}, ${source.slice(
4201
+ propsRuntimeDefaults.start + startOffset,
4202
+ propsRuntimeDefaults.end + startOffset
4203
+ )})`;
4115
4204
  }
4116
- const { type, required, skipCheck } = props[key];
4117
- if (!isProd) {
4118
- return `${key}: { type: ${toRuntimeTypeString(
4119
- type
4120
- )}, required: ${required}${skipCheck ? ", skipCheck: true" : ""}${defaultString ? `, ${defaultString}` : ``} }`;
4121
- } else if (type.some(
4122
- (el) => el === "Boolean" || (!hasStaticDefaults || defaultString) && el === "Function"
4123
- )) {
4124
- return `${key}: { type: ${toRuntimeTypeString(type)}${defaultString ? `, ${defaultString}` : ``} }`;
4125
- } else {
4126
- return `${key}: ${defaultString ? `{ ${defaultString} }` : "null"}`;
4205
+ return propsDecls2;
4206
+ }
4207
+ function genModels() {
4208
+ if (!hasDefineModelCall)
4209
+ return;
4210
+ let modelPropsDecl = "";
4211
+ for (const [name, { type, options: options2 }] of Object.entries(modelDecls)) {
4212
+ let skipCheck = false;
4213
+ let runtimeTypes = type && inferRuntimeType(type, declaredTypes);
4214
+ if (runtimeTypes) {
4215
+ const hasUnknownType = runtimeTypes.includes(UNKNOWN_TYPE);
4216
+ runtimeTypes = runtimeTypes.filter((el) => {
4217
+ if (el === UNKNOWN_TYPE)
4218
+ return false;
4219
+ return isProd ? el === "Boolean" || el === "Function" && options2 : true;
4220
+ });
4221
+ skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0;
4222
+ }
4223
+ let runtimeType = runtimeTypes && runtimeTypes.length > 0 && toRuntimeTypeString(runtimeTypes) || void 0;
4224
+ const codegenOptions = concatStrings([
4225
+ runtimeType && `type: ${runtimeType}`,
4226
+ skipCheck && "skipCheck: true"
4227
+ ]);
4228
+ let decl;
4229
+ if (runtimeType && options2) {
4230
+ decl = isTS ? `{ ${codegenOptions}, ...${options2} }` : `Object.assign({ ${codegenOptions} }, ${options2})`;
4231
+ } else {
4232
+ decl = options2 || (runtimeType ? `{ ${codegenOptions} }` : "{}");
4233
+ }
4234
+ modelPropsDecl += `
4235
+ ${JSON.stringify(name)}: ${decl},`;
4127
4236
  }
4128
- }).join(",\n ")}
4237
+ return `{${modelPropsDecl}
4129
4238
  }`;
4130
- if (propsRuntimeDefaults && !hasStaticDefaults) {
4131
- propsDecls = `${helper("mergeDefaults")}(${propsDecls}, ${source.slice(
4132
- propsRuntimeDefaults.start + startOffset,
4133
- propsRuntimeDefaults.end + startOffset
4134
- )})`;
4135
4239
  }
4136
- return `
4137
- props: ${propsDecls},`;
4240
+ let propsDecls;
4241
+ if (propsRuntimeDecl) {
4242
+ propsDecls = scriptSetup.content.slice(propsRuntimeDecl.start, propsRuntimeDecl.end).trim();
4243
+ if (propsDestructureDecl) {
4244
+ const defaults = [];
4245
+ for (const key in propsDestructuredBindings) {
4246
+ const d = genDestructuredDefaultValue(key);
4247
+ if (d)
4248
+ defaults.push(
4249
+ `${key}: ${d.valueString}${d.needSkipFactory ? `, __skip_${key}: true` : ``}`
4250
+ );
4251
+ }
4252
+ if (defaults.length) {
4253
+ propsDecls = `${helper(
4254
+ `mergeDefaults`
4255
+ )}(${propsDecls}, {
4256
+ ${defaults.join(",\n ")}
4257
+ })`;
4258
+ }
4259
+ }
4260
+ } else if (propsTypeDecl) {
4261
+ propsDecls = genPropsFromTS();
4262
+ }
4263
+ const modelsDecls = genModels();
4264
+ if (propsDecls && modelsDecls) {
4265
+ return `${helper("mergeModels")}(${propsDecls}, ${modelsDecls})`;
4266
+ } else {
4267
+ return modelsDecls || propsDecls;
4268
+ }
4138
4269
  }
4139
4270
  function genDestructuredDefaultValue(key, inferredType) {
4140
4271
  const destructured = propsDestructuredBindings[key];
@@ -4188,6 +4319,22 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
4188
4319
  return scriptSource.slice(node.start, node.end);
4189
4320
  }
4190
4321
  }
4322
+ function genRuntimeEmits() {
4323
+ function genEmitsFromTS() {
4324
+ return typeDeclaredEmits.size ? `[${Array.from(typeDeclaredEmits).map((k) => JSON.stringify(k)).join(", ")}]` : ``;
4325
+ }
4326
+ let emitsDecl2 = "";
4327
+ if (emitsRuntimeDecl) {
4328
+ emitsDecl2 = scriptSetup.content.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end).trim();
4329
+ } else if (emitsTypeDecl) {
4330
+ emitsDecl2 = genEmitsFromTS();
4331
+ }
4332
+ if (hasDefineModelCall) {
4333
+ let modelEmitsDecl = `[${Object.keys(modelDecls).map((n) => JSON.stringify(`update:${n}`)).join(", ")}]`;
4334
+ emitsDecl2 = emitsDecl2 ? `${helper("mergeModels")}(${emitsDecl2}, ${modelEmitsDecl})` : modelEmitsDecl;
4335
+ }
4336
+ return emitsDecl2;
4337
+ }
4191
4338
  const scriptAst = script && parse(
4192
4339
  script.content,
4193
4340
  {
@@ -4333,10 +4480,22 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
4333
4480
  }
4334
4481
  }
4335
4482
  if (node.declaration) {
4336
- walkDeclaration(node.declaration, scriptBindings, vueImportAliases);
4483
+ walkDeclaration(
4484
+ "script",
4485
+ node.declaration,
4486
+ scriptBindings,
4487
+ vueImportAliases,
4488
+ hoistStatic
4489
+ );
4337
4490
  }
4338
4491
  } else if ((node.type === "VariableDeclaration" || node.type === "FunctionDeclaration" || node.type === "ClassDeclaration" || node.type === "TSEnumDeclaration") && !node.declare) {
4339
- walkDeclaration(node, scriptBindings, vueImportAliases);
4492
+ walkDeclaration(
4493
+ "script",
4494
+ node,
4495
+ scriptBindings,
4496
+ vueImportAliases,
4497
+ hoistStatic
4498
+ );
4340
4499
  }
4341
4500
  }
4342
4501
  if (enableReactivityTransform && reactivityTransform.shouldTransform(script.content)) {
@@ -4376,6 +4535,8 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
4376
4535
  callee.end + startOffset,
4377
4536
  "__expose"
4378
4537
  );
4538
+ } else {
4539
+ processDefineModel(expr);
4379
4540
  }
4380
4541
  }
4381
4542
  if (node.type === "VariableDeclaration" && !node.declare) {
@@ -4394,7 +4555,7 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
4394
4555
  }
4395
4556
  const isDefineProps = processDefineProps(init, decl.id) || processWithDefaults(init, decl.id);
4396
4557
  const isDefineEmits = !isDefineProps && processDefineEmits(init, decl.id);
4397
- !isDefineEmits && processDefineSlots(init, decl.id);
4558
+ !isDefineEmits && (processDefineSlots(init, decl.id) || processDefineModel(init, decl.id));
4398
4559
  if (isDefineProps || isDefineEmits) {
4399
4560
  if (left === 1) {
4400
4561
  s.remove(node.start + startOffset, node.end + startOffset);
@@ -4417,7 +4578,13 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
4417
4578
  }
4418
4579
  let isAllLiteral = false;
4419
4580
  if ((node.type === "VariableDeclaration" || node.type === "FunctionDeclaration" || node.type === "ClassDeclaration" || node.type === "TSEnumDeclaration") && !node.declare) {
4420
- isAllLiteral = walkDeclaration(node, setupBindings, vueImportAliases);
4581
+ isAllLiteral = walkDeclaration(
4582
+ "scriptSetup",
4583
+ node,
4584
+ setupBindings,
4585
+ vueImportAliases,
4586
+ hoistStatic
4587
+ );
4421
4588
  }
4422
4589
  if (hoistStatic && isAllLiteral) {
4423
4590
  hoistNode(node);
@@ -4525,6 +4692,9 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
4525
4692
  for (const key in typeDeclaredProps) {
4526
4693
  bindingMetadata[key] = "props";
4527
4694
  }
4695
+ for (const key in modelDecls) {
4696
+ bindingMetadata[key] = "props";
4697
+ }
4528
4698
  if (propsDestructureDecl) {
4529
4699
  if (propsDestructureRestId) {
4530
4700
  bindingMetadata[propsDestructureRestId] = "setup-reactive-const";
@@ -4707,36 +4877,14 @@ return ${returned}
4707
4877
  runtimeOptions += `
4708
4878
  __ssrInlineRender: true,`;
4709
4879
  }
4710
- if (propsRuntimeDecl) {
4711
- let declCode = scriptSetup.content.slice(propsRuntimeDecl.start, propsRuntimeDecl.end).trim();
4712
- if (propsDestructureDecl) {
4713
- const defaults = [];
4714
- for (const key in propsDestructuredBindings) {
4715
- const d = genDestructuredDefaultValue(key);
4716
- if (d)
4717
- defaults.push(
4718
- `${key}: ${d.valueString}${d.needSkipFactory ? `, __skip_${key}: true` : ``}`
4719
- );
4720
- }
4721
- if (defaults.length) {
4722
- declCode = `${helper(
4723
- `mergeDefaults`
4724
- )}(${declCode}, {
4725
- ${defaults.join(",\n ")}
4726
- })`;
4727
- }
4728
- }
4880
+ const propsDecl = genRuntimeProps();
4881
+ if (propsDecl)
4729
4882
  runtimeOptions += `
4730
- props: ${declCode},`;
4731
- } else if (propsTypeDecl) {
4732
- runtimeOptions += genRuntimeProps(typeDeclaredProps);
4733
- }
4734
- if (emitsRuntimeDecl) {
4883
+ props: ${propsDecl},`;
4884
+ const emitsDecl = genRuntimeEmits();
4885
+ if (emitsDecl)
4735
4886
  runtimeOptions += `
4736
- emits: ${scriptSetup.content.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end).trim()},`;
4737
- } else if (emitsTypeDecl) {
4738
- runtimeOptions += genRuntimeEmits(typeDeclaredEmits);
4739
- }
4887
+ emits: ${emitsDecl},`;
4740
4888
  let definedOptions = "";
4741
4889
  if (optionsRuntimeDecl) {
4742
4890
  definedOptions = scriptSetup.content.slice(optionsRuntimeDecl.start, optionsRuntimeDecl.end).trim();
@@ -4802,7 +4950,7 @@ ${exposeCall}`
4802
4950
  function registerBinding(bindings, node, type) {
4803
4951
  bindings[node.name] = type;
4804
4952
  }
4805
- function walkDeclaration(node, bindings, userImportAliases) {
4953
+ function walkDeclaration(from, node, bindings, userImportAliases, hoistStatic) {
4806
4954
  let isAllLiteral = false;
4807
4955
  if (node.type === "VariableDeclaration") {
4808
4956
  const isConst = node.kind === "const";
@@ -4818,7 +4966,7 @@ function walkDeclaration(node, bindings, userImportAliases) {
4818
4966
  if (id.type === "Identifier") {
4819
4967
  let bindingType;
4820
4968
  const userReactiveBinding = userImportAliases["reactive"];
4821
- if (isAllLiteral || isConst && isStaticNode(init)) {
4969
+ if ((hoistStatic || from === "script") && (isAllLiteral || isConst && isStaticNode(init))) {
4822
4970
  bindingType = "literal-const";
4823
4971
  } else if (CompilerDOM.isCallOf(init, userReactiveBinding)) {
4824
4972
  bindingType = isConst ? "setup-reactive-const" : "setup-let";
@@ -4829,7 +4977,7 @@ function walkDeclaration(node, bindings, userImportAliases) {
4829
4977
  ) {
4830
4978
  bindingType = CompilerDOM.isCallOf(init, DEFINE_PROPS) ? "setup-reactive-const" : "setup-const";
4831
4979
  } else if (isConst) {
4832
- if (CompilerDOM.isCallOf(init, userImportAliases["ref"])) {
4980
+ if (CompilerDOM.isCallOf(init, userImportAliases["ref"]) || CompilerDOM.isCallOf(init, DEFINE_MODEL)) {
4833
4981
  bindingType = "setup-ref";
4834
4982
  } else {
4835
4983
  bindingType = "setup-maybe-ref";
@@ -5113,11 +5261,15 @@ function extractRuntimeEmits(node, emits, error) {
5113
5261
  hasCallSignature = true;
5114
5262
  }
5115
5263
  if (t.type === "TSPropertySignature") {
5116
- if (t.key.type !== "Identifier" || t.computed) {
5264
+ if (t.key.type === "Identifier" && !t.computed) {
5265
+ emits.add(t.key.name);
5266
+ hasProperty = true;
5267
+ } else if (t.key.type === "StringLiteral" && !t.computed) {
5268
+ emits.add(t.key.value);
5269
+ hasProperty = true;
5270
+ } else {
5117
5271
  error(`defineEmits() type cannot use computed keys.`, t.key);
5118
5272
  }
5119
- emits.add(t.key.name);
5120
- hasProperty = true;
5121
5273
  }
5122
5274
  }
5123
5275
  if (hasCallSignature && hasProperty) {
@@ -5147,10 +5299,6 @@ function extractEventNames(eventName, emits) {
5147
5299
  }
5148
5300
  }
5149
5301
  }
5150
- function genRuntimeEmits(emits) {
5151
- return emits.size ? `
5152
- emits: [${Array.from(emits).map((p) => JSON.stringify(p)).join(", ")}],` : ``;
5153
- }
5154
5302
  function canNeverBeRef(node, userReactiveImport) {
5155
5303
  if (CompilerDOM.isCallOf(node, userReactiveImport)) {
5156
5304
  return true;
@@ -14318,7 +14466,7 @@ function preprocess(options, preprocessor) {
14318
14466
  );
14319
14467
  }
14320
14468
 
14321
- const version = "3.3.0-alpha.7";
14469
+ const version = "3.3.0-alpha.9";
14322
14470
  const walk = estreeWalker.walk;
14323
14471
 
14324
14472
  exports.MagicString = MagicString;
@@ -119,6 +119,10 @@ export interface SFCScriptCompileOptions {
119
119
  * @default true
120
120
  */
121
121
  hoistStatic?: boolean;
122
+ /**
123
+ * (**Experimental**) Enable macro `defineModel`
124
+ */
125
+ defineModel?: boolean;
122
126
  }
123
127
  interface ImportBinding {
124
128
  isType: boolean;
@@ -22874,7 +22874,7 @@ const transformText = (node, context) => {
22874
22874
  const seen$1 = /* @__PURE__ */ new WeakSet();
22875
22875
  const transformOnce = (node, context) => {
22876
22876
  if (node.type === 1 && findDir(node, "once", true)) {
22877
- if (seen$1.has(node) || context.inVOnce) {
22877
+ if (seen$1.has(node) || context.inVOnce || context.inSSR) {
22878
22878
  return;
22879
22879
  }
22880
22880
  seen$1.add(node);
@@ -34501,6 +34501,13 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34501
34501
  rootScope[local] = true;
34502
34502
  propsLocalToPublicMap[local] = key;
34503
34503
  }
34504
+ function pushScope() {
34505
+ scopeStack.push(currentScope = Object.create(currentScope));
34506
+ }
34507
+ function popScope() {
34508
+ scopeStack.pop();
34509
+ currentScope = scopeStack[scopeStack.length - 1] || null;
34510
+ }
34504
34511
  function registerLocalBinding(id) {
34505
34512
  excludedIds.add(id);
34506
34513
  if (currentScope) {
@@ -34544,36 +34551,29 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34544
34551
  }
34545
34552
  }
34546
34553
  }
34547
- function rewriteId(scope, id, parent, parentStack2) {
34548
- if (hasOwn(scope, id.name)) {
34549
- const binding = scope[id.name];
34550
- if (binding) {
34551
- if (parent.type === "AssignmentExpression" && id === parent.left || parent.type === "UpdateExpression") {
34552
- error(`Cannot assign to destructured props as they are readonly.`, id);
34553
- }
34554
- if (isStaticProperty(parent) && parent.shorthand) {
34555
- if (!parent.inPattern || isInDestructureAssignment(parent, parentStack2)) {
34556
- s.appendLeft(
34557
- id.end + offset,
34558
- `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`
34559
- );
34560
- }
34561
- } else {
34562
- s.overwrite(
34563
- id.start + offset,
34564
- id.end + offset,
34565
- genPropsAccessExp(propsLocalToPublicMap[id.name])
34566
- );
34567
- }
34554
+ function rewriteId(id, parent, parentStack2) {
34555
+ if (parent.type === "AssignmentExpression" && id === parent.left || parent.type === "UpdateExpression") {
34556
+ error(`Cannot assign to destructured props as they are readonly.`, id);
34557
+ }
34558
+ if (isStaticProperty(parent) && parent.shorthand) {
34559
+ if (!parent.inPattern || isInDestructureAssignment(parent, parentStack2)) {
34560
+ s.appendLeft(
34561
+ id.end + offset,
34562
+ `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`
34563
+ );
34568
34564
  }
34569
- return true;
34565
+ } else {
34566
+ s.overwrite(
34567
+ id.start + offset,
34568
+ id.end + offset,
34569
+ genPropsAccessExp(propsLocalToPublicMap[id.name])
34570
+ );
34570
34571
  }
34571
- return false;
34572
34572
  }
34573
34573
  function checkUsage(node, method, alias = method) {
34574
34574
  if (isCallOf(node, alias)) {
34575
34575
  const arg = unwrapTSNode(node.arguments[0]);
34576
- if (arg.type === "Identifier") {
34576
+ if (arg.type === "Identifier" && currentScope[arg.name]) {
34577
34577
  error(
34578
34578
  `"${arg.name}" is a destructured prop and should not be passed directly to ${method}(). Pass a getter () => ${arg.name} instead.`,
34579
34579
  arg
@@ -34591,7 +34591,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34591
34591
  checkUsage(node, "watch", vueImportAliases.watch);
34592
34592
  checkUsage(node, "toRef", vueImportAliases.toRef);
34593
34593
  if (isFunctionType(node)) {
34594
- scopeStack.push(currentScope = {});
34594
+ pushScope();
34595
34595
  walkFunctionParams(node, registerLocalBinding);
34596
34596
  if (node.body.type === "BlockStatement") {
34597
34597
  walkScope(node.body);
@@ -34599,7 +34599,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34599
34599
  return;
34600
34600
  }
34601
34601
  if (node.type === "CatchClause") {
34602
- scopeStack.push(currentScope = {});
34602
+ pushScope();
34603
34603
  if (node.param && node.param.type === "Identifier") {
34604
34604
  registerLocalBinding(node.param);
34605
34605
  }
@@ -34607,17 +34607,14 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34607
34607
  return;
34608
34608
  }
34609
34609
  if (node.type === "BlockStatement" && !isFunctionType(parent)) {
34610
- scopeStack.push(currentScope = {});
34610
+ pushScope();
34611
34611
  walkScope(node);
34612
34612
  return;
34613
34613
  }
34614
34614
  if (node.type === "Identifier") {
34615
34615
  if (isReferencedIdentifier(node, parent, parentStack) && !excludedIds.has(node)) {
34616
- let i = scopeStack.length;
34617
- while (i--) {
34618
- if (rewriteId(scopeStack[i], node, parent, parentStack)) {
34619
- return;
34620
- }
34616
+ if (currentScope[node.name]) {
34617
+ rewriteId(node, parent, parentStack);
34621
34618
  }
34622
34619
  }
34623
34620
  }
@@ -34625,8 +34622,7 @@ function transformDestructuredProps(ast, s, offset = 0, knownProps, error, vueIm
34625
34622
  leave(node, parent) {
34626
34623
  parent && parentStack.pop();
34627
34624
  if (node.type === "BlockStatement" && !isFunctionType(parent) || isFunctionType(node)) {
34628
- scopeStack.pop();
34629
- currentScope = scopeStack[scopeStack.length - 1] || null;
34625
+ popScope();
34630
34626
  }
34631
34627
  }
34632
34628
  });
@@ -34657,6 +34653,7 @@ const DEFINE_EXPOSE = "defineExpose";
34657
34653
  const WITH_DEFAULTS = "withDefaults";
34658
34654
  const DEFINE_OPTIONS = "defineOptions";
34659
34655
  const DEFINE_SLOTS = "defineSlots";
34656
+ const DEFINE_MODEL = "defineModel";
34660
34657
  const isBuiltInDir = makeMap(
34661
34658
  `once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`
34662
34659
  );
@@ -34664,6 +34661,7 @@ function compileScript(sfc, options) {
34664
34661
  var _a;
34665
34662
  let { script, scriptSetup, source, filename } = sfc;
34666
34663
  const enableReactivityTransform = !!options.reactivityTransform;
34664
+ const enableDefineModel = !!options.defineModel;
34667
34665
  const isProd = !!options.isProd;
34668
34666
  const genSourceMap = options.sourceMap !== false;
34669
34667
  const hoistStatic = options.hoistStatic !== false && !script;
@@ -34786,6 +34784,7 @@ export default ${defaultVar}`;
34786
34784
  let hasDefaultExportRender = false;
34787
34785
  let hasDefineOptionsCall = false;
34788
34786
  let hasDefineSlotsCall = false;
34787
+ let hasDefineModelCall = false;
34789
34788
  let propsRuntimeDecl;
34790
34789
  let propsRuntimeDefaults;
34791
34790
  let propsDestructureDecl;
@@ -34797,6 +34796,7 @@ export default ${defaultVar}`;
34797
34796
  let emitsTypeDecl;
34798
34797
  let emitIdentifier;
34799
34798
  let optionsRuntimeDecl;
34799
+ let modelDecls = {};
34800
34800
  let hasAwait = false;
34801
34801
  let hasInlinedSsrRenderFn = false;
34802
34802
  const typeDeclaredProps = {};
@@ -35019,6 +35019,61 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
35019
35019
  }
35020
35020
  return true;
35021
35021
  }
35022
+ function processDefineModel(node, declId) {
35023
+ if (!enableDefineModel || !isCallOf(node, DEFINE_MODEL)) {
35024
+ return false;
35025
+ }
35026
+ hasDefineModelCall = true;
35027
+ const type = node.typeParameters && node.typeParameters.params[0] || void 0;
35028
+ let modelName;
35029
+ let options2;
35030
+ const arg0 = node.arguments[0] && unwrapTSNode(node.arguments[0]);
35031
+ if (arg0 && arg0.type === "StringLiteral") {
35032
+ modelName = arg0.value;
35033
+ options2 = node.arguments[1];
35034
+ } else {
35035
+ modelName = "modelValue";
35036
+ options2 = arg0;
35037
+ }
35038
+ if (modelDecls[modelName]) {
35039
+ error(`duplicate model name ${JSON.stringify(modelName)}`, node);
35040
+ }
35041
+ const optionsString = options2 ? s.slice(startOffset + options2.start, startOffset + options2.end) : void 0;
35042
+ modelDecls[modelName] = {
35043
+ type,
35044
+ options: optionsString,
35045
+ identifier: declId && declId.type === "Identifier" ? declId.name : void 0
35046
+ };
35047
+ let runtimeOptions2 = "";
35048
+ if (options2) {
35049
+ if (options2.type === "ObjectExpression") {
35050
+ const local = options2.properties.find(
35051
+ (p) => p.type === "ObjectProperty" && (p.key.type === "Identifier" && p.key.name === "local" || p.key.type === "StringLiteral" && p.key.value === "local")
35052
+ );
35053
+ if (local) {
35054
+ runtimeOptions2 = `{ ${s.slice(
35055
+ startOffset + local.start,
35056
+ startOffset + local.end
35057
+ )} }`;
35058
+ } else {
35059
+ for (const p of options2.properties) {
35060
+ if (p.type === "SpreadElement" || p.computed) {
35061
+ runtimeOptions2 = optionsString;
35062
+ break;
35063
+ }
35064
+ }
35065
+ }
35066
+ } else {
35067
+ runtimeOptions2 = optionsString;
35068
+ }
35069
+ }
35070
+ s.overwrite(
35071
+ startOffset + node.start,
35072
+ startOffset + node.end,
35073
+ `${helper("useModel")}(__props, ${JSON.stringify(modelName)}${runtimeOptions2 ? `, ${runtimeOptions2}` : ``})`
35074
+ );
35075
+ return true;
35076
+ }
35022
35077
  function getAstBody() {
35023
35078
  return scriptAst ? [...scriptSetupAst.body, ...scriptAst.body] : scriptSetupAst.body;
35024
35079
  }
@@ -35078,8 +35133,10 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
35078
35133
  if (node.typeParameters) {
35079
35134
  error(`${DEFINE_OPTIONS}() cannot accept type arguments`, node);
35080
35135
  }
35136
+ if (!node.arguments[0])
35137
+ return true;
35081
35138
  hasDefineOptionsCall = true;
35082
- optionsRuntimeDecl = node.arguments[0];
35139
+ optionsRuntimeDecl = unwrapTSNode(node.arguments[0]);
35083
35140
  let propsOption = void 0;
35084
35141
  let emitsOption = void 0;
35085
35142
  let exposeOption = void 0;
@@ -35166,7 +35223,7 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
35166
35223
  return;
35167
35224
  walkIdentifiers(node, (id) => {
35168
35225
  const binding = setupBindings[id.name];
35169
- if (binding && (binding !== "literal-const" || !hoistStatic)) {
35226
+ if (binding && binding !== "literal-const") {
35170
35227
  error(
35171
35228
  `\`${method}()\` in <script setup> cannot reference locally declared variables because it will be hoisted outside of the setup() function. If your component options require initialization in the module scope, use a separate normal <script> to export the options instead.`,
35172
35229
  id
@@ -35203,61 +35260,135 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
35203
35260
  (node) => node.type !== "SpreadElement" && (!node.computed || node.key.type.endsWith("Literal"))
35204
35261
  );
35205
35262
  }
35206
- function genRuntimeProps(props) {
35207
- const keys = Object.keys(props);
35208
- if (!keys.length) {
35209
- return ``;
35210
- }
35211
- const hasStaticDefaults = hasStaticWithDefaults();
35212
- const scriptSetupSource = scriptSetup.content;
35213
- let propsDecls = `{
35263
+ function concatStrings(strs) {
35264
+ return strs.filter((s2) => !!s2).join(", ");
35265
+ }
35266
+ function genRuntimeProps() {
35267
+ function genPropsFromTS() {
35268
+ const keys = Object.keys(typeDeclaredProps);
35269
+ if (!keys.length)
35270
+ return;
35271
+ const hasStaticDefaults = hasStaticWithDefaults();
35272
+ const scriptSetupSource = scriptSetup.content;
35273
+ let propsDecls2 = `{
35214
35274
  ${keys.map((key) => {
35215
- let defaultString;
35216
- const destructured = genDestructuredDefaultValue(key, props[key].type);
35217
- if (destructured) {
35218
- defaultString = `default: ${destructured.valueString}${destructured.needSkipFactory ? `, skipFactory: true` : ``}`;
35219
- } else if (hasStaticDefaults) {
35220
- const prop = propsRuntimeDefaults.properties.find((node) => {
35221
- if (node.type === "SpreadElement")
35222
- return false;
35223
- return resolveObjectKey(node.key, node.computed) === key;
35224
- });
35225
- if (prop) {
35226
- if (prop.type === "ObjectProperty") {
35227
- defaultString = `default: ${scriptSetupSource.slice(
35228
- prop.value.start,
35229
- prop.value.end
35230
- )}`;
35231
- } else {
35232
- defaultString = `${prop.async ? "async " : ""}${prop.kind !== "method" ? `${prop.kind} ` : ""}default() ${scriptSetupSource.slice(
35233
- prop.body.start,
35234
- prop.body.end
35235
- )}`;
35275
+ let defaultString;
35276
+ const destructured = genDestructuredDefaultValue(
35277
+ key,
35278
+ typeDeclaredProps[key].type
35279
+ );
35280
+ if (destructured) {
35281
+ defaultString = `default: ${destructured.valueString}${destructured.needSkipFactory ? `, skipFactory: true` : ``}`;
35282
+ } else if (hasStaticDefaults) {
35283
+ const prop = propsRuntimeDefaults.properties.find((node) => {
35284
+ if (node.type === "SpreadElement")
35285
+ return false;
35286
+ return resolveObjectKey(node.key, node.computed) === key;
35287
+ });
35288
+ if (prop) {
35289
+ if (prop.type === "ObjectProperty") {
35290
+ defaultString = `default: ${scriptSetupSource.slice(
35291
+ prop.value.start,
35292
+ prop.value.end
35293
+ )}`;
35294
+ } else {
35295
+ defaultString = `${prop.async ? "async " : ""}${prop.kind !== "method" ? `${prop.kind} ` : ""}default() ${scriptSetupSource.slice(
35296
+ prop.body.start,
35297
+ prop.body.end
35298
+ )}`;
35299
+ }
35236
35300
  }
35237
35301
  }
35302
+ const { type, required, skipCheck } = typeDeclaredProps[key];
35303
+ if (!isProd) {
35304
+ return `${key}: { ${concatStrings([
35305
+ `type: ${toRuntimeTypeString(type)}`,
35306
+ `required: ${required}`,
35307
+ skipCheck && "skipCheck: true",
35308
+ defaultString
35309
+ ])} }`;
35310
+ } else if (type.some(
35311
+ (el) => el === "Boolean" || (!hasStaticDefaults || defaultString) && el === "Function"
35312
+ )) {
35313
+ return `${key}: { ${concatStrings([
35314
+ `type: ${toRuntimeTypeString(type)}`,
35315
+ defaultString
35316
+ ])} }`;
35317
+ } else {
35318
+ return `${key}: ${defaultString ? `{ ${defaultString} }` : `{}`}`;
35319
+ }
35320
+ }).join(",\n ")}
35321
+ }`;
35322
+ if (propsRuntimeDefaults && !hasStaticDefaults) {
35323
+ propsDecls2 = `${helper("mergeDefaults")}(${propsDecls2}, ${source.slice(
35324
+ propsRuntimeDefaults.start + startOffset,
35325
+ propsRuntimeDefaults.end + startOffset
35326
+ )})`;
35238
35327
  }
35239
- const { type, required, skipCheck } = props[key];
35240
- if (!isProd) {
35241
- return `${key}: { type: ${toRuntimeTypeString(
35242
- type
35243
- )}, required: ${required}${skipCheck ? ", skipCheck: true" : ""}${defaultString ? `, ${defaultString}` : ``} }`;
35244
- } else if (type.some(
35245
- (el) => el === "Boolean" || (!hasStaticDefaults || defaultString) && el === "Function"
35246
- )) {
35247
- return `${key}: { type: ${toRuntimeTypeString(type)}${defaultString ? `, ${defaultString}` : ``} }`;
35248
- } else {
35249
- return `${key}: ${defaultString ? `{ ${defaultString} }` : "null"}`;
35328
+ return propsDecls2;
35329
+ }
35330
+ function genModels() {
35331
+ if (!hasDefineModelCall)
35332
+ return;
35333
+ let modelPropsDecl = "";
35334
+ for (const [name, { type, options: options2 }] of Object.entries(modelDecls)) {
35335
+ let skipCheck = false;
35336
+ let runtimeTypes = type && inferRuntimeType(type, declaredTypes);
35337
+ if (runtimeTypes) {
35338
+ const hasUnknownType = runtimeTypes.includes(UNKNOWN_TYPE);
35339
+ runtimeTypes = runtimeTypes.filter((el) => {
35340
+ if (el === UNKNOWN_TYPE)
35341
+ return false;
35342
+ return isProd ? el === "Boolean" || el === "Function" && options2 : true;
35343
+ });
35344
+ skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0;
35345
+ }
35346
+ let runtimeType = runtimeTypes && runtimeTypes.length > 0 && toRuntimeTypeString(runtimeTypes) || void 0;
35347
+ const codegenOptions = concatStrings([
35348
+ runtimeType && `type: ${runtimeType}`,
35349
+ skipCheck && "skipCheck: true"
35350
+ ]);
35351
+ let decl;
35352
+ if (runtimeType && options2) {
35353
+ decl = isTS ? `{ ${codegenOptions}, ...${options2} }` : `Object.assign({ ${codegenOptions} }, ${options2})`;
35354
+ } else {
35355
+ decl = options2 || (runtimeType ? `{ ${codegenOptions} }` : "{}");
35356
+ }
35357
+ modelPropsDecl += `
35358
+ ${JSON.stringify(name)}: ${decl},`;
35250
35359
  }
35251
- }).join(",\n ")}
35360
+ return `{${modelPropsDecl}
35252
35361
  }`;
35253
- if (propsRuntimeDefaults && !hasStaticDefaults) {
35254
- propsDecls = `${helper("mergeDefaults")}(${propsDecls}, ${source.slice(
35255
- propsRuntimeDefaults.start + startOffset,
35256
- propsRuntimeDefaults.end + startOffset
35257
- )})`;
35258
35362
  }
35259
- return `
35260
- props: ${propsDecls},`;
35363
+ let propsDecls;
35364
+ if (propsRuntimeDecl) {
35365
+ propsDecls = scriptSetup.content.slice(propsRuntimeDecl.start, propsRuntimeDecl.end).trim();
35366
+ if (propsDestructureDecl) {
35367
+ const defaults = [];
35368
+ for (const key in propsDestructuredBindings) {
35369
+ const d = genDestructuredDefaultValue(key);
35370
+ if (d)
35371
+ defaults.push(
35372
+ `${key}: ${d.valueString}${d.needSkipFactory ? `, __skip_${key}: true` : ``}`
35373
+ );
35374
+ }
35375
+ if (defaults.length) {
35376
+ propsDecls = `${helper(
35377
+ `mergeDefaults`
35378
+ )}(${propsDecls}, {
35379
+ ${defaults.join(",\n ")}
35380
+ })`;
35381
+ }
35382
+ }
35383
+ } else if (propsTypeDecl) {
35384
+ propsDecls = genPropsFromTS();
35385
+ }
35386
+ const modelsDecls = genModels();
35387
+ if (propsDecls && modelsDecls) {
35388
+ return `${helper("mergeModels")}(${propsDecls}, ${modelsDecls})`;
35389
+ } else {
35390
+ return modelsDecls || propsDecls;
35391
+ }
35261
35392
  }
35262
35393
  function genDestructuredDefaultValue(key, inferredType) {
35263
35394
  const destructured = propsDestructuredBindings[key];
@@ -35311,6 +35442,22 @@ Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(..
35311
35442
  return scriptSource.slice(node.start, node.end);
35312
35443
  }
35313
35444
  }
35445
+ function genRuntimeEmits() {
35446
+ function genEmitsFromTS() {
35447
+ return typeDeclaredEmits.size ? `[${Array.from(typeDeclaredEmits).map((k) => JSON.stringify(k)).join(", ")}]` : ``;
35448
+ }
35449
+ let emitsDecl2 = "";
35450
+ if (emitsRuntimeDecl) {
35451
+ emitsDecl2 = scriptSetup.content.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end).trim();
35452
+ } else if (emitsTypeDecl) {
35453
+ emitsDecl2 = genEmitsFromTS();
35454
+ }
35455
+ if (hasDefineModelCall) {
35456
+ let modelEmitsDecl = `[${Object.keys(modelDecls).map((n) => JSON.stringify(`update:${n}`)).join(", ")}]`;
35457
+ emitsDecl2 = emitsDecl2 ? `${helper("mergeModels")}(${emitsDecl2}, ${modelEmitsDecl})` : modelEmitsDecl;
35458
+ }
35459
+ return emitsDecl2;
35460
+ }
35314
35461
  const scriptAst = script && parse(
35315
35462
  script.content,
35316
35463
  {
@@ -35456,10 +35603,22 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
35456
35603
  }
35457
35604
  }
35458
35605
  if (node.declaration) {
35459
- walkDeclaration(node.declaration, scriptBindings, vueImportAliases);
35606
+ walkDeclaration(
35607
+ "script",
35608
+ node.declaration,
35609
+ scriptBindings,
35610
+ vueImportAliases,
35611
+ hoistStatic
35612
+ );
35460
35613
  }
35461
35614
  } else if ((node.type === "VariableDeclaration" || node.type === "FunctionDeclaration" || node.type === "ClassDeclaration" || node.type === "TSEnumDeclaration") && !node.declare) {
35462
- walkDeclaration(node, scriptBindings, vueImportAliases);
35615
+ walkDeclaration(
35616
+ "script",
35617
+ node,
35618
+ scriptBindings,
35619
+ vueImportAliases,
35620
+ hoistStatic
35621
+ );
35463
35622
  }
35464
35623
  }
35465
35624
  if (enableReactivityTransform && shouldTransform(script.content)) {
@@ -35499,6 +35658,8 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
35499
35658
  callee.end + startOffset,
35500
35659
  "__expose"
35501
35660
  );
35661
+ } else {
35662
+ processDefineModel(expr);
35502
35663
  }
35503
35664
  }
35504
35665
  if (node.type === "VariableDeclaration" && !node.declare) {
@@ -35517,7 +35678,7 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
35517
35678
  }
35518
35679
  const isDefineProps = processDefineProps(init, decl.id) || processWithDefaults(init, decl.id);
35519
35680
  const isDefineEmits = !isDefineProps && processDefineEmits(init, decl.id);
35520
- !isDefineEmits && processDefineSlots(init, decl.id);
35681
+ !isDefineEmits && (processDefineSlots(init, decl.id) || processDefineModel(init, decl.id));
35521
35682
  if (isDefineProps || isDefineEmits) {
35522
35683
  if (left === 1) {
35523
35684
  s.remove(node.start + startOffset, node.end + startOffset);
@@ -35540,7 +35701,13 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
35540
35701
  }
35541
35702
  let isAllLiteral = false;
35542
35703
  if ((node.type === "VariableDeclaration" || node.type === "FunctionDeclaration" || node.type === "ClassDeclaration" || node.type === "TSEnumDeclaration") && !node.declare) {
35543
- isAllLiteral = walkDeclaration(node, setupBindings, vueImportAliases);
35704
+ isAllLiteral = walkDeclaration(
35705
+ "scriptSetup",
35706
+ node,
35707
+ setupBindings,
35708
+ vueImportAliases,
35709
+ hoistStatic
35710
+ );
35544
35711
  }
35545
35712
  if (hoistStatic && isAllLiteral) {
35546
35713
  hoistNode(node);
@@ -35648,6 +35815,9 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
35648
35815
  for (const key in typeDeclaredProps) {
35649
35816
  bindingMetadata[key] = "props";
35650
35817
  }
35818
+ for (const key in modelDecls) {
35819
+ bindingMetadata[key] = "props";
35820
+ }
35651
35821
  if (propsDestructureDecl) {
35652
35822
  if (propsDestructureRestId) {
35653
35823
  bindingMetadata[propsDestructureRestId] = "setup-reactive-const";
@@ -35826,36 +35996,14 @@ return ${returned}
35826
35996
  runtimeOptions += `
35827
35997
  __ssrInlineRender: true,`;
35828
35998
  }
35829
- if (propsRuntimeDecl) {
35830
- let declCode = scriptSetup.content.slice(propsRuntimeDecl.start, propsRuntimeDecl.end).trim();
35831
- if (propsDestructureDecl) {
35832
- const defaults = [];
35833
- for (const key in propsDestructuredBindings) {
35834
- const d = genDestructuredDefaultValue(key);
35835
- if (d)
35836
- defaults.push(
35837
- `${key}: ${d.valueString}${d.needSkipFactory ? `, __skip_${key}: true` : ``}`
35838
- );
35839
- }
35840
- if (defaults.length) {
35841
- declCode = `${helper(
35842
- `mergeDefaults`
35843
- )}(${declCode}, {
35844
- ${defaults.join(",\n ")}
35845
- })`;
35846
- }
35847
- }
35999
+ const propsDecl = genRuntimeProps();
36000
+ if (propsDecl)
35848
36001
  runtimeOptions += `
35849
- props: ${declCode},`;
35850
- } else if (propsTypeDecl) {
35851
- runtimeOptions += genRuntimeProps(typeDeclaredProps);
35852
- }
35853
- if (emitsRuntimeDecl) {
36002
+ props: ${propsDecl},`;
36003
+ const emitsDecl = genRuntimeEmits();
36004
+ if (emitsDecl)
35854
36005
  runtimeOptions += `
35855
- emits: ${scriptSetup.content.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end).trim()},`;
35856
- } else if (emitsTypeDecl) {
35857
- runtimeOptions += genRuntimeEmits(typeDeclaredEmits);
35858
- }
36006
+ emits: ${emitsDecl},`;
35859
36007
  let definedOptions = "";
35860
36008
  if (optionsRuntimeDecl) {
35861
36009
  definedOptions = scriptSetup.content.slice(optionsRuntimeDecl.start, optionsRuntimeDecl.end).trim();
@@ -35920,7 +36068,7 @@ ${exposeCall}`
35920
36068
  function registerBinding(bindings, node, type) {
35921
36069
  bindings[node.name] = type;
35922
36070
  }
35923
- function walkDeclaration(node, bindings, userImportAliases) {
36071
+ function walkDeclaration(from, node, bindings, userImportAliases, hoistStatic) {
35924
36072
  let isAllLiteral = false;
35925
36073
  if (node.type === "VariableDeclaration") {
35926
36074
  const isConst = node.kind === "const";
@@ -35936,7 +36084,7 @@ function walkDeclaration(node, bindings, userImportAliases) {
35936
36084
  if (id.type === "Identifier") {
35937
36085
  let bindingType;
35938
36086
  const userReactiveBinding = userImportAliases["reactive"];
35939
- if (isAllLiteral || isConst && isStaticNode(init)) {
36087
+ if ((hoistStatic || from === "script") && (isAllLiteral || isConst && isStaticNode(init))) {
35940
36088
  bindingType = "literal-const";
35941
36089
  } else if (isCallOf(init, userReactiveBinding)) {
35942
36090
  bindingType = isConst ? "setup-reactive-const" : "setup-let";
@@ -35947,7 +36095,7 @@ function walkDeclaration(node, bindings, userImportAliases) {
35947
36095
  ) {
35948
36096
  bindingType = isCallOf(init, DEFINE_PROPS) ? "setup-reactive-const" : "setup-const";
35949
36097
  } else if (isConst) {
35950
- if (isCallOf(init, userImportAliases["ref"])) {
36098
+ if (isCallOf(init, userImportAliases["ref"]) || isCallOf(init, DEFINE_MODEL)) {
35951
36099
  bindingType = "setup-ref";
35952
36100
  } else {
35953
36101
  bindingType = "setup-maybe-ref";
@@ -36231,11 +36379,15 @@ function extractRuntimeEmits(node, emits, error) {
36231
36379
  hasCallSignature = true;
36232
36380
  }
36233
36381
  if (t.type === "TSPropertySignature") {
36234
- if (t.key.type !== "Identifier" || t.computed) {
36382
+ if (t.key.type === "Identifier" && !t.computed) {
36383
+ emits.add(t.key.name);
36384
+ hasProperty = true;
36385
+ } else if (t.key.type === "StringLiteral" && !t.computed) {
36386
+ emits.add(t.key.value);
36387
+ hasProperty = true;
36388
+ } else {
36235
36389
  error(`defineEmits() type cannot use computed keys.`, t.key);
36236
36390
  }
36237
- emits.add(t.key.name);
36238
- hasProperty = true;
36239
36391
  }
36240
36392
  }
36241
36393
  if (hasCallSignature && hasProperty) {
@@ -36265,10 +36417,6 @@ function extractEventNames(eventName, emits) {
36265
36417
  }
36266
36418
  }
36267
36419
  }
36268
- function genRuntimeEmits(emits) {
36269
- return emits.size ? `
36270
- emits: [${Array.from(emits).map((p) => JSON.stringify(p)).join(", ")}],` : ``;
36271
- }
36272
36420
  function canNeverBeRef(node, userReactiveImport) {
36273
36421
  if (isCallOf(node, userReactiveImport)) {
36274
36422
  return true;
@@ -49228,7 +49376,7 @@ function preprocess(options, preprocessor) {
49228
49376
  );
49229
49377
  }
49230
49378
 
49231
- const version = "3.3.0-alpha.7";
49379
+ const version = "3.3.0-alpha.9";
49232
49380
  const walk = walk$1;
49233
49381
 
49234
49382
  export { MagicString, parse_1$1 as babelParse, compileScript, compileStyle, compileStyleAsync, compileTemplate, extractIdentifiers, generateCodeFrame, isInDestructureAssignment, isStaticProperty, parse$5 as parse, rewriteDefault, rewriteDefaultAST, shouldTransform as shouldTransformRef, transform as transformRef, transformAST as transformRefAST, version, walk, walkIdentifiers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "3.3.0-alpha.7",
3
+ "version": "3.3.0-alpha.9",
4
4
  "description": "@vue/compiler-sfc",
5
5
  "main": "dist/compiler-sfc.cjs.js",
6
6
  "module": "dist/compiler-sfc.esm-browser.js",
@@ -33,11 +33,11 @@
33
33
  "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme",
34
34
  "dependencies": {
35
35
  "@babel/parser": "^7.20.15",
36
- "@vue/compiler-core": "3.3.0-alpha.7",
37
- "@vue/compiler-dom": "3.3.0-alpha.7",
38
- "@vue/compiler-ssr": "3.3.0-alpha.7",
39
- "@vue/reactivity-transform": "3.3.0-alpha.7",
40
- "@vue/shared": "3.3.0-alpha.7",
36
+ "@vue/compiler-core": "3.3.0-alpha.9",
37
+ "@vue/compiler-dom": "3.3.0-alpha.9",
38
+ "@vue/compiler-ssr": "3.3.0-alpha.9",
39
+ "@vue/reactivity-transform": "3.3.0-alpha.9",
40
+ "@vue/shared": "3.3.0-alpha.9",
41
41
  "estree-walker": "^2.0.2",
42
42
  "magic-string": "^0.30.0",
43
43
  "postcss": "^8.1.10",