82 lines
2.1 KiB
Plaintext
82 lines
2.1 KiB
Plaintext
|
/**
|
||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*
|
||
|
* @flow strict-local
|
||
|
* @format
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
import type {ParserOptions} from 'hermes-parser';
|
||
|
|
||
|
import * as HermesParser from 'hermes-parser';
|
||
|
|
||
|
type Options = {
|
||
|
/**
|
||
|
* When set to 'flow', will check files for a `@flow` annotation to apply
|
||
|
* this plugin, otherwise falling back to Babel's parser.
|
||
|
*
|
||
|
* This is independent of `parserOpts.flow`, which may customise 'detect'
|
||
|
* behaviour within hermes-parser (downstream from this plugin).
|
||
|
*
|
||
|
* Defaults to 'all'.
|
||
|
*/
|
||
|
parseLangTypes?: 'flow' | 'all',
|
||
|
};
|
||
|
|
||
|
export default function BabelPluginSyntaxHermesParser(
|
||
|
// $FlowExpectedError[unclear-type] We don't have types for this.
|
||
|
api: any,
|
||
|
options: Options,
|
||
|
): $ReadOnly<{...}> {
|
||
|
api.assertVersion('^7.0.0 || ^8.0.0-alpha.6');
|
||
|
|
||
|
const {parseLangTypes = 'all'} = options;
|
||
|
|
||
|
let curParserOpts: ParserOptions = {};
|
||
|
let curFilename: ?string = null;
|
||
|
|
||
|
return {
|
||
|
name: 'syntax-hermes-parser',
|
||
|
|
||
|
manipulateOptions(
|
||
|
opts: $ReadOnly<{parserOpts: ParserOptions, filename?: ?string}>,
|
||
|
) {
|
||
|
curParserOpts = opts.parserOpts;
|
||
|
curFilename = opts.filename;
|
||
|
},
|
||
|
|
||
|
// API suggested via https://babeljs.io/docs/babel-parser#will-the-babel-parser-support-a-plugin-system
|
||
|
parserOverride(code: string) {
|
||
|
const filename = curFilename;
|
||
|
if (
|
||
|
filename != null &&
|
||
|
(filename.endsWith('.ts') || filename.endsWith('.tsx'))
|
||
|
) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const parserOpts: ParserOptions = {};
|
||
|
for (const [key, value] of Object.entries(curParserOpts)) {
|
||
|
if (HermesParser.ParserOptionsKeys.has(key)) {
|
||
|
// $FlowExpectedError[incompatible-type]
|
||
|
parserOpts[key] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (parseLangTypes === 'flow' && !/@flow/.test(code)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
return HermesParser.parse(code, {...parserOpts, babel: true});
|
||
|
},
|
||
|
|
||
|
pre() {
|
||
|
curParserOpts = {};
|
||
|
},
|
||
|
};
|
||
|
}
|