blob: 3b2ac028f0485fcfab9ac558b38f19cc7312beb6 [file] [log] [blame]
Tim van der Lippe2c891972021-07-29 16:22:50 +01001'use strict';
2exports.__esModule = true;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +01003
Tim van der Lippe2c891972021-07-29 16:22:50 +01004const moduleRequire = require('./module-require').default;
5const extname = require('path').extname;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +01006
Tim van der Lippe2c891972021-07-29 16:22:50 +01007const log = require('debug')('eslint-plugin-import:parse');
Tim van der Lippefdbd42e2020-04-07 15:14:36 +01008
9exports.default = function parse(path, content, context) {
10
Tim van der Lippe2c891972021-07-29 16:22:50 +010011 if (context == null) throw new Error('need context to parse properly');
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010012
Tim van der Lippe2c891972021-07-29 16:22:50 +010013 let parserOptions = context.parserOptions;
14 const parserPath = getParserPath(path, context);
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010015
Tim van der Lippe2c891972021-07-29 16:22:50 +010016 if (!parserPath) throw new Error('parserPath is required!');
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010017
18 // hack: espree blows up with frozen options
Tim van der Lippe2c891972021-07-29 16:22:50 +010019 parserOptions = Object.assign({}, parserOptions);
20 parserOptions.ecmaFeatures = Object.assign({}, parserOptions.ecmaFeatures);
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010021
22 // always include comments and tokens (for doc parsing)
Tim van der Lippe2c891972021-07-29 16:22:50 +010023 parserOptions.comment = true;
24 parserOptions.attachComment = true; // keeping this for backward-compat with older parsers
25 parserOptions.tokens = true;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010026
27 // attach node locations
Tim van der Lippe2c891972021-07-29 16:22:50 +010028 parserOptions.loc = true;
29 parserOptions.range = true;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010030
31 // provide the `filePath` like eslint itself does, in `parserOptions`
32 // https://github.com/eslint/eslint/blob/3ec436ee/lib/linter.js#L637
Tim van der Lippe2c891972021-07-29 16:22:50 +010033 parserOptions.filePath = path;
34
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010035 // @typescript-eslint/parser will parse the entire project with typechecking if you provide
36 // "project" or "projects" in parserOptions. Removing these options means the parser will
37 // only parse one file in isolate mode, which is much, much faster.
Tim van der Lippea6619412021-09-13 14:28:55 +020038 // https://github.com/import-js/eslint-plugin-import/issues/1408#issuecomment-509298962
Tim van der Lippe2c891972021-07-29 16:22:50 +010039 delete parserOptions.project;
40 delete parserOptions.projects;
41
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010042 // require the parser relative to the main module (i.e., ESLint)
Tim van der Lippe2c891972021-07-29 16:22:50 +010043 const parser = moduleRequire(parserPath);
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010044
45 if (typeof parser.parseForESLint === 'function') {
Tim van der Lippe2c891972021-07-29 16:22:50 +010046 let ast;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010047 try {
Tim van der Lippe2c891972021-07-29 16:22:50 +010048 ast = parser.parseForESLint(content, parserOptions).ast;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010049 } catch (e) {
Tim van der Lippe2c891972021-07-29 16:22:50 +010050 console.warn();
51 console.warn('Error while parsing ' + parserOptions.filePath);
52 console.warn('Line ' + e.lineNumber + ', column ' + e.column + ': ' + e.message);
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010053 }
54 if (!ast || typeof ast !== 'object') {
Tim van der Lippea6619412021-09-13 14:28:55 +020055 console.warn('`parseForESLint` from parser `' + parserPath + '` is invalid and will just be ignored');
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010056 } else {
Tim van der Lippe2c891972021-07-29 16:22:50 +010057 return ast;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010058 }
59 }
60
Tim van der Lippe2c891972021-07-29 16:22:50 +010061 return parser.parse(content, parserOptions);
62};
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010063
64function getParserPath(path, context) {
Tim van der Lippe2c891972021-07-29 16:22:50 +010065 const parsers = context.settings['import/parsers'];
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010066 if (parsers != null) {
Tim van der Lippe2c891972021-07-29 16:22:50 +010067 const extension = extname(path);
68 for (const parserPath in parsers) {
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010069 if (parsers[parserPath].indexOf(extension) > -1) {
70 // use this alternate parser
Tim van der Lippe2c891972021-07-29 16:22:50 +010071 log('using alt parser:', parserPath);
72 return parserPath;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010073 }
74 }
75 }
76 // default to use ESLint parser
Tim van der Lippe2c891972021-07-29 16:22:50 +010077 return context.parserPath;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010078}