@vue/compiler-sfc 3.2.2 → 3.2.6

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.
@@ -16,6 +16,7 @@ var merge = require('merge-source-map');
16
16
  var MagicString = require('magic-string');
17
17
  var parser = require('@babel/parser');
18
18
  var estreeWalker = require('estree-walker');
19
+ var refTransform = require('@vue/ref-transform');
19
20
 
20
21
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e['default'] : e; }
21
22
 
@@ -639,16 +640,6 @@ function warnOnce(msg) {
639
640
  }
640
641
  function warn(msg) {
641
642
  console.warn(`\x1b[1m\x1b[33m[@vue/compiler-sfc]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
642
- }
643
- function warnExperimental(feature, url) {
644
- // eslint-disable-next-line
645
- if (typeof window !== 'undefined') {
646
- return;
647
- }
648
- warnOnce(`${feature} is still an experimental proposal.\n` +
649
- `Follow its status at ${url}.`);
650
- warnOnce(`When using experimental features,\n` +
651
- `it is recommended to pin your vue dependencies to exact versions to avoid breakage.`);
652
643
  }
653
644
 
654
645
  function preprocess({ source, filename, preprocessOptions }, preprocessor) {
@@ -1251,11 +1242,6 @@ const DEFINE_PROPS = 'defineProps';
1251
1242
  const DEFINE_EMITS = 'defineEmits';
1252
1243
  const DEFINE_EXPOSE = 'defineExpose';
1253
1244
  const WITH_DEFAULTS = 'withDefaults';
1254
- const $REF = `$ref`;
1255
- const $SHALLOW_REF = '$shallowRef';
1256
- const $COMPUTED = `$computed`;
1257
- const $FROM_REFS = `$fromRefs`;
1258
- const $RAW = `$raw`;
1259
1245
  const isBuiltInDir = shared.makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
1260
1246
  /**
1261
1247
  * Compile `<script setup>`
@@ -1265,18 +1251,8 @@ const isBuiltInDir = shared.makeMap(`once,memo,if,else,else-if,slot,text,html,on
1265
1251
  function compileScript(sfc, options) {
1266
1252
  let { script, scriptSetup, source, filename } = sfc;
1267
1253
  // feature flags
1268
- const enableRefSugar = !!options.refSugar;
1269
- const parseOnly = !!options.parseOnly;
1270
- if (parseOnly && !scriptSetup) {
1271
- // in parse-only mode, construct a fake script setup so we still perform
1272
- // the full parse logic.
1273
- scriptSetup = {
1274
- type: 'script',
1275
- content: '',
1276
- attrs: {},
1277
- loc: CompilerDOM.locStub
1278
- };
1279
- }
1254
+ const enableRefTransform = !!options.refSugar || !!options.refTransform;
1255
+ let refBindings;
1280
1256
  // for backwards compat
1281
1257
  if (!options) {
1282
1258
  options = { id: '' };
@@ -1311,23 +1287,40 @@ function compileScript(sfc, options) {
1311
1287
  return script;
1312
1288
  }
1313
1289
  try {
1314
- const scriptAst = parser.parse(script.content, {
1315
- plugins,
1316
- sourceType: 'module',
1317
- errorRecovery: parseOnly
1318
- }).program.body;
1319
- const bindings = analyzeScriptBindings(scriptAst);
1320
1290
  let content = script.content;
1291
+ let map = script.map;
1292
+ const scriptAst = parser.parse(content, {
1293
+ plugins,
1294
+ sourceType: 'module'
1295
+ }).program;
1296
+ const bindings = analyzeScriptBindings(scriptAst.body);
1297
+ if (enableRefTransform && refTransform.shouldTransform(content)) {
1298
+ const s = new MagicString__default(source);
1299
+ const startOffset = script.loc.start.offset;
1300
+ const endOffset = script.loc.end.offset;
1301
+ const { importedHelpers } = refTransform.transformAST(scriptAst, s, startOffset);
1302
+ if (importedHelpers.length) {
1303
+ s.prepend(`import { ${importedHelpers
1304
+ .map(h => `${h} as _${h}`)
1305
+ .join(', ')} } from 'vue'\n`);
1306
+ }
1307
+ s.remove(0, startOffset);
1308
+ s.remove(endOffset, source.length);
1309
+ content = s.toString();
1310
+ map = s.generateMap({
1311
+ source: filename,
1312
+ hires: true,
1313
+ includeContent: true
1314
+ });
1315
+ }
1321
1316
  if (cssVars.length) {
1322
1317
  content = rewriteDefault(content, `__default__`, plugins);
1323
- if (cssVars.length) {
1324
- content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
1325
- }
1318
+ content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
1326
1319
  content += `\nexport default __default__`;
1327
1320
  }
1328
1321
  return Object.assign(Object.assign({}, script), { content,
1329
- bindings,
1330
- scriptAst });
1322
+ map,
1323
+ bindings, scriptAst: scriptAst.body });
1331
1324
  }
1332
1325
  catch (e) {
1333
1326
  // silently fallback if parse fails since user may be using custom
@@ -1345,19 +1338,11 @@ function compileScript(sfc, options) {
1345
1338
  }
1346
1339
  // metadata that needs to be returned
1347
1340
  const bindingMetadata = {};
1348
- const ranges = parseOnly
1349
- ? {
1350
- scriptBindings: [],
1351
- scriptSetupBindings: []
1352
- }
1353
- : undefined;
1354
1341
  const defaultTempVar = `__default__`;
1355
1342
  const helperImports = new Set();
1356
1343
  const userImports = Object.create(null);
1357
1344
  const userImportAlias = Object.create(null);
1358
1345
  const setupBindings = Object.create(null);
1359
- const refBindings = Object.create(null);
1360
- const refIdentifiers = new Set();
1361
1346
  let defaultExport;
1362
1347
  let hasDefinePropsCall = false;
1363
1348
  let hasDefineEmitCall = false;
@@ -1390,8 +1375,7 @@ function compileScript(sfc, options) {
1390
1375
  }
1391
1376
  function parse(input, options, offset) {
1392
1377
  try {
1393
- options.errorRecovery = parseOnly;
1394
- return parser.parse(input, options).program.body;
1378
+ return parser.parse(input, options).program;
1395
1379
  }
1396
1380
  catch (e) {
1397
1381
  e.message = `[@vue/compiler-sfc] ${e.message}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, e.pos + offset, e.pos + offset + 1)}`;
@@ -1401,12 +1385,12 @@ function compileScript(sfc, options) {
1401
1385
  function error(msg, node, end = node.end + startOffset) {
1402
1386
  throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, node.start + startOffset, end)}`);
1403
1387
  }
1404
- function registerUserImport(source, local, imported, isType, isFromSetup, rangeNode) {
1388
+ function registerUserImport(source, local, imported, isType, isFromSetup) {
1405
1389
  if (source === 'vue' && imported) {
1406
1390
  userImportAlias[imported] = local;
1407
1391
  }
1408
1392
  let isUsedInTemplate = true;
1409
- if (isTS && sfc.template && !sfc.template.src) {
1393
+ if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
1410
1394
  isUsedInTemplate = new RegExp(
1411
1395
  // #4274 escape $ since it's a special char in regex
1412
1396
  // (and is the only regex special char that is valid in identifiers)
@@ -1416,7 +1400,6 @@ function compileScript(sfc, options) {
1416
1400
  isType,
1417
1401
  imported: imported || 'default',
1418
1402
  source,
1419
- rangeNode,
1420
1403
  isFromSetup,
1421
1404
  isUsedInTemplate
1422
1405
  };
@@ -1505,7 +1488,7 @@ function compileScript(sfc, options) {
1505
1488
  return isQualifiedType(node.declaration);
1506
1489
  }
1507
1490
  };
1508
- for (const node of scriptSetupAst) {
1491
+ for (const node of scriptSetupAst.body) {
1509
1492
  const qualified = isQualifiedType(node);
1510
1493
  if (qualified) {
1511
1494
  return qualified;
@@ -1526,7 +1509,7 @@ function compileScript(sfc, options) {
1526
1509
  function checkInvalidScopeReference(node, method) {
1527
1510
  if (!node)
1528
1511
  return;
1529
- walkIdentifiers(node, id => {
1512
+ CompilerDOM.walkIdentifiers(node, id => {
1530
1513
  if (setupBindings[id.name]) {
1531
1514
  error(`\`${method}()\` in <script setup> cannot reference locally ` +
1532
1515
  `declared variables because it will be hoisted outside of the ` +
@@ -1545,145 +1528,6 @@ function compileScript(sfc, options) {
1545
1528
  s.overwrite(node.start + startOffset, node.argument.start + startOffset, `${isStatement ? `;` : ``}(([__temp,__restore]=${helper(`withAsyncContext`)}(()=>(`);
1546
1529
  s.appendLeft(node.end + startOffset, `))),__temp=await __temp,__restore()${isStatement ? `` : `,__temp`})`);
1547
1530
  }
1548
- function isRefSugarCall(callee) {
1549
- return (callee === $REF ||
1550
- callee === $COMPUTED ||
1551
- callee === $FROM_REFS ||
1552
- callee === $SHALLOW_REF);
1553
- }
1554
- function processRefSugar(decl, statement) {
1555
- if (!isCallOf(decl.init, isRefSugarCall)) {
1556
- return;
1557
- }
1558
- if (!enableRefSugar) {
1559
- error(`ref sugar is an experimental proposal and must be explicitly ` +
1560
- `enabled via @vue/compiler-sfc options.`,
1561
- // TODO link to RFC details
1562
- decl.init);
1563
- }
1564
- else {
1565
- warnExperimental(`ref sugar`, `https://github.com/vuejs/rfcs/discussions/369`);
1566
- }
1567
- const callee = decl.init.callee.name;
1568
- const start = decl.init.start + startOffset;
1569
- if (callee === $REF || callee === $SHALLOW_REF) {
1570
- if (statement.kind !== 'let') {
1571
- error(`${callee}() bindings can only be declared with let.`, decl);
1572
- }
1573
- if (decl.id.type !== 'Identifier') {
1574
- error(`${callee}() bindings cannot be used with destructuring. ` +
1575
- `If you are trying to destructure from an object of refs, ` +
1576
- `use \`let { x } = $fromRefs(obj)\`.`, decl.id);
1577
- }
1578
- registerRefBinding(decl.id);
1579
- s.overwrite(start, start + callee.length, helper(callee === $REF ? 'ref' : 'shallowRef'));
1580
- }
1581
- else if (callee === $COMPUTED) {
1582
- if (decl.id.type !== 'Identifier') {
1583
- error(`${callee}() bindings cannot be used with destructuring.`, decl.id);
1584
- }
1585
- registerRefBinding(decl.id);
1586
- s.overwrite(start, start + $COMPUTED.length, helper('computed'));
1587
- }
1588
- else if (callee === $FROM_REFS) {
1589
- if (!decl.id.type.endsWith('Pattern')) {
1590
- error(`${callee}() declaration must be used with destructure patterns.`, decl);
1591
- }
1592
- if (decl.id.type === 'ObjectPattern') {
1593
- processRefObjectPattern(decl.id, statement);
1594
- }
1595
- else if (decl.id.type === 'ArrayPattern') {
1596
- processRefArrayPattern(decl.id, statement);
1597
- }
1598
- s.remove(start, start + callee.length);
1599
- }
1600
- }
1601
- function registerRefBinding(id) {
1602
- if (id.name[0] === '$') {
1603
- error(`ref variable identifiers cannot start with $.`, id);
1604
- }
1605
- refBindings[id.name] = setupBindings[id.name] = {
1606
- type: "setup-ref" /* SETUP_REF */,
1607
- rangeNode: id
1608
- };
1609
- refIdentifiers.add(id);
1610
- }
1611
- function processRefObjectPattern(pattern, statement) {
1612
- for (const p of pattern.properties) {
1613
- let nameId;
1614
- if (p.type === 'ObjectProperty') {
1615
- if (p.key.start === p.value.start) {
1616
- // shorthand { foo } --> { foo: __foo }
1617
- nameId = p.key;
1618
- s.appendLeft(nameId.end + startOffset, `: __${nameId.name}`);
1619
- if (p.value.type === 'AssignmentPattern') {
1620
- // { foo = 1 }
1621
- refIdentifiers.add(p.value.left);
1622
- }
1623
- }
1624
- else {
1625
- if (p.value.type === 'Identifier') {
1626
- // { foo: bar } --> { foo: __bar }
1627
- nameId = p.value;
1628
- s.prependRight(nameId.start + startOffset, `__`);
1629
- }
1630
- else if (p.value.type === 'ObjectPattern') {
1631
- processRefObjectPattern(p.value, statement);
1632
- }
1633
- else if (p.value.type === 'ArrayPattern') {
1634
- processRefArrayPattern(p.value, statement);
1635
- }
1636
- else if (p.value.type === 'AssignmentPattern') {
1637
- // { foo: bar = 1 } --> { foo: __bar = 1 }
1638
- nameId = p.value.left;
1639
- s.prependRight(nameId.start + startOffset, `__`);
1640
- }
1641
- }
1642
- }
1643
- else {
1644
- // rest element { ...foo } --> { ...__foo }
1645
- nameId = p.argument;
1646
- s.prependRight(nameId.start + startOffset, `__`);
1647
- }
1648
- if (nameId) {
1649
- registerRefBinding(nameId);
1650
- // append binding declarations after the parent statement
1651
- s.appendLeft(statement.end + startOffset, `\nconst ${nameId.name} = ${helper('shallowRef')}(__${nameId.name});`);
1652
- }
1653
- }
1654
- }
1655
- function processRefArrayPattern(pattern, statement) {
1656
- for (const e of pattern.elements) {
1657
- if (!e)
1658
- continue;
1659
- let nameId;
1660
- if (e.type === 'Identifier') {
1661
- // [a] --> [__a]
1662
- nameId = e;
1663
- }
1664
- else if (e.type === 'AssignmentPattern') {
1665
- // [a = 1] --> [__a = 1]
1666
- nameId = e.left;
1667
- }
1668
- else if (e.type === 'RestElement') {
1669
- // [...a] --> [...__a]
1670
- nameId = e.argument;
1671
- }
1672
- else if (e.type === 'ObjectPattern') {
1673
- processRefObjectPattern(e, statement);
1674
- }
1675
- else if (e.type === 'ArrayPattern') {
1676
- processRefArrayPattern(e, statement);
1677
- }
1678
- if (nameId) {
1679
- registerRefBinding(nameId);
1680
- // prefix original
1681
- s.prependRight(nameId.start + startOffset, `__`);
1682
- // append binding declarations after the parent statement
1683
- s.appendLeft(statement.end + startOffset, `\nconst ${nameId.name} = ${helper('shallowRef')}(__${nameId.name});`);
1684
- }
1685
- }
1686
- }
1687
1531
  function genRuntimeProps(props) {
1688
1532
  const keys = Object.keys(props);
1689
1533
  if (!keys.length) {
@@ -1725,21 +1569,22 @@ function compileScript(sfc, options) {
1725
1569
  plugins,
1726
1570
  sourceType: 'module'
1727
1571
  }, scriptStartOffset);
1728
- for (const node of scriptAst) {
1572
+ for (const node of scriptAst.body) {
1729
1573
  if (node.type === 'ImportDeclaration') {
1730
1574
  // record imports for dedupe
1731
1575
  for (const specifier of node.specifiers) {
1732
1576
  const imported = specifier.type === 'ImportSpecifier' &&
1733
1577
  specifier.imported.type === 'Identifier' &&
1734
1578
  specifier.imported.name;
1735
- registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false, specifier.local);
1579
+ registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false);
1736
1580
  }
1737
1581
  }
1738
1582
  else if (node.type === 'ExportDefaultDeclaration') {
1739
1583
  // export default
1740
1584
  defaultExport = node;
1741
1585
  const start = node.start + scriptStartOffset;
1742
- s.overwrite(start, start + `export default`.length, `const ${defaultTempVar} =`);
1586
+ const end = node.declaration.start + scriptStartOffset;
1587
+ s.overwrite(start, end, `const ${defaultTempVar} = `);
1743
1588
  }
1744
1589
  else if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
1745
1590
  const defaultSpecifier = node.specifiers.find(s => s.exported.type === 'Identifier' && s.exported.name === 'default');
@@ -1765,6 +1610,20 @@ function compileScript(sfc, options) {
1765
1610
  }
1766
1611
  }
1767
1612
  }
1613
+ else if ((node.type === 'VariableDeclaration' ||
1614
+ node.type === 'FunctionDeclaration' ||
1615
+ node.type === 'ClassDeclaration') &&
1616
+ !node.declare) {
1617
+ walkDeclaration(node, setupBindings, userImportAlias);
1618
+ }
1619
+ }
1620
+ // apply ref transform
1621
+ if (enableRefTransform && refTransform.shouldTransform(script.content)) {
1622
+ const { rootVars, importedHelpers } = refTransform.transformAST(scriptAst, s, scriptStartOffset);
1623
+ refBindings = rootVars;
1624
+ for (const h of importedHelpers) {
1625
+ helperImports.add(h);
1626
+ }
1768
1627
  }
1769
1628
  }
1770
1629
  // 2. parse <script setup> and walk over top level statements
@@ -1776,7 +1635,7 @@ function compileScript(sfc, options) {
1776
1635
  ],
1777
1636
  sourceType: 'module'
1778
1637
  }, startOffset);
