blob: 9cc2380b3aa12fea44501e4b19d2c605db8634c1 [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.
38 // https://github.com/benmosher/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') {
55 console.warn(
56 '`parseForESLint` from parser `' +
57 parserPath +
58 '` is invalid and will just be ignored'
Tim van der Lippe2c891972021-07-29 16:22:50 +010059 );
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010060 } else {
Tim van der Lippe2c891972021-07-29 16:22:50 +010061 return ast;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010062 }
63 }
64
Tim van der Lippe2c891972021-07-29 16:22:50 +010065 return parser.parse(content, parserOptions);
66};
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010067
68function getParserPath(path, context) {
Tim van der Lippe2c891972021-07-29 16:22:50 +010069 const parsers = context.settings['import/parsers'];
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010070 if (parsers != null) {
Tim van der Lippe2c891972021-07-29 16:22:50 +010071 const extension = extname(path);
72 for (const parserPath in parsers) {
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010073 if (parsers[parserPath].indexOf(extension) > -1) {
74 // use this alternate parser
Tim van der Lippe2c891972021-07-29 16:22:50 +010075 log('using alt parser:', parserPath);
76 return parserPath;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010077 }
78 }
79 }
80 // default to use ESLint parser
Tim van der Lippe2c891972021-07-29 16:22:50 +010081 return context.parserPath;
Tim van der Lippefdbd42e2020-04-07 15:14:36 +010082}