@vue/compiler-sfc 3.1.0 → 3.1.4

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.
@@ -421,15 +421,9 @@ const defaultAssetUrlOptions = {
421
421
  const normalizeOptions = (options) => {
422
422
  if (Object.keys(options).some(key => shared.isArray(options[key]))) {
423
423
  // legacy option format which directly passes in tags config
424
- return {
425
- ...defaultAssetUrlOptions,
426
- tags: options
427
- };
424
+ return Object.assign(Object.assign({}, defaultAssetUrlOptions), { tags: options });
428
425
  }
429
- return {
430
- ...defaultAssetUrlOptions,
431
- ...options
432
- };
426
+ return Object.assign(Object.assign({}, defaultAssetUrlOptions), options);
433
427
  };
434
428
  const createAssetUrlTransformWithOptions = (options) => {
435
429
  return (node, context) => transformAssetUrl(node, context, options);
@@ -637,7 +631,7 @@ function preprocess({ source, filename, preprocessOptions }, preprocessor) {
637
631
  // have to be sync because they are applied via Node.js require hooks)
638
632
  let res = '';
639
633
  let err = null;
640
- preprocessor.render(source, { filename, ...preprocessOptions }, (_err, _res) => {
634
+ preprocessor.render(source, Object.assign({ filename }, preprocessOptions), (_err, _res) => {
641
635
  if (_err)
642
636
  err = _err;
643
637
  res = _res;
@@ -655,10 +649,7 @@ function compileTemplate(options) {
655
649
  : false;
656
650
  if (preprocessor) {
657
651
  try {
658
- return doCompileTemplate({
659
- ...options,
660
- source: preprocess(options, preprocessor)
661
- });
652
+ return doCompileTemplate(Object.assign(Object.assign({}, options), { source: preprocess(options, preprocessor) }));
662
653
  }
663
654
  catch (e) {
664
655
  return {
@@ -709,23 +700,9 @@ function doCompileTemplate({ filename, id, scoped, slotted, inMap, source, ssr =
709
700
  }
710
701
  const shortId = id.replace(/^data-v-/, '');
711
702
  const longId = `data-v-${shortId}`;
712
- let { code, ast, preamble, map } = compiler.compile(source, {
713
- mode: 'module',
714
- prefixIdentifiers: true,
715
- hoistStatic: true,
716
- cacheHandlers: true,
717
- ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
703
+ let { code, ast, preamble, map } = compiler.compile(source, Object.assign(Object.assign({ mode: 'module', prefixIdentifiers: true, hoistStatic: true, cacheHandlers: true, ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
718
704
  ? genCssVarsFromList(ssrCssVars, shortId, isProd)
719
- : '',
720
- scopeId: scoped ? longId : undefined,
721
- slotted,
722
- ...compilerOptions,
723
- nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
724
- filename,
725
- sourceMap: true,
726
- onError: e => errors.push(e),
727
- onWarn: w => warnings.push(w)
728
- });
705
+ : '', scopeId: scoped ? longId : undefined, slotted }, compilerOptions), { nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []), filename, sourceMap: true, onError: e => errors.push(e), onWarn: w => warnings.push(w) }));
729
706
  // inMap should be the map produced by ./parse.ts which is a simple line-only
730
707
  // mapping. If it is present, we need to adjust the final map and errors to
731
708
  // reflect the original line numbers.
@@ -1002,13 +979,7 @@ scopedPlugin.postcss = true;
1002
979
  // .scss/.sass processor
1003
980
  const scss = (source, map, options, load = require) => {
1004
981
  const nodeSass = load('sass');
1005
- const finalOptions = {
1006
- ...options,
1007
- data: getSource(source, options.filename, options.additionalData),
1008
- file: options.filename,
1009
- outFile: options.filename,
1010
- sourceMap: !!map
1011
- };
982
+ const finalOptions = Object.assign(Object.assign({}, options), { data: getSource(source, options.filename, options.additionalData), file: options.filename, outFile: options.filename, sourceMap: !!map });
1012
983
  try {
1013
984
  const result = nodeSass.renderSync(finalOptions);
1014
985
  const dependencies = result.stats.includedFiles;
@@ -1026,16 +997,13 @@ const scss = (source, map, options, load = require) => {
1026
997
  return { code: '', errors: [e], dependencies: [] };
1027
998
  }
1028
999
  };
1029
- const sass = (source, map, options, load) => scss(source, map, {
1030
- ...options,
1031
- indentedSyntax: true
1032
- }, load);
1000
+ const sass = (source, map, options, load) => scss(source, map, Object.assign(Object.assign({}, options), { indentedSyntax: true }), load);
1033
1001
  // .less
1034
1002
  const less = (source, map, options, load = require) => {
1035
1003
  const nodeLess = load('less');
1036
1004
  let result;
1037
1005
  let error = null;
1038
- nodeLess.render(getSource(source, options.filename, options.additionalData), { ...options, syncImport: true }, (err, output) => {
1006
+ nodeLess.render(getSource(source, options.filename, options.additionalData), Object.assign(Object.assign({}, options), { syncImport: true }), (err, output) => {
1039
1007
  error = err;
1040
1008
  result = output;
1041
1009
  });
@@ -1097,13 +1065,10 @@ const processors = {
1097
1065
  };
1098
1066
 
1099
1067
  function compileStyle(options) {
1100
- return doCompileStyle({
1101
- ...options,
1102
- isAsync: false
1103
- });
1068
+ return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: false }));
1104
1069
  }
1105
1070
  function compileStyleAsync(options) {
1106
- return doCompileStyle({ ...options, isAsync: true });
1071
+ return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: true }));
1107
1072
  }
1108
1073
  function doCompileStyle(options) {
1109
1074
  const { filename, id, scoped = false, trim = true, isProd = false, modules = false, modulesOptions = {}, preprocessLang, postcssOptions, postcssPlugins } = options;
@@ -1128,18 +1093,11 @@ function doCompileStyle(options) {
1128
1093
  if (!options.isAsync) {
1129
1094
  throw new Error('[@vue/compiler-sfc] `modules` option can only be used with compileStyleAsync().');
1130
1095
  }
1131
- plugins.push(require('postcss-modules')({
1132
- ...modulesOptions,
1133
- getJSON: (_cssFileName, json) => {
1096
+ plugins.push(require('postcss-modules')(Object.assign(Object.assign({}, modulesOptions), { getJSON: (_cssFileName, json) => {
1134
1097
  cssModules = json;
1135
- }
1136
- }));
1098
+ } })));
1137
1099
  }
1138
- const postCSSOptions = {
1139
- ...postcssOptions,
1140
- to: filename,
1141
- from: filename
1142
- };
1100
+ const postCSSOptions = Object.assign(Object.assign({}, postcssOptions), { to: filename, from: filename });
1143
1101
  if (map) {
1144
1102
  postCSSOptions.map = {
1145
1103
  inline: false,
@@ -1205,14 +1163,11 @@ function doCompileStyle(options) {
1205
1163
  };
1206
1164
  }
1207
1165
  function preprocess$1(options, preprocessor) {
1208
- return preprocessor(options.source, options.inMap || options.map, {
1209
- filename: options.filename,
1210
- ...options.preprocessOptions
1211
- }, options.preprocessCustomRequire);
1166
+ return preprocessor(options.source, options.inMap || options.map, Object.assign({ filename: options.filename }, options.preprocessOptions), options.preprocessCustomRequire);
1212
1167
  }
1213
1168
 
1214
1169
  const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
1215
- const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/;
1170
+ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/s;
1216
1171
  const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
1217
1172
  /**
1218
1173
  * Utility for rewriting `export default` in a script block into a variable
@@ -1266,15 +1221,32 @@ function hasDefaultExport(input) {
1266
1221
 
1267
1222
  const DEFINE_PROPS = 'defineProps';
1268
1223
  const DEFINE_EMIT = 'defineEmit';
1224
+ const DEFINE_EXPOSE = 'defineExpose';
1225
+ const WITH_DEFAULTS = 'withDefaults';
1226
+ // deprecated
1227
+ const DEFINE_EMITS = 'defineEmits';
1269
1228
  /**
1270
1229
  * Compile `<script setup>`
1271
1230
  * It requires the whole SFC descriptor because we need to handle and merge
1272
1231
  * normal `<script>` + `<script setup>` if both are present.
1273
1232
  */
1274
1233
  function compileScript(sfc, options) {
1275
- const { script, scriptSetup, source, filename } = sfc;
1234
+ let { script, scriptSetup, source, filename } = sfc;
1235
+ // feature flags
1236
+ const enableRefSugar = !!options.refSugar;
1237
+ const parseOnly = !!options.parseOnly;
1276
1238
  if (scriptSetup) {
1277
- warnExperimental(`<script setup>`, 227);
1239
+ !parseOnly && warnExperimental(`<script setup>`, 227);
1240
+ }
1241
+ else if (parseOnly) {
1242
+ // in parse-only mode, construct a fake script setup so we still perform
1243
+ // the full parse logic.
1244
+ scriptSetup = {
1245
+ type: 'script',
1246
+ content: '',
1247
+ attrs: {},
1248
+ loc: compilerCore.locStub
1249
+ };
1278
1250
  }
1279
1251
  // for backwards compat
1280
1252
  if (!options) {
@@ -1285,9 +1257,14 @@ function compileScript(sfc, options) {
1285
1257
  `Upgrade your vite or vue-loader version for compatibility with ` +
1286
1258
  `the latest experimental proposals.`);
1287
1259
  }
1260
+ // TODO remove on 3.2
1261
+ if (sfc.template && sfc.template.attrs['inherit-attrs'] === 'false') {
1262
+ warnOnce(`experimetnal support for <template inherit-attrs="false"> support has ` +
1263
+ `been removed. Use a <script> block with \`export default\` to ` +
1264
+ `declare options.`);
1265
+ }
1288
1266
  const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '';
1289
1267
  const cssVars = sfc.cssVars;
1290
- const hasInheritAttrsFlag = sfc.template && sfc.template.attrs['inherit-attrs'] === 'false';
1291
1268
  const scriptLang = script && script.lang;
1292
1269
  const scriptSetupLang = scriptSetup && scriptSetup.lang;
1293
1270
  const isTS = scriptLang === 'ts' ||
@@ -1310,27 +1287,21 @@ function compileScript(sfc, options) {
1310
1287
  try {
1311
1288
  const scriptAst = parser.parse(script.content, {
1312
1289
  plugins,
1313
- sourceType: 'module'
1290
+ sourceType: 'module',
1291
+ errorRecovery: parseOnly
1314
1292
  }).program.body;
1315
1293
  const bindings = analyzeScriptBindings(scriptAst);
1316
- const needRewrite = cssVars.length || hasInheritAttrsFlag;
1317
1294
  let content = script.content;
1318
- if (needRewrite) {
1295
+ if (cssVars.length) {
1319
1296
  content = rewriteDefault(content, `__default__`, plugins);
1320
1297
  if (cssVars.length) {
1321
1298
  content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
1322
1299
  }
1323
- if (hasInheritAttrsFlag) {
1324
- content += `__default__.inheritAttrs = false`;
1325
- }
1326
1300
  content += `\nexport default __default__`;
1327
1301
  }
1328
- return {
1329
- ...script,
1330
- content,
1302
+ return Object.assign(Object.assign({}, script), { content,
1331
1303
  bindings,
1332
- scriptAst
1333
- };
1304
+ scriptAst });
1334
1305
  }
1335
1306
  catch (e) {
1336
1307
  // silently fallback if parse fails since user may be using custom
@@ -1339,29 +1310,40 @@ function compileScript(sfc, options) {
1339
1310
  }
1340
1311
  }
1341
1312
  if (script && scriptLang !== scriptSetupLang) {
1342
- throw new Error(`[@vue/compiler-sfc] <script> and <script setup> must have the same language type.`);
1313
+ throw new Error(`[@vue/compiler-sfc] <script> and <script setup> must have the same ` +
1314
+ `language type.`);
1343
1315
  }
1344
1316
  if (scriptSetupLang && !isTS && scriptSetupLang !== 'jsx') {
1345
1317
  // do not process non js/ts script blocks
1346
1318
  return scriptSetup;
1347
1319
  }
1348
- const defaultTempVar = `__default__`;
1320
+ // metadata that needs to be returned
1349
1321
  const bindingMetadata = {};
1322
+ const ranges = parseOnly
1323
+ ? {
1324
+ scriptBindings: [],
1325
+ scriptSetupBindings: []
1326
+ }
1327
+ : undefined;
1328
+ const defaultTempVar = `__default__`;
1350
1329
  const helperImports = new Set();
1351
1330
  const userImports = Object.create(null);
1352
1331
  const userImportAlias = Object.create(null);
1353
1332
  const setupBindings = Object.create(null);
1354
1333
  const refBindings = Object.create(null);
1355
1334
  const refIdentifiers = new Set();
1356
- const enableRefSugar = options.refSugar !== false;
1357
1335
  let defaultExport;
1358
1336
  let hasDefinePropsCall = false;
1359
1337
  let hasDefineEmitCall = false;
1338
+ let hasDefineExposeCall = false;
1360
1339
  let propsRuntimeDecl;
1340
+ let propsRuntimeDefaults;
1361
1341
  let propsTypeDecl;
1342
+ let propsTypeDeclRaw;
1362
1343
  let propsIdentifier;
1363
- let emitRuntimeDecl;
1364
- let emitTypeDecl;
1344
+ let emitsRuntimeDecl;
1345
+ let emitsTypeDecl;
1346
+ let emitsTypeDeclRaw;
1365
1347
  let emitIdentifier;
1366
1348
  let hasAwait = false;
1367
1349
  let hasInlinedSsrRenderFn = false;
@@ -1382,6 +1364,7 @@ function compileScript(sfc, options) {
1382
1364
  }
1383
1365
  function parse(input, options, offset) {
1384
1366
  try {
1367
+ options.errorRecovery = parseOnly;
1385
1368
  return parser.parse(input, options).program.body;
1386
1369
  }
1387
1370
  catch (e) {
@@ -1392,63 +1375,116 @@ function compileScript(sfc, options) {
1392
1375
  function error(msg, node, end = node.end + startOffset) {
1393
1376
  throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, node.start + startOffset, end)}`);
1394
1377
  }
1395
- function registerUserImport(source, local, imported, isType) {
1378
+ function registerUserImport(source, local, imported, isType, isFromSetup, rangeNode) {
1396
1379
  if (source === 'vue' && imported) {
1397
1380
  userImportAlias[imported] = local;
1398
1381
  }
1399
1382
  userImports[local] = {
1400
1383
  isType,
1401
1384
  imported: imported || 'default',
1402
- source
1385
+ source,
1386
+ rangeNode,
1387
+ isFromSetup
1403
1388
  };
1404
1389
  }
1405
1390
  function processDefineProps(node) {
1406
- if (isCallOf(node, DEFINE_PROPS)) {
1407
- if (hasDefinePropsCall) {
1408
- error(`duplicate ${DEFINE_PROPS}() call`, node);
1409
- }
1410
- hasDefinePropsCall = true;
1411
- propsRuntimeDecl = node.arguments[0];
1412
- // context call has type parameters - infer runtime types from it
1413
- if (node.typeParameters) {
1414
- if (propsRuntimeDecl) {
1415
- error(`${DEFINE_PROPS}() cannot accept both type and non-type arguments ` +
1416
- `at the same time. Use one or the other.`, node);
1417
- }
1418
- const typeArg = node.typeParameters.params[0];
1419
- if (typeArg.type === 'TSTypeLiteral') {
1420
- propsTypeDecl = typeArg;
1421
- }
1422
- else {
1423
- error(`type argument passed to ${DEFINE_PROPS}() must be a literal type.`, typeArg);
1424
- }
1391
+ if (!isCallOf(node, DEFINE_PROPS)) {
1392
+ return false;
1393
+ }
1394
+ if (hasDefinePropsCall) {
1395
+ error(`duplicate ${DEFINE_PROPS}() call`, node);
1396
+ }
1397
+ hasDefinePropsCall = true;
1398
+ propsRuntimeDecl = node.arguments[0];
1399
+ // call has type parameters - infer runtime types from it
1400
+ if (node.typeParameters) {
1401
+ if (propsRuntimeDecl) {
1402
+ error(`${DEFINE_PROPS}() cannot accept both type and non-type arguments ` +
1403
+ `at the same time. Use one or the other.`, node);
1404
+ }
1405
+ propsTypeDeclRaw = node.typeParameters.params[0];
1406
+ propsTypeDecl = resolveQualifiedType(propsTypeDeclRaw, node => node.type === 'TSTypeLiteral');
1407
+ if (!propsTypeDecl) {
1408
+ error(`type argument passed to ${DEFINE_PROPS}() must be a literal type, ` +
1409
+ `or a reference to an interface or literal type.`, propsTypeDeclRaw);
1425
1410
  }
1426
- return true;
1427
1411
  }
1428
- return false;
1412
+ return true;
1413
+ }
1414
+ function processWithDefaults(node) {
1415
+ if (!isCallOf(node, WITH_DEFAULTS)) {
1416
+ return false;
1417
+ }
1418
+ if (processDefineProps(node.arguments[0])) {
1419
+ if (propsRuntimeDecl) {
1420
+ error(`${WITH_DEFAULTS} can only be used with type-based ` +
1421
+ `${DEFINE_PROPS} declaration.`, node);
1422
+ }
1423
+ propsRuntimeDefaults = node.arguments[1];
1424
+ }
1425
+ else {
1426
+ error(`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`, node.arguments[0] || node);
1427
+ }
1428
+ return true;
1429
1429
  }
1430
- function processDefineEmit(node) {
1431
- if (isCallOf(node, DEFINE_EMIT)) {
1432
- if (hasDefineEmitCall) {
1433
- error(`duplicate ${DEFINE_EMIT}() call`, node);
1434
- }
1435
- hasDefineEmitCall = true;
1436
- emitRuntimeDecl = node.arguments[0];
1437
- if (node.typeParameters) {
1438
- if (emitRuntimeDecl) {
1439
- error(`${DEFINE_EMIT}() cannot accept both type and non-type arguments ` +
1440
- `at the same time. Use one or the other.`, node);
1430
+ function processDefineEmits(node) {
1431
+ if (!isCallOf(node, c => c === DEFINE_EMIT || c === DEFINE_EMITS)) {
1432
+ return false;
1433
+ }
1434
+ if (hasDefineEmitCall) {
1435
+ error(`duplicate ${DEFINE_EMITS}() call`, node);
1436
+ }
1437
+ hasDefineEmitCall = true;
1438
+ emitsRuntimeDecl = node.arguments[0];
1439
+ if (node.typeParameters) {
1440
+ if (emitsRuntimeDecl) {
1441
+ error(`${DEFINE_EMIT}() cannot accept both type and non-type arguments ` +
1442
+ `at the same time. Use one or the other.`, node);
1443
+ }
1444
+ emitsTypeDeclRaw = node.typeParameters.params[0];
1445
+ emitsTypeDecl = resolveQualifiedType(emitsTypeDeclRaw, node => node.type === 'TSFunctionType' || node.type === 'TSTypeLiteral');
1446
+ if (!emitsTypeDecl) {
1447
+ error(`type argument passed to ${DEFINE_EMITS}() must be a function type, ` +
1448
+ `a literal type with call signatures, or a reference to the above types.`, emitsTypeDeclRaw);
1449
+ }
1450
+ }
1451
+ return true;
1452
+ }
1453
+ function resolveQualifiedType(node, qualifier) {
1454
+ if (qualifier(node)) {
1455
+ return node;
1456
+ }
1457
+ if (node.type === 'TSTypeReference' &&
1458
+ node.typeName.type === 'Identifier') {
1459
+ const refName = node.typeName.name;
1460
+ const isQualifiedType = (node) => {
1461
+ if (node.type === 'TSInterfaceDeclaration' &&
1462
+ node.id.name === refName) {
1463
+ return node.body;
1441
1464
  }
1442
- const typeArg = node.typeParameters.params[0];
1443
- if (typeArg.type === 'TSFunctionType' ||
1444
- typeArg.type === 'TSTypeLiteral') {
1445
- emitTypeDecl = typeArg;
1465
+ else if (node.type === 'TSTypeAliasDeclaration' &&
1466
+ node.id.name === refName &&
1467
+ qualifier(node.typeAnnotation)) {
1468
+ return node.typeAnnotation;
1446
1469
  }
1447
- else {
1448
- error(`type argument passed to ${DEFINE_EMIT}() must be a function type ` +
1449
- `or a literal type with call signatures.`, typeArg);
1470
+ else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
1471
+ return isQualifiedType(node.declaration);
1472
+ }
1473
+ };
1474
+ for (const node of scriptSetupAst) {
1475
+ const qualified = isQualifiedType(node);
1476
+ if (qualified) {
1477
+ return qualified;
1450
1478
  }
1451
1479
  }
1480
+ }
1481
+ }
1482
+ function processDefineExpose(node) {
1483
+ if (isCallOf(node, DEFINE_EXPOSE)) {
1484
+ if (hasDefineExposeCall) {
1485
+ error(`duplicate ${DEFINE_EXPOSE}() call`, node);
1486
+ }
1487
+ hasDefineExposeCall = true;
1452
1488
  return true;
1453
1489
  }
1454
1490
  return false;
@@ -1513,7 +1549,10 @@ function compileScript(sfc, options) {
1513
1549
  if (id.name[0] === '$') {
1514
1550
  error(`ref variable identifiers cannot start with $.`, id);
1515
1551
  }
1516
- refBindings[id.name] = setupBindings[id.name] = "setup-ref" /* SETUP_REF */;
1552
+ refBindings[id.name] = setupBindings[id.name] = {
1553
+ type: "setup-ref" /* SETUP_REF */,
1554
+ rangeNode: id
1555
+ };
1517
1556
  refIdentifiers.add(id);
1518
1557
  }
1519
1558
  function processRefObjectPattern(pattern, statement) {
@@ -1592,6 +1631,39 @@ function compileScript(sfc, options) {
1592
1631
  }
1593
1632
  }
1594
1633
  }
1634
+ function genRuntimeProps(props) {
1635
+ const keys = Object.keys(props);
1636
+ if (!keys.length) {
1637
+ return ``;
1638
+ }
1639
+ // check defaults. If the default object is an object literal with only
1640
+ // static properties, we can directly generate more optimzied default
1641
+ // decalrations. Otherwise we will have to fallback to runtime merging.
1642
+ const hasStaticDefaults = propsRuntimeDefaults &&
1643
+ propsRuntimeDefaults.type === 'ObjectExpression' &&
1644
+ propsRuntimeDefaults.properties.every(node => node.type === 'ObjectProperty' && !node.computed);
1645
+ let propsDecls = `{
1646
+ ${keys
1647
+ .map(key => {
1648
+ let defaultString;
1649
+ if (hasStaticDefaults) {
1650
+ const prop = propsRuntimeDefaults.properties.find((node) => node.key.name === key);
1651
+ if (prop) {
1652
+ // prop has corresponding static default value
1653
+ defaultString = `default: ${source.slice(prop.value.start + startOffset, prop.value.end + startOffset)}`;
1654
+ }
1655
+ }
1656
+ {
1657
+ const { type, required } = props[key];
1658
+ return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required}${defaultString ? `, ${defaultString}` : ``} }`;
1659
+ }
1660
+ })
1661
+ .join(',\n ')}\n }`;
1662
+ if (propsRuntimeDefaults && !hasStaticDefaults) {
1663
+ propsDecls = `${helper('mergeDefaults')}(${propsDecls}, ${source.slice(propsRuntimeDefaults.start + startOffset, propsRuntimeDefaults.end + startOffset)})`;
1664
+ }
1665
+ return `\n props: ${propsDecls} as unknown as undefined,`;
1666
+ }
1595
1667
  // 1. process normal <script> first if it exists
1596
1668
  let scriptAst;
1597
1669
  if (script) {
@@ -1607,7 +1679,7 @@ function compileScript(sfc, options) {
1607
1679
  const imported = specifier.type === 'ImportSpecifier' &&
1608
1680
  specifier.imported.type === 'Identifier' &&
1609
1681
  specifier.imported.name;
1610
- registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type');
1682
+ registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false, specifier.local);
1611
1683
  }
1612
1684
  }
1613
1685
  else if (node.type === 'ExportDefaultDeclaration') {
@@ -1654,7 +1726,6 @@ function compileScript(sfc, options) {
1654
1726
  for (const node of scriptSetupAst) {
1655
1727
  const start = node.start + startOffset;
1656
1728
  let end = node.end + startOffset;
1657
- // import or type declarations: move to top
1658
1729
  // locate comment
1659
1730
  if (node.trailingComments && node.trailingComments.length > 0) {
1660
1731
  const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
@@ -1672,14 +1743,15 @@ function compileScript(sfc, options) {
1672
1743
  node.label.name === 'ref' &&
1673
1744
  node.body.type === 'ExpressionStatement') {
1674
1745
  if (enableRefSugar) {
1675
- warnExperimental(`ref: sugar`, 228);
1746
+ !parseOnly && warnExperimental(`ref: sugar`, 228);
1676
1747
  s.overwrite(node.label.start + startOffset, node.body.start + startOffset, 'const ');
1677
1748
  processRefExpression(node.body.expression, node);
1678
1749
  }
1679
1750
  else {
1680
- // TODO if we end up shipping ref: sugar as an opt-in feature,
1681
- // need to proxy the option in vite, vue-loader and rollup-plugin-vue.
1682
- error(`ref: sugar needs to be explicitly enabled via vite or vue-loader options.`, node);
1751
+ error(`ref: sugar now needs to be explicitly enabled via @vitejs/plugin-vue ` +
1752
+ `or vue-loader options:\n` +
1753
+ `- @vitejs/plugin-vue: via \`script.refSugar\`\n` +
1754
+ `- vue-loader: via \`refSugar\` (requires 16.3.0+)`, node);
1683
1755
  }
1684
1756
  }
1685
1757
  if (node.type === 'ImportDeclaration') {
@@ -1707,7 +1779,11 @@ function compileScript(sfc, options) {
1707
1779
  const source = node.source.value;
1708
1780
  const existing = userImports[local];
1709
1781
  if (source === 'vue' &&
1710
- (imported === DEFINE_PROPS || imported === DEFINE_EMIT)) {
1782
+ (imported === DEFINE_PROPS ||
1783
+ imported === DEFINE_EMIT ||
1784
+ imported === DEFINE_EMITS ||
1785
+ imported === DEFINE_EXPOSE)) {
1786
+ warnOnce(`\`${imported}\` is a compiler macro and no longer needs to be imported.`);
1711
1787
  removeSpecifier(i);
1712
1788
  }
1713
1789
  else if (existing) {
@@ -1720,36 +1796,57 @@ function compileScript(sfc, options) {
1720
1796
  }
1721
1797
  }
1722
1798
  else {
1723
- registerUserImport(source, local, imported, node.importKind === 'type');
1799
+ registerUserImport(source, local, imported, node.importKind === 'type', true, specifier.local);
1724
1800
  }
1725
1801
  }
1726
1802
  if (node.specifiers.length && removed === node.specifiers.length) {
1727
1803
  s.remove(node.start + startOffset, node.end + startOffset);
1728
1804
  }
1729
1805
  }
1730
- // process `defineProps` and `defineEmit` calls
1731
- if (node.type === 'ExpressionStatement' &&
1732
- (processDefineProps(node.expression) ||
1733
- processDefineEmit(node.expression))) {
1734
- s.remove(node.start + startOffset, node.end + startOffset);
1806
+ if (node.type === 'ExpressionStatement') {
1807
+ // process `defineProps` and `defineEmit(s)` calls
1808
+ if (processDefineProps(node.expression) ||
1809
+ processDefineEmits(node.expression) ||
1810
+ processWithDefaults(node.expression)) {
1811
+ s.remove(node.start + startOffset, node.end + startOffset);
1812
+ }
1813
+ else if (processDefineExpose(node.expression)) {
1814
+ // defineExpose({}) -> expose({})
1815
+ const callee = node.expression.callee;
1816
+ s.overwrite(callee.start + startOffset, callee.end + startOffset, 'expose');
1817
+ }
1735
1818
  }
1736
1819
  if (node.type === 'VariableDeclaration' && !node.declare) {
1737
- for (const decl of node.declarations) {
1820
+ const total = node.declarations.length;
1821
+ let left = total;
1822
+ for (let i = 0; i < total; i++) {
1823
+ const decl = node.declarations[i];
1738
1824
  if (decl.init) {
1739
- const isDefineProps = processDefineProps(decl.init);
1825
+ const isDefineProps = processDefineProps(decl.init) || processWithDefaults(decl.init);
1740
1826
  if (isDefineProps) {
1741
1827
  propsIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
1742
1828
  }
1743
- const isDefineEmit = processDefineEmit(decl.init);
1744
- if (isDefineEmit) {
1829
+ const isDefineEmits = processDefineEmits(decl.init);
1830
+ if (isDefineEmits) {
1745
1831
  emitIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
1746
1832
  }
1747
- if (isDefineProps || isDefineEmit)
1748
- if (node.declarations.length === 1) {
1833
+ if (isDefineProps || isDefineEmits)
1834
+ if (left === 1) {
1749
1835
  s.remove(node.start + startOffset, node.end + startOffset);
1750
1836
  }
1751
1837
  else {
1752
- s.remove(decl.start + startOffset, decl.end + startOffset);
1838
+ let start = decl.start + startOffset;
1839
+ let end = decl.end + startOffset;
1840
+ if (i < total - 1) {
1841
+ // not the last one, locate the start of the next
1842
+ end = node.declarations[i + 1].start + startOffset;
1843
+ }
1844
+ else {
1845
+ // last one, locate the end of the prev
1846
+ start = node.declarations[i - 1].end + startOffset;
1847
+ }
1848
+ s.remove(start, end);
1849
+ left--;
1753
1850
  }
1754
1851
  }
1755
1852
  }
@@ -1761,16 +1858,6 @@ function compileScript(sfc, options) {
1761
1858
  !node.declare) {
1762
1859
  walkDeclaration(node, setupBindings, userImportAlias);
1763
1860
  }
1764
- // Type declarations
1765
- if (node.type === 'VariableDeclaration' && node.declare) {
1766
- s.remove(start, end);
1767
- }
1768
- // move all type declarations to outer scope
1769
- if (node.type.startsWith('TS') ||
1770
- (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type')) {
1771
- recordType(node, declaredTypes);
1772
- s.move(start, end, 0);
1773
- }
1774
1861
  // walk statements & named exports / variable declarations for top level
1775
1862
  // await
1776
1863
  if ((node.type === 'VariableDeclaration' && !node.declare) ||
@@ -1782,6 +1869,8 @@ function compileScript(sfc, options) {
1782
1869
  }
1783
1870
  if (node.type === 'AwaitExpression') {
1784
1871
  hasAwait = true;
1872
+ s.prependRight(node.argument.start + startOffset, helper(`withAsyncContext`) + `(`);
1873
+ s.appendLeft(node.argument.end + startOffset, `)`);
1785
1874
  }
1786
1875
  }
1787
1876
  });
@@ -1793,6 +1882,52 @@ function compileScript(sfc, options) {
1793
1882
  `If you are using a previous version of <script setup>, please ` +
1794
1883
  `consult the updated RFC at https://github.com/vuejs/rfcs/pull/227.`, node);
1795
1884
  }
1885
+ if (isTS) {
1886
+ // runtime enum
1887
+ if (node.type === 'TSEnumDeclaration' && !node.const) {
1888
+ registerBinding(setupBindings, node.id, "setup-const" /* SETUP_CONST */);
1889
+ }
1890
+ // move all Type declarations to outer scope
1891
+ if (node.type.startsWith('TS') ||
1892
+ (node.type === 'ExportNamedDeclaration' &&
1893
+ node.exportKind === 'type') ||
1894
+ (node.type === 'VariableDeclaration' && node.declare)) {
1895
+ recordType(node, declaredTypes);
1896
+ s.move(start, end, 0);
1897
+ }
1898
+ }
1899
+ }
1900
+ // in parse only mode, we should have collected all the information we need,
1901
+ // return early.
1902
+ if (parseOnly) {
1903
+ for (const key in userImports) {
1904
+ const { rangeNode, isFromSetup } = userImports[key];
1905
+ const bindings = isFromSetup
1906
+ ? ranges.scriptSetupBindings
1907
+ : ranges.scriptBindings;
1908
+ bindings.push(toTextRange(rangeNode));
1909
+ }
1910
+ for (const key in setupBindings) {
1911
+ ranges.scriptSetupBindings.push(toTextRange(setupBindings[key].rangeNode));
1912
+ }
1913
+ if (propsRuntimeDecl) {
1914
+ ranges.propsRuntimeArg = toTextRange(propsRuntimeDecl);
1915
+ }
1916
+ if (propsTypeDeclRaw) {
1917
+ ranges.propsTypeArg = toTextRange(propsTypeDeclRaw);
1918
+ }
1919
+ if (emitsRuntimeDecl) {
1920
+ ranges.emitsRuntimeArg = toTextRange(emitsRuntimeDecl);
1921
+ }
1922
+ if (emitsTypeDeclRaw) {
1923
+ ranges.emitsTypeArg = toTextRange(emitsTypeDeclRaw);
1924
+ }
1925
+ if (propsRuntimeDefaults) {
1926
+ ranges.withDefaultsArg = toTextRange(propsRuntimeDefaults);
1927
+ }
1928
+ return Object.assign(Object.assign({}, scriptSetup), { ranges,
1929
+ scriptAst,
1930
+ scriptSetupAst });
1796
1931
  }
1797
1932
  // 3. Do a full walk to rewrite identifiers referencing let exports with ref
1798
1933
  // value access
@@ -1826,13 +1961,14 @@ function compileScript(sfc, options) {
1826
1961
  if (propsTypeDecl) {
1827
1962
  extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes);
1828
1963
  }
1829
- if (emitTypeDecl) {
1830
- extractRuntimeEmits(emitTypeDecl, typeDeclaredEmits);
1964
+ if (emitsTypeDecl) {
1965
+ extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits);
1831
1966
  }
1832
1967
  // 5. check useOptions args to make sure it doesn't reference setup scope
1833
1968
  // variables
1834
1969
  checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
1835
- checkInvalidScopeReference(emitRuntimeDecl, DEFINE_PROPS);
1970
+ checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
1971
+ checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
1836
1972
  // 6. remove non-script content
1837
1973
  if (script) {
1838
1974
  if (startOffset < scriptStartOffset) {
@@ -1874,7 +2010,7 @@ function compileScript(sfc, options) {
1874
2010
  : "setup-maybe-ref" /* SETUP_MAYBE_REF */;
1875
2011
  }
1876
2012
  for (const key in setupBindings) {
1877
- bindingMetadata[key] = setupBindings[key];
2013
+ bindingMetadata[key] = setupBindings[key].type;
1878
2014
  }
1879
2015
  // 8. inject `useCssVars` calls
1880
2016
  if (cssVars.length) {
@@ -1893,15 +2029,14 @@ function compileScript(sfc, options) {
1893
2029
  if (propsIdentifier) {
1894
2030
  s.prependRight(startOffset, `\nconst ${propsIdentifier} = __props`);
1895
2031
  }
2032
+ const destructureElements = hasDefineExposeCall || !options.inlineTemplate ? [`expose`] : [];
1896
2033
  if (emitIdentifier) {
1897
- args +=
1898
- emitIdentifier === `emit` ? `, { emit }` : `, { emit: ${emitIdentifier} }`;
1899
- if (emitTypeDecl) {
1900
- args += `: {
1901
- emit: (${scriptSetup.content.slice(emitTypeDecl.start, emitTypeDecl.end)}),
1902
- slots: any,
1903
- attrs: any
1904
- }`;
2034
+ destructureElements.push(emitIdentifier === `emit` ? `emit` : `emit: ${emitIdentifier}`);
2035
+ }
2036
+ if (destructureElements.length) {
2037
+ args += `, { ${destructureElements.join(', ')} }`;
2038
+ if (emitsTypeDecl) {
2039
+ args += `: { emit: (${scriptSetup.content.slice(emitsTypeDecl.start, emitsTypeDecl.end)}), expose: any, slots: any, attrs: any }`;
1905
2040
  }
1906
2041
  }
1907
2042
  // 10. generate return statement
@@ -1913,23 +2048,9 @@ function compileScript(sfc, options) {
1913
2048
  }
1914
2049
  // inline render function mode - we are going to compile the template and
1915
2050
  // inline it right here
1916
- const { code, ast, preamble, tips, errors } = compileTemplate({
1917
- filename,
1918
- source: sfc.template.content,
1919
- inMap: sfc.template.map,
1920
- ...options.templateOptions,
1921
- id: scopeId,
1922
- scoped: sfc.styles.some(s => s.scoped),
1923
- isProd: options.isProd,
1924
- ssrCssVars: sfc.cssVars,
1925
- compilerOptions: {
1926
- ...(options.templateOptions &&
1927
- options.templateOptions.compilerOptions),
1928
- inline: true,
1929
- isTS,
1930
- bindingMetadata
1931
- }
1932
- });
2051
+ const { code, ast, preamble, tips, errors } = compileTemplate(Object.assign(Object.assign({ filename, source: sfc.template.content, inMap: sfc.template.map }, options.templateOptions), { id: scopeId, scoped: sfc.styles.some(s => s.scoped), isProd: options.isProd, ssrCssVars: sfc.cssVars, compilerOptions: Object.assign(Object.assign({}, (options.templateOptions &&
2052
+ options.templateOptions.compilerOptions)), { inline: true, isTS,
2053
+ bindingMetadata }) }));
1933
2054
  if (tips.length) {
1934
2055
  tips.forEach(warnOnce);
1935
2056
  }
@@ -1965,7 +2086,7 @@ function compileScript(sfc, options) {
1965
2086
  }
1966
2087
  else {
1967
2088
  // return bindings from setup
1968
- const allBindings = { ...setupBindings };
2089
+ const allBindings = Object.assign({}, setupBindings);
1969
2090
  for (const key in userImports) {
1970
2091
  if (!userImports[key].isType) {
1971
2092
  allBindings[key] = true;
@@ -1973,13 +2094,19 @@ function compileScript(sfc, options) {
1973
2094
  }
1974
2095
  returned = `{ ${Object.keys(allBindings).join(', ')} }`;
1975
2096
  }
1976
- s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`);
1977
- // 11. finalize default export
1978
- // expose: [] makes <script setup> components "closed" by default.
1979
- let runtimeOptions = `\n expose: [],`;
1980
- if (hasInheritAttrsFlag) {
1981
- runtimeOptions += `\n inheritAttrs: false,`;
2097
+ if (!options.inlineTemplate && !false) {
2098
+ // in non-inline mode, the `__isScriptSetup: true` flag is used by
2099
+ // componentPublicInstance proxy to allow properties that start with $ or _
2100
+ s.appendRight(endOffset, `\nconst __returned__ = ${returned}\n` +
2101
+ `Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true })\n` +
2102
+ `return __returned__` +
2103
+ `\n}\n\n`);
1982
2104
  }
2105
+ else {
2106
+ s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`);
2107
+ }
2108
+ // 11. finalize default export
2109
+ let runtimeOptions = ``;
1983
2110
  if (hasInlinedSsrRenderFn) {
1984
2111
  runtimeOptions += `\n __ssrInlineRender: true,`;
1985
2112
  }
@@ -1991,14 +2118,17 @@ function compileScript(sfc, options) {
1991
2118
  else if (propsTypeDecl) {
1992
2119
  runtimeOptions += genRuntimeProps(typeDeclaredProps);
1993
2120
  }
1994
- if (emitRuntimeDecl) {
2121
+ if (emitsRuntimeDecl) {
1995
2122
  runtimeOptions += `\n emits: ${scriptSetup.content
1996
- .slice(emitRuntimeDecl.start, emitRuntimeDecl.end)
2123
+ .slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end)
1997
2124
  .trim()},`;
1998
2125
  }
1999
- else if (emitTypeDecl) {
2126
+ else if (emitsTypeDecl) {
2000
2127
  runtimeOptions += genRuntimeEmits(typeDeclaredEmits);
2001
2128
  }
2129
+ // <script setup> components are closed by default. If the user did not
2130
+ // explicitly call `defineExpose`, call expose() with no args.
2131
+ const exposeCall = hasDefineExposeCall || options.inlineTemplate ? `` : ` expose()\n`;
2002
2132
  if (isTS) {
2003
2133
  // for TS, make sure the exported type is still valid type with
2004
2134
  // correct props information
@@ -2008,7 +2138,7 @@ function compileScript(sfc, options) {
2008
2138
  // wrap setup code with function.
2009
2139
  // export the content of <script setup> as a named export, `setup`.
2010
2140
  // this allows `import { setup } from '*.vue'` for testing purposes.
2011
- s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n`);
2141
+ s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
2012
2142
  s.appendRight(endOffset, `})`);
2013
2143
  }
2014
2144
  else {
@@ -2019,7 +2149,7 @@ function compileScript(sfc, options) {
2019
2149
  }
2020
2150
  else {
2021
2151
  s.prependLeft(startOffset, `\nexport default {${runtimeOptions}\n ` +
2022
- `${hasAwait ? `async ` : ``}setup(${args}) {\n`);
2152
+ `${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
2023
2153
  s.appendRight(endOffset, `}`);
2024
2154
  }
2025
2155
  }
@@ -2030,17 +2160,17 @@ function compileScript(sfc, options) {
2030
2160
  .join(', ')} } from 'vue'\n`);
2031
2161
  }
2032
2162
  s.trim();
2033
- return {
2034
- ...scriptSetup,
2035
- bindings: bindingMetadata,
2036
- content: s.toString(),
2037
- map: s.generateMap({
2163
+ return Object.assign(Object.assign({}, scriptSetup), { bindings: bindingMetadata, content: s.toString(), map: s.generateMap({
2038
2164
  source: filename,
2039
2165
  hires: true,
2040
2166
  includeContent: true
2041
- }),
2042
- scriptAst,
2043
- scriptSetupAst
2167
+ }), scriptAst,
2168
+ scriptSetupAst });
2169
+ }
2170
+ function registerBinding(bindings, node, type) {
2171
+ bindings[node.name] = {
2172
+ type,
2173
+ rangeNode: node
2044
2174
  };
2045
2175
  }
2046
2176
  function walkDeclaration(node, bindings, userImportAlias) {
@@ -2049,7 +2179,10 @@ function walkDeclaration(node, bindings, userImportAlias) {
2049
2179
  // export const foo = ...
2050
2180
  for (const { id, init } of node.declarations) {
2051
2181
  const isDefineCall = !!(isConst &&
2052
- (isCallOf(init, DEFINE_PROPS) || isCallOf(init, DEFINE_EMIT)));
2182
+ isCallOf(init, c => c === DEFINE_PROPS ||
2183
+ c === DEFINE_EMIT ||
2184
+ c === DEFINE_EMITS ||
2185
+ c === WITH_DEFAULTS));
2053
2186
  if (id.type === 'Identifier') {
2054
2187
  let bindingType;
2055
2188
  const userReactiveBinding = userImportAlias['reactive'] || 'reactive';
@@ -2075,7 +2208,7 @@ function walkDeclaration(node, bindings, userImportAlias) {
2075
2208
  else {
2076
2209
  bindingType = "setup-let" /* SETUP_LET */;
2077
2210
  }
2078
- bindings[id.name] = bindingType;
2211
+ registerBinding(bindings, id, bindingType);
2079
2212
  }
2080
2213
  else if (id.type === 'ObjectPattern') {
2081
2214
  walkObjectPattern(id, bindings, isConst, isDefineCall);
@@ -2089,7 +2222,10 @@ function walkDeclaration(node, bindings, userImportAlias) {
2089
2222
  node.type === 'ClassDeclaration') {
2090
2223
  // export function foo() {} / export class Foo {}
2091
2224
  // export declarations must be named.
2092
- bindings[node.id.name] = "setup-const" /* SETUP_CONST */;
2225
+ bindings[node.id.name] = {
2226
+ type: "setup-const" /* SETUP_CONST */,
2227
+ rangeNode: node.id
2228
+ };
2093
2229
  }
2094
2230
  }
2095
2231
  function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
@@ -2099,11 +2235,12 @@ function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
2099
2235
  if (p.key.type === 'Identifier') {
2100
2236
  if (p.key === p.value) {
2101
2237
  // const { x } = ...
2102
- bindings[p.key.name] = isDefineCall
2238
+ const type = isDefineCall
2103
2239
  ? "setup-const" /* SETUP_CONST */
2104
2240
  : isConst
2105
2241
  ? "setup-maybe-ref" /* SETUP_MAYBE_REF */
2106
2242
  : "setup-let" /* SETUP_LET */;
2243
+ registerBinding(bindings, p.key, type);
2107
2244
  }
2108
2245
  else {
2109
2246
  walkPattern(p.value, bindings, isConst, isDefineCall);
@@ -2113,9 +2250,8 @@ function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
2113
2250
  else {
2114
2251
  // ...rest
2115
2252
  // argument can only be identifer when destructuring
2116
- bindings[p.argument.name] = isConst
2117
- ? "setup-const" /* SETUP_CONST */
2118
- : "setup-let" /* SETUP_LET */;
2253
+ const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
2254
+ registerBinding(bindings, p.argument, type);
2119
2255
  }
2120
2256
  }
2121
2257
  }
@@ -2126,17 +2262,17 @@ function walkArrayPattern(node, bindings, isConst, isDefineCall = false) {
2126
2262
  }
2127
2263
  function walkPattern(node, bindings, isConst, isDefineCall = false) {
2128
2264
  if (node.type === 'Identifier') {
2129
- bindings[node.name] = isDefineCall
2265
+ const type = isDefineCall
2130
2266
  ? "setup-const" /* SETUP_CONST */
2131
2267
  : isConst
2132
2268
  ? "setup-maybe-ref" /* SETUP_MAYBE_REF */
2133
2269
  : "setup-let" /* SETUP_LET */;
2270
+ registerBinding(bindings, node, type);
2134
2271
  }
2135
2272
  else if (node.type === 'RestElement') {
2136
2273
  // argument can only be identifer when destructuring
2137
- bindings[node.argument.name] = isConst
2138
- ? "setup-const" /* SETUP_CONST */
2139
- : "setup-let" /* SETUP_LET */;
2274
+ const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
2275
+ registerBinding(bindings, node.argument, type);
2140
2276
  }
2141
2277
  else if (node.type === 'ObjectPattern') {
2142
2278
  walkObjectPattern(node, bindings, isConst);
@@ -2146,11 +2282,12 @@ function walkPattern(node, bindings, isConst, isDefineCall = false) {
2146
2282
  }
2147
2283
  else if (node.type === 'AssignmentPattern') {
2148
2284
  if (node.left.type === 'Identifier') {
2149
- bindings[node.left.name] = isDefineCall
2285
+ const type = isDefineCall
2150
2286
  ? "setup-const" /* SETUP_CONST */
2151
2287
  : isConst
2152
2288
  ? "setup-maybe-ref" /* SETUP_MAYBE_REF */
2153
2289
  : "setup-let" /* SETUP_LET */;
2290
+ registerBinding(bindings, node.left, type);
2154
2291
  }
2155
2292
  else {
2156
2293
  walkPattern(node.left, bindings, isConst);
@@ -2169,14 +2306,23 @@ function recordType(node, declaredTypes) {
2169
2306
  }
2170
2307
  }
2171
2308
  function extractRuntimeProps(node, props, declaredTypes) {
2172
- for (const m of node.members) {
2173
- if (m.type === 'TSPropertySignature' && m.key.type === 'Identifier') {
2309
+ const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
2310
+ for (const m of members) {
2311
+ if ((m.type === 'TSPropertySignature' || m.type === 'TSMethodSignature') &&
2312
+ m.key.type === 'Identifier') {
2313
+ let type;
2314
+ {
2315
+ if (m.type === 'TSMethodSignature') {
2316
+ type = ['Function'];
2317
+ }
2318
+ else if (m.typeAnnotation) {
2319
+ type = inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes);
2320
+ }
2321
+ }
2174
2322
  props[m.key.name] = {
2175
2323
  key: m.key.name,
2176
2324
  required: !m.optional,
2177
- type: m.typeAnnotation
2178
- ? inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes)
2179
- : [`null`]
2325
+ type: type || [`null`]
2180
2326
  };
2181
2327
  }
2182
2328
  }
@@ -2249,18 +2395,6 @@ function inferRuntimeType(node, declaredTypes) {
2249
2395
  return [`null`]; // no runtime check
2250
2396
  }
2251
2397
  }
2252
- function genRuntimeProps(props) {
2253
- const keys = Object.keys(props);
2254
- if (!keys.length) {
2255
- return ``;
2256
- }
2257
- return `\n props: {\n ${keys
2258
- .map(key => {
2259
- const { type, required } = props[key];
2260
- return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required} }`;
2261
- })
2262
- .join(',\n ')}\n } as unknown as undefined,`;
2263
- }
2264
2398
  function toRuntimeTypeString(types) {
2265
2399
  return types.some(t => t === 'null')
2266
2400
  ? `null`
@@ -2269,8 +2403,9 @@ function toRuntimeTypeString(types) {
2269
2403
  : types[0];
2270
2404
  }
2271
2405
  function extractRuntimeEmits(node, emits) {
2272
- if (node.type === 'TSTypeLiteral') {
2273
- for (let t of node.members) {
2406
+ if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
2407
+ const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
2408
+ for (let t of members) {
2274
2409
  if (t.type === 'TSCallSignatureDeclaration') {
2275
2410
  extractEventNames(t.parameters[0], emits);
2276
2411
  }
@@ -2386,6 +2521,9 @@ function walkIdentifiers(root, onIdentifier) {
2386
2521
  });
2387
2522
  }
2388
2523
  function isRefIdentifier(id, parent, parentStack) {
2524
+ if (!parent) {
2525
+ return true;
2526
+ }
2389
2527
  // declaration id
2390
2528
  if ((parent.type === 'VariableDeclarator' ||
2391
2529
  parent.type === 'ClassDeclaration') &&
@@ -2432,11 +2570,13 @@ const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent
2432
2570
  function isFunction(node) {
2433
2571
  return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
2434
2572
  }
2435
- function isCallOf(node, name) {
2573
+ function isCallOf(node, test) {
2436
2574
  return !!(node &&
2437
2575
  node.type === 'CallExpression' &&
2438
2576
  node.callee.type === 'Identifier' &&
2439
- node.callee.name === name);
2577
+ (typeof test === 'string'
2578
+ ? node.callee.name === test
2579
+ : test(node.callee.name)));
2440
2580
  }
2441
2581
  function canNeverBeRef(node, userReactiveImport) {
2442
2582
  if (isCallOf(node, userReactiveImport)) {
@@ -2627,6 +2767,12 @@ function extractIdentifiers(param, nodes = []) {
2627
2767
  break;
2628
2768
  }
2629
2769
  return nodes;
2770
+ }
2771
+ function toTextRange(node) {
2772
+ return {
2773
+ start: node.start,
2774
+ end: node.end
2775
+ };
2630
2776
  }
2631
2777
 
2632
2778
  exports.generateCodeFrame = compilerCore.generateCodeFrame;