web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
17 KiB

  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. return new (P || (P = Promise))(function (resolve, reject) {
  4. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  5. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  6. function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
  7. step((generator = generator.apply(thisArg, _arguments || [])).next());
  8. });
  9. };
  10. var __generator = (this && this.__generator) || function (thisArg, body) {
  11. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  12. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  13. function verb(n) { return function (v) { return step([n, v]); }; }
  14. function step(op) {
  15. if (f) throw new TypeError("Generator is already executing.");
  16. while (_) try {
  17. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  18. if (y = 0, t) op = [op[0] & 2, t.value];
  19. switch (op[0]) {
  20. case 0: case 1: t = op; break;
  21. case 4: _.label++; return { value: op[1], done: false };
  22. case 5: _.label++; y = op[1]; op = [0]; continue;
  23. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  24. default:
  25. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  26. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  27. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  28. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  29. if (t[2]) _.ops.pop();
  30. _.trys.pop(); continue;
  31. }
  32. op = body.call(thisArg, _);
  33. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  34. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  35. }
  36. };
  37. Object.defineProperty(exports, "__esModule", { value: true });
  38. var LinkedList_1 = require("./LinkedList");
  39. var VueProgram_1 = require("./VueProgram");
  40. var CompilerHost = /** @class */ (function () {
  41. function CompilerHost(typescript, vueOptions, programConfigFile, compilerOptions, checkSyntacticErrors, userResolveModuleName, userResolveTypeReferenceDirective) {
  42. var _this = this;
  43. this.typescript = typescript;
  44. this.vueOptions = vueOptions;
  45. // intercept all watch events and collect them until we get notification to start compilation
  46. this.directoryWatchers = new LinkedList_1.LinkedList();
  47. this.fileWatchers = new LinkedList_1.LinkedList();
  48. this.knownFiles = new Set();
  49. this.gatheredDiagnostic = [];
  50. this.afterCompile = function () {
  51. /* do nothing */
  52. };
  53. this.compilationStarted = false;
  54. this.createProgram = this.typescript
  55. .createEmitAndSemanticDiagnosticsBuilderProgram;
  56. this.tsHost = typescript.createWatchCompilerHost(programConfigFile, compilerOptions, typescript.sys, typescript.createEmitAndSemanticDiagnosticsBuilderProgram, function (diag) {
  57. if (!checkSyntacticErrors &&
  58. diag.code >= 1000 &&
  59. diag.code < 2000 &&
  60. diag.file // if diag.file is undefined, this is not a syntactic error, but a global error that should be emitted
  61. ) {
  62. return;
  63. }
  64. _this.gatheredDiagnostic.push(diag);
  65. }, function () {
  66. // do nothing
  67. });
  68. this.configFileName = this.tsHost.configFileName;
  69. this.optionsToExtend = this.tsHost.optionsToExtend || {};
  70. if (userResolveModuleName) {
  71. this.resolveModuleNames = function (moduleNames, containingFile) {
  72. return moduleNames.map(function (moduleName) {
  73. return userResolveModuleName(_this.typescript, moduleName, containingFile, _this.optionsToExtend, _this).resolvedModule;
  74. });
  75. };
  76. }
  77. if (userResolveTypeReferenceDirective) {
  78. this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) {
  79. return typeDirectiveNames.map(function (typeDirectiveName) {
  80. return userResolveTypeReferenceDirective(_this.typescript, typeDirectiveName, containingFile, _this.optionsToExtend, _this).resolvedTypeReferenceDirective;
  81. });
  82. };
  83. }
  84. }
  85. CompilerHost.prototype.getProgram = function () {
  86. if (!this.program) {
  87. throw new Error('Program is not created yet.');
  88. }
  89. return this.program.getProgram().getProgram();
  90. };
  91. CompilerHost.prototype.getAllKnownFiles = function () {
  92. return this.knownFiles;
  93. };
  94. CompilerHost.prototype.processChanges = function () {
  95. return __awaiter(this, void 0, void 0, function () {
  96. var initialCompile, errors, previousDiagnostic, resultPromise, files, updatedFiles, removedFiles, results;
  97. var _this = this;
  98. return __generator(this, function (_a) {
  99. switch (_a.label) {
  100. case 0:
  101. if (!!this.lastProcessing) return [3 /*break*/, 2];
  102. initialCompile = new Promise(function (resolve) {
  103. _this.afterCompile = function () {
  104. resolve(_this.gatheredDiagnostic);
  105. _this.afterCompile = function () {
  106. /* do nothing */
  107. };
  108. _this.compilationStarted = false;
  109. };
  110. });
  111. this.lastProcessing = initialCompile;
  112. this.program = this.typescript.createWatchProgram(this);
  113. return [4 /*yield*/, initialCompile];
  114. case 1:
  115. errors = _a.sent();
  116. return [2 /*return*/, {
  117. results: errors,
  118. updatedFiles: Array.from(this.knownFiles),
  119. removedFiles: []
  120. }];
  121. case 2:
  122. // since we do not have a way to pass cancellation token to typescript,
  123. // we just wait until previous compilation finishes.
  124. return [4 /*yield*/, this.lastProcessing];
  125. case 3:
  126. // since we do not have a way to pass cancellation token to typescript,
  127. // we just wait until previous compilation finishes.
  128. _a.sent();
  129. previousDiagnostic = this.gatheredDiagnostic;
  130. this.gatheredDiagnostic = [];
  131. resultPromise = new Promise(function (resolve) {
  132. _this.afterCompile = function () {
  133. resolve(_this.gatheredDiagnostic);
  134. _this.afterCompile = function () {
  135. /* do nothing */
  136. };
  137. _this.compilationStarted = false;
  138. };
  139. });
  140. this.lastProcessing = resultPromise;
  141. files = [];
  142. this.directoryWatchers.forEach(function (item) {
  143. for (var _i = 0, _a = item.events; _i < _a.length; _i++) {
  144. var e = _a[_i];
  145. item.callback(e.fileName);
  146. }
  147. item.events.length = 0;
  148. });
  149. updatedFiles = [];
  150. removedFiles = [];
  151. this.fileWatchers.forEach(function (item) {
  152. for (var _i = 0, _a = item.events; _i < _a.length; _i++) {
  153. var e = _a[_i];
  154. item.callback(e.fileName, e.eventKind);
  155. files.push(e.fileName);
  156. if (e.eventKind === _this.typescript.FileWatcherEventKind.Created ||
  157. e.eventKind === _this.typescript.FileWatcherEventKind.Changed) {
  158. updatedFiles.push(e.fileName);
  159. }
  160. else if (e.eventKind === _this.typescript.FileWatcherEventKind.Deleted) {
  161. removedFiles.push(e.fileName);
  162. }
  163. }
  164. item.events.length = 0;
  165. });
  166. // if the files are not relevant to typescript it may choose not to compile
  167. // in this case we need to trigger promise resolution from here
  168. if (!this.compilationStarted) {
  169. // keep diagnostic from previous run
  170. this.gatheredDiagnostic = previousDiagnostic;
  171. this.afterCompile();
  172. return [2 /*return*/, {
  173. results: this.gatheredDiagnostic,
  174. updatedFiles: [],
  175. removedFiles: []
  176. }];
  177. }
  178. return [4 /*yield*/, resultPromise];
  179. case 4:
  180. results = _a.sent();
  181. return [2 /*return*/, { results: results, updatedFiles: updatedFiles, removedFiles: removedFiles }];
  182. }
  183. });
  184. });
  185. };
  186. CompilerHost.prototype.setTimeout = function (
  187. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  188. callback, ms) {
  189. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  190. var args = [];
  191. for (
  192. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  193. var _i = 2;
  194. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  195. _i < arguments.length;
  196. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  197. _i++) {
  198. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  199. args[_i - 2] = arguments[_i];
  200. }
  201. // There are 2 things we are hacking here:
  202. // 1. This method only called from watch program to wait until all files
  203. // are written to filesystem (for example, when doing 'save all')
  204. // We are intercepting all change notifications, and letting
  205. // them through only when webpack starts processing changes.
  206. // Therefore, at this point normally files are already all saved,
  207. // so we do not need to waste another 250 ms (hardcoded in TypeScript).
  208. // On the other hand there may be occasional glitch, when our incremental
  209. // compiler will receive the notification too late, and process it when
  210. // next compilation would start.
  211. // 2. It seems to be only reliable way to intercept a moment when TypeScript
  212. // actually starts compilation.
  213. //
  214. // Ideally we probably should not let TypeScript call all those watching
  215. // methods by itself, and instead forward changes from webpack.
  216. // Unfortunately, at the moment TypeScript incremental API is quite
  217. // immature (for example, minor changes in how you use it cause
  218. // dramatic compilation time increase), so we have to stick with these
  219. // hacks for now.
  220. this.compilationStarted = true;
  221. return (this.typescript.sys.setTimeout || setTimeout)(callback, 1, args);
  222. };
  223. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  224. CompilerHost.prototype.clearTimeout = function (timeoutId) {
  225. (this.typescript.sys.clearTimeout || clearTimeout)(timeoutId);
  226. };
  227. CompilerHost.prototype.onWatchStatusChange = function () {
  228. // do nothing
  229. };
  230. CompilerHost.prototype.watchDirectory = function (path, callback, recursive) {
  231. var slot = { callback: callback, events: [] };
  232. var node = this.directoryWatchers.add(slot);
  233. this.tsHost.watchDirectory(path, function (fileName) {
  234. slot.events.push({ fileName: fileName });
  235. }, recursive);
  236. return {
  237. close: function () {
  238. node.detachSelf();
  239. }
  240. };
  241. };
  242. CompilerHost.prototype.watchFile = function (path, callback, pollingInterval) {
  243. var _this = this;
  244. var slot = { callback: callback, events: [] };
  245. var node = this.fileWatchers.add(slot);
  246. this.knownFiles.add(path);
  247. this.tsHost.watchFile(path, function (fileName, eventKind) {
  248. if (eventKind === _this.typescript.FileWatcherEventKind.Created) {
  249. _this.knownFiles.add(fileName);
  250. }
  251. else if (eventKind === _this.typescript.FileWatcherEventKind.Deleted) {
  252. _this.knownFiles.delete(fileName);
  253. }
  254. slot.events.push({ fileName: fileName, eventKind: eventKind });
  255. }, pollingInterval);
  256. return {
  257. close: function () {
  258. node.detachSelf();
  259. }
  260. };
  261. };
  262. CompilerHost.prototype.fileExists = function (path) {
  263. return this.tsHost.fileExists(path);
  264. };
  265. CompilerHost.prototype.readFile = function (path, encoding) {
  266. var content = this.tsHost.readFile(path, encoding);
  267. // get typescript contents from Vue file
  268. if (content && VueProgram_1.VueProgram.isVue(path)) {
  269. var resolved = VueProgram_1.VueProgram.resolveScriptBlock(this.typescript, content, this.vueOptions.compiler);
  270. return resolved.content;
  271. }
  272. return content;
  273. };
  274. CompilerHost.prototype.directoryExists = function (path) {
  275. return ((this.tsHost.directoryExists && this.tsHost.directoryExists(path)) ||
  276. false);
  277. };
  278. CompilerHost.prototype.getDirectories = function (path) {
  279. return ((this.tsHost.getDirectories && this.tsHost.getDirectories(path)) || []);
  280. };
  281. CompilerHost.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
  282. return this.typescript.sys.readDirectory(path, extensions, exclude, include, depth);
  283. };
  284. CompilerHost.prototype.getCurrentDirectory = function () {
  285. return this.tsHost.getCurrentDirectory();
  286. };
  287. CompilerHost.prototype.getDefaultLibFileName = function (options) {
  288. return this.tsHost.getDefaultLibFileName(options);
  289. };
  290. CompilerHost.prototype.getEnvironmentVariable = function (name) {
  291. return (this.tsHost.getEnvironmentVariable &&
  292. this.tsHost.getEnvironmentVariable(name));
  293. };
  294. CompilerHost.prototype.getNewLine = function () {
  295. return this.tsHost.getNewLine();
  296. };
  297. CompilerHost.prototype.realpath = function (path) {
  298. if (!this.tsHost.realpath) {
  299. throw new Error('The realpath function is not supported by the CompilerHost.');
  300. }
  301. return this.tsHost.realpath(path);
  302. };
  303. CompilerHost.prototype.trace = function (s) {
  304. if (this.tsHost.trace) {
  305. this.tsHost.trace(s);
  306. }
  307. };
  308. CompilerHost.prototype.useCaseSensitiveFileNames = function () {
  309. return this.tsHost.useCaseSensitiveFileNames();
  310. };
  311. CompilerHost.prototype.onUnRecoverableConfigFileDiagnostic = function () {
  312. // do nothing
  313. };
  314. CompilerHost.prototype.afterProgramCreate = function (program) {
  315. // all actual diagnostics happens here
  316. if (this.tsHost.afterProgramCreate) {
  317. this.tsHost.afterProgramCreate(program);
  318. }
  319. this.afterCompile();
  320. };
  321. // the functions below are use internally by typescript. we cannot use non-emitting version of incremental watching API
  322. // because it is
  323. // - much slower for some reason,
  324. // - writes files anyway (o_O)
  325. // - has different way of providing diagnostics. (with this version we can at least reliably get it from afterProgramCreate)
  326. CompilerHost.prototype.createDirectory = function () {
  327. // pretend everything was ok
  328. };
  329. CompilerHost.prototype.writeFile = function () {
  330. // pretend everything was ok
  331. };
  332. CompilerHost.prototype.onCachedDirectoryStructureHostCreate = function () {
  333. // pretend everything was ok
  334. };
  335. return CompilerHost;
  336. }());
  337. exports.CompilerHost = CompilerHost;
  338. //# sourceMappingURL=CompilerHost.js.map