Skip to content

Commit 0642419

Browse files
michaelfaithljharb
authored andcommitted
[utils] [fix] parse: add ecmaVersion and sourceType to parserOptions
This change adds `ecmaVersion` and `sourceType` to the options we're passing to the parsers, if they're present on `languageOptions` (which would only be the case for flat config).
1 parent 6075b9c commit 0642419

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

tests/src/core/parse.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,18 @@ describe('parse(content, { settings, ecmaFeatures })', function () {
138138
parseStubParser.parse = parseSpy;
139139
expect(parse.bind(null, path, content, { settings: {}, parserPath: 'espree', languageOptions: { parserOptions: { sourceType: 'module', ecmaVersion: 2015, ecmaFeatures: { jsx: true } } }, parserOptions: { sourceType: 'script' } })).not.to.throw(Error);
140140
});
141+
142+
it('passes ecmaVersion and sourceType from languageOptions to parser', () => {
143+
const parseSpy = sinon.spy();
144+
const languageOptions = { ecmaVersion: 'latest', sourceType: 'module', parserOptions: { ecmaFeatures: { jsx: true } } };
145+
parseStubParser.parse = parseSpy;
146+
parse(path, content, { settings: {}, parserPath: parseStubParserPath, languageOptions });
147+
expect(parseSpy.args[0][1], 'custom parser to clone the parserOptions object').to.not.equal(languageOptions);
148+
expect(parseSpy.args[0][1], 'custom parser to get ecmaFeatures in parserOptions which is a clone of ecmaFeatures passed in')
149+
.to.have.property('ecmaFeatures')
150+
.that.is.eql(languageOptions.parserOptions.ecmaFeatures)
151+
.and.is.not.equal(languageOptions.parserOptions.ecmaFeatures);
152+
expect(parseSpy.args[0][1], 'custom parser to get ecmaVersion in parserOptions from languageOptions').to.have.property('ecmaVersion', languageOptions.ecmaVersion);
153+
expect(parseSpy.args[0][1], 'custom parser to get sourceType in parserOptions from languageOptions').to.have.property('sourceType', languageOptions.sourceType);
154+
});
141155
});

utils/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
88
### Fixed
99
- `parse`: remove unneeded extra backticks ([#3057], thanks [@G-Rath])
1010
- `parse`: espree parser isn't working with flat config ([#3061], thanks [@michaelfaith])
11+
- `parse`: add `ecmaVersion` and `sourceType` to `parserOptions` ([#3061], thanks [@michaelfaith])
1112

1213
## v2.11.0 - 2024-09-05
1314

utils/parse.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function keysFromParser(parserPath, parserInstance, parsedResult) {
3636
if (typeof parserPath === 'string' && (/.*babel-eslint.*/).test(parserPath)) {
3737
return getBabelEslintVisitorKeys(parserPath);
3838
}
39-
// The espree parser doesn't have the `parseForESLint` function, so we don't ended up with a
39+
// The espree parser doesn't have the `parseForESLint` function, so we don't end up with a
4040
// `parsedResult` here, but it does expose the visitor keys on the parser instance that we can use.
4141
if (parserInstance && parserInstance.VisitorKeys) {
4242
return parserInstance.VisitorKeys;
@@ -113,7 +113,8 @@ exports.default = function parse(path, content, context) {
113113
if (context == null) { throw new Error('need context to parse properly'); }
114114

115115
// ESLint in "flat" mode only sets context.languageOptions.parserOptions
116-
let parserOptions = context.languageOptions && context.languageOptions.parserOptions || context.parserOptions;
116+
const languageOptions = context.languageOptions;
117+
let parserOptions = languageOptions && languageOptions.parserOptions || context.parserOptions;
117118
const parserOrPath = getParser(path, context);
118119

119120
if (!parserOrPath) { throw new Error('parserPath or languageOptions.parser is required!'); }
@@ -144,6 +145,17 @@ exports.default = function parse(path, content, context) {
144145
delete parserOptions.project;
145146
delete parserOptions.projects;
146147

148+
// If this is a flat config, we need to add ecmaVersion and sourceType (if present) from languageOptions
149+
if (languageOptions && languageOptions.ecmaVersion) {
150+
parserOptions.ecmaVersion = languageOptions.ecmaVersion;
151+
}
152+
if (languageOptions && languageOptions.sourceType) {
153+
// @ts-expect-error languageOptions is from the flatConfig Linter type in 8.57 while parserOptions is not.
154+
// Non-flat config parserOptions.sourceType doesn't have "commonjs" in the type. Once upgraded to v9 types,
155+
// they'll be the same and this expect-error should be removed.
156+
parserOptions.sourceType = languageOptions.sourceType;
157+
}
158+
147159
// require the parser relative to the main module (i.e., ESLint)
148160
const parser = typeof parserOrPath === 'string' ? moduleRequire(parserOrPath) : parserOrPath;
149161

0 commit comments

Comments
 (0)