版博士V2.0程序
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

114 satır
3.2 KiB

  1. // src/core/utils.ts
  2. import { DEFINE_OPTIONS, isCallOf } from "@vue-macros/common";
  3. function filterMacro(stmts) {
  4. return stmts.map((raw) => {
  5. let node = raw;
  6. if (raw.type === "ExpressionStatement")
  7. node = raw.expression;
  8. return isCallOf(node, DEFINE_OPTIONS) ? node : void 0;
  9. }).filter((node) => !!node);
  10. }
  11. function hasPropsOrEmits(node) {
  12. return node.properties.some(
  13. (prop) => (prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && prop.key.type === "Identifier" && (prop.key.name === "props" || prop.key.name === "emits")
  14. );
  15. }
  16. // src/core/transform.ts
  17. import {
  18. DEFINE_OPTIONS as DEFINE_OPTIONS2,
  19. HELPER_PREFIX,
  20. MagicString,
  21. addNormalScript,
  22. checkInvalidScopeReference,
  23. getTransformResult,
  24. importHelperFn,
  25. parseSFC
  26. } from "@vue-macros/common";
  27. import { walkAST } from "ast-walker-scope";
  28. function transformDefineOptions(code, id) {
  29. if (!code.includes(DEFINE_OPTIONS2))
  30. return;
  31. const sfc = parseSFC(code, id);
  32. if (!sfc.scriptSetup)
  33. return;
  34. const { scriptSetup, getSetupAst, getScriptAst } = sfc;
  35. const setupOffset = scriptSetup.loc.start.offset;
  36. const setupAst = getSetupAst();
  37. const nodes = filterMacro(setupAst.body);
  38. if (nodes.length === 0) {
  39. return;
  40. } else if (nodes.length > 1)
  41. throw new SyntaxError(`duplicate ${DEFINE_OPTIONS2}() call`);
  42. const scriptAst = getScriptAst();
  43. if (scriptAst)
  44. checkDefaultExport(scriptAst.body);
  45. const setupBindings = getIdentifiers(setupAst.body);
  46. const s = new MagicString(code);
  47. const [node] = nodes;
  48. const [arg] = node.arguments;
  49. if (arg) {
  50. const normalScript = addNormalScript(sfc, s);
  51. const scriptOffset = normalScript.start();
  52. importHelperFn(s, scriptOffset, "defineComponent", "vue");
  53. s.appendLeft(
  54. scriptOffset,
  55. `
  56. export default /*#__PURE__*/ ${HELPER_PREFIX}defineComponent(`
  57. );
  58. if (arg.type === "ObjectExpression" && hasPropsOrEmits(arg))
  59. throw new SyntaxError(
  60. `${DEFINE_OPTIONS2}() please use defineProps or defineEmits instead.`
  61. );
  62. checkInvalidScopeReference(arg, DEFINE_OPTIONS2, setupBindings);
  63. s.moveNode(arg, scriptOffset, { offset: setupOffset });
  64. s.remove(setupOffset + node.start, setupOffset + arg.start);
  65. s.remove(setupOffset + arg.end, setupOffset + node.end);
  66. s.appendRight(scriptOffset, ");");
  67. normalScript.end();
  68. } else {
  69. s.removeNode(node, { offset: setupOffset });
  70. }
  71. return getTransformResult(s, id);
  72. }
  73. var checkDefaultExport = (stmts) => {
  74. const hasDefaultExport = stmts.some(
  75. (node) => node.type === "ExportDefaultDeclaration"
  76. );
  77. if (hasDefaultExport)
  78. throw new SyntaxError(
  79. `${DEFINE_OPTIONS2} cannot be used with default export within <script>.`
  80. );
  81. };
  82. var getIdentifiers = (stmts) => {
  83. let ids = [];
  84. const program = {
  85. type: "Program",
  86. body: stmts,
  87. directives: [],
  88. sourceType: "module",
  89. sourceFile: ""
  90. };
  91. walkAST(program, {
  92. enter(node) {
  93. if (node.type === "BlockStatement") {
  94. this.skip();
  95. }
  96. },
  97. leave(node) {
  98. if (node.type !== "Program")
  99. return;
  100. ids = Object.keys(this.scope);
  101. }
  102. });
  103. return ids;
  104. };
  105. export {
  106. filterMacro,
  107. hasPropsOrEmits,
  108. transformDefineOptions,
  109. checkDefaultExport,
  110. getIdentifiers
  111. };