1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
22 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
23 | };
|
24 | Object.defineProperty(exports, "__esModule", { value: true });
|
25 | exports.clearParseAndGenerateServicesCalls = exports.clearProgramCache = exports.parseWithNodeMaps = exports.parseAndGenerateServices = exports.parse = void 0;
|
26 | const debug_1 = __importDefault(require("debug"));
|
27 | const globby_1 = require("globby");
|
28 | const is_glob_1 = __importDefault(require("is-glob"));
|
29 | const semver_1 = __importDefault(require("semver"));
|
30 | const path_1 = require("path");
|
31 | const ts = __importStar(require("typescript"));
|
32 | const ast_converter_1 = require("./ast-converter");
|
33 | const convert_1 = require("./convert");
|
34 | const createDefaultProgram_1 = require("./create-program/createDefaultProgram");
|
35 | const createIsolatedProgram_1 = require("./create-program/createIsolatedProgram");
|
36 | const createProjectProgram_1 = require("./create-program/createProjectProgram");
|
37 | const createSourceFile_1 = require("./create-program/createSourceFile");
|
38 | const semantic_or_syntactic_errors_1 = require("./semantic-or-syntactic-errors");
|
39 | const shared_1 = require("./create-program/shared");
|
40 | const useProvidedPrograms_1 = require("./create-program/useProvidedPrograms");
|
41 | const log = (0, debug_1.default)('typescript-eslint:typescript-estree:parser');
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | const SUPPORTED_TYPESCRIPT_VERSIONS = '>=3.3.1 <4.6.0';
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | const SUPPORTED_PRERELEASE_RANGES = ['4.5.0-beta', '4.5.1-rc'];
|
52 | const ACTIVE_TYPESCRIPT_VERSION = ts.version;
|
53 | const isRunningSupportedTypeScriptVersion = semver_1.default.satisfies(ACTIVE_TYPESCRIPT_VERSION, [SUPPORTED_TYPESCRIPT_VERSIONS]
|
54 | .concat(SUPPORTED_PRERELEASE_RANGES)
|
55 | .join(' || '));
|
56 | let extra;
|
57 | let warnedAboutTSVersion = false;
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | const existingPrograms = new Map();
|
64 | function clearProgramCache() {
|
65 | existingPrograms.clear();
|
66 | }
|
67 | exports.clearProgramCache = clearProgramCache;
|
68 | function enforceString(code) {
|
69 | |
70 |
|
71 |
|
72 | if (typeof code !== 'string') {
|
73 | return String(code);
|
74 | }
|
75 | return code;
|
76 | }
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | function getProgramAndAST(code, programInstances, shouldProvideParserServices, shouldCreateDefaultProgram) {
|
85 | return ((programInstances && (0, useProvidedPrograms_1.useProvidedPrograms)(programInstances, extra)) ||
|
86 | (shouldProvideParserServices &&
|
87 | (0, createProjectProgram_1.createProjectProgram)(code, shouldCreateDefaultProgram, extra)) ||
|
88 | (shouldProvideParserServices &&
|
89 | shouldCreateDefaultProgram &&
|
90 | (0, createDefaultProgram_1.createDefaultProgram)(code, extra)) ||
|
91 | (0, createIsolatedProgram_1.createIsolatedProgram)(code, extra));
|
92 | }
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 | function getFileName({ jsx } = {}) {
|
102 | return jsx ? 'estree.tsx' : 'estree.ts';
|
103 | }
|
104 |
|
105 |
|
106 |
|
107 | function resetExtra() {
|
108 | extra = {
|
109 | code: '',
|
110 | comment: false,
|
111 | comments: [],
|
112 | createDefaultProgram: false,
|
113 | debugLevel: new Set(),
|
114 | errorOnTypeScriptSyntacticAndSemanticIssues: false,
|
115 | errorOnUnknownASTType: false,
|
116 | EXPERIMENTAL_useSourceOfProjectReferenceRedirect: false,
|
117 | extraFileExtensions: [],
|
118 | filePath: getFileName(),
|
119 | jsx: false,
|
120 | loc: false,
|
121 | log: console.log,
|
122 | preserveNodeMaps: true,
|
123 | programs: null,
|
124 | projects: [],
|
125 | range: false,
|
126 | strict: false,
|
127 | tokens: null,
|
128 | tsconfigRootDir: process.cwd(),
|
129 | |
130 |
|
131 |
|
132 |
|
133 | singleRun: false,
|
134 | moduleResolver: '',
|
135 | };
|
136 | }
|
137 | function getTsconfigPath(tsconfigPath, extra) {
|
138 | return (0, shared_1.getCanonicalFileName)((0, shared_1.ensureAbsolutePath)(tsconfigPath, extra));
|
139 | }
|
140 |
|
141 |
|
142 |
|
143 | function prepareAndTransformProjects(projectsInput, ignoreListInput) {
|
144 | const sanitizedProjects = [];
|
145 |
|
146 | if (typeof projectsInput === 'string') {
|
147 | sanitizedProjects.push(projectsInput);
|
148 | }
|
149 | else if (Array.isArray(projectsInput)) {
|
150 | for (const project of projectsInput) {
|
151 | if (typeof project === 'string') {
|
152 | sanitizedProjects.push(project);
|
153 | }
|
154 | }
|
155 | }
|
156 | if (sanitizedProjects.length === 0) {
|
157 | return [];
|
158 | }
|
159 |
|
160 | const nonGlobProjects = sanitizedProjects.filter(project => !(0, is_glob_1.default)(project));
|
161 | const globProjects = sanitizedProjects.filter(project => (0, is_glob_1.default)(project));
|
162 | const uniqueCanonicalProjectPaths = new Set(nonGlobProjects
|
163 | .concat((0, globby_1.sync)([...globProjects, ...ignoreListInput], {
|
164 | cwd: extra.tsconfigRootDir,
|
165 | }))
|
166 | .map(project => getTsconfigPath(project, extra)));
|
167 | log('parserOptions.project (excluding ignored) matched projects: %s', uniqueCanonicalProjectPaths);
|
168 | return Array.from(uniqueCanonicalProjectPaths);
|
169 | }
|
170 | function applyParserOptionsToExtra(options) {
|
171 | var _a;
|
172 | |
173 |
|
174 |
|
175 | if (options.debugLevel === true) {
|
176 | extra.debugLevel = new Set(['typescript-eslint']);
|
177 | }
|
178 | else if (Array.isArray(options.debugLevel)) {
|
179 | extra.debugLevel = new Set(options.debugLevel);
|
180 | }
|
181 | if (extra.debugLevel.size > 0) {
|
182 |
|
183 | const namespaces = [];
|
184 | if (extra.debugLevel.has('typescript-eslint')) {
|
185 | namespaces.push('typescript-eslint:*');
|
186 | }
|
187 | if (extra.debugLevel.has('eslint') ||
|
188 |
|
189 | debug_1.default.enabled('eslint:*,-eslint:code-path')) {
|
190 |
|
191 | namespaces.push('eslint:*,-eslint:code-path');
|
192 | }
|
193 | debug_1.default.enable(namespaces.join(','));
|
194 | }
|
195 | |
196 |
|
197 |
|
198 | extra.range = typeof options.range === 'boolean' && options.range;
|
199 | extra.loc = typeof options.loc === 'boolean' && options.loc;
|
200 | |
201 |
|
202 |
|
203 | if (typeof options.tokens === 'boolean' && options.tokens) {
|
204 | extra.tokens = [];
|
205 | }
|
206 | |
207 |
|
208 |
|
209 | if (typeof options.comment === 'boolean' && options.comment) {
|
210 | extra.comment = true;
|
211 | extra.comments = [];
|
212 | }
|
213 | |
214 |
|
215 |
|
216 | if (typeof options.jsx === 'boolean' && options.jsx) {
|
217 | extra.jsx = true;
|
218 | }
|
219 | |
220 |
|
221 |
|
222 | if (typeof options.filePath === 'string' && options.filePath !== '<input>') {
|
223 | extra.filePath = options.filePath;
|
224 | }
|
225 | else {
|
226 | extra.filePath = getFileName(extra);
|
227 | }
|
228 | |
229 |
|
230 |
|
231 |
|
232 | if (typeof options.errorOnUnknownASTType === 'boolean' &&
|
233 | options.errorOnUnknownASTType) {
|
234 | extra.errorOnUnknownASTType = true;
|
235 | }
|
236 | |
237 |
|
238 |
|
239 | if (typeof options.loggerFn === 'function') {
|
240 | extra.log = options.loggerFn;
|
241 | }
|
242 | else if (options.loggerFn === false) {
|
243 | extra.log = () => { };
|
244 | }
|
245 | if (typeof options.tsconfigRootDir === 'string') {
|
246 | extra.tsconfigRootDir = options.tsconfigRootDir;
|
247 | }
|
248 |
|
249 | extra.filePath = (0, shared_1.ensureAbsolutePath)(extra.filePath, extra);
|
250 | if (Array.isArray(options.programs)) {
|
251 | if (!options.programs.length) {
|
252 | throw new Error(`You have set parserOptions.programs to an empty array. This will cause all files to not be found in existing programs. Either provide one or more existing TypeScript Program instances in the array, or remove the parserOptions.programs setting.`);
|
253 | }
|
254 | extra.programs = options.programs;
|
255 | log('parserOptions.programs was provided, so parserOptions.project will be ignored.');
|
256 | }
|
257 | if (!extra.programs) {
|
258 |
|
259 | const projectFolderIgnoreList = ((_a = options.projectFolderIgnoreList) !== null && _a !== void 0 ? _a : ['**/node_modules/**'])
|
260 | .reduce((acc, folder) => {
|
261 | if (typeof folder === 'string') {
|
262 | acc.push(folder);
|
263 | }
|
264 | return acc;
|
265 | }, [])
|
266 |
|
267 | .map(folder => (folder.startsWith('!') ? folder : `!${folder}`));
|
268 |
|
269 | extra.projects = prepareAndTransformProjects(options.project, projectFolderIgnoreList);
|
270 | }
|
271 | if (Array.isArray(options.extraFileExtensions) &&
|
272 | options.extraFileExtensions.every(ext => typeof ext === 'string')) {
|
273 | extra.extraFileExtensions = options.extraFileExtensions;
|
274 | }
|
275 | |
276 |
|
277 |
|
278 |
|
279 | if (typeof options.preserveNodeMaps === 'boolean') {
|
280 | extra.preserveNodeMaps = options.preserveNodeMaps;
|
281 | }
|
282 | extra.createDefaultProgram =
|
283 | typeof options.createDefaultProgram === 'boolean' &&
|
284 | options.createDefaultProgram;
|
285 | extra.EXPERIMENTAL_useSourceOfProjectReferenceRedirect =
|
286 | typeof options.EXPERIMENTAL_useSourceOfProjectReferenceRedirect ===
|
287 | 'boolean' && options.EXPERIMENTAL_useSourceOfProjectReferenceRedirect;
|
288 | if (typeof options.moduleResolver === 'string') {
|
289 | extra.moduleResolver = options.moduleResolver;
|
290 | }
|
291 | }
|
292 | function warnAboutTSVersion() {
|
293 | var _a;
|
294 | if (!isRunningSupportedTypeScriptVersion && !warnedAboutTSVersion) {
|
295 | const isTTY = typeof process === 'undefined' ? false : (_a = process.stdout) === null || _a === void 0 ? void 0 : _a.isTTY;
|
296 | if (isTTY) {
|
297 | const border = '=============';
|
298 | const versionWarning = [
|
299 | border,
|
300 | 'WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.',
|
301 | 'You may find that it works just fine, or you may not.',
|
302 | `SUPPORTED TYPESCRIPT VERSIONS: ${SUPPORTED_TYPESCRIPT_VERSIONS}`,
|
303 | `YOUR TYPESCRIPT VERSION: ${ACTIVE_TYPESCRIPT_VERSION}`,
|
304 | 'Please only submit bug reports when using the officially supported version.',
|
305 | border,
|
306 | ];
|
307 | extra.log(versionWarning.join('\n\n'));
|
308 | }
|
309 | warnedAboutTSVersion = true;
|
310 | }
|
311 | }
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 | function inferSingleRun(options) {
|
323 |
|
324 | if (process.env.TSESTREE_SINGLE_RUN === 'false') {
|
325 | extra.singleRun = false;
|
326 | return;
|
327 | }
|
328 | if (process.env.TSESTREE_SINGLE_RUN === 'true') {
|
329 | extra.singleRun = true;
|
330 | return;
|
331 | }
|
332 |
|
333 | if (options === null || options === void 0 ? void 0 : options.allowAutomaticSingleRunInference) {
|
334 | if (
|
335 |
|
336 | process.env.CI === 'true' ||
|
337 |
|
338 | process.argv[1].endsWith((0, path_1.normalize)('node_modules/.bin/eslint'))) {
|
339 | extra.singleRun = true;
|
340 | return;
|
341 | }
|
342 | }
|
343 | |
344 |
|
345 |
|
346 |
|
347 | extra.singleRun = false;
|
348 | }
|
349 | function parse(code, options) {
|
350 | const { ast } = parseWithNodeMapsInternal(code, options, false);
|
351 | return ast;
|
352 | }
|
353 | exports.parse = parse;
|
354 | function parseWithNodeMapsInternal(code, options, shouldPreserveNodeMaps) {
|
355 | |
356 |
|
357 |
|
358 | resetExtra();
|
359 | |
360 |
|
361 |
|
362 | if (options === null || options === void 0 ? void 0 : options.errorOnTypeScriptSyntacticAndSemanticIssues) {
|
363 | throw new Error(`"errorOnTypeScriptSyntacticAndSemanticIssues" is only supported for parseAndGenerateServices()`);
|
364 | }
|
365 | |
366 |
|
367 |
|
368 | code = enforceString(code);
|
369 | extra.code = code;
|
370 | |
371 |
|
372 |
|
373 | if (typeof options !== 'undefined') {
|
374 | applyParserOptionsToExtra(options);
|
375 | }
|
376 | |
377 |
|
378 |
|
379 | warnAboutTSVersion();
|
380 | |
381 |
|
382 |
|
383 | inferSingleRun(options);
|
384 | |
385 |
|
386 |
|
387 |
|
388 | const ast = (0, createSourceFile_1.createSourceFile)(code, extra);
|
389 | |
390 |
|
391 |
|
392 | const { estree, astMaps } = (0, ast_converter_1.astConverter)(ast, extra, shouldPreserveNodeMaps);
|
393 | return {
|
394 | ast: estree,
|
395 | esTreeNodeToTSNodeMap: astMaps.esTreeNodeToTSNodeMap,
|
396 | tsNodeToESTreeNodeMap: astMaps.tsNodeToESTreeNodeMap,
|
397 | };
|
398 | }
|
399 | function parseWithNodeMaps(code, options) {
|
400 | return parseWithNodeMapsInternal(code, options, true);
|
401 | }
|
402 | exports.parseWithNodeMaps = parseWithNodeMaps;
|
403 | let parseAndGenerateServicesCalls = {};
|
404 |
|
405 | function clearParseAndGenerateServicesCalls() {
|
406 | parseAndGenerateServicesCalls = {};
|
407 | }
|
408 | exports.clearParseAndGenerateServicesCalls = clearParseAndGenerateServicesCalls;
|
409 | function parseAndGenerateServices(code, options) {
|
410 | var _a;
|
411 | |
412 |
|
413 |
|
414 | resetExtra();
|
415 | |
416 |
|
417 |
|
418 | code = enforceString(code);
|
419 | extra.code = code;
|
420 | |
421 |
|
422 |
|
423 | if (typeof options !== 'undefined') {
|
424 | applyParserOptionsToExtra(options);
|
425 | if (typeof options.errorOnTypeScriptSyntacticAndSemanticIssues ===
|
426 | 'boolean' &&
|
427 | options.errorOnTypeScriptSyntacticAndSemanticIssues) {
|
428 | extra.errorOnTypeScriptSyntacticAndSemanticIssues = true;
|
429 | }
|
430 | }
|
431 | |
432 |
|
433 |
|
434 | warnAboutTSVersion();
|
435 | |
436 |
|
437 |
|
438 | inferSingleRun(options);
|
439 | |
440 |
|
441 |
|
442 |
|
443 |
|
444 | if (extra.singleRun && !extra.programs && ((_a = extra.projects) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
445 | extra.programs = {
|
446 | *[Symbol.iterator]() {
|
447 | for (const configFile of extra.projects) {
|
448 | const existingProgram = existingPrograms.get(configFile);
|
449 | if (existingProgram) {
|
450 | yield existingProgram;
|
451 | }
|
452 | else {
|
453 | log('Detected single-run/CLI usage, creating Program once ahead of time for project: %s', configFile);
|
454 | const newProgram = (0, useProvidedPrograms_1.createProgramFromConfigFile)(configFile);
|
455 | existingPrograms.set(configFile, newProgram);
|
456 | yield newProgram;
|
457 | }
|
458 | }
|
459 | },
|
460 | };
|
461 | }
|
462 | |
463 |
|
464 |
|
465 | const shouldProvideParserServices = extra.programs != null || (extra.projects && extra.projects.length > 0);
|
466 | |
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 |
|
473 |
|
474 | let ast;
|
475 | let program;
|
476 | if (extra.singleRun && options.filePath) {
|
477 | parseAndGenerateServicesCalls[options.filePath] =
|
478 | (parseAndGenerateServicesCalls[options.filePath] || 0) + 1;
|
479 | }
|
480 | if (extra.singleRun &&
|
481 | options.filePath &&
|
482 | parseAndGenerateServicesCalls[options.filePath] > 1) {
|
483 | const isolatedAstAndProgram = (0, createIsolatedProgram_1.createIsolatedProgram)(code, extra);
|
484 | ast = isolatedAstAndProgram.ast;
|
485 | program = isolatedAstAndProgram.program;
|
486 | }
|
487 | else {
|
488 | const astAndProgram = getProgramAndAST(code, extra.programs, shouldProvideParserServices, extra.createDefaultProgram);
|
489 | ast = astAndProgram.ast;
|
490 | program = astAndProgram.program;
|
491 | }
|
492 | |
493 |
|
494 |
|
495 |
|
496 | const preserveNodeMaps = typeof extra.preserveNodeMaps === 'boolean' ? extra.preserveNodeMaps : true;
|
497 | const { estree, astMaps } = (0, ast_converter_1.astConverter)(ast, extra, preserveNodeMaps);
|
498 | |
499 |
|
500 |
|
501 |
|
502 | if (program && extra.errorOnTypeScriptSyntacticAndSemanticIssues) {
|
503 | const error = (0, semantic_or_syntactic_errors_1.getFirstSemanticOrSyntacticError)(program, ast);
|
504 | if (error) {
|
505 | throw (0, convert_1.convertError)(error);
|
506 | }
|
507 | }
|
508 | |
509 |
|
510 |
|
511 | return {
|
512 | ast: estree,
|
513 | services: {
|
514 | hasFullTypeInformation: shouldProvideParserServices,
|
515 | program,
|
516 | esTreeNodeToTSNodeMap: astMaps.esTreeNodeToTSNodeMap,
|
517 | tsNodeToESTreeNodeMap: astMaps.tsNodeToESTreeNodeMap,
|
518 | },
|
519 | };
|
520 | }
|
521 | exports.parseAndGenerateServices = parseAndGenerateServices;
|
522 |
|
\ | No newline at end of file |