index.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.createProgram = void 0;
  4. const vue = require("@vue/language-core");
  5. const volarTs = require("@volar/typescript");
  6. const shared_1 = require("./shared");
  7. const windowsPathReg = /\\/g;
  8. function createProgram(options) {
  9. if (!options.options.noEmit && !options.options.emitDeclarationOnly)
  10. throw toThrow('js emit is not supported');
  11. if (!options.options.noEmit && options.options.noEmitOnError)
  12. throw toThrow('noEmitOnError is not supported');
  13. if (options.options.extendedDiagnostics || options.options.generateTrace)
  14. throw toThrow('--extendedDiagnostics / --generateTrace is not supported, please run `Write Virtual Files` in VSCode to write virtual files and use `--extendedDiagnostics` / `--generateTrace` via tsc instead of vue-tsc to debug.');
  15. if (!options.host)
  16. throw toThrow('!options.host');
  17. const ts = require('typescript');
  18. let program = options.oldProgram;
  19. if (shared_1.state.hook) {
  20. program = shared_1.state.hook.program;
  21. program.__vue.options = options;
  22. }
  23. else if (!program) {
  24. const ctx = {
  25. projectVersion: 0,
  26. options,
  27. get languageHost() {
  28. return languageHost;
  29. },
  30. get vueCompilerOptions() {
  31. return vueCompilerOptions;
  32. },
  33. get languageService() {
  34. return vueTsLs;
  35. },
  36. get langaugeContext() {
  37. return languageContext;
  38. },
  39. };
  40. const vueCompilerOptions = getVueCompilerOptions();
  41. const scripts = new Map();
  42. const languageHost = {
  43. workspacePath: ctx.options.host.getCurrentDirectory().replace(windowsPathReg, '/'),
  44. rootPath: ctx.options.host.getCurrentDirectory().replace(windowsPathReg, '/'),
  45. getCompilationSettings: () => ctx.options.options,
  46. getScriptFileNames: () => {
  47. return ctx.options.rootNames;
  48. },
  49. getScriptSnapshot,
  50. getProjectVersion: () => {
  51. return ctx.projectVersion.toString();
  52. },
  53. getProjectReferences: () => ctx.options.projectReferences,
  54. getCancellationToken: ctx.options.host.getCancellationToken ? () => ctx.options.host.getCancellationToken() : undefined,
  55. };
  56. const languageContext = vue.createLanguageContext(languageHost, vue.createLanguages(ts, languageHost.getCompilationSettings(), vueCompilerOptions));
  57. const languageServiceHost = volarTs.createLanguageServiceHost(languageContext, ts, ts.sys);
  58. const vueTsLs = ts.createLanguageService(languageServiceHost, volarTs.getDocumentRegistry(ts, ts.sys.useCaseSensitiveFileNames, languageHost.workspacePath));
  59. volarTs.decorateLanguageService(languageContext.virtualFiles, vueTsLs, false);
  60. program = volarTs.getProgram(ts, languageContext, vueTsLs, ts.sys);
  61. program.__vue = ctx;
  62. function getVueCompilerOptions() {
  63. const tsConfig = ctx.options.options.configFilePath;
  64. if (typeof tsConfig === 'string') {
  65. return vue.createParsedCommandLine(ts, ts.sys, tsConfig.replace(windowsPathReg, '/')).vueOptions;
  66. }
  67. return {};
  68. }
  69. function getScriptSnapshot(fileName) {
  70. return getScript(fileName)?.scriptSnapshot;
  71. }
  72. function getScript(fileName) {
  73. const script = scripts.get(fileName);
  74. if (script?.projectVersion === ctx.projectVersion) {
  75. return script;
  76. }
  77. const modifiedTime = ts.sys.getModifiedTime?.(fileName)?.valueOf() ?? 0;
  78. if (script?.modifiedTime === modifiedTime) {
  79. return script;
  80. }
  81. if (ctx.options.host.fileExists(fileName)) {
  82. const fileContent = ctx.options.host.readFile(fileName);
  83. if (fileContent !== undefined) {
  84. const script = {
  85. projectVersion: ctx.projectVersion,
  86. modifiedTime,
  87. scriptSnapshot: ts.ScriptSnapshot.fromString(fileContent),
  88. version: ctx.options.host.createHash?.(fileContent) ?? fileContent,
  89. };
  90. scripts.set(fileName, script);
  91. return script;
  92. }
  93. }
  94. }
  95. }
  96. else {
  97. const ctx = program.__vue;
  98. ctx.options = options;
  99. ctx.projectVersion++;
  100. }
  101. const vueCompilerOptions = program.__vue.vueCompilerOptions;
  102. if (vueCompilerOptions?.hooks) {
  103. const index = (shared_1.state.hook?.index ?? -1) + 1;
  104. if (index < vueCompilerOptions.hooks.length) {
  105. const hookPath = vueCompilerOptions.hooks[index];
  106. const hook = require(hookPath);
  107. shared_1.state.hook = {
  108. program,
  109. index,
  110. worker: (async () => await hook(program))(),
  111. };
  112. throw 'hook';
  113. }
  114. }
  115. for (const rootName of options.rootNames) {
  116. // register file watchers
  117. options.host.getSourceFile(rootName, ts.ScriptTarget.ESNext);
  118. }
  119. return program;
  120. }
  121. exports.createProgram = createProgram;
  122. function toThrow(msg) {
  123. console.error(msg);
  124. return msg;
  125. }
  126. //# sourceMappingURL=index.js.map