computedFiles.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.computedFiles = void 0;
  4. const source_map_1 = require("@volar/source-map");
  5. const muggle = require("muggle-string");
  6. const embeddedFile_1 = require("./embeddedFile");
  7. const computeds_1 = require("computeds");
  8. function computedFiles(plugins, fileName, sfc, codegenStack) {
  9. const nameToBlock = (0, computeds_1.computed)(() => {
  10. const blocks = {};
  11. if (sfc.template) {
  12. blocks[sfc.template.name] = sfc.template;
  13. }
  14. if (sfc.script) {
  15. blocks[sfc.script.name] = sfc.script;
  16. }
  17. if (sfc.scriptSetup) {
  18. blocks[sfc.scriptSetup.name] = sfc.scriptSetup;
  19. }
  20. for (const block of sfc.styles) {
  21. blocks[block.name] = block;
  22. }
  23. for (const block of sfc.customBlocks) {
  24. blocks[block.name] = block;
  25. }
  26. return blocks;
  27. });
  28. const pluginsResult = plugins.map(plugin => compiledPluginFiles(plugins, plugin, fileName, sfc, nameToBlock, codegenStack));
  29. const flatResult = (0, computeds_1.computed)(() => pluginsResult.map(r => r()).flat());
  30. const structuredResult = (0, computeds_1.computed)(() => {
  31. const embeddedFiles = [];
  32. let remain = [...flatResult()];
  33. while (remain.length) {
  34. const beforeLength = remain.length;
  35. consumeRemain();
  36. if (beforeLength === remain.length) {
  37. break;
  38. }
  39. }
  40. for (const { file, snapshot, mappings, codegenStacks } of remain) {
  41. embeddedFiles.push({
  42. ...file,
  43. snapshot,
  44. mappings,
  45. codegenStacks,
  46. embeddedFiles: [],
  47. });
  48. console.error('Unable to resolve embedded: ' + file.parentFileName + ' -> ' + file.fileName);
  49. }
  50. return embeddedFiles;
  51. function consumeRemain() {
  52. for (let i = remain.length - 1; i >= 0; i--) {
  53. const { file, snapshot, mappings, codegenStacks } = remain[i];
  54. if (!file.parentFileName) {
  55. embeddedFiles.push({
  56. ...file,
  57. snapshot,
  58. mappings,
  59. codegenStacks,
  60. embeddedFiles: [],
  61. });
  62. remain.splice(i, 1);
  63. }
  64. else {
  65. const parent = findParentStructure(file.parentFileName, embeddedFiles);
  66. if (parent) {
  67. parent.embeddedFiles.push({
  68. ...file,
  69. snapshot,
  70. mappings,
  71. codegenStacks,
  72. embeddedFiles: [],
  73. });
  74. remain.splice(i, 1);
  75. }
  76. }
  77. }
  78. }
  79. function findParentStructure(fileName, current) {
  80. for (const child of current) {
  81. if (child.fileName === fileName) {
  82. return child;
  83. }
  84. let parent = findParentStructure(fileName, child.embeddedFiles);
  85. if (parent) {
  86. return parent;
  87. }
  88. }
  89. }
  90. });
  91. return structuredResult;
  92. }
  93. exports.computedFiles = computedFiles;
  94. function compiledPluginFiles(plugins, plugin, fileName, sfc, nameToBlock, codegenStack) {
  95. const embeddedFiles = {};
  96. const files = (0, computeds_1.computed)(() => {
  97. try {
  98. if (!plugin.getEmbeddedFileNames) {
  99. return Object.values(embeddedFiles);
  100. }
  101. const embeddedFileNames = plugin.getEmbeddedFileNames(fileName, sfc);
  102. for (const oldFileName of Object.keys(embeddedFiles)) {
  103. if (!embeddedFileNames.includes(oldFileName)) {
  104. delete embeddedFiles[oldFileName];
  105. }
  106. }
  107. for (const embeddedFileName of embeddedFileNames) {
  108. if (!embeddedFiles[embeddedFileName]) {
  109. embeddedFiles[embeddedFileName] = (0, computeds_1.computed)(() => {
  110. const [content, stacks] = codegenStack ? muggle.track([]) : [[], []];
  111. const file = new embeddedFile_1.VueEmbeddedFile(embeddedFileName, content, stacks);
  112. for (const plugin of plugins) {
  113. if (!plugin.resolveEmbeddedFile) {
  114. continue;
  115. }
  116. try {
  117. plugin.resolveEmbeddedFile(fileName, sfc, file);
  118. }
  119. catch (e) {
  120. console.error(e);
  121. }
  122. }
  123. const newText = (0, source_map_1.toString)(file.content);
  124. const changeRanges = new Map();
  125. const snapshot = {
  126. getText: (start, end) => newText.slice(start, end),
  127. getLength: () => newText.length,
  128. getChangeRange(oldSnapshot) {
  129. if (!changeRanges.has(oldSnapshot)) {
  130. changeRanges.set(oldSnapshot, undefined);
  131. const oldText = oldSnapshot.getText(0, oldSnapshot.getLength());
  132. const changeRange = fullDiffTextChangeRange(oldText, newText);
  133. if (changeRange) {
  134. changeRanges.set(oldSnapshot, changeRange);
  135. }
  136. }
  137. return changeRanges.get(oldSnapshot);
  138. },
  139. };
  140. return {
  141. file,
  142. snapshot,
  143. };
  144. });
  145. }
  146. }
  147. }
  148. catch (e) {
  149. console.error(e);
  150. }
  151. return Object.values(embeddedFiles);
  152. });
  153. return (0, computeds_1.computed)(() => {
  154. return files().map(_file => {
  155. const { file, snapshot } = _file();
  156. const mappings = (0, source_map_1.buildMappings)(file.content);
  157. for (const mapping of mappings) {
  158. if (mapping.source !== undefined) {
  159. const block = nameToBlock()[mapping.source];
  160. if (block) {
  161. mapping.sourceRange = [
  162. mapping.sourceRange[0] + block.startTagEnd,
  163. mapping.sourceRange[1] + block.startTagEnd,
  164. ];
  165. }
  166. else {
  167. // ignore
  168. }
  169. mapping.source = undefined;
  170. }
  171. }
  172. return {
  173. file,
  174. snapshot,
  175. mappings,
  176. codegenStacks: (0, source_map_1.buildStacks)(file.content, file.contentStacks),
  177. };
  178. });
  179. });
  180. }
  181. function fullDiffTextChangeRange(oldText, newText) {
  182. for (let start = 0; start < oldText.length && start < newText.length; start++) {
  183. if (oldText[start] !== newText[start]) {
  184. let end = oldText.length;
  185. for (let i = 0; i < oldText.length - start && i < newText.length - start; i++) {
  186. if (oldText[oldText.length - i - 1] !== newText[newText.length - i - 1]) {
  187. break;
  188. }
  189. end--;
  190. }
  191. let length = end - start;
  192. let newLength = length + (newText.length - oldText.length);
  193. if (newLength < 0) {
  194. length -= newLength;
  195. newLength = 0;
  196. }
  197. return {
  198. span: { start, length },
  199. newLength,
  200. };
  201. }
  202. }
  203. }
  204. //# sourceMappingURL=computedFiles.js.map