1779
- for (const node of scriptSetupAst) {
1638
+ for (const node of scriptSetupAst.body) {
1780
1639
  const start = node.start + startOffset;
1781
1640
  let end = node.end + startOffset;
1782
1641
  // locate comment
@@ -1796,9 +1655,8 @@ function compileScript(sfc, options) {
1796
1655
  node.label.name === 'ref' &&
1797
1656
  node.body.type === 'ExpressionStatement') {
1798
1657
  error(`ref sugar using the label syntax was an experimental proposal and ` +
1799
- `has been dropped based on community feedback.`,
1800
- // TODO + ` Please check out the adjusted proposal at ...`,
1801
- node);
1658
+ `has been dropped based on community feedback. Please check out ` +
1659
+ `the new proposal at https://github.com/vuejs/rfcs/discussions/369`, node);
1802
1660
  }
1803
1661
  if (node.type === 'ImportDeclaration') {
1804
1662
  // import declarations are moved to top
@@ -1841,7 +1699,7 @@ function compileScript(sfc, options) {
1841
1699
  }
1842
1700
  }
1843
1701
  else {
1844
- registerUserImport(source, local, imported, node.importKind === 'type', true, specifier.local);
1702
+ registerUserImport(source, local, imported, node.importKind === 'type', true);
1845
1703
  }
1846
1704
  }
1847
1705
  if (node.specifiers.length && removed === node.specifiers.length) {
@@ -1895,9 +1753,6 @@ function compileScript(sfc, options) {
1895
1753
  left--;
1896
1754
  }
1897
1755
  }
1898
- else {
1899
- processRefSugar(decl, node);
1900
- }
1901
1756
  }
1902
1757
  }
1903
1758
  }
@@ -1914,7 +1769,7 @@ function compileScript(sfc, options) {
1914
1769
  node.type.endsWith('Statement')) {
1915
1770
  estreeWalker.walk(node, {
1916
1771
  enter(child, parent) {
1917
- if (isFunction(child)) {
1772
+ if (CompilerDOM.isFunctionType(child)) {
1918
1773
  this.skip();
1919
1774
  }
1920
1775
  if (child.type === 'AwaitExpression') {
@@ -1946,74 +1801,12 @@ function compileScript(sfc, options) {
1946
1801
  }
1947
1802
  }
1948
1803
  }
1949
- // in parse only mode, we should have collected all the information we need,
1950
- // return early.
1951
- if (parseOnly) {
1952
- for (const key in userImports) {
1953
- const { rangeNode, isFromSetup } = userImports[key];
1954
- const bindings = isFromSetup
1955
- ? ranges.scriptSetupBindings
1956
- : ranges.scriptBindings;
1957
- bindings.push(toTextRange(rangeNode));
1958
- }
1959
- for (const key in setupBindings) {
1960
- ranges.scriptSetupBindings.push(toTextRange(setupBindings[key].rangeNode));
1961
- }
1962
- if (propsRuntimeDecl) {
1963
- ranges.propsRuntimeArg = toTextRange(propsRuntimeDecl);
1964
- }
1965
- if (propsTypeDeclRaw) {
1966
- ranges.propsTypeArg = toTextRange(propsTypeDeclRaw);
1967
- }
1968
- if (emitsRuntimeDecl) {
1969
- ranges.emitsRuntimeArg = toTextRange(emitsRuntimeDecl);
1970
- }
1971
- if (emitsTypeDeclRaw) {
1972
- ranges.emitsTypeArg = toTextRange(emitsTypeDeclRaw);
1973
- }
1974
- if (propsRuntimeDefaults) {
1975
- ranges.withDefaultsArg = toTextRange(propsRuntimeDefaults);
1976
- }
1977
- return Object.assign(Object.assign({}, scriptSetup), { ranges,
1978
- scriptAst,
1979
- scriptSetupAst });
1980
- }
1981
- // 3. Do a full walk to rewrite identifiers referencing let exports with ref
1982
- // value access
1983
- if (enableRefSugar) {
1984
- const onIdent = (id, parent, parentStack) => {
1985
- if (refBindings[id.name] && !refIdentifiers.has(id)) {
1986
- if (isStaticProperty(parent) && parent.shorthand) {
1987
- // let binding used in a property shorthand
1988
- // { foo } -> { foo: foo.value }
1989
- // skip for destructure patterns
1990
- if (!parent.inPattern ||
1991
- isInDestructureAssignment(parent, parentStack)) {
1992
- s.appendLeft(id.end + startOffset, `: ${id.name}.value`);
1993
- }
1994
- }
1995
- else {
1996
- s.appendLeft(id.end + startOffset, '.value');
1997
- }
1998
- }
1999
- };
2000
- const onNode = (node, parent) => {
2001
- if (isCallOf(node, $RAW)) {
2002
- s.remove(node.callee.start + startOffset, node.callee.end + startOffset);
2003
- return false; // skip walk
2004
- }
2005
- else if (parent &&
2006
- isCallOf(node, isRefSugarCall) &&
2007
- (parent.type !== 'VariableDeclarator' || node !== parent.init)) {
2008
- error(
2009
- // @ts-ignore
2010
- `${node.callee.name} can only be used directly as a variable initializer.`, node);
2011
- }
2012
- };
2013
- for (const node of scriptSetupAst) {
2014
- if (node.type !== 'ImportDeclaration') {
2015
- walkIdentifiers(node, onIdent, onNode);
2016
- }
1804
+ // 3. Apply ref sugar transform
1805
+ if (enableRefTransform && refTransform.shouldTransform(scriptSetup.content)) {
1806
+ const { rootVars, importedHelpers } = refTransform.transformAST(scriptSetupAst, s, startOffset, refBindings);
1807
+ refBindings = refBindings ? [...refBindings, ...rootVars] : rootVars;
1808
+ for (const h of importedHelpers) {
1809
+ helperImports.add(h);
2017
1810
  }
2018
1811
  }
2019
1812
  // 4. extract runtime props/emits code from setup context type
@@ -2050,7 +1843,7 @@ function compileScript(sfc, options) {
2050
1843
  }
2051
1844
  // 7. analyze binding metadata
2052
1845
  if (scriptAst) {
2053
- Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst));
1846
+ Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst.body));
2054
1847
  }
2055
1848
  if (propsRuntimeDecl) {
2056
1849
  for (const key of getObjectOrArrayExpressionKeys(propsRuntimeDecl)) {
@@ -2069,11 +1862,13 @@ function compileScript(sfc, options) {
2069
1862
  : "setup-maybe-ref" /* SETUP_MAYBE_REF */;
2070
1863
  }
2071
1864
  for (const key in setupBindings) {
2072
- bindingMetadata[key] = setupBindings[key].type;
1865
+ bindingMetadata[key] = setupBindings[key];
2073
1866
  }
2074
1867
  // known ref bindings
2075
- for (const key in refBindings) {
2076
- bindingMetadata[key] = "setup-ref" /* SETUP_REF */;
1868
+ if (refBindings) {
1869
+ for (const key of refBindings) {
1870
+ bindingMetadata[key] = "setup-ref" /* SETUP_REF */;
1871
+ }
2077
1872
  }
2078
1873
  // 8. inject `useCssVars` calls
2079
1874
  if (cssVars.length) {
@@ -2206,8 +2001,14 @@ function compileScript(sfc, options) {
2206
2001
  // wrap setup code with function.
2207
2002
  // export the content of <script setup> as a named export, `setup`.
2208
2003
  // this allows `import { setup } from '*.vue'` for testing purposes.
2209
- s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
2210
- s.appendRight(endOffset, `})`);
2004
+ if (defaultExport) {
2005
+ s.prependLeft(startOffset, `\n${hasAwait ? `async ` : ``}function setup(${args}) {\n`);
2006
+ s.append(`\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n setup})`);
2007
+ }
2008
+ else {
2009
+ s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
2010
+ s.appendRight(endOffset, `})`);
2011
+ }
2211
2012
  }
2212
2013
  else {
2213
2014
  if (defaultExport) {
@@ -2232,14 +2033,10 @@ function compileScript(sfc, options) {
2232
2033
  source: filename,
2233
2034
  hires: true,
2234
2035
  includeContent: true
2235
- }), scriptAst,
2236
- scriptSetupAst });
2036
+ }), scriptAst: scriptAst === null || scriptAst === void 0 ? void 0 : scriptAst.body, scriptSetupAst: scriptSetupAst === null || scriptSetupAst === void 0 ? void 0 : scriptSetupAst.body });
2237
2037
  }
2238
2038
  function registerBinding(bindings, node, type) {
2239
- bindings[node.name] = {
2240
- type,
2241
- rangeNode: node
2242
- };
2039
+ bindings[node.name] = type;
2243
2040
  }
2244
2041
  function walkDeclaration(node, bindings, userImportAlias) {
2245
2042
  if (node.type === 'VariableDeclaration') {
@@ -2287,10 +2084,7 @@ function walkDeclaration(node, bindings, userImportAlias) {
2287
2084
  node.type === 'ClassDeclaration') {
2288
2085
  // export function foo() {} / export class Foo {}
2289
2086
  // export declarations must be named.
2290
- bindings[node.id.name] = {
2291
- type: "setup-const" /* SETUP_CONST */,
2292
- rangeNode: node.id
2293
- };
2087
+ bindings[node.id.name] = "setup-const" /* SETUP_CONST */;
2294
2088
  }
2295
2089
  }
2296
2090
  function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
@@ -2454,7 +2248,7 @@ function inferRuntimeType(node, declaredTypes) {
2454
2248
  return inferRuntimeType(node.typeAnnotation, declaredTypes);
2455
2249
  case 'TSUnionType':
2456
2250
  return [
2457
- ...new Set([].concat(node.types.map(t => inferRuntimeType(t, declaredTypes))))
2251
+ ...new Set([].concat(...node.types.map(t => inferRuntimeType(t, declaredTypes))))
2458
2252
  ];
2459
2253
  case 'TSIntersectionType':
2460
2254
  return ['Object'];
@@ -2463,11 +2257,7 @@ function inferRuntimeType(node, declaredTypes) {
2463
2257
  }
2464
2258
  }
2465
2259
  function toRuntimeTypeString(types) {
2466
- return types.some(t => t === 'null')
2467
- ? `null`
2468
- : types.length > 1
2469
- ? `[${types.join(', ')}]`
2470
- : types[0];
2260
+ return types.length > 1 ? `[${types.join(', ')}]` : types[0];
2471
2261
  }
2472
2262
  function extractRuntimeEmits(node, emits) {
2473
2263
  if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
@@ -2489,11 +2279,14 @@ function extractEventNames(eventName, emits) {
2489
2279
  eventName.typeAnnotation.type === 'TSTypeAnnotation') {
2490
2280
  const typeNode = eventName.typeAnnotation.typeAnnotation;
2491
2281
  if (typeNode.type === 'TSLiteralType') {
2492
- emits.add(String(typeNode.literal.value));
2282
+ if (typeNode.literal.type !== 'UnaryExpression') {
2283
+ emits.add(String(typeNode.literal.value));
2284
+ }
2493
2285
  }
2494
2286
  else if (typeNode.type === 'TSUnionType') {
2495
2287
  for (const t of typeNode.types) {
2496
- if (t.type === 'TSLiteralType') {
2288
+ if (t.type === 'TSLiteralType' &&
2289
+ t.literal.type !== 'UnaryExpression') {
2497
2290
  emits.add(String(t.literal.value));
2498
2291
  }
2499
2292
  }
@@ -2507,146 +2300,6 @@ function genRuntimeEmits(emits) {
2507
2300
  .join(', ')}] as unknown as undefined,`
2508
2301
  : ``;
2509
2302
  }
2510
- function markScopeIdentifier(node, child, knownIds) {
2511
- const { name } = child;
2512
- if (node.scopeIds && node.scopeIds.has(name)) {
2513
- return;
2514
- }
2515
- if (name in knownIds) {
2516
- knownIds[name]++;
2517
- }
2518
- else {
2519
- knownIds[name] = 1;
2520
- }
2521
- (node.scopeIds || (node.scopeIds = new Set())).add(name);
2522
- }
2523
- /**
2524
- * Walk an AST and find identifiers that are variable references.
2525
- * This is largely the same logic with `transformExpressions` in compiler-core
2526
- * but with some subtle differences as this needs to handle a wider range of
2527
- * possible syntax.
2528
- */
2529
- function walkIdentifiers(root, onIdentifier, onNode) {
2530
- const parentStack = [];
2531
- const knownIds = Object.create(null);
2532
- estreeWalker.walk(root, {
2533
- enter(node, parent) {
2534
- parent && parentStack.push(parent);
2535
- if (parent &&
2536
- parent.type.startsWith('TS') &&
2537
- parent.type !== 'TSAsExpression' &&
2538
- parent.type !== 'TSNonNullExpression' &&
2539
- parent.type !== 'TSTypeAssertion') {
2540
- return this.skip();
2541
- }
2542
- if (onNode && onNode(node, parent, parentStack) === false) {
2543
- return this.skip();
2544
- }
2545
- if (node.type === 'Identifier') {
2546
- if (!knownIds[node.name] &&
2547
- isRefIdentifier(node, parent, parentStack)) {
2548
- onIdentifier(node, parent, parentStack);
2549
- }
2550
- }
2551
- else if (isFunction(node)) {
2552
- // #3445
2553
- // should not rewrite local variables sharing a name with a top-level ref
2554
- if (node.body.type === 'BlockStatement') {
2555
- node.body.body.forEach(p => {
2556
- if (p.type === 'VariableDeclaration') {
2557
- for (const decl of p.declarations) {
2558
- extractIdentifiers(decl.id).forEach(id => {
2559
- markScopeIdentifier(node, id, knownIds);
2560
- });
2561
- }
2562
- }
2563
- });
2564
- }
2565
- // walk function expressions and add its arguments to known identifiers
2566
- // so that we don't prefix them
2567
- node.params.forEach(p => estreeWalker.walk(p, {
2568
- enter(child, parent) {
2569
- if (child.type === 'Identifier' &&
2570
- // do not record as scope variable if is a destructured key
2571
- !isStaticPropertyKey(child, parent) &&
2572
- // do not record if this is a default value
2573
- // assignment of a destructured variable
2574
- !(parent &&
2575
- parent.type === 'AssignmentPattern' &&
2576
- parent.right === child)) {
2577
- markScopeIdentifier(node, child, knownIds);
2578
- }
2579
- }
2580
- }));
2581
- }
2582
- else if (node.type === 'ObjectProperty' &&
2583
- parent.type === 'ObjectPattern') {
2584
- node.inPattern = true;
2585
- }
2586
- },
2587
- leave(node, parent) {
2588
- parent && parentStack.pop();
2589
- if (node.scopeIds) {
2590
- node.scopeIds.forEach((id) => {
2591
- knownIds[id]--;
2592
- if (knownIds[id] === 0) {
2593
- delete knownIds[id];
2594
- }
2595
- });
2596
- }
2597
- }
2598
- });
2599
- }
2600
- function isRefIdentifier(id, parent, parentStack) {
2601
- if (!parent) {
2602
- return true;
2603
- }
2604
- // declaration id
2605
- if ((parent.type === 'VariableDeclarator' ||
2606
- parent.type === 'ClassDeclaration') &&
2607
- parent.id === id) {
2608
- return false;
2609
- }
2610
- if (isFunction(parent)) {
2611
- // function decalration/expression id
2612
- if (parent.id === id) {
2613
- return false;
2614
- }
2615
- // params list
2616
- if (parent.params.includes(id)) {
2617
- return false;
2618
- }
2619
- }
2620
- // property key
2621
- // this also covers object destructure pattern
2622
- if (isStaticPropertyKey(id, parent)) {
2623
- return false;
2624
- }
2625
- // non-assignment array destructure pattern
2626
- if (parent.type === 'ArrayPattern' &&
2627
- !isInDestructureAssignment(parent, parentStack)) {
2628
- return false;
2629
- }
2630
- // member expression property
2631
- if ((parent.type === 'MemberExpression' ||
2632
- parent.type === 'OptionalMemberExpression') &&
2633
- parent.property === id &&
2634
- !parent.computed) {
2635
- return false;
2636
- }
2637
- // is a special keyword but parsed as identifier
2638
- if (id.name === 'arguments') {
2639
- return false;
2640
- }
2641
- return true;
2642
- }
2643
- const isStaticProperty = (node) => node &&
2644
- (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
2645
- !node.computed;
2646
- const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;
2647
- function isFunction(node) {
2648
- return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
2649
- }
2650
2303
  function isCallOf(node, test) {
2651
2304
  return !!(node &&
2652
2305
  node.type === 'CallExpression' &&
@@ -2679,25 +2332,6 @@ function canNeverBeRef(node, userReactiveImport) {
2679
2332
  return false;
2680
2333
  }
2681
2334
  }
2682
- function isInDestructureAssignment(parent, parentStack) {
2683
- if (parent &&
2684
- (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {
2685
- let i = parentStack.length;
2686
- while (i--) {
2687
- const p = parentStack[i];
2688
- if (p.type === 'AssignmentExpression') {
2689
- const root = parentStack[0];
2690
- // if this is a ref: destructure, it should be treated like a
2691
- // variable decalration!
2692
- return !(root.type === 'LabeledStatement' && root.label.name === 'ref');
2693
- }
2694
- else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
2695
- break;
2696
- }
2697
- }
2698
- }
2699
- return false;
2700
- }
2701
2335
  /**
2702
2336
  * Analyze bindings in normal `<script>`
2703
2337
  * Note that `compileScriptSetup` already analyzes bindings as part of its
@@ -2808,49 +2442,6 @@ function getObjectOrArrayExpressionKeys(value) {
2808
2442
  }
2809
2443
  return [];
2810
2444
  }
2811
- function extractIdentifiers(param, nodes = []) {
2812
- switch (param.type) {
2813
- case 'Identifier':
2814
- nodes.push(param);
2815
- break;
2816
- case 'MemberExpression':
2817
- let object = param;
2818
- while (object.type === 'MemberExpression') {
2819
- object = object.object;
2820
- }
2821
- nodes.push(object);
2822
- break;
2823
- case 'ObjectPattern':
2824
- param.properties.forEach(prop => {
2825
- if (prop.type === 'RestElement') {
2826
- extractIdentifiers(prop.argument, nodes);
2827
- }
2828
- else {
2829
- extractIdentifiers(prop.value, nodes);
2830
- }
2831
- });
2832
- break;
2833
- case 'ArrayPattern':
2834
- param.elements.forEach(element => {
2835
- if (element)
2836
- extractIdentifiers(element, nodes);
2837
- });
2838
- break;
2839
- case 'RestElement':
2840
- extractIdentifiers(param.argument, nodes);
2841
- break;
2842
- case 'AssignmentPattern':
2843
- extractIdentifiers(param.left, nodes);
2844
- break;
2845
- }
2846
- return nodes;
2847
- }
2848
- function toTextRange(node) {
2849
- return {
2850
- start: node.start,
2851
- end: node.end
2852
- };
2853
- }
2854
2445
  const templateUsageCheckCache = createCache();
2855
2446
  function resolveTemplateUsageCheckString(sfc) {
2856
2447
  const { content, ast } = sfc.template;
@@ -2865,7 +2456,7 @@ function resolveTemplateUsageCheckString(sfc) {
2865
2456
  if (node.type === 1 /* ELEMENT */) {
2866
2457
  if (!CompilerDOM.parserOptions.isNativeTag(node.tag) &&
2867
2458
  !CompilerDOM.parserOptions.isBuiltInComponent(node.tag)) {
2868
- code += `,${shared.capitalize(shared.camelize(node.tag))}`;
2459
+ code += `,${shared.camelize(node.tag)},${shared.capitalize(shared.camelize(node.tag))}`;
2869
2460
  }
2870
2461
  for (let i = 0; i < node.props.length; i++) {
2871
2462
  const prop = node.props[i];
@@ -2890,17 +2481,32 @@ function resolveTemplateUsageCheckString(sfc) {
2890
2481
  return code;
2891
2482
  }
2892
2483
  function stripStrings(exp) {
2893
- return exp.replace(/'[^']+'|"[^"]+"|`[^`]+`/g, '');
2484
+ return exp
2485
+ .replace(/'[^']+'|"[^"]+"/g, '')
2486
+ .replace(/`[^`]+`/g, stripTemplateString);
2487
+ }
2488
+ function stripTemplateString(str) {
2489
+ const interpMatch = str.match(/\${[^}]+}/g);
2490
+ if (interpMatch) {
2491
+ return interpMatch.map(m => m.slice(2, -1)).join(',');
2492
+ }
2493
+ return '';
2894
2494
  }
2895
2495
 
2496
+ exports.extractIdentifiers = compilerCore.extractIdentifiers;
2896
2497
  exports.generateCodeFrame = compilerCore.generateCodeFrame;
2498
+ exports.isInDestructureAssignment = compilerCore.isInDestructureAssignment;
2499
+ exports.isStaticProperty = compilerCore.isStaticProperty;
2500
+ exports.walkIdentifiers = compilerCore.walkIdentifiers;
2897
2501
  exports.MagicString = MagicString__default;
2898
2502
  exports.babelParse = parser.parse;
2899
2503
  exports.walk = estreeWalker.walk;
2504
+ exports.shouldTransformRef = refTransform.shouldTransform;
2505
+ exports.transformRef = refTransform.transform;
2506
+ exports.transformRefAST = refTransform.transformAST;
2900
2507
  exports.compileScript = compileScript;
2901
2508
  exports.compileStyle = compileStyle;
2902
2509
  exports.compileStyleAsync = compileStyleAsync;
2903
2510
  exports.compileTemplate = compileTemplate;
2904
2511
  exports.parse = parse;
2905
2512
  exports.rewriteDefault = rewriteDefault;
2906
- exports.walkIdentifiers = walkIdentifiers;