1 | import * as ts from "typescript";
|
2 | import ConfigParser from "./compiler/config-parser";
|
3 | import createCompilerHost from "./compiler/create-compiler-host";
|
4 | import Input from "./compiler/input-io";
|
5 | import OutputPatcher from "./compiler/output-patcher";
|
6 | import PathResolver from "./compiler/path-resolver";
|
7 | import SourceCache from "./compiler/source-cache";
|
8 | import { normalizePath, relativePathWithin, toAbsolutePath, } from "./fs/path-utils";
|
9 | import { heimdall } from "./helpers";
|
10 | export default class Compiler {
|
11 | constructor(inputPath, outputPath, options, diagnosticsHandler) {
|
12 | this.inputPath = inputPath;
|
13 | this.outputPath = outputPath;
|
14 | this.options = options;
|
15 | this.diagnosticsHandler = diagnosticsHandler;
|
16 | const workingPath = (this.workingPath = options.workingPath);
|
17 | const rootPath = (this.rootPath = options.rootPath);
|
18 | this.buildPath = options.buildPath;
|
19 | const resolver = (this.resolver = new PathResolver(rootPath, inputPath));
|
20 | const input = (this.input = new Input(resolver));
|
21 | this.configParser = new ConfigParser(options.projectPath, options.rawConfig, options.configFileName, options.compilerOptions, workingPath, input);
|
22 | this.output = new OutputPatcher(outputPath);
|
23 | }
|
24 | compile() {
|
25 | const config = this.parseConfig();
|
26 | const sourceCache = this.getSourceCache(config.options);
|
27 | const program = this.createProgram(config, sourceCache);
|
28 | this.emitDiagnostics(program);
|
29 | sourceCache.releaseUnusedSourceFiles(program);
|
30 | this.emitProgram(program, this.resolveBuildPath(config.options));
|
31 | this.patchOutput();
|
32 | this.resetCaches();
|
33 | }
|
34 | parseConfig() {
|
35 | const token = heimdall.start("TypeScript:parseConfig");
|
36 | const config = this.configParser.parseConfig();
|
37 | heimdall.stop(token);
|
38 | return config;
|
39 | }
|
40 | getSourceCache(options) {
|
41 | let sourceCache = this.sourceCache;
|
42 | if (sourceCache === undefined) {
|
43 | sourceCache = this.sourceCache = new SourceCache(this.resolver, options);
|
44 | }
|
45 | else {
|
46 | sourceCache.updateOptions(options);
|
47 | }
|
48 | return sourceCache;
|
49 | }
|
50 | createProgram(config, sourceCache) {
|
51 | const token = heimdall.start("TypeScript:createProgram");
|
52 | const host = createCompilerHost(this.workingPath, this.input, sourceCache, config.options);
|
53 | const oldProgram = this.program;
|
54 | const program = ts.createProgram(config.fileNames, config.options, host, oldProgram);
|
55 | this.program = program;
|
56 | heimdall.stop(token);
|
57 | return program;
|
58 | }
|
59 | emitDiagnostics(program) {
|
60 |
|
61 | const token = heimdall.start("TypeScript:emitDiagnostics");
|
62 | const diagnostics = ts.getPreEmitDiagnostics(program);
|
63 | heimdall.stop(token);
|
64 | this.diagnosticsHandler.check(diagnostics);
|
65 | }
|
66 | resolveBuildPath(options) {
|
67 | if (this.buildPath !== undefined) {
|
68 | return this.buildPath;
|
69 | }
|
70 | if (options.outDir !== undefined) {
|
71 | return normalizePath(options.outDir);
|
72 | }
|
73 | return this.rootPath;
|
74 | }
|
75 | emitProgram(program, buildPath) {
|
76 | const token = heimdall.start("TypeScript:emitProgram");
|
77 | const { output } = this;
|
78 | const emitResult = program.emit(undefined, (fileName, data) => {
|
79 |
|
80 |
|
81 | const relativePath = relativePathWithin(buildPath, toAbsolutePath(fileName, this.workingPath));
|
82 | if (relativePath) {
|
83 | output.add(relativePath, data);
|
84 | }
|
85 | });
|
86 | heimdall.stop(token);
|
87 | this.diagnosticsHandler.check(emitResult.diagnostics);
|
88 | }
|
89 | patchOutput() {
|
90 | const token = heimdall.start("TypeScript:patchOutput");
|
91 | this.output.patch();
|
92 | heimdall.stop(token);
|
93 | }
|
94 | resetCaches() {
|
95 | this.resolver.reset();
|
96 | this.input.reset();
|
97 | }
|
98 | }
|
99 |
|
\ | No newline at end of file |