languagePlugin.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. "use strict";
  2. /// <reference types="@volar/typescript" />
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. exports.createVueLanguagePlugin = createVueLanguagePlugin;
  5. exports.getAllExtensions = getAllExtensions;
  6. const language_core_1 = require("@volar/language-core");
  7. const CompilerDOM = require("@vue/compiler-dom");
  8. const plugins_1 = require("./plugins");
  9. const CompilerVue2 = require("./utils/vue2TemplateCompiler");
  10. const vueFile_1 = require("./virtualFile/vueFile");
  11. const fileRegistries = [];
  12. function getVueFileRegistry(key, plugins) {
  13. let fileRegistry = fileRegistries.find(r => r.key === key
  14. && r.plugins.length === plugins.length
  15. && r.plugins.every(plugin => plugins.includes(plugin)))?.files;
  16. if (!fileRegistry) {
  17. fileRegistry = new Map();
  18. fileRegistries.push({
  19. key: key,
  20. plugins: plugins,
  21. files: fileRegistry,
  22. });
  23. }
  24. return fileRegistry;
  25. }
  26. function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
  27. const values = [
  28. ...Object.keys(vueCompilerOptions)
  29. .sort()
  30. .filter(key => key !== 'plugins')
  31. .map(key => [key, vueCompilerOptions[key]]),
  32. [...new Set(plugins.map(plugin => plugin.requiredCompilerOptions ?? []).flat())]
  33. .sort()
  34. .map(key => [key, compilerOptions[key]]),
  35. ];
  36. return JSON.stringify(values);
  37. }
  38. function createVueLanguagePlugin(ts, compilerOptions, vueCompilerOptions, asFileName) {
  39. const pluginContext = {
  40. modules: {
  41. '@vue/compiler-dom': vueCompilerOptions.target < 3
  42. ? {
  43. ...CompilerDOM,
  44. compile: CompilerVue2.compile,
  45. }
  46. : CompilerDOM,
  47. typescript: ts,
  48. },
  49. compilerOptions,
  50. vueCompilerOptions,
  51. };
  52. const plugins = (0, plugins_1.createPlugins)(pluginContext);
  53. const fileRegistry = getVueFileRegistry(getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins), vueCompilerOptions.plugins);
  54. return {
  55. getLanguageId(scriptId) {
  56. const fileName = asFileName(scriptId);
  57. for (const plugin of plugins) {
  58. const languageId = plugin.getLanguageId?.(fileName);
  59. if (languageId) {
  60. return languageId;
  61. }
  62. }
  63. },
  64. createVirtualCode(scriptId, languageId, snapshot) {
  65. const fileName = asFileName(scriptId);
  66. if (plugins.some(plugin => plugin.isValidFile?.(fileName, languageId))) {
  67. const code = fileRegistry.get(fileName);
  68. if (code) {
  69. code.update(snapshot);
  70. return code;
  71. }
  72. else {
  73. const code = new vueFile_1.VueVirtualCode(fileName, languageId, snapshot, vueCompilerOptions, plugins, ts);
  74. fileRegistry.set(fileName, code);
  75. return code;
  76. }
  77. }
  78. },
  79. updateVirtualCode(_fileId, code, snapshot) {
  80. code.update(snapshot);
  81. return code;
  82. },
  83. typescript: {
  84. extraFileExtensions: getAllExtensions(vueCompilerOptions)
  85. .map(ext => ({
  86. extension: ext.slice(1),
  87. isMixedContent: true,
  88. scriptKind: 7,
  89. })),
  90. getServiceScript(root) {
  91. for (const code of (0, language_core_1.forEachEmbeddedCode)(root)) {
  92. if (/script_(js|jsx|ts|tsx)/.test(code.id)) {
  93. const lang = code.id.slice('script_'.length);
  94. return {
  95. code,
  96. extension: '.' + lang,
  97. scriptKind: lang === 'js' ? ts.ScriptKind.JS
  98. : lang === 'jsx' ? ts.ScriptKind.JSX
  99. : lang === 'tsx' ? ts.ScriptKind.TSX
  100. : ts.ScriptKind.TS,
  101. };
  102. }
  103. }
  104. },
  105. },
  106. };
  107. }
  108. function getAllExtensions(options) {
  109. const result = new Set();
  110. for (const key in options) {
  111. if (key === 'extensions' || key.endsWith('Extensions')) {
  112. const value = options[key];
  113. if (Array.isArray(value) && value.every(v => typeof v === 'string')) {
  114. for (const ext of value) {
  115. result.add(ext);
  116. }
  117. }
  118. }
  119. }
  120. return [...result];
  121. }
  122. //# sourceMappingURL=languagePlugin.js.map