Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / @typescript-eslint / typescript-estree / dist / tsconfig-parser.js
1 "use strict";
2 var __importDefault = (this && this.__importDefault) || function (mod) {
3     return (mod && mod.__esModule) ? mod : { "default": mod };
4 };
5 var __importStar = (this && this.__importStar) || function (mod) {
6     if (mod && mod.__esModule) return mod;
7     var result = {};
8     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
9     result["default"] = mod;
10     return result;
11 };
12 Object.defineProperty(exports, "__esModule", { value: true });
13 const chokidar_1 = __importDefault(require("chokidar"));
14 const path_1 = __importDefault(require("path"));
15 const ts = __importStar(require("typescript")); // leave this as * as ts so people using util package don't need syntheticDefaultImports
16 //------------------------------------------------------------------------------
17 // Environment calculation
18 //------------------------------------------------------------------------------
19 /**
20  * Default compiler options for program generation from single root file
21  */
22 exports.defaultCompilerOptions = {
23     allowNonTsExtensions: true,
24     allowJs: true,
25     checkJs: true,
26     noEmit: true,
27 };
28 /**
29  * Maps tsconfig paths to their corresponding file contents and resulting watches
30  */
31 const knownWatchProgramMap = new Map();
32 /**
33  * Maps file paths to their set of corresponding watch callbacks
34  * There may be more than one per file if a file is shared between projects
35  */
36 const watchCallbackTrackingMap = new Map();
37 /**
38  * Tracks the ts.sys.watchFile watchers that we've opened for config files.
39  * We store these so we can clean up our handles if required.
40  */
41 const configSystemFileWatcherTrackingSet = new Set();
42 /**
43  * Tracks the ts.sys.watchDirectory watchers that we've opened for project folders.
44  * We store these so we can clean up our handles if required.
45  */
46 const directorySystemFileWatcherTrackingSet = new Set();
47 const parsedFilesSeen = new Set();
48 /**
49  * Clear all of the parser caches.
50  * This should only be used in testing to ensure the parser is clean between tests.
51  */
52 function clearCaches() {
53     knownWatchProgramMap.clear();
54     watchCallbackTrackingMap.clear();
55     parsedFilesSeen.clear();
56     // stop tracking config files
57     configSystemFileWatcherTrackingSet.forEach(cb => cb.close());
58     configSystemFileWatcherTrackingSet.clear();
59     // stop tracking folders
60     directorySystemFileWatcherTrackingSet.forEach(cb => cb.close());
61     directorySystemFileWatcherTrackingSet.clear();
62 }
63 exports.clearCaches = clearCaches;
64 /**
65  * Holds information about the file currently being linted
66  */
67 const currentLintOperationState = {
68     code: '',
69     filePath: '',
70 };
71 /**
72  * Appropriately report issues found when reading a config file
73  * @param diagnostic The diagnostic raised when creating a program
74  */
75 function diagnosticReporter(diagnostic) {
76     throw new Error(ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine));
77 }
78 function getTsconfigPath(tsconfigPath, extra) {
79     return path_1.default.isAbsolute(tsconfigPath)
80         ? tsconfigPath
81         : path_1.default.join(extra.tsconfigRootDir || process.cwd(), tsconfigPath);
82 }
83 /**
84  * Watches a file or directory for changes
85  */
86 function watch(path, options, extra) {
87     // an escape hatch to disable the file watchers as they can take a bit to initialise in some cases
88     // this also supports an env variable so it's easy to switch on/off from the CLI
89     if (process.env.PARSER_NO_WATCH === 'true' || extra.noWatch === true) {
90         return {
91             close: () => { },
92             on: () => { },
93         };
94     }
95     return chokidar_1.default.watch(path, Object.assign({ ignoreInitial: true, persistent: false, useFsEvents: false }, options));
96 }
97 /**
98  * Calculate project environments using options provided by consumer and paths from config
99  * @param code The code being linted
100  * @param filePath The path of the file being parsed
101  * @param extra.tsconfigRootDir The root directory for relative tsconfig paths
102  * @param extra.projects Provided tsconfig paths
103  * @returns The programs corresponding to the supplied tsconfig paths
104  */
105 function calculateProjectParserOptions(code, filePath, extra) {
106     const results = [];
107     // preserve reference to code and file being linted
108     currentLintOperationState.code = code;
109     currentLintOperationState.filePath = filePath;
110     // Update file version if necessary
111     // TODO: only update when necessary, currently marks as changed on every lint
112     const watchCallbacks = watchCallbackTrackingMap.get(filePath);
113     if (parsedFilesSeen.has(filePath) &&
114         watchCallbacks &&
115         watchCallbacks.size > 0) {
116         watchCallbacks.forEach(cb => cb(filePath, ts.FileWatcherEventKind.Changed));
117     }
118     for (const rawTsconfigPath of extra.projects) {
119         const tsconfigPath = getTsconfigPath(rawTsconfigPath, extra);
120         const existingWatch = knownWatchProgramMap.get(tsconfigPath);
121         if (typeof existingWatch !== 'undefined') {
122             // get new program (updated if necessary)
123             const updatedProgram = existingWatch.getProgram().getProgram();
124             updatedProgram.getTypeChecker(); // sets parent pointers in source files
125             results.push(updatedProgram);
126             continue;
127         }
128         // create compiler host
129         const watchCompilerHost = ts.createWatchCompilerHost(tsconfigPath, exports.defaultCompilerOptions, ts.sys, ts.createSemanticDiagnosticsBuilderProgram, diagnosticReporter, 
130         /*reportWatchStatus*/ () => { });
131         // ensure readFile reads the code being linted instead of the copy on disk
132         const oldReadFile = watchCompilerHost.readFile;
133         watchCompilerHost.readFile = (filePath, encoding) => path_1.default.normalize(filePath) ===
134             path_1.default.normalize(currentLintOperationState.filePath)
135             ? currentLintOperationState.code
136             : oldReadFile(filePath, encoding);
137         // ensure process reports error on failure instead of exiting process immediately
138         watchCompilerHost.onUnRecoverableConfigFileDiagnostic = diagnosticReporter;
139         // ensure process doesn't emit programs
140         watchCompilerHost.afterProgramCreate = (program) => {
141             // report error if there are any errors in the config file
142             const configFileDiagnostics = program
143                 .getConfigFileParsingDiagnostics()
144                 .filter(diag => diag.category === ts.DiagnosticCategory.Error &&
145                 diag.code !== 18003);
146             if (configFileDiagnostics.length > 0) {
147                 diagnosticReporter(configFileDiagnostics[0]);
148             }
149         };
150         // in watch mode, eslint will give us the latest file contents
151         // store the watch callback so we can trigger an update with eslint's content
152         watchCompilerHost.watchFile = (fileName, callback, interval) => {
153             // specifically (and separately) watch the tsconfig file
154             // this allows us to react to changes in the tsconfig's include/exclude options
155             let watcher = null;
156             if (fileName.includes(tsconfigPath)) {
157                 watcher = watch(fileName, {
158                     interval,
159                 }, extra);
160                 watcher.on('change', path => {
161                     callback(path, ts.FileWatcherEventKind.Changed);
162                 });
163                 configSystemFileWatcherTrackingSet.add(watcher);
164             }
165             const normalizedFileName = path_1.default.normalize(fileName);
166             const watchers = (() => {
167                 let watchers = watchCallbackTrackingMap.get(normalizedFileName);
168                 if (!watchers) {
169                     watchers = new Set();
170                     watchCallbackTrackingMap.set(normalizedFileName, watchers);
171                 }
172                 return watchers;
173             })();
174             watchers.add(callback);
175             return {
176                 close: () => {
177                     watchers.delete(callback);
178                     if (watcher) {
179                         watcher.close();
180                         configSystemFileWatcherTrackingSet.delete(watcher);
181                     }
182                 },
183             };
184         };
185         // when new files are added in watch mode, we need to tell typescript about those files
186         // if we don't then typescript will act like they don't exist.
187         watchCompilerHost.watchDirectory = (dirPath, callback, recursive) => {
188             const watcher = watch(dirPath, {
189                 depth: recursive ? 0 : undefined,
190                 interval: 250,
191             }, extra);
192             watcher.on('add', path => {
193                 callback(path);
194             });
195             directorySystemFileWatcherTrackingSet.add(watcher);
196             return {
197                 close() {
198                     watcher.close();
199                     directorySystemFileWatcherTrackingSet.delete(watcher);
200                 },
201             };
202         };
203         // allow files with custom extensions to be included in program (uses internal ts api)
204         const oldOnDirectoryStructureHostCreate = watchCompilerHost.onCachedDirectoryStructureHostCreate;
205         watchCompilerHost.onCachedDirectoryStructureHostCreate = (host) => {
206             const oldReadDirectory = host.readDirectory;
207             host.readDirectory = (path, extensions, exclude, include, depth) => oldReadDirectory(path, !extensions
208                 ? undefined
209                 : extensions.concat(extra.extraFileExtensions), exclude, include, depth);
210             oldOnDirectoryStructureHostCreate(host);
211         };
212         // create program
213         const programWatch = ts.createWatchProgram(watchCompilerHost);
214         const program = programWatch.getProgram().getProgram();
215         // cache watch program and return current program
216         knownWatchProgramMap.set(tsconfigPath, programWatch);
217         results.push(program);
218     }
219     parsedFilesSeen.add(filePath);
220     return results;
221 }
222 exports.calculateProjectParserOptions = calculateProjectParserOptions;
223 /**
224  * Create program from single root file. Requires a single tsconfig to be specified.
225  * @param code The code being linted
226  * @param filePath The file being linted
227  * @param extra.tsconfigRootDir The root directory for relative tsconfig paths
228  * @param extra.projects Provided tsconfig paths
229  * @returns The program containing just the file being linted and associated library files
230  */
231 function createProgram(code, filePath, extra) {
232     if (!extra.projects || extra.projects.length !== 1) {
233         return undefined;
234     }
235     const tsconfigPath = getTsconfigPath(extra.projects[0], extra);
236     const commandLine = ts.getParsedCommandLineOfConfigFile(tsconfigPath, exports.defaultCompilerOptions, Object.assign(Object.assign({}, ts.sys), { onUnRecoverableConfigFileDiagnostic: () => { } }));
237     if (!commandLine) {
238         return undefined;
239     }
240     const compilerHost = ts.createCompilerHost(commandLine.options, true);
241     const oldReadFile = compilerHost.readFile;
242     compilerHost.readFile = (fileName) => path_1.default.normalize(fileName) === path_1.default.normalize(filePath)
243         ? code
244         : oldReadFile(fileName);
245     return ts.createProgram([filePath], commandLine.options, compilerHost);
246 }
247 exports.createProgram = createProgram;
248 //# sourceMappingURL=tsconfig-parser.js.map