mirror of
https://github.com/hex248/ob248.com.git
synced 2026-02-08 02:33:02 +00:00
merge new into master
This commit is contained in:
21
node_modules/hermes-parser/LICENSE
generated
vendored
Normal file
21
node_modules/hermes-parser/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
11
node_modules/hermes-parser/README.md
generated
vendored
Normal file
11
node_modules/hermes-parser/README.md
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# hermes-parser
|
||||
A JavaScript parser built from the Hermes engine's parser compiled to WebAssembly. Can parse ES6, Flow, and JSX syntax.
|
||||
|
||||
## API
|
||||
The Hermes parser exposes a single `parse(code, [options])` function, where `code` is the source code to parse as a string, and `options` is an optional object that may contain the following properties:
|
||||
- **babel**: `boolean`, defaults to `false`. If `true`, output an AST conforming to Babel's AST format. If `false`, output an AST conforming to the ESTree AST format.
|
||||
- **allowReturnOutsideFunction**: `boolean`, defaults to `false`. If `true`, do not error on return statements found outside functions.
|
||||
- **flow**: `"all"` or `"detect"`, defaults to `"detect"`. If `"detect"`, only parse syntax as Flow syntax where it is ambiguous whether it is a Flow feature or regular JavaScript when the `@flow` pragma is present in the file. Otherwise if `"all"`, always parse ambiguous syntax as Flow syntax regardless of the presence of an `@flow` pragma. For example `foo<T>(x)` in a file without an `@flow` pragma will be parsed as two comparisons if set to `"detect"`, otherwise if set to `"all"` or the `@flow` pragma is included it will be parsed as a call expression with a type argument.
|
||||
- **sourceFilename**: `string`, defaults to `null`. The filename corresponding to the code that is to be parsed. If non-null, the filename will be added to all source locations in the output AST.
|
||||
- **sourceType**: `"module"`, `"script"`, or `"unambiguous"` (default). If `"unambiguous"`, source type will be automatically detected and set to `"module"` if any ES6 imports or exports are present in the code, otherwise source type will be set to `"script"`.
|
||||
- **tokens**: `boolean`, defaults to `false`. If `true`, add all tokens to a `tokens` property on the root node.
|
||||
57
node_modules/hermes-parser/dist/HermesAST.js.flow
generated
vendored
Normal file
57
node_modules/hermes-parser/dist/HermesAST.js.flow
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
// flowlint unclear-type:off
|
||||
|
||||
export type HermesPosition = {
|
||||
/** >= 1 */
|
||||
+line: number,
|
||||
/** >= 0 */
|
||||
+column: number,
|
||||
};
|
||||
export type HermesSourceLocation = {
|
||||
start?: HermesPosition,
|
||||
end?: HermesPosition,
|
||||
rangeStart?: number,
|
||||
rangeEnd?: number,
|
||||
};
|
||||
export type HermesNode = {
|
||||
type: string,
|
||||
[string]: any,
|
||||
};
|
||||
export type HermesToken = {
|
||||
type:
|
||||
| 'Boolean'
|
||||
| 'Identifier'
|
||||
| 'Keyword'
|
||||
| 'Null'
|
||||
| 'Numeric'
|
||||
| 'BigInt'
|
||||
| 'Punctuator'
|
||||
| 'String'
|
||||
| 'RegularExpression'
|
||||
| 'Template'
|
||||
| 'JSXText',
|
||||
loc: HermesSourceLocation,
|
||||
value: ?string,
|
||||
};
|
||||
export type HermesComment = {
|
||||
type: 'CommentLine' | 'CommentBlock' | 'InterpreterDirective',
|
||||
loc: HermesSourceLocation,
|
||||
value: ?string,
|
||||
};
|
||||
export type HermesProgram = {
|
||||
type: 'Program',
|
||||
loc: HermesSourceLocation,
|
||||
body: Array<?HermesNode>,
|
||||
comments: Array<HermesComment>,
|
||||
tokens?: Array<HermesToken>,
|
||||
interpreter?: ?HermesComment,
|
||||
};
|
||||
193
node_modules/hermes-parser/dist/HermesASTAdapter.js
generated
vendored
Normal file
193
node_modules/hermes-parser/dist/HermesASTAdapter.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _ParserVisitorKeys = require("./generated/ParserVisitorKeys");
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* The base class for transforming the Hermes AST to the desired output format.
|
||||
* Extended by concrete adapters which output an ESTree or Babel AST.
|
||||
*/
|
||||
class HermesASTAdapter {
|
||||
constructor(options) {
|
||||
this.sourceFilename = void 0;
|
||||
this.sourceType = void 0;
|
||||
this.sourceFilename = options.sourceFilename;
|
||||
this.sourceType = options.sourceType;
|
||||
}
|
||||
/**
|
||||
* Transform the input Hermes AST to the desired output format.
|
||||
* This modifies the input AST in place instead of constructing a new AST.
|
||||
*/
|
||||
|
||||
|
||||
transform(program) {
|
||||
// Comments are not traversed via visitor keys
|
||||
const comments = program.comments;
|
||||
|
||||
for (let i = 0; i < comments.length; i++) {
|
||||
const comment = comments[i];
|
||||
this.fixSourceLocation(comment);
|
||||
comments[i] = this.mapComment(comment);
|
||||
} // The first comment may be an interpreter directive and is stored directly on the program node
|
||||
|
||||
|
||||
program.interpreter = comments.length > 0 && comments[0].type === 'InterpreterDirective' ? comments.shift() : null; // Tokens are not traversed via visitor keys
|
||||
|
||||
const tokens = program.tokens;
|
||||
|
||||
if (tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
this.fixSourceLocation(tokens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const resultNode = this.mapNode(program);
|
||||
|
||||
if (resultNode.type !== 'Program') {
|
||||
throw new Error(`HermesToESTreeAdapter: Must return a Program node, instead of "${resultNode.type}". `);
|
||||
} // $FlowExpectedError[incompatible-return] We know this is a program at this point.
|
||||
|
||||
|
||||
return resultNode;
|
||||
}
|
||||
/**
|
||||
* Transform a Hermes AST node to the output AST format.
|
||||
*
|
||||
* This may modify the input node in-place and return that same node, or a completely
|
||||
* new node may be constructed and returned. Overriden in child classes.
|
||||
*/
|
||||
|
||||
|
||||
mapNode(_node) {
|
||||
throw new Error('Implemented in subclasses');
|
||||
}
|
||||
|
||||
mapNodeDefault(node) {
|
||||
const visitorKeys = _ParserVisitorKeys.HERMES_AST_VISITOR_KEYS[node.type];
|
||||
|
||||
for (const key in visitorKeys) {
|
||||
const childType = visitorKeys[key];
|
||||
|
||||
if (childType === _ParserVisitorKeys.NODE_CHILD) {
|
||||
const child = node[key];
|
||||
|
||||
if (child != null) {
|
||||
node[key] = this.mapNode(child);
|
||||
}
|
||||
} else if (childType === _ParserVisitorKeys.NODE_LIST_CHILD) {
|
||||
const children = node[key];
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
|
||||
if (child != null) {
|
||||
children[i] = this.mapNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Update the source location for this node depending on the output AST format.
|
||||
* This can modify the input node in-place. Overriden in child classes.
|
||||
*/
|
||||
|
||||
|
||||
fixSourceLocation(_node) {
|
||||
throw new Error('Implemented in subclasses');
|
||||
}
|
||||
|
||||
getSourceType() {
|
||||
var _this$sourceType;
|
||||
|
||||
return (_this$sourceType = this.sourceType) != null ? _this$sourceType : 'script';
|
||||
}
|
||||
|
||||
setModuleSourceType() {
|
||||
if (this.sourceType == null) {
|
||||
this.sourceType = 'module';
|
||||
}
|
||||
}
|
||||
|
||||
mapComment(node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
mapEmpty(_node) {
|
||||
// $FlowExpectedError
|
||||
return null;
|
||||
}
|
||||
|
||||
mapImportDeclaration(node) {
|
||||
if (node.importKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapImportSpecifier(node) {
|
||||
if (node.importKind === 'value') {
|
||||
node.importKind = null;
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportDefaultDeclaration(node) {
|
||||
this.setModuleSourceType();
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportNamedDeclaration(node) {
|
||||
if (node.exportKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportAllDeclaration(node) {
|
||||
if (node.exportKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
formatError(node, message) {
|
||||
return `${message} (${node.loc.start.line}:${node.loc.start.column})`;
|
||||
}
|
||||
|
||||
getBigIntLiteralValue(bigintString) {
|
||||
// TODO - once we update flow we can remove this
|
||||
const bigint = bigintString // estree spec is to not have a trailing `n` on this property
|
||||
// https://github.com/estree/estree/blob/db962bb417a97effcfe9892f87fbb93c81a68584/es2020.md#bigintliteral
|
||||
.replace(/n$/, '') // `BigInt` doesn't accept numeric separator and `bigint` property should not include numeric separator
|
||||
.replace(/_/, '');
|
||||
return {
|
||||
bigint,
|
||||
// coerce the string to a bigint value if supported by the environment
|
||||
value: typeof BigInt === 'function' ? BigInt(bigint) : null
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = HermesASTAdapter;
|
||||
192
node_modules/hermes-parser/dist/HermesASTAdapter.js.flow
generated
vendored
Normal file
192
node_modules/hermes-parser/dist/HermesASTAdapter.js.flow
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {Program} from 'hermes-estree';
|
||||
import type {HermesNode} from './HermesAST';
|
||||
import type {ParserOptions} from './ParserOptions';
|
||||
|
||||
import {
|
||||
HERMES_AST_VISITOR_KEYS,
|
||||
NODE_CHILD,
|
||||
NODE_LIST_CHILD,
|
||||
} from './generated/ParserVisitorKeys';
|
||||
|
||||
/**
|
||||
* The base class for transforming the Hermes AST to the desired output format.
|
||||
* Extended by concrete adapters which output an ESTree or Babel AST.
|
||||
*/
|
||||
export default class HermesASTAdapter {
|
||||
sourceFilename: ParserOptions['sourceFilename'];
|
||||
sourceType: ParserOptions['sourceType'];
|
||||
|
||||
constructor(options: ParserOptions) {
|
||||
this.sourceFilename = options.sourceFilename;
|
||||
this.sourceType = options.sourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the input Hermes AST to the desired output format.
|
||||
* This modifies the input AST in place instead of constructing a new AST.
|
||||
*/
|
||||
transform(program: HermesNode): Program {
|
||||
// Comments are not traversed via visitor keys
|
||||
const comments = program.comments;
|
||||
for (let i = 0; i < comments.length; i++) {
|
||||
const comment = comments[i];
|
||||
this.fixSourceLocation(comment);
|
||||
comments[i] = this.mapComment(comment);
|
||||
}
|
||||
|
||||
// The first comment may be an interpreter directive and is stored directly on the program node
|
||||
program.interpreter =
|
||||
comments.length > 0 && comments[0].type === 'InterpreterDirective'
|
||||
? comments.shift()
|
||||
: null;
|
||||
|
||||
// Tokens are not traversed via visitor keys
|
||||
const tokens = program.tokens;
|
||||
if (tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
this.fixSourceLocation(tokens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const resultNode = this.mapNode(program);
|
||||
if (resultNode.type !== 'Program') {
|
||||
throw new Error(
|
||||
`HermesToESTreeAdapter: Must return a Program node, instead of "${resultNode.type}". `,
|
||||
);
|
||||
}
|
||||
|
||||
// $FlowExpectedError[incompatible-return] We know this is a program at this point.
|
||||
return resultNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a Hermes AST node to the output AST format.
|
||||
*
|
||||
* This may modify the input node in-place and return that same node, or a completely
|
||||
* new node may be constructed and returned. Overriden in child classes.
|
||||
*/
|
||||
mapNode(_node: HermesNode): HermesNode {
|
||||
throw new Error('Implemented in subclasses');
|
||||
}
|
||||
|
||||
mapNodeDefault(node: HermesNode): HermesNode {
|
||||
const visitorKeys = HERMES_AST_VISITOR_KEYS[node.type];
|
||||
for (const key in visitorKeys) {
|
||||
const childType = visitorKeys[key];
|
||||
if (childType === NODE_CHILD) {
|
||||
const child = node[key];
|
||||
if (child != null) {
|
||||
node[key] = this.mapNode(child);
|
||||
}
|
||||
} else if (childType === NODE_LIST_CHILD) {
|
||||
const children = node[key];
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
if (child != null) {
|
||||
children[i] = this.mapNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the source location for this node depending on the output AST format.
|
||||
* This can modify the input node in-place. Overriden in child classes.
|
||||
*/
|
||||
fixSourceLocation(_node: HermesNode): void {
|
||||
throw new Error('Implemented in subclasses');
|
||||
}
|
||||
|
||||
getSourceType(): ParserOptions['sourceType'] {
|
||||
return this.sourceType ?? 'script';
|
||||
}
|
||||
|
||||
setModuleSourceType(): void {
|
||||
if (this.sourceType == null) {
|
||||
this.sourceType = 'module';
|
||||
}
|
||||
}
|
||||
|
||||
mapComment(node: HermesNode): HermesNode {
|
||||
return node;
|
||||
}
|
||||
|
||||
mapEmpty(_node: HermesNode): HermesNode {
|
||||
// $FlowExpectedError
|
||||
return null;
|
||||
}
|
||||
|
||||
mapImportDeclaration(node: HermesNode): HermesNode {
|
||||
if (node.importKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapImportSpecifier(node: HermesNode): HermesNode {
|
||||
if (node.importKind === 'value') {
|
||||
node.importKind = null;
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportDefaultDeclaration(node: HermesNode): HermesNode {
|
||||
this.setModuleSourceType();
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportNamedDeclaration(node: HermesNode): HermesNode {
|
||||
if (node.exportKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapExportAllDeclaration(node: HermesNode): HermesNode {
|
||||
if (node.exportKind === 'value') {
|
||||
this.setModuleSourceType();
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
formatError(node: HermesNode, message: string): string {
|
||||
return `${message} (${node.loc.start.line}:${node.loc.start.column})`;
|
||||
}
|
||||
|
||||
getBigIntLiteralValue(bigintString: string): {
|
||||
bigint: string,
|
||||
value: $FlowFixMe /* bigint */,
|
||||
} {
|
||||
// TODO - once we update flow we can remove this
|
||||
declare var BigInt: ?(value: $FlowFixMe) => mixed;
|
||||
|
||||
const bigint = bigintString
|
||||
// estree spec is to not have a trailing `n` on this property
|
||||
// https://github.com/estree/estree/blob/db962bb417a97effcfe9892f87fbb93c81a68584/es2020.md#bigintliteral
|
||||
.replace(/n$/, '')
|
||||
// `BigInt` doesn't accept numeric separator and `bigint` property should not include numeric separator
|
||||
.replace(/_/, '');
|
||||
return {
|
||||
bigint,
|
||||
// coerce the string to a bigint value if supported by the environment
|
||||
value: typeof BigInt === 'function' ? BigInt(bigint) : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
108
node_modules/hermes-parser/dist/HermesParser.js
generated
vendored
Normal file
108
node_modules/hermes-parser/dist/HermesParser.js
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.parse = parse;
|
||||
|
||||
var _HermesParserDeserializer = _interopRequireDefault(require("./HermesParserDeserializer"));
|
||||
|
||||
var _HermesParserWASM = _interopRequireDefault(require("./HermesParserWASM"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
let HermesParserWASM;
|
||||
let hermesParse;
|
||||
let hermesParseResult_free;
|
||||
let hermesParseResult_getError;
|
||||
let hermesParseResult_getErrorLine;
|
||||
let hermesParseResult_getErrorColumn;
|
||||
let hermesParseResult_getProgramBuffer;
|
||||
let hermesParseResult_getPositionBuffer;
|
||||
let hermesParseResult_getPositionBufferSize;
|
||||
/**
|
||||
* Init the WASM wrapper code generated by `emscripten` to preparse the
|
||||
* HermesParser WASM code.
|
||||
*/
|
||||
|
||||
function initHermesParserWASM() {
|
||||
if (HermesParserWASM != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HermesParserWASM = (0, _HermesParserWASM.default)({
|
||||
/**
|
||||
* The emscripten version of `quit` unconditionally assigns the `status` to
|
||||
* `process.exitCode` which overrides any pre-existing code that has been
|
||||
* set, even if it is non zero. For our use case we never want an
|
||||
* `exitCode` to be set so this override removes that functionality.
|
||||
*/
|
||||
quit(_status, toThrow) {
|
||||
throw toThrow;
|
||||
}
|
||||
|
||||
});
|
||||
hermesParse = HermesParserWASM.cwrap('hermesParse', 'number', ['number', 'number', 'number', 'number', 'number', 'number']);
|
||||
hermesParseResult_free = HermesParserWASM.cwrap('hermesParseResult_free', 'void', ['number']);
|
||||
hermesParseResult_getError = HermesParserWASM.cwrap('hermesParseResult_getError', 'string', ['number']);
|
||||
hermesParseResult_getErrorLine = HermesParserWASM.cwrap('hermesParseResult_getErrorLine', 'number', ['number']);
|
||||
hermesParseResult_getErrorColumn = HermesParserWASM.cwrap('hermesParseResult_getErrorColumn', 'number', ['number']);
|
||||
hermesParseResult_getProgramBuffer = HermesParserWASM.cwrap('hermesParseResult_getProgramBuffer', 'number', ['number']);
|
||||
hermesParseResult_getPositionBuffer = HermesParserWASM.cwrap('hermesParseResult_getPositionBuffer', 'number', ['number']);
|
||||
hermesParseResult_getPositionBufferSize = HermesParserWASM.cwrap('hermesParseResult_getPositionBufferSize', 'number', ['number']);
|
||||
} // Copy a string into the WASM heap and null-terminate
|
||||
|
||||
|
||||
function copyToHeap(buffer, addr) {
|
||||
HermesParserWASM.HEAP8.set(buffer, addr);
|
||||
HermesParserWASM.HEAP8[addr + buffer.length] = 0;
|
||||
}
|
||||
|
||||
function parse(source, options) {
|
||||
initHermesParserWASM(); // Allocate space on heap for source text
|
||||
|
||||
const sourceBuffer = Buffer.from(source, 'utf8');
|
||||
|
||||
const sourceAddr = HermesParserWASM._malloc(sourceBuffer.length + 1);
|
||||
|
||||
if (!sourceAddr) {
|
||||
throw new Error('Parser out of memory');
|
||||
}
|
||||
|
||||
try {
|
||||
// Copy source text onto WASM heap
|
||||
copyToHeap(sourceBuffer, sourceAddr);
|
||||
const parseResult = hermesParse(sourceAddr, sourceBuffer.length + 1, options.flow === 'detect', options.enableExperimentalComponentSyntax, options.tokens, options.allowReturnOutsideFunction);
|
||||
|
||||
try {
|
||||
// Extract and throw error from parse result if parsing failed
|
||||
const err = hermesParseResult_getError(parseResult);
|
||||
|
||||
if (err) {
|
||||
const syntaxError = new SyntaxError(err); // $FlowExpectedError[prop-missing]
|
||||
|
||||
syntaxError.loc = {
|
||||
line: hermesParseResult_getErrorLine(parseResult),
|
||||
column: hermesParseResult_getErrorColumn(parseResult)
|
||||
};
|
||||
throw syntaxError;
|
||||
}
|
||||
|
||||
const deserializer = new _HermesParserDeserializer.default(hermesParseResult_getProgramBuffer(parseResult), hermesParseResult_getPositionBuffer(parseResult), hermesParseResult_getPositionBufferSize(parseResult), HermesParserWASM, options);
|
||||
return deserializer.deserialize();
|
||||
} finally {
|
||||
hermesParseResult_free(parseResult);
|
||||
}
|
||||
} finally {
|
||||
HermesParserWASM._free(sourceAddr);
|
||||
}
|
||||
}
|
||||
159
node_modules/hermes-parser/dist/HermesParser.js.flow
generated
vendored
Normal file
159
node_modules/hermes-parser/dist/HermesParser.js.flow
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {HermesNode} from './HermesAST';
|
||||
import type {ParserOptions} from './ParserOptions';
|
||||
|
||||
import HermesParserDeserializer from './HermesParserDeserializer';
|
||||
import HermesParserWASMModule from './HermesParserWASM';
|
||||
|
||||
let HermesParserWASM;
|
||||
let hermesParse;
|
||||
let hermesParseResult_free;
|
||||
let hermesParseResult_getError;
|
||||
let hermesParseResult_getErrorLine;
|
||||
let hermesParseResult_getErrorColumn;
|
||||
let hermesParseResult_getProgramBuffer;
|
||||
let hermesParseResult_getPositionBuffer;
|
||||
let hermesParseResult_getPositionBufferSize;
|
||||
|
||||
/**
|
||||
* Init the WASM wrapper code generated by `emscripten` to preparse the
|
||||
* HermesParser WASM code.
|
||||
*/
|
||||
function initHermesParserWASM() {
|
||||
if (HermesParserWASM != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HermesParserWASM = HermesParserWASMModule({
|
||||
/**
|
||||
* The emscripten version of `quit` unconditionally assigns the `status` to
|
||||
* `process.exitCode` which overrides any pre-existing code that has been
|
||||
* set, even if it is non zero. For our use case we never want an
|
||||
* `exitCode` to be set so this override removes that functionality.
|
||||
*/
|
||||
quit(_status: number, toThrow: Error) {
|
||||
throw toThrow;
|
||||
},
|
||||
});
|
||||
|
||||
hermesParse = HermesParserWASM.cwrap('hermesParse', 'number', [
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
]);
|
||||
|
||||
hermesParseResult_free = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_free',
|
||||
'void',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getError = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getError',
|
||||
'string',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getErrorLine = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getErrorLine',
|
||||
'number',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getErrorColumn = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getErrorColumn',
|
||||
'number',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getProgramBuffer = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getProgramBuffer',
|
||||
'number',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getPositionBuffer = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getPositionBuffer',
|
||||
'number',
|
||||
['number'],
|
||||
);
|
||||
|
||||
hermesParseResult_getPositionBufferSize = HermesParserWASM.cwrap(
|
||||
'hermesParseResult_getPositionBufferSize',
|
||||
'number',
|
||||
['number'],
|
||||
);
|
||||
}
|
||||
|
||||
// Copy a string into the WASM heap and null-terminate
|
||||
function copyToHeap(buffer: Buffer, addr: number) {
|
||||
HermesParserWASM.HEAP8.set(buffer, addr);
|
||||
HermesParserWASM.HEAP8[addr + buffer.length] = 0;
|
||||
}
|
||||
|
||||
export function parse(source: string, options: ParserOptions): HermesNode {
|
||||
initHermesParserWASM();
|
||||
|
||||
// Allocate space on heap for source text
|
||||
const sourceBuffer = Buffer.from(source, 'utf8');
|
||||
const sourceAddr = HermesParserWASM._malloc(sourceBuffer.length + 1);
|
||||
if (!sourceAddr) {
|
||||
throw new Error('Parser out of memory');
|
||||
}
|
||||
|
||||
try {
|
||||
// Copy source text onto WASM heap
|
||||
copyToHeap(sourceBuffer, sourceAddr);
|
||||
|
||||
const parseResult = hermesParse(
|
||||
sourceAddr,
|
||||
sourceBuffer.length + 1,
|
||||
options.flow === 'detect',
|
||||
options.enableExperimentalComponentSyntax,
|
||||
options.tokens,
|
||||
options.allowReturnOutsideFunction,
|
||||
);
|
||||
|
||||
try {
|
||||
// Extract and throw error from parse result if parsing failed
|
||||
const err = hermesParseResult_getError(parseResult);
|
||||
if (err) {
|
||||
const syntaxError = new SyntaxError(err);
|
||||
// $FlowExpectedError[prop-missing]
|
||||
syntaxError.loc = {
|
||||
line: hermesParseResult_getErrorLine(parseResult),
|
||||
column: hermesParseResult_getErrorColumn(parseResult),
|
||||
};
|
||||
|
||||
throw syntaxError;
|
||||
}
|
||||
|
||||
const deserializer = new HermesParserDeserializer(
|
||||
hermesParseResult_getProgramBuffer(parseResult),
|
||||
hermesParseResult_getPositionBuffer(parseResult),
|
||||
hermesParseResult_getPositionBufferSize(parseResult),
|
||||
HermesParserWASM,
|
||||
options,
|
||||
);
|
||||
return deserializer.deserialize();
|
||||
} finally {
|
||||
hermesParseResult_free(parseResult);
|
||||
}
|
||||
} finally {
|
||||
HermesParserWASM._free(sourceAddr);
|
||||
}
|
||||
}
|
||||
68
node_modules/hermes-parser/dist/HermesParserDecodeUTF8String.js
generated
vendored
Normal file
68
node_modules/hermes-parser/dist/HermesParserDecodeUTF8String.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
/**
|
||||
* Decode a UTF-8 encoded string from Hermes with a known length.
|
||||
* Based on Emscripten's UTF8ToString with the following differences:
|
||||
* - Always reads all bytes up to the given length, including null bytes. This
|
||||
* means that we can decode strings that contain null bytes in the middle.
|
||||
* - Allow UTF-8 encoded code points that are part of a surrogate pair, even though
|
||||
* this is technically invalid UTF-8 that UTF8ToString would convert to 0xfffd.
|
||||
*/
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = HermesParserDecodeUTF8String;
|
||||
|
||||
function HermesParserDecodeUTF8String(ptrIn, length, heap) {
|
||||
let ptr = ptrIn;
|
||||
const endPtr = ptr + length;
|
||||
let str = '';
|
||||
|
||||
while (ptr < endPtr) {
|
||||
// ASCII characters fit in single byte code point
|
||||
let u0 = heap[ptr++];
|
||||
|
||||
if (!(u0 & 0x80)) {
|
||||
str += String.fromCharCode(u0);
|
||||
continue;
|
||||
} // Two byte code point
|
||||
|
||||
|
||||
const u1 = heap[ptr++] & 0x3f;
|
||||
|
||||
if ((u0 & 0xe0) === 0xc0) {
|
||||
str += String.fromCharCode((u0 & 0x1f) << 6 | u1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const u2 = heap[ptr++] & 0x3f;
|
||||
|
||||
if ((u0 & 0xf0) === 0xe0) {
|
||||
// Three byte code point
|
||||
u0 = (u0 & 0x0f) << 12 | u1 << 6 | u2;
|
||||
} else {
|
||||
// Four byte code point
|
||||
u0 = (u0 & 0x07) << 18 | u1 << 12 | u2 << 6 | heap[ptr++] & 0x3f;
|
||||
}
|
||||
|
||||
if (u0 < 0x10000) {
|
||||
// Code point fits into a single UTF-16 code unit
|
||||
str += String.fromCharCode(u0);
|
||||
} else {
|
||||
// Code point does not fit into single UTF-16 code unit so convert to surrogate pair
|
||||
u0 -= 0x10000;
|
||||
str += String.fromCharCode(0xd800 | u0 >> 10, 0xdc00 | u0 & 0x3ff);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
65
node_modules/hermes-parser/dist/HermesParserDecodeUTF8String.js.flow
generated
vendored
Normal file
65
node_modules/hermes-parser/dist/HermesParserDecodeUTF8String.js.flow
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Decode a UTF-8 encoded string from Hermes with a known length.
|
||||
* Based on Emscripten's UTF8ToString with the following differences:
|
||||
* - Always reads all bytes up to the given length, including null bytes. This
|
||||
* means that we can decode strings that contain null bytes in the middle.
|
||||
* - Allow UTF-8 encoded code points that are part of a surrogate pair, even though
|
||||
* this is technically invalid UTF-8 that UTF8ToString would convert to 0xfffd.
|
||||
*/
|
||||
export default function HermesParserDecodeUTF8String(
|
||||
ptrIn: number,
|
||||
length: number,
|
||||
heap: Uint8Array,
|
||||
): string {
|
||||
let ptr = ptrIn;
|
||||
const endPtr = ptr + length;
|
||||
let str = '';
|
||||
|
||||
while (ptr < endPtr) {
|
||||
// ASCII characters fit in single byte code point
|
||||
let u0 = heap[ptr++];
|
||||
if (!(u0 & 0x80)) {
|
||||
str += String.fromCharCode(u0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Two byte code point
|
||||
const u1 = heap[ptr++] & 0x3f;
|
||||
if ((u0 & 0xe0) === 0xc0) {
|
||||
str += String.fromCharCode(((u0 & 0x1f) << 6) | u1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const u2 = heap[ptr++] & 0x3f;
|
||||
if ((u0 & 0xf0) === 0xe0) {
|
||||
// Three byte code point
|
||||
u0 = ((u0 & 0x0f) << 12) | (u1 << 6) | u2;
|
||||
} else {
|
||||
// Four byte code point
|
||||
u0 = ((u0 & 0x07) << 18) | (u1 << 12) | (u2 << 6) | (heap[ptr++] & 0x3f);
|
||||
}
|
||||
|
||||
if (u0 < 0x10000) {
|
||||
// Code point fits into a single UTF-16 code unit
|
||||
str += String.fromCharCode(u0);
|
||||
} else {
|
||||
// Code point does not fit into single UTF-16 code unit so convert to surrogate pair
|
||||
u0 -= 0x10000;
|
||||
str += String.fromCharCode(0xd800 | (u0 >> 10), 0xdc00 | (u0 & 0x3ff));
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
243
node_modules/hermes-parser/dist/HermesParserDeserializer.js
generated
vendored
Normal file
243
node_modules/hermes-parser/dist/HermesParserDeserializer.js
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _HermesParserDecodeUTF8String = _interopRequireDefault(require("./HermesParserDecodeUTF8String"));
|
||||
|
||||
var _HermesParserNodeDeserializers = _interopRequireDefault(require("./HermesParserNodeDeserializers"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
class HermesParserDeserializer {
|
||||
// Matches StoredComment::Kind enum in JSLexer.h
|
||||
// Matches TokenType enum in HermesParserJSSerializer.h
|
||||
constructor(programBuffer, positionBuffer, positionBufferSize, wasmParser, options) {
|
||||
this.programBufferIdx = void 0;
|
||||
this.positionBufferIdx = void 0;
|
||||
this.positionBufferSize = void 0;
|
||||
this.locMap = void 0;
|
||||
this.HEAPU8 = void 0;
|
||||
this.HEAPU32 = void 0;
|
||||
this.HEAPF64 = void 0;
|
||||
this.options = void 0;
|
||||
this.commentTypes = ['CommentLine', 'CommentBlock', 'InterpreterDirective'];
|
||||
this.tokenTypes = ['Boolean', 'Identifier', 'Keyword', 'Null', 'Numeric', 'BigInt', 'Punctuator', 'String', 'RegularExpression', 'Template', 'JSXText'];
|
||||
// Program and position buffer are memory addresses, so we must convert
|
||||
// into indices into HEAPU32 (an array of 4-byte integers).
|
||||
this.programBufferIdx = programBuffer / 4;
|
||||
this.positionBufferIdx = positionBuffer / 4;
|
||||
this.positionBufferSize = positionBufferSize;
|
||||
this.locMap = {};
|
||||
this.HEAPU8 = wasmParser.HEAPU8;
|
||||
this.HEAPU32 = wasmParser.HEAPU32;
|
||||
this.HEAPF64 = wasmParser.HEAPF64;
|
||||
this.options = options;
|
||||
}
|
||||
/**
|
||||
* Consume and return the next 4 bytes in the program buffer.
|
||||
*/
|
||||
|
||||
|
||||
next() {
|
||||
const num = this.HEAPU32[this.programBufferIdx++];
|
||||
return num;
|
||||
}
|
||||
|
||||
deserialize() {
|
||||
const program = {
|
||||
type: 'Program',
|
||||
loc: this.addEmptyLoc(),
|
||||
body: this.deserializeNodeList(),
|
||||
comments: this.deserializeComments()
|
||||
};
|
||||
|
||||
if (this.options.tokens === true) {
|
||||
program.tokens = this.deserializeTokens();
|
||||
}
|
||||
|
||||
this.fillLocs();
|
||||
return program;
|
||||
}
|
||||
/**
|
||||
* Booleans are serialized as a single 4-byte integer.
|
||||
*/
|
||||
|
||||
|
||||
deserializeBoolean() {
|
||||
return Boolean(this.next());
|
||||
}
|
||||
/**
|
||||
* Numbers are serialized directly into program buffer, taking up 8 bytes
|
||||
* preceded by 4 bytes of alignment padding if necessary.
|
||||
*/
|
||||
|
||||
|
||||
deserializeNumber() {
|
||||
let floatIdx; // Numbers are aligned on 8-byte boundaries, so skip padding if we are at
|
||||
// an odd index into the 4-byte aligned program buffer.
|
||||
|
||||
if (this.programBufferIdx % 2 === 0) {
|
||||
floatIdx = this.programBufferIdx / 2;
|
||||
this.programBufferIdx += 2;
|
||||
} else {
|
||||
floatIdx = (this.programBufferIdx + 1) / 2;
|
||||
this.programBufferIdx += 3;
|
||||
}
|
||||
|
||||
return this.HEAPF64[floatIdx];
|
||||
}
|
||||
/**
|
||||
* Strings are serialized as a 4-byte pointer into the heap, followed
|
||||
* by their size as a 4-byte integer. The size is only present if the
|
||||
* pointer is non-null.
|
||||
*/
|
||||
|
||||
|
||||
deserializeString() {
|
||||
const ptr = this.next();
|
||||
|
||||
if (ptr === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const size = this.next();
|
||||
return (0, _HermesParserDecodeUTF8String.default)(ptr, size, this.HEAPU8);
|
||||
}
|
||||
/**
|
||||
* Nodes are serialized as a 4-byte integer denoting their node kind,
|
||||
* followed by a 4-byte loc ID, followed by serialized node properties.
|
||||
*
|
||||
* If the node kind is 0 the node is null, otherwise the node kind - 1 is an
|
||||
* index into the array of node deserialization functions.
|
||||
*/
|
||||
|
||||
|
||||
deserializeNode() {
|
||||
const nodeType = this.next();
|
||||
|
||||
if (nodeType === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nodeDeserializer = _HermesParserNodeDeserializers.default[nodeType - 1].bind(this);
|
||||
|
||||
return nodeDeserializer();
|
||||
}
|
||||
/**
|
||||
* Node lists are serialized as a 4-byte integer denoting the number of
|
||||
* elements in the list, followed by the serialized elements.
|
||||
*/
|
||||
|
||||
|
||||
deserializeNodeList() {
|
||||
const size = this.next();
|
||||
const nodeList = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
nodeList.push(this.deserializeNode());
|
||||
}
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
/**
|
||||
* Comments are serialized as a node list, where each comment is serialized
|
||||
* as a 4-byte integer denoting comment type, followed by a 4-byte value
|
||||
* denoting the loc ID, followed by a serialized string for the comment value.
|
||||
*/
|
||||
|
||||
|
||||
deserializeComments() {
|
||||
const size = this.next();
|
||||
const comments = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const commentType = this.commentTypes[this.next()];
|
||||
const loc = this.addEmptyLoc();
|
||||
const value = this.deserializeString();
|
||||
comments.push({
|
||||
type: commentType,
|
||||
loc,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
deserializeTokens() {
|
||||
const size = this.next();
|
||||
const tokens = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const tokenType = this.tokenTypes[this.next()];
|
||||
const loc = this.addEmptyLoc();
|
||||
const value = this.deserializeString();
|
||||
tokens.push({
|
||||
type: tokenType,
|
||||
loc,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
/**
|
||||
* While deserializing the AST locations are represented by
|
||||
* a 4-byte loc ID. This is used to create a map of loc IDs to empty loc
|
||||
* objects that are filled after the AST has been deserialized.
|
||||
*/
|
||||
|
||||
|
||||
addEmptyLoc() {
|
||||
// $FlowExpectedError
|
||||
const loc = {};
|
||||
this.locMap[this.next()] = loc;
|
||||
return loc;
|
||||
}
|
||||
/**
|
||||
* Positions are serialized as a loc ID which denotes which loc it is associated with,
|
||||
* followed by kind which denotes whether it is a start or end position,
|
||||
* followed by line, column, and offset (4-bytes each).
|
||||
*/
|
||||
|
||||
|
||||
fillLocs() {
|
||||
for (let i = 0; i < this.positionBufferSize; i++) {
|
||||
const locId = this.HEAPU32[this.positionBufferIdx++];
|
||||
const kind = this.HEAPU32[this.positionBufferIdx++];
|
||||
const line = this.HEAPU32[this.positionBufferIdx++];
|
||||
const column = this.HEAPU32[this.positionBufferIdx++];
|
||||
const offset = this.HEAPU32[this.positionBufferIdx++];
|
||||
const loc = this.locMap[locId];
|
||||
|
||||
if (kind === 0) {
|
||||
loc.start = {
|
||||
line,
|
||||
column
|
||||
};
|
||||
loc.rangeStart = offset;
|
||||
} else {
|
||||
loc.end = {
|
||||
line,
|
||||
column
|
||||
};
|
||||
loc.rangeEnd = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = HermesParserDeserializer;
|
||||
261
node_modules/hermes-parser/dist/HermesParserDeserializer.js.flow
generated
vendored
Normal file
261
node_modules/hermes-parser/dist/HermesParserDeserializer.js.flow
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {
|
||||
HermesSourceLocation,
|
||||
HermesNode,
|
||||
HermesToken,
|
||||
HermesComment,
|
||||
} from './HermesAST';
|
||||
import type {HermesParserWASM} from './HermesParserWASM';
|
||||
import type {ParserOptions} from './ParserOptions';
|
||||
|
||||
import HermesParserDecodeUTF8String from './HermesParserDecodeUTF8String';
|
||||
import NODE_DESERIALIZERS from './HermesParserNodeDeserializers';
|
||||
|
||||
export default class HermesParserDeserializer {
|
||||
programBufferIdx: number;
|
||||
positionBufferIdx: number;
|
||||
+positionBufferSize: number;
|
||||
+locMap: {[number]: HermesSourceLocation};
|
||||
+HEAPU8: HermesParserWASM['HEAPU8'];
|
||||
+HEAPU32: HermesParserWASM['HEAPU32'];
|
||||
+HEAPF64: HermesParserWASM['HEAPF64'];
|
||||
+options: ParserOptions;
|
||||
|
||||
// Matches StoredComment::Kind enum in JSLexer.h
|
||||
+commentTypes: $ReadOnlyArray<HermesComment['type']> = [
|
||||
'CommentLine',
|
||||
'CommentBlock',
|
||||
'InterpreterDirective',
|
||||
];
|
||||
|
||||
// Matches TokenType enum in HermesParserJSSerializer.h
|
||||
+tokenTypes: $ReadOnlyArray<HermesToken['type']> = [
|
||||
'Boolean',
|
||||
'Identifier',
|
||||
'Keyword',
|
||||
'Null',
|
||||
'Numeric',
|
||||
'BigInt',
|
||||
'Punctuator',
|
||||
'String',
|
||||
'RegularExpression',
|
||||
'Template',
|
||||
'JSXText',
|
||||
];
|
||||
|
||||
constructor(
|
||||
programBuffer: number,
|
||||
positionBuffer: number,
|
||||
positionBufferSize: number,
|
||||
wasmParser: HermesParserWASM,
|
||||
options: ParserOptions,
|
||||
) {
|
||||
// Program and position buffer are memory addresses, so we must convert
|
||||
// into indices into HEAPU32 (an array of 4-byte integers).
|
||||
this.programBufferIdx = programBuffer / 4;
|
||||
this.positionBufferIdx = positionBuffer / 4;
|
||||
|
||||
this.positionBufferSize = positionBufferSize;
|
||||
this.locMap = {};
|
||||
|
||||
this.HEAPU8 = wasmParser.HEAPU8;
|
||||
this.HEAPU32 = wasmParser.HEAPU32;
|
||||
this.HEAPF64 = wasmParser.HEAPF64;
|
||||
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume and return the next 4 bytes in the program buffer.
|
||||
*/
|
||||
next(): number {
|
||||
const num = this.HEAPU32[this.programBufferIdx++];
|
||||
return num;
|
||||
}
|
||||
|
||||
deserialize(): HermesNode {
|
||||
const program: HermesNode = {
|
||||
type: 'Program',
|
||||
loc: this.addEmptyLoc(),
|
||||
body: this.deserializeNodeList(),
|
||||
comments: this.deserializeComments(),
|
||||
};
|
||||
|
||||
if (this.options.tokens === true) {
|
||||
program.tokens = this.deserializeTokens();
|
||||
}
|
||||
|
||||
this.fillLocs();
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
/**
|
||||
* Booleans are serialized as a single 4-byte integer.
|
||||
*/
|
||||
deserializeBoolean(): boolean {
|
||||
return Boolean(this.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Numbers are serialized directly into program buffer, taking up 8 bytes
|
||||
* preceded by 4 bytes of alignment padding if necessary.
|
||||
*/
|
||||
deserializeNumber(): number {
|
||||
let floatIdx;
|
||||
|
||||
// Numbers are aligned on 8-byte boundaries, so skip padding if we are at
|
||||
// an odd index into the 4-byte aligned program buffer.
|
||||
if (this.programBufferIdx % 2 === 0) {
|
||||
floatIdx = this.programBufferIdx / 2;
|
||||
this.programBufferIdx += 2;
|
||||
} else {
|
||||
floatIdx = (this.programBufferIdx + 1) / 2;
|
||||
this.programBufferIdx += 3;
|
||||
}
|
||||
|
||||
return this.HEAPF64[floatIdx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Strings are serialized as a 4-byte pointer into the heap, followed
|
||||
* by their size as a 4-byte integer. The size is only present if the
|
||||
* pointer is non-null.
|
||||
*/
|
||||
deserializeString(): ?string {
|
||||
const ptr = this.next();
|
||||
if (ptr === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const size = this.next();
|
||||
|
||||
return HermesParserDecodeUTF8String(ptr, size, this.HEAPU8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nodes are serialized as a 4-byte integer denoting their node kind,
|
||||
* followed by a 4-byte loc ID, followed by serialized node properties.
|
||||
*
|
||||
* If the node kind is 0 the node is null, otherwise the node kind - 1 is an
|
||||
* index into the array of node deserialization functions.
|
||||
*/
|
||||
deserializeNode(): ?HermesNode {
|
||||
const nodeType = this.next();
|
||||
if (nodeType === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nodeDeserializer = NODE_DESERIALIZERS[nodeType - 1].bind(this);
|
||||
return nodeDeserializer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Node lists are serialized as a 4-byte integer denoting the number of
|
||||
* elements in the list, followed by the serialized elements.
|
||||
*/
|
||||
deserializeNodeList(): Array<?HermesNode> {
|
||||
const size = this.next();
|
||||
const nodeList = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
nodeList.push(this.deserializeNode());
|
||||
}
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comments are serialized as a node list, where each comment is serialized
|
||||
* as a 4-byte integer denoting comment type, followed by a 4-byte value
|
||||
* denoting the loc ID, followed by a serialized string for the comment value.
|
||||
*/
|
||||
deserializeComments(): Array<HermesComment> {
|
||||
const size = this.next();
|
||||
const comments = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const commentType = this.commentTypes[this.next()];
|
||||
const loc = this.addEmptyLoc();
|
||||
const value = this.deserializeString();
|
||||
comments.push({
|
||||
type: commentType,
|
||||
loc,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
deserializeTokens(): Array<HermesToken> {
|
||||
const size = this.next();
|
||||
const tokens = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const tokenType = this.tokenTypes[this.next()];
|
||||
const loc = this.addEmptyLoc();
|
||||
const value = this.deserializeString();
|
||||
tokens.push({
|
||||
type: tokenType,
|
||||
loc,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* While deserializing the AST locations are represented by
|
||||
* a 4-byte loc ID. This is used to create a map of loc IDs to empty loc
|
||||
* objects that are filled after the AST has been deserialized.
|
||||
*/
|
||||
addEmptyLoc(): HermesSourceLocation {
|
||||
// $FlowExpectedError
|
||||
const loc: HermesSourceLocation = {};
|
||||
this.locMap[this.next()] = loc;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Positions are serialized as a loc ID which denotes which loc it is associated with,
|
||||
* followed by kind which denotes whether it is a start or end position,
|
||||
* followed by line, column, and offset (4-bytes each).
|
||||
*/
|
||||
fillLocs(): void {
|
||||
for (let i = 0; i < this.positionBufferSize; i++) {
|
||||
const locId = this.HEAPU32[this.positionBufferIdx++];
|
||||
const kind = this.HEAPU32[this.positionBufferIdx++];
|
||||
const line = this.HEAPU32[this.positionBufferIdx++];
|
||||
const column = this.HEAPU32[this.positionBufferIdx++];
|
||||
const offset = this.HEAPU32[this.positionBufferIdx++];
|
||||
|
||||
const loc = this.locMap[locId];
|
||||
if (kind === 0) {
|
||||
loc.start = {
|
||||
line,
|
||||
column,
|
||||
};
|
||||
loc.rangeStart = offset;
|
||||
} else {
|
||||
loc.end = {
|
||||
line,
|
||||
column,
|
||||
};
|
||||
loc.rangeEnd = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2291
node_modules/hermes-parser/dist/HermesParserNodeDeserializers.js
generated
vendored
Normal file
2291
node_modules/hermes-parser/dist/HermesParserNodeDeserializers.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
16
node_modules/hermes-parser/dist/HermesParserNodeDeserializers.js.flow
generated
vendored
Normal file
16
node_modules/hermes-parser/dist/HermesParserNodeDeserializers.js.flow
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {HermesNode} from './HermesAST';
|
||||
import type HermesParserDeserializer from './HermesParserDeserializer';
|
||||
|
||||
declare module.exports: $ReadOnlyArray<
|
||||
(this: HermesParserDeserializer) => HermesNode,
|
||||
>;
|
||||
6
node_modules/hermes-parser/dist/HermesParserWASM.js
generated
vendored
Normal file
6
node_modules/hermes-parser/dist/HermesParserWASM.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
79
node_modules/hermes-parser/dist/HermesParserWASM.js.flow
generated
vendored
Normal file
79
node_modules/hermes-parser/dist/HermesParserWASM.js.flow
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
type INTENTIONAL_ANY = $FlowFixMe;
|
||||
type JSType = 'number' | 'string' | 'array' | 'boolean';
|
||||
type CBoolean = ?(number | boolean);
|
||||
|
||||
type WASMModuleOverrides = $ReadOnly<{
|
||||
quit(status: number, toThrow: Error): void,
|
||||
}>;
|
||||
|
||||
export type HermesParserWASM = $ReadOnly<{
|
||||
HEAP8: Int8Array,
|
||||
HEAP16: Int16Array,
|
||||
HEAP32: Int32Array,
|
||||
HEAPU8: Uint8Array,
|
||||
HEAPU16: Uint16Array,
|
||||
HEAPU32: Uint32Array,
|
||||
HEAPF32: Float32Array,
|
||||
HEAPF64: Float64Array,
|
||||
|
||||
_malloc(size: number): number,
|
||||
_free(ptr: number): void,
|
||||
|
||||
ccall(
|
||||
ident: string,
|
||||
returnType: JSType | null,
|
||||
argTypes: $ReadOnlyArray<JSType>,
|
||||
args: $ReadOnlyArray<
|
||||
number | string | $ReadOnlyArray<INTENTIONAL_ANY> | boolean,
|
||||
>,
|
||||
opts?: $ReadOnly<{
|
||||
async?: boolean | void,
|
||||
}>,
|
||||
): INTENTIONAL_ANY,
|
||||
cwrap: {
|
||||
(
|
||||
'hermesParse',
|
||||
'number',
|
||||
['number', 'number', 'number', 'number', 'number', 'number'],
|
||||
): (number, number, CBoolean, CBoolean, CBoolean, CBoolean) => number,
|
||||
('hermesParseResult_free', 'void', ['number']): number => void,
|
||||
('hermesParseResult_getError', 'string', ['number']): number => string,
|
||||
('hermesParseResult_getErrorLine', 'number', ['number']): number => number,
|
||||
(
|
||||
'hermesParseResult_getErrorColumn',
|
||||
'number',
|
||||
['number'],
|
||||
): number => number,
|
||||
(
|
||||
'hermesParseResult_getProgramBuffer',
|
||||
'number',
|
||||
['number'],
|
||||
): number => number,
|
||||
(
|
||||
'hermesParseResult_getPositionBuffer',
|
||||
'number',
|
||||
['number'],
|
||||
): number => number,
|
||||
(
|
||||
'hermesParseResult_getPositionBufferSize',
|
||||
'number',
|
||||
['number'],
|
||||
): number => number,
|
||||
},
|
||||
|
||||
stackAlloc(size: number): number,
|
||||
stackSave(): number,
|
||||
stackRestore(ptr: number): void,
|
||||
}>;
|
||||
|
||||
declare module.exports: WASMModuleOverrides => HermesParserWASM;
|
||||
441
node_modules/hermes-parser/dist/HermesToESTreeAdapter.js
generated
vendored
Normal file
441
node_modules/hermes-parser/dist/HermesToESTreeAdapter.js
generated
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _HermesASTAdapter = _interopRequireDefault(require("./HermesASTAdapter"));
|
||||
|
||||
var _getModuleDocblock = require("./getModuleDocblock");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
class HermesToESTreeAdapter extends _HermesASTAdapter.default {
|
||||
constructor(options, code) {
|
||||
super(options);
|
||||
this.code = void 0;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
fixSourceLocation(node) {
|
||||
var _this$sourceFilename;
|
||||
|
||||
const loc = node.loc;
|
||||
|
||||
if (loc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.loc = {
|
||||
source: (_this$sourceFilename = this.sourceFilename) != null ? _this$sourceFilename : null,
|
||||
start: loc.start,
|
||||
end: loc.end
|
||||
};
|
||||
node.range = [loc.rangeStart, loc.rangeEnd];
|
||||
delete node.start;
|
||||
delete node.end;
|
||||
}
|
||||
|
||||
mapNode(node) {
|
||||
this.fixSourceLocation(node);
|
||||
|
||||
switch (node.type) {
|
||||
case 'Program':
|
||||
return this.mapProgram(node);
|
||||
|
||||
case 'NullLiteral':
|
||||
return this.mapNullLiteral(node);
|
||||
|
||||
case 'BooleanLiteral':
|
||||
case 'StringLiteral':
|
||||
case 'NumericLiteral':
|
||||
case 'JSXStringLiteral':
|
||||
return this.mapSimpleLiteral(node);
|
||||
|
||||
case 'BigIntLiteral':
|
||||
return this.mapBigIntLiteral(node);
|
||||
|
||||
case 'RegExpLiteral':
|
||||
return this.mapRegExpLiteral(node);
|
||||
|
||||
case 'Empty':
|
||||
return this.mapEmpty(node);
|
||||
|
||||
case 'TemplateElement':
|
||||
return this.mapTemplateElement(node);
|
||||
|
||||
case 'BigIntLiteralTypeAnnotation':
|
||||
return this.mapBigIntLiteralTypeAnnotation(node);
|
||||
|
||||
case 'GenericTypeAnnotation':
|
||||
return this.mapGenericTypeAnnotation(node);
|
||||
|
||||
case 'ImportDeclaration':
|
||||
return this.mapImportDeclaration(node);
|
||||
|
||||
case 'ImportSpecifier':
|
||||
return this.mapImportSpecifier(node);
|
||||
|
||||
case 'ExportDefaultDeclaration':
|
||||
return this.mapExportDefaultDeclaration(node);
|
||||
|
||||
case 'ExportNamedDeclaration':
|
||||
return this.mapExportNamedDeclaration(node);
|
||||
|
||||
case 'ExportAllDeclaration':
|
||||
return this.mapExportAllDeclaration(node);
|
||||
|
||||
case 'Property':
|
||||
return this.mapProperty(node);
|
||||
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
case 'ArrowFunctionExpression':
|
||||
return this.mapFunction(node);
|
||||
|
||||
case 'PrivateName':
|
||||
return this.mapPrivateName(node);
|
||||
|
||||
case 'ClassProperty':
|
||||
case 'ClassPrivateProperty':
|
||||
return this.mapClassProperty(node);
|
||||
|
||||
case 'MemberExpression':
|
||||
case 'OptionalMemberExpression':
|
||||
case 'CallExpression':
|
||||
case 'OptionalCallExpression':
|
||||
return this.mapChainExpression(node);
|
||||
|
||||
default:
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
}
|
||||
|
||||
mapProgram(node) {
|
||||
const nodeDefault = this.mapNodeDefault(node);
|
||||
node.sourceType = this.getSourceType();
|
||||
node.docblock = (0, _getModuleDocblock.getModuleDocblock)(nodeDefault);
|
||||
return nodeDefault;
|
||||
}
|
||||
|
||||
mapSimpleLiteral(node) {
|
||||
return {
|
||||
type: 'Literal',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
value: node.value,
|
||||
raw: this.code.slice(node.range[0], node.range[1]),
|
||||
literalType: (() => {
|
||||
switch (node.type) {
|
||||
case 'NullLiteral':
|
||||
return 'null';
|
||||
|
||||
case 'BooleanLiteral':
|
||||
return 'boolean';
|
||||
|
||||
case 'StringLiteral':
|
||||
case 'JSXStringLiteral':
|
||||
return 'string';
|
||||
|
||||
case 'NumericLiteral':
|
||||
return 'numeric';
|
||||
|
||||
case 'BigIntLiteral':
|
||||
return 'bigint';
|
||||
|
||||
case 'RegExpLiteral':
|
||||
return 'regexp';
|
||||
}
|
||||
|
||||
return null;
|
||||
})()
|
||||
};
|
||||
}
|
||||
|
||||
mapBigIntLiteral(node) {
|
||||
const newNode = this.mapSimpleLiteral(node);
|
||||
return { ...newNode,
|
||||
...this.getBigIntLiteralValue(node.bigint)
|
||||
};
|
||||
}
|
||||
|
||||
mapNullLiteral(node) {
|
||||
return { ...this.mapSimpleLiteral(node),
|
||||
value: null
|
||||
};
|
||||
}
|
||||
|
||||
mapRegExpLiteral(node) {
|
||||
const {
|
||||
pattern,
|
||||
flags
|
||||
} = node; // Create RegExp value if possible. This can fail when the flags are invalid.
|
||||
|
||||
let value;
|
||||
|
||||
try {
|
||||
value = new RegExp(pattern, flags);
|
||||
} catch (e) {
|
||||
value = null;
|
||||
}
|
||||
|
||||
return { ...this.mapSimpleLiteral(node),
|
||||
value,
|
||||
regex: {
|
||||
pattern,
|
||||
flags
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mapBigIntLiteralTypeAnnotation(node) {
|
||||
return { ...node,
|
||||
...this.getBigIntLiteralValue(node.raw)
|
||||
};
|
||||
}
|
||||
|
||||
mapTemplateElement(node) {
|
||||
return {
|
||||
type: 'TemplateElement',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
tail: node.tail,
|
||||
value: {
|
||||
cooked: node.cooked,
|
||||
raw: node.raw
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mapGenericTypeAnnotation(node) {
|
||||
// Convert simple `this` generic type to ThisTypeAnnotation
|
||||
if (node.typeParameters == null && node.id.type === 'Identifier' && node.id.name === 'this') {
|
||||
return {
|
||||
type: 'ThisTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range
|
||||
};
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapProperty(nodeUnprocessed) {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
if (node.value.type === 'FunctionExpression' && (node.method || node.kind !== 'init')) {
|
||||
node.value.loc.start = node.key.loc.end;
|
||||
node.value.range[0] = node.key.range[1];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapComment(node) {
|
||||
if (node.type === 'CommentBlock') {
|
||||
node.type = 'Block';
|
||||
} else if (node.type === 'CommentLine') {
|
||||
node.type = 'Line';
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapFunction(nodeUnprocessed) {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
switch (node.type) {
|
||||
// This prop should ideally only live on `ArrowFunctionExpression` but to
|
||||
// match espree output we place it on all functions types.
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
node.expression = false;
|
||||
return node;
|
||||
|
||||
case 'ArrowFunctionExpression':
|
||||
node.expression = node.body.type !== 'BlockStatement';
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapChainExpression(nodeUnprocessed) {
|
||||
/*
|
||||
NOTE - In the below comments `MemberExpression` and `CallExpression`
|
||||
are completely interchangable. For terseness we just reference
|
||||
one each time.
|
||||
*/
|
||||
|
||||
/*
|
||||
Hermes uses the old babel-style AST:
|
||||
```
|
||||
(one?.two).three?.four;
|
||||
^^^^^^^^^^^^^^^^^^^^^^ OptionalMemberExpression
|
||||
^^^^^^^^^^^^^^^^ MemberExpression
|
||||
^^^^^^^^ OptionalMemberExpression
|
||||
```
|
||||
We need to convert it to the ESTree representation:
|
||||
```
|
||||
(one?.two).three?.four;
|
||||
^^^^^^^^^^^^^^^^^^^^^^ ChainExpression
|
||||
^^^^^^^^^^^^^^^^^^^^^^ MemberExpression[optional = true]
|
||||
^^^^^^^^^^^^^^^^ MemberExpression[optional = false]
|
||||
^^^^^^^^ ChainExpression
|
||||
^^^^^^^^ MemberExpression[optional = true]
|
||||
```
|
||||
We do this by converting the AST and its children (depth first), and then unwrapping
|
||||
the resulting AST as appropriate.
|
||||
Put another way:
|
||||
1) traverse to the leaf
|
||||
2) if the current node is an `OptionalMemberExpression`:
|
||||
a) if the `.object` is a `ChainExpression`:
|
||||
i) unwrap the child (`node.object = child.expression`)
|
||||
b) convert this node to a `MemberExpression[optional = true]`
|
||||
c) wrap this node (`node = ChainExpression[expression = node]`)
|
||||
3) if the current node is a `MemberExpression`:
|
||||
a) convert this node to a `MemberExpression[optional = true]`
|
||||
*/
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
const {
|
||||
child,
|
||||
childKey,
|
||||
isOptional
|
||||
} = (() => {
|
||||
const isOptional = node.optional === true;
|
||||
|
||||
if (node.type.endsWith('MemberExpression')) {
|
||||
return {
|
||||
child: node.object,
|
||||
childKey: 'object',
|
||||
isOptional
|
||||
};
|
||||
} else if (node.type.endsWith('CallExpression')) {
|
||||
return {
|
||||
child: node.callee,
|
||||
childKey: 'callee',
|
||||
isOptional
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
child: node.expression,
|
||||
childKey: 'expression',
|
||||
isOptional: false
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
const isChildUnwrappable = child.type === 'ChainExpression' && // (x?.y).z is semantically different to `x?.y.z`.
|
||||
// In the un-parenthesised case `.z` is only executed if and only if `x?.y` returns a non-nullish value.
|
||||
// In the parenthesised case, `.z` is **always** executed, regardless of the return of `x?.y`.
|
||||
// As such the AST is different between the two cases.
|
||||
//
|
||||
// In the hermes AST - any member part of a non-short-circuited optional chain is represented with `OptionalMemberExpression`
|
||||
// so if we see a `MemberExpression`, then we know we've hit a parenthesis boundary.
|
||||
node.type !== 'MemberExpression' && node.type !== 'CallExpression';
|
||||
|
||||
if (node.type.startsWith('Optional')) {
|
||||
node.type = node.type.replace('Optional', '');
|
||||
node.optional = isOptional;
|
||||
} else {
|
||||
node.optional = false;
|
||||
}
|
||||
|
||||
if (!isChildUnwrappable && !isOptional) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (isChildUnwrappable) {
|
||||
const newChild = child.expression;
|
||||
node[childKey] = newChild;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'ChainExpression',
|
||||
expression: node,
|
||||
loc: node.loc,
|
||||
range: node.range
|
||||
};
|
||||
}
|
||||
|
||||
mapClassProperty(nodeUnprocessed) {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
const key = (() => {
|
||||
if (node.type === 'ClassPrivateProperty') {
|
||||
const key = this.mapNodeDefault(node.key);
|
||||
return {
|
||||
type: 'PrivateIdentifier',
|
||||
name: key.name,
|
||||
range: key.range,
|
||||
loc: key.loc
|
||||
};
|
||||
}
|
||||
|
||||
return node.key;
|
||||
})();
|
||||
|
||||
return { ...node,
|
||||
computed: node.type === 'ClassPrivateProperty' ? false : node.computed,
|
||||
key,
|
||||
type: 'PropertyDefinition'
|
||||
};
|
||||
}
|
||||
|
||||
mapPrivateName(node) {
|
||||
return {
|
||||
type: 'PrivateIdentifier',
|
||||
name: node.id.name,
|
||||
// estree the location refers to the entire string including the hash token
|
||||
range: node.range,
|
||||
loc: node.loc
|
||||
};
|
||||
}
|
||||
|
||||
mapExportNamedDeclaration(nodeUnprocessed) {
|
||||
const node = super.mapExportNamedDeclaration(nodeUnprocessed);
|
||||
const namespaceSpecifier = node.specifiers.find(spec => spec.type === 'ExportNamespaceSpecifier');
|
||||
|
||||
if (namespaceSpecifier != null) {
|
||||
var _node$exportKind;
|
||||
|
||||
if (node.specifiers.length !== 1) {
|
||||
// this should already a hermes parser error - but let's be absolutely sure we're aligned with the spec
|
||||
throw new Error('Cannot use an export all with any other specifiers');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'ExportAllDeclaration',
|
||||
source: node.source,
|
||||
exportKind: (_node$exportKind = node.exportKind) != null ? _node$exportKind : 'value',
|
||||
exported: namespaceSpecifier.exported,
|
||||
range: node.range,
|
||||
loc: node.loc
|
||||
};
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapExportAllDeclaration(nodeUnprocessed) {
|
||||
var _node$exported;
|
||||
|
||||
const node = super.mapExportAllDeclaration(nodeUnprocessed);
|
||||
node.exported = (_node$exported = node.exported) != null ? _node$exported : null;
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = HermesToESTreeAdapter;
|
||||
427
node_modules/hermes-parser/dist/HermesToESTreeAdapter.js.flow
generated
vendored
Normal file
427
node_modules/hermes-parser/dist/HermesToESTreeAdapter.js.flow
generated
vendored
Normal file
@@ -0,0 +1,427 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {HermesNode} from './HermesAST';
|
||||
import type {ParserOptions} from './ParserOptions';
|
||||
|
||||
import HermesASTAdapter from './HermesASTAdapter';
|
||||
import {getModuleDocblock} from './getModuleDocblock';
|
||||
|
||||
declare var BigInt: ?(value: $FlowFixMe) => mixed;
|
||||
|
||||
export default class HermesToESTreeAdapter extends HermesASTAdapter {
|
||||
+code: string;
|
||||
|
||||
constructor(options: ParserOptions, code: string) {
|
||||
super(options);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
fixSourceLocation(node: HermesNode): void {
|
||||
const loc = node.loc;
|
||||
if (loc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.loc = {
|
||||
source: this.sourceFilename ?? null,
|
||||
start: loc.start,
|
||||
end: loc.end,
|
||||
};
|
||||
|
||||
node.range = [loc.rangeStart, loc.rangeEnd];
|
||||
|
||||
delete node.start;
|
||||
delete node.end;
|
||||
}
|
||||
|
||||
mapNode(node: HermesNode): HermesNode {
|
||||
this.fixSourceLocation(node);
|
||||
switch (node.type) {
|
||||
case 'Program':
|
||||
return this.mapProgram(node);
|
||||
case 'NullLiteral':
|
||||
return this.mapNullLiteral(node);
|
||||
case 'BooleanLiteral':
|
||||
case 'StringLiteral':
|
||||
case 'NumericLiteral':
|
||||
case 'JSXStringLiteral':
|
||||
return this.mapSimpleLiteral(node);
|
||||
case 'BigIntLiteral':
|
||||
return this.mapBigIntLiteral(node);
|
||||
case 'RegExpLiteral':
|
||||
return this.mapRegExpLiteral(node);
|
||||
case 'Empty':
|
||||
return this.mapEmpty(node);
|
||||
case 'TemplateElement':
|
||||
return this.mapTemplateElement(node);
|
||||
case 'BigIntLiteralTypeAnnotation':
|
||||
return this.mapBigIntLiteralTypeAnnotation(node);
|
||||
case 'GenericTypeAnnotation':
|
||||
return this.mapGenericTypeAnnotation(node);
|
||||
case 'ImportDeclaration':
|
||||
return this.mapImportDeclaration(node);
|
||||
case 'ImportSpecifier':
|
||||
return this.mapImportSpecifier(node);
|
||||
case 'ExportDefaultDeclaration':
|
||||
return this.mapExportDefaultDeclaration(node);
|
||||
case 'ExportNamedDeclaration':
|
||||
return this.mapExportNamedDeclaration(node);
|
||||
case 'ExportAllDeclaration':
|
||||
return this.mapExportAllDeclaration(node);
|
||||
case 'Property':
|
||||
return this.mapProperty(node);
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
case 'ArrowFunctionExpression':
|
||||
return this.mapFunction(node);
|
||||
case 'PrivateName':
|
||||
return this.mapPrivateName(node);
|
||||
case 'ClassProperty':
|
||||
case 'ClassPrivateProperty':
|
||||
return this.mapClassProperty(node);
|
||||
case 'MemberExpression':
|
||||
case 'OptionalMemberExpression':
|
||||
case 'CallExpression':
|
||||
case 'OptionalCallExpression':
|
||||
return this.mapChainExpression(node);
|
||||
default:
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
}
|
||||
|
||||
mapProgram(node: HermesNode): HermesNode {
|
||||
const nodeDefault = this.mapNodeDefault(node);
|
||||
node.sourceType = this.getSourceType();
|
||||
|
||||
node.docblock = getModuleDocblock(nodeDefault);
|
||||
|
||||
return nodeDefault;
|
||||
}
|
||||
|
||||
mapSimpleLiteral(node: HermesNode): HermesNode {
|
||||
return {
|
||||
type: 'Literal',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
value: node.value,
|
||||
raw: this.code.slice(node.range[0], node.range[1]),
|
||||
literalType: (() => {
|
||||
switch (node.type) {
|
||||
case 'NullLiteral':
|
||||
return 'null';
|
||||
|
||||
case 'BooleanLiteral':
|
||||
return 'boolean';
|
||||
|
||||
case 'StringLiteral':
|
||||
case 'JSXStringLiteral':
|
||||
return 'string';
|
||||
|
||||
case 'NumericLiteral':
|
||||
return 'numeric';
|
||||
|
||||
case 'BigIntLiteral':
|
||||
return 'bigint';
|
||||
|
||||
case 'RegExpLiteral':
|
||||
return 'regexp';
|
||||
}
|
||||
return null;
|
||||
})(),
|
||||
};
|
||||
}
|
||||
|
||||
mapBigIntLiteral(node: HermesNode): HermesNode {
|
||||
const newNode = this.mapSimpleLiteral(node);
|
||||
return {
|
||||
...newNode,
|
||||
...this.getBigIntLiteralValue(node.bigint),
|
||||
};
|
||||
}
|
||||
|
||||
mapNullLiteral(node: HermesNode): HermesNode {
|
||||
return {
|
||||
...this.mapSimpleLiteral(node),
|
||||
value: null,
|
||||
};
|
||||
}
|
||||
|
||||
mapRegExpLiteral(node: HermesNode): HermesNode {
|
||||
const {pattern, flags} = node;
|
||||
|
||||
// Create RegExp value if possible. This can fail when the flags are invalid.
|
||||
let value;
|
||||
try {
|
||||
value = new RegExp(pattern, flags);
|
||||
} catch (e) {
|
||||
value = null;
|
||||
}
|
||||
|
||||
return {
|
||||
...this.mapSimpleLiteral(node),
|
||||
value,
|
||||
regex: {
|
||||
pattern,
|
||||
flags,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
mapBigIntLiteralTypeAnnotation(node: HermesNode): HermesNode {
|
||||
return {
|
||||
...node,
|
||||
...this.getBigIntLiteralValue(node.raw),
|
||||
};
|
||||
}
|
||||
|
||||
mapTemplateElement(node: HermesNode): HermesNode {
|
||||
return {
|
||||
type: 'TemplateElement',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
tail: node.tail,
|
||||
value: {
|
||||
cooked: node.cooked,
|
||||
raw: node.raw,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
mapGenericTypeAnnotation(node: HermesNode): HermesNode {
|
||||
// Convert simple `this` generic type to ThisTypeAnnotation
|
||||
if (
|
||||
node.typeParameters == null &&
|
||||
node.id.type === 'Identifier' &&
|
||||
node.id.name === 'this'
|
||||
) {
|
||||
return {
|
||||
type: 'ThisTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
};
|
||||
}
|
||||
|
||||
return this.mapNodeDefault(node);
|
||||
}
|
||||
|
||||
mapProperty(nodeUnprocessed: HermesNode): HermesNode {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
if (
|
||||
node.value.type === 'FunctionExpression' &&
|
||||
(node.method || node.kind !== 'init')
|
||||
) {
|
||||
node.value.loc.start = node.key.loc.end;
|
||||
node.value.range[0] = node.key.range[1];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapComment(node: HermesNode): HermesNode {
|
||||
if (node.type === 'CommentBlock') {
|
||||
node.type = 'Block';
|
||||
} else if (node.type === 'CommentLine') {
|
||||
node.type = 'Line';
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapFunction(nodeUnprocessed: HermesNode): HermesNode {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
switch (node.type) {
|
||||
// This prop should ideally only live on `ArrowFunctionExpression` but to
|
||||
// match espree output we place it on all functions types.
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
node.expression = false;
|
||||
return node;
|
||||
|
||||
case 'ArrowFunctionExpression':
|
||||
node.expression = node.body.type !== 'BlockStatement';
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapChainExpression(nodeUnprocessed: HermesNode): HermesNode {
|
||||
/*
|
||||
NOTE - In the below comments `MemberExpression` and `CallExpression`
|
||||
are completely interchangable. For terseness we just reference
|
||||
one each time.
|
||||
*/
|
||||
|
||||
/*
|
||||
Hermes uses the old babel-style AST:
|
||||
```
|
||||
(one?.two).three?.four;
|
||||
^^^^^^^^^^^^^^^^^^^^^^ OptionalMemberExpression
|
||||
^^^^^^^^^^^^^^^^ MemberExpression
|
||||
^^^^^^^^ OptionalMemberExpression
|
||||
```
|
||||
|
||||
We need to convert it to the ESTree representation:
|
||||
```
|
||||
(one?.two).three?.four;
|
||||
^^^^^^^^^^^^^^^^^^^^^^ ChainExpression
|
||||
^^^^^^^^^^^^^^^^^^^^^^ MemberExpression[optional = true]
|
||||
^^^^^^^^^^^^^^^^ MemberExpression[optional = false]
|
||||
^^^^^^^^ ChainExpression
|
||||
^^^^^^^^ MemberExpression[optional = true]
|
||||
```
|
||||
|
||||
We do this by converting the AST and its children (depth first), and then unwrapping
|
||||
the resulting AST as appropriate.
|
||||
|
||||
Put another way:
|
||||
1) traverse to the leaf
|
||||
2) if the current node is an `OptionalMemberExpression`:
|
||||
a) if the `.object` is a `ChainExpression`:
|
||||
i) unwrap the child (`node.object = child.expression`)
|
||||
b) convert this node to a `MemberExpression[optional = true]`
|
||||
c) wrap this node (`node = ChainExpression[expression = node]`)
|
||||
3) if the current node is a `MemberExpression`:
|
||||
a) convert this node to a `MemberExpression[optional = true]`
|
||||
*/
|
||||
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
const {child, childKey, isOptional} = ((): {
|
||||
child: HermesNode,
|
||||
childKey: string,
|
||||
isOptional: boolean,
|
||||
} => {
|
||||
const isOptional: boolean = node.optional === true;
|
||||
if (node.type.endsWith('MemberExpression')) {
|
||||
return {
|
||||
child: node.object,
|
||||
childKey: 'object',
|
||||
isOptional,
|
||||
};
|
||||
} else if (node.type.endsWith('CallExpression')) {
|
||||
return {
|
||||
child: node.callee,
|
||||
childKey: 'callee',
|
||||
isOptional,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
child: node.expression,
|
||||
childKey: 'expression',
|
||||
isOptional: false,
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
const isChildUnwrappable =
|
||||
child.type === 'ChainExpression' &&
|
||||
// (x?.y).z is semantically different to `x?.y.z`.
|
||||
// In the un-parenthesised case `.z` is only executed if and only if `x?.y` returns a non-nullish value.
|
||||
// In the parenthesised case, `.z` is **always** executed, regardless of the return of `x?.y`.
|
||||
// As such the AST is different between the two cases.
|
||||
//
|
||||
// In the hermes AST - any member part of a non-short-circuited optional chain is represented with `OptionalMemberExpression`
|
||||
// so if we see a `MemberExpression`, then we know we've hit a parenthesis boundary.
|
||||
node.type !== 'MemberExpression' &&
|
||||
node.type !== 'CallExpression';
|
||||
|
||||
if (node.type.startsWith('Optional')) {
|
||||
node.type = node.type.replace('Optional', '');
|
||||
node.optional = isOptional;
|
||||
} else {
|
||||
node.optional = false;
|
||||
}
|
||||
|
||||
if (!isChildUnwrappable && !isOptional) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (isChildUnwrappable) {
|
||||
const newChild = child.expression;
|
||||
node[childKey] = newChild;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'ChainExpression',
|
||||
expression: node,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
};
|
||||
}
|
||||
|
||||
mapClassProperty(nodeUnprocessed: HermesNode): HermesNode {
|
||||
const node = this.mapNodeDefault(nodeUnprocessed);
|
||||
|
||||
const key = (() => {
|
||||
if (node.type === 'ClassPrivateProperty') {
|
||||
const key = this.mapNodeDefault(node.key);
|
||||
return {
|
||||
type: 'PrivateIdentifier',
|
||||
name: key.name,
|
||||
range: key.range,
|
||||
loc: key.loc,
|
||||
};
|
||||
}
|
||||
|
||||
return node.key;
|
||||
})();
|
||||
|
||||
return {
|
||||
...node,
|
||||
computed: node.type === 'ClassPrivateProperty' ? false : node.computed,
|
||||
key,
|
||||
type: 'PropertyDefinition',
|
||||
};
|
||||
}
|
||||
|
||||
mapPrivateName(node: HermesNode): HermesNode {
|
||||
return {
|
||||
type: 'PrivateIdentifier',
|
||||
name: node.id.name,
|
||||
// estree the location refers to the entire string including the hash token
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
};
|
||||
}
|
||||
|
||||
mapExportNamedDeclaration(nodeUnprocessed: HermesNode): HermesNode {
|
||||
const node = super.mapExportNamedDeclaration(nodeUnprocessed);
|
||||
|
||||
const namespaceSpecifier = node.specifiers.find(
|
||||
spec => spec.type === 'ExportNamespaceSpecifier',
|
||||
);
|
||||
if (namespaceSpecifier != null) {
|
||||
if (node.specifiers.length !== 1) {
|
||||
// this should already a hermes parser error - but let's be absolutely sure we're aligned with the spec
|
||||
throw new Error('Cannot use an export all with any other specifiers');
|
||||
}
|
||||
return {
|
||||
type: 'ExportAllDeclaration',
|
||||
source: node.source,
|
||||
exportKind: node.exportKind ?? 'value',
|
||||
exported: namespaceSpecifier.exported,
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
};
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mapExportAllDeclaration(nodeUnprocessed: HermesNode): HermesNode {
|
||||
const node = super.mapExportAllDeclaration(nodeUnprocessed);
|
||||
node.exported = node.exported ?? null;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
18
node_modules/hermes-parser/dist/ParserOptions.js
generated
vendored
Normal file
18
node_modules/hermes-parser/dist/ParserOptions.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ParserOptionsKeys = void 0;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
const ParserOptionsKeys = new Set(['allowReturnOutsideFunction', 'babel', 'flow', 'enableExperimentalComponentSyntax', 'reactRuntimeTarget', 'sourceFilename', 'sourceType', 'tokens']);
|
||||
exports.ParserOptionsKeys = ParserOptionsKeys;
|
||||
31
node_modules/hermes-parser/dist/ParserOptions.js.flow
generated
vendored
Normal file
31
node_modules/hermes-parser/dist/ParserOptions.js.flow
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
export type ParserOptions = {
|
||||
allowReturnOutsideFunction?: boolean,
|
||||
babel?: boolean,
|
||||
flow?: 'all' | 'detect',
|
||||
enableExperimentalComponentSyntax?: boolean,
|
||||
reactRuntimeTarget?: '18' | '19',
|
||||
sourceFilename?: string,
|
||||
sourceType?: 'module' | 'script' | 'unambiguous',
|
||||
tokens?: boolean,
|
||||
};
|
||||
|
||||
export const ParserOptionsKeys: $ReadOnlySet<$Keys<ParserOptions>> = new Set([
|
||||
'allowReturnOutsideFunction',
|
||||
'babel',
|
||||
'flow',
|
||||
'enableExperimentalComponentSyntax',
|
||||
'reactRuntimeTarget',
|
||||
'sourceFilename',
|
||||
'sourceType',
|
||||
'tokens',
|
||||
]);
|
||||
1104
node_modules/hermes-parser/dist/babel/TransformESTreeToBabel.js
generated
vendored
Normal file
1104
node_modules/hermes-parser/dist/babel/TransformESTreeToBabel.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1260
node_modules/hermes-parser/dist/babel/TransformESTreeToBabel.js.flow
generated
vendored
Normal file
1260
node_modules/hermes-parser/dist/babel/TransformESTreeToBabel.js.flow
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
788
node_modules/hermes-parser/dist/estree/StripComponentSyntax.js
generated
vendored
Normal file
788
node_modules/hermes-parser/dist/estree/StripComponentSyntax.js
generated
vendored
Normal file
@@ -0,0 +1,788 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transforms component syntax (https://flow.org/en/docs/react/component-syntax/)
|
||||
* and hook syntax (https://flow.org/en/docs/react/hook-syntax/).
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.transformProgram = transformProgram;
|
||||
|
||||
var _SimpleTransform = require("../transform/SimpleTransform");
|
||||
|
||||
var _astNodeMutationHelpers = require("../transform/astNodeMutationHelpers");
|
||||
|
||||
var _SimpleTraverser = require("../traverse/SimpleTraverser");
|
||||
|
||||
var _createSyntaxError = require("../utils/createSyntaxError");
|
||||
|
||||
const nodeWith = _SimpleTransform.SimpleTransform.nodeWith; // Rely on the mapper to fix up parent relationships.
|
||||
|
||||
const EMPTY_PARENT = null;
|
||||
|
||||
function createDefaultPosition() {
|
||||
return {
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
}
|
||||
|
||||
function mapDeclareComponent(node) {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT
|
||||
}
|
||||
}),
|
||||
kind: 'const',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
|
||||
function getComponentParameterName(paramName) {
|
||||
switch (paramName.type) {
|
||||
case 'Identifier':
|
||||
return paramName.name;
|
||||
|
||||
case 'Literal':
|
||||
return paramName.value;
|
||||
|
||||
default:
|
||||
throw (0, _createSyntaxError.createSyntaxError)(paramName, `Unknown Component parameter name type of "${paramName.type}"`);
|
||||
}
|
||||
}
|
||||
|
||||
function createPropsTypeAnnotation(propTypes, spread, loc, range) {
|
||||
// Create empty loc for type annotation nodes
|
||||
const createParamsTypeLoc = () => ({
|
||||
loc: {
|
||||
start: (loc == null ? void 0 : loc.start) != null ? loc.start : createDefaultPosition(),
|
||||
end: (loc == null ? void 0 : loc.end) != null ? loc.end : createDefaultPosition()
|
||||
},
|
||||
range: range != null ? range : [0, 0],
|
||||
parent: EMPTY_PARENT
|
||||
}); // Optimize `{...Props}` -> `Props`
|
||||
|
||||
|
||||
if (spread != null && propTypes.length === 0) {
|
||||
return {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: spread.argument,
|
||||
...createParamsTypeLoc()
|
||||
};
|
||||
}
|
||||
|
||||
const typeProperties = [...propTypes];
|
||||
|
||||
if (spread != null) {
|
||||
// Spread needs to be the first type, as inline properties take precedence.
|
||||
typeProperties.unshift(spread);
|
||||
}
|
||||
|
||||
const propTypeObj = {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
callProperties: [],
|
||||
properties: typeProperties,
|
||||
indexers: [],
|
||||
internalSlots: [],
|
||||
exact: false,
|
||||
inexact: false,
|
||||
...createParamsTypeLoc()
|
||||
};
|
||||
return {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: '$ReadOnly',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createParamsTypeLoc()
|
||||
},
|
||||
typeParameters: {
|
||||
type: 'TypeParameterInstantiation',
|
||||
params: [propTypeObj],
|
||||
...createParamsTypeLoc()
|
||||
},
|
||||
...createParamsTypeLoc()
|
||||
},
|
||||
...createParamsTypeLoc()
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameters(params, options) {
|
||||
var _options$reactRuntime;
|
||||
|
||||
if (params.length === 0) {
|
||||
return {
|
||||
props: null,
|
||||
ref: null
|
||||
};
|
||||
} // Optimize `component Foo(...props: Props) {}` to `function Foo(props: Props) {}
|
||||
|
||||
|
||||
if (params.length === 1 && params[0].type === 'RestElement' && params[0].argument.type === 'Identifier') {
|
||||
const restElementArgument = params[0].argument;
|
||||
return {
|
||||
props: restElementArgument,
|
||||
ref: null
|
||||
};
|
||||
} // Filter out any ref param and capture it's details when targeting React 18.
|
||||
// React 19+ treats ref as a regular prop for function components.
|
||||
|
||||
|
||||
let refParam = null;
|
||||
const paramsWithoutRef = ((_options$reactRuntime = options.reactRuntimeTarget) != null ? _options$reactRuntime : '18') === '18' ? params.filter(param => {
|
||||
if (param.type === 'ComponentParameter' && getComponentParameterName(param.name) === 'ref') {
|
||||
refParam = param;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}) : params;
|
||||
const [propTypes, spread] = paramsWithoutRef.reduce(([propTypes, spread], param) => {
|
||||
switch (param.type) {
|
||||
case 'RestElement':
|
||||
{
|
||||
if (spread != null) {
|
||||
throw (0, _createSyntaxError.createSyntaxError)(param, `Invalid state, multiple rest elements found as Component Parameters`);
|
||||
}
|
||||
|
||||
return [propTypes, mapComponentParameterRestElementType(param)];
|
||||
}
|
||||
|
||||
case 'ComponentParameter':
|
||||
{
|
||||
propTypes.push(mapComponentParameterType(param));
|
||||
return [propTypes, spread];
|
||||
}
|
||||
}
|
||||
}, [[], null]);
|
||||
const propsProperties = paramsWithoutRef.flatMap(mapComponentParameter);
|
||||
let props = null;
|
||||
|
||||
if (propsProperties.length === 0) {
|
||||
if (refParam == null) {
|
||||
throw new Error('StripComponentSyntax: Invalid state, ref should always be set at this point if props are empty');
|
||||
}
|
||||
|
||||
const emptyParamsLoc = {
|
||||
start: refParam.loc.start,
|
||||
end: refParam.loc.start
|
||||
};
|
||||
const emptyParamsRange = [refParam.range[0], refParam.range[0]]; // no properties provided (must have had a single ref)
|
||||
|
||||
props = {
|
||||
type: 'Identifier',
|
||||
name: '_$$empty_props_placeholder$$',
|
||||
optional: false,
|
||||
typeAnnotation: createPropsTypeAnnotation([], null, emptyParamsLoc, emptyParamsRange),
|
||||
loc: emptyParamsLoc,
|
||||
range: emptyParamsRange,
|
||||
parent: EMPTY_PARENT
|
||||
};
|
||||
} else {
|
||||
const lastPropsProperty = propsProperties[propsProperties.length - 1];
|
||||
props = {
|
||||
type: 'ObjectPattern',
|
||||
properties: propsProperties,
|
||||
typeAnnotation: createPropsTypeAnnotation(propTypes, spread, {
|
||||
start: lastPropsProperty.loc.end,
|
||||
end: lastPropsProperty.loc.end
|
||||
}, [lastPropsProperty.range[1], lastPropsProperty.range[1]]),
|
||||
loc: {
|
||||
start: propsProperties[0].loc.start,
|
||||
end: lastPropsProperty.loc.end
|
||||
},
|
||||
range: [propsProperties[0].range[0], lastPropsProperty.range[1]],
|
||||
parent: EMPTY_PARENT
|
||||
};
|
||||
}
|
||||
|
||||
let ref = null;
|
||||
|
||||
if (refParam != null) {
|
||||
ref = refParam.local;
|
||||
}
|
||||
|
||||
return {
|
||||
props,
|
||||
ref
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameterType(param) {
|
||||
var _typeAnnotation$typeA;
|
||||
|
||||
const typeAnnotation = param.local.type === 'AssignmentPattern' ? param.local.left.typeAnnotation : param.local.typeAnnotation;
|
||||
const optional = param.local.type === 'AssignmentPattern' ? true : param.local.type === 'Identifier' ? param.local.optional : false;
|
||||
return {
|
||||
type: 'ObjectTypeProperty',
|
||||
key: (0, _astNodeMutationHelpers.shallowCloneNode)(param.name),
|
||||
value: (_typeAnnotation$typeA = typeAnnotation == null ? void 0 : typeAnnotation.typeAnnotation) != null ? _typeAnnotation$typeA : {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: param.local.loc,
|
||||
range: param.local.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
kind: 'init',
|
||||
optional,
|
||||
method: false,
|
||||
static: false,
|
||||
proto: false,
|
||||
variance: null,
|
||||
loc: param.local.loc,
|
||||
range: param.local.range,
|
||||
parent: EMPTY_PARENT
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameterRestElementType(param) {
|
||||
var _param$argument$typeA, _param$argument$typeA2;
|
||||
|
||||
if (param.argument.type !== 'Identifier' && param.argument.type !== 'ObjectPattern') {
|
||||
throw (0, _createSyntaxError.createSyntaxError)(param, `Invalid ${param.argument.type} encountered in restParameter`);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'ObjectTypeSpreadProperty',
|
||||
argument: (_param$argument$typeA = (_param$argument$typeA2 = param.argument.typeAnnotation) == null ? void 0 : _param$argument$typeA2.typeAnnotation) != null ? _param$argument$typeA : {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameter(param) {
|
||||
switch (param.type) {
|
||||
case 'RestElement':
|
||||
{
|
||||
switch (param.argument.type) {
|
||||
case 'Identifier':
|
||||
{
|
||||
const a = nodeWith(param, {
|
||||
typeAnnotation: null,
|
||||
argument: nodeWith(param.argument, {
|
||||
typeAnnotation: null
|
||||
})
|
||||
});
|
||||
return [a];
|
||||
}
|
||||
|
||||
case 'ObjectPattern':
|
||||
{
|
||||
return param.argument.properties.map(property => {
|
||||
return nodeWith(property, {
|
||||
typeAnnotation: null
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw (0, _createSyntaxError.createSyntaxError)(param, `Unhandled ${param.argument.type} encountered in restParameter`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case 'ComponentParameter':
|
||||
{
|
||||
let value;
|
||||
|
||||
if (param.local.type === 'AssignmentPattern') {
|
||||
value = nodeWith(param.local, {
|
||||
left: nodeWith(param.local.left, {
|
||||
typeAnnotation: null,
|
||||
optional: false
|
||||
})
|
||||
});
|
||||
} else {
|
||||
value = nodeWith(param.local, {
|
||||
typeAnnotation: null,
|
||||
optional: false
|
||||
});
|
||||
} // Shorthand params
|
||||
|
||||
|
||||
if (param.name.type === 'Identifier' && param.shorthand && (value.type === 'Identifier' || value.type === 'AssignmentPattern')) {
|
||||
return [{
|
||||
type: 'Property',
|
||||
key: param.name,
|
||||
kind: 'init',
|
||||
value,
|
||||
method: false,
|
||||
shorthand: true,
|
||||
computed: false,
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT
|
||||
}];
|
||||
} // Complex params
|
||||
|
||||
|
||||
return [{
|
||||
type: 'Property',
|
||||
key: param.name,
|
||||
kind: 'init',
|
||||
value,
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT
|
||||
}];
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw (0, _createSyntaxError.createSyntaxError)(param, `Unknown Component parameter type of "${param.type}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createForwardRefWrapper(originalComponent) {
|
||||
const internalCompId = {
|
||||
type: 'Identifier',
|
||||
name: `${originalComponent.id.name}_withRef`,
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.id.loc,
|
||||
range: originalComponent.id.range,
|
||||
parent: EMPTY_PARENT
|
||||
};
|
||||
return {
|
||||
forwardRefStatement: {
|
||||
type: 'VariableDeclaration',
|
||||
kind: 'const',
|
||||
declarations: [{
|
||||
type: 'VariableDeclarator',
|
||||
id: (0, _astNodeMutationHelpers.shallowCloneNode)(originalComponent.id),
|
||||
init: {
|
||||
type: 'CallExpression',
|
||||
callee: {
|
||||
type: 'MemberExpression',
|
||||
object: {
|
||||
type: 'Identifier',
|
||||
name: 'React',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
name: 'forwardRef',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
computed: false,
|
||||
optional: false,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
arguments: [(0, _astNodeMutationHelpers.shallowCloneNode)(internalCompId)],
|
||||
typeArguments: null,
|
||||
optional: false,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT
|
||||
}],
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: originalComponent.parent
|
||||
},
|
||||
internalCompId: internalCompId,
|
||||
forwardRefCompId: originalComponent.id
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentDeclaration(node, options) {
|
||||
// Create empty loc for return type annotation nodes
|
||||
const createRendersTypeLoc = () => ({
|
||||
loc: {
|
||||
start: node.body.loc.end,
|
||||
end: node.body.loc.end
|
||||
},
|
||||
range: [node.body.range[1], node.body.range[1]],
|
||||
parent: EMPTY_PARENT
|
||||
});
|
||||
|
||||
const returnType = {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'QualifiedTypeIdentifier',
|
||||
qualification: {
|
||||
type: 'Identifier',
|
||||
name: 'React',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createRendersTypeLoc()
|
||||
},
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: 'Node',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createRendersTypeLoc()
|
||||
},
|
||||
...createRendersTypeLoc()
|
||||
},
|
||||
typeParameters: null,
|
||||
...createRendersTypeLoc()
|
||||
},
|
||||
...createRendersTypeLoc()
|
||||
};
|
||||
const {
|
||||
props,
|
||||
ref
|
||||
} = mapComponentParameters(node.params, options);
|
||||
let forwardRefDetails = null;
|
||||
|
||||
if (ref != null) {
|
||||
forwardRefDetails = createForwardRefWrapper(node);
|
||||
}
|
||||
|
||||
const comp = {
|
||||
type: 'FunctionDeclaration',
|
||||
id: forwardRefDetails != null ? (0, _astNodeMutationHelpers.shallowCloneNode)(forwardRefDetails.internalCompId) : (0, _astNodeMutationHelpers.shallowCloneNode)(node.id),
|
||||
__componentDeclaration: true,
|
||||
typeParameters: node.typeParameters,
|
||||
params: props == null ? [] : ref == null ? [props] : [props, ref],
|
||||
returnType,
|
||||
body: node.body,
|
||||
async: false,
|
||||
generator: false,
|
||||
predicate: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
return {
|
||||
comp,
|
||||
forwardRefDetails
|
||||
};
|
||||
}
|
||||
|
||||
function mapDeclareHook(node) {
|
||||
return {
|
||||
type: 'DeclareFunction',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: node.id.name,
|
||||
optional: node.id.optional,
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
this: null,
|
||||
params: node.id.typeAnnotation.typeAnnotation.params,
|
||||
typeParameters: node.id.typeAnnotation.typeAnnotation.typeParameters,
|
||||
rest: node.id.typeAnnotation.typeAnnotation.rest,
|
||||
returnType: node.id.typeAnnotation.typeAnnotation.returnType,
|
||||
loc: node.id.typeAnnotation.typeAnnotation.loc,
|
||||
range: node.id.typeAnnotation.typeAnnotation.range,
|
||||
parent: node.id.typeAnnotation.typeAnnotation.parent
|
||||
},
|
||||
loc: node.id.typeAnnotation.loc,
|
||||
range: node.id.typeAnnotation.range,
|
||||
parent: node.id.typeAnnotation.parent
|
||||
},
|
||||
loc: node.id.loc,
|
||||
range: node.id.range,
|
||||
parent: node.id.parent
|
||||
},
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
predicate: null
|
||||
};
|
||||
}
|
||||
|
||||
function mapHookDeclaration(node) {
|
||||
const comp = {
|
||||
type: 'FunctionDeclaration',
|
||||
id: node.id && (0, _astNodeMutationHelpers.shallowCloneNode)(node.id),
|
||||
__hookDeclaration: true,
|
||||
typeParameters: node.typeParameters,
|
||||
params: node.params,
|
||||
returnType: node.returnType,
|
||||
body: node.body,
|
||||
async: false,
|
||||
generator: false,
|
||||
predicate: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
return comp;
|
||||
}
|
||||
/**
|
||||
* Scan a list of statements and return the position of the
|
||||
* first statement that contains a reference to a given component
|
||||
* or null of no references were found.
|
||||
*/
|
||||
|
||||
|
||||
function scanForFirstComponentReference(compName, bodyList) {
|
||||
for (let i = 0; i < bodyList.length; i++) {
|
||||
const bodyNode = bodyList[i];
|
||||
let referencePos = null;
|
||||
|
||||
_SimpleTraverser.SimpleTraverser.traverse(bodyNode, {
|
||||
enter(node) {
|
||||
switch (node.type) {
|
||||
case 'Identifier':
|
||||
{
|
||||
if (node.name === compName) {
|
||||
// We found a reference, record it and stop.
|
||||
referencePos = i;
|
||||
throw _SimpleTraverser.SimpleTraverser.Break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
leave(_node) {}
|
||||
|
||||
});
|
||||
|
||||
if (referencePos != null) {
|
||||
return referencePos;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function mapComponentDeclarationIntoList(node, newBody, options, insertExport) {
|
||||
const {
|
||||
comp,
|
||||
forwardRefDetails
|
||||
} = mapComponentDeclaration(node, options);
|
||||
|
||||
if (forwardRefDetails != null) {
|
||||
// Scan for references to our component.
|
||||
const referencePos = scanForFirstComponentReference(forwardRefDetails.forwardRefCompId.name, newBody); // If a reference is found insert the forwardRef statement before it (to simulate function hoisting).
|
||||
|
||||
if (referencePos != null) {
|
||||
newBody.splice(referencePos, 0, forwardRefDetails.forwardRefStatement);
|
||||
} else {
|
||||
newBody.push(forwardRefDetails.forwardRefStatement);
|
||||
}
|
||||
|
||||
newBody.push(comp);
|
||||
|
||||
if (insertExport != null) {
|
||||
newBody.push(insertExport(forwardRefDetails.forwardRefCompId));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
newBody.push(insertExport != null ? insertExport(comp) : comp);
|
||||
}
|
||||
|
||||
function mapStatementList(stmts, options) {
|
||||
const newBody = [];
|
||||
|
||||
for (const node of stmts) {
|
||||
switch (node.type) {
|
||||
case 'ComponentDeclaration':
|
||||
{
|
||||
mapComponentDeclarationIntoList(node, newBody, options);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'HookDeclaration':
|
||||
{
|
||||
const decl = mapHookDeclaration(node);
|
||||
newBody.push(decl);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ExportNamedDeclaration':
|
||||
{
|
||||
var _node$declaration, _node$declaration2;
|
||||
|
||||
if (((_node$declaration = node.declaration) == null ? void 0 : _node$declaration.type) === 'ComponentDeclaration') {
|
||||
mapComponentDeclarationIntoList(node.declaration, newBody, options, componentOrRef => {
|
||||
switch (componentOrRef.type) {
|
||||
case 'FunctionDeclaration':
|
||||
{
|
||||
// No ref, so we can export the component directly.
|
||||
return nodeWith(node, {
|
||||
declaration: componentOrRef
|
||||
});
|
||||
}
|
||||
|
||||
case 'Identifier':
|
||||
{
|
||||
// If a ref is inserted, we should just export that id.
|
||||
return {
|
||||
type: 'ExportNamedDeclaration',
|
||||
declaration: null,
|
||||
specifiers: [{
|
||||
type: 'ExportSpecifier',
|
||||
exported: (0, _astNodeMutationHelpers.shallowCloneNode)(componentOrRef),
|
||||
local: (0, _astNodeMutationHelpers.shallowCloneNode)(componentOrRef),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT
|
||||
}],
|
||||
exportKind: 'value',
|
||||
source: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (((_node$declaration2 = node.declaration) == null ? void 0 : _node$declaration2.type) === 'HookDeclaration') {
|
||||
const comp = mapHookDeclaration(node.declaration);
|
||||
newBody.push(nodeWith(node, {
|
||||
declaration: comp
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
newBody.push(node);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ExportDefaultDeclaration':
|
||||
{
|
||||
var _node$declaration3, _node$declaration4;
|
||||
|
||||
if (((_node$declaration3 = node.declaration) == null ? void 0 : _node$declaration3.type) === 'ComponentDeclaration') {
|
||||
mapComponentDeclarationIntoList(node.declaration, newBody, options, componentOrRef => nodeWith(node, {
|
||||
declaration: componentOrRef
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
if (((_node$declaration4 = node.declaration) == null ? void 0 : _node$declaration4.type) === 'HookDeclaration') {
|
||||
const comp = mapHookDeclaration(node.declaration);
|
||||
newBody.push(nodeWith(node, {
|
||||
declaration: comp
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
newBody.push(node);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
newBody.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newBody;
|
||||
}
|
||||
|
||||
function transformProgram(program, options) {
|
||||
return _SimpleTransform.SimpleTransform.transformProgram(program, {
|
||||
transform(node) {
|
||||
switch (node.type) {
|
||||
case 'DeclareComponent':
|
||||
{
|
||||
return mapDeclareComponent(node);
|
||||
}
|
||||
|
||||
case 'DeclareHook':
|
||||
{
|
||||
return mapDeclareHook(node);
|
||||
}
|
||||
|
||||
case 'Program':
|
||||
case 'BlockStatement':
|
||||
{
|
||||
return nodeWith(node, {
|
||||
body: mapStatementList(node.body, options)
|
||||
});
|
||||
}
|
||||
|
||||
case 'SwitchCase':
|
||||
{
|
||||
const consequent = mapStatementList(node.consequent, options);
|
||||
return nodeWith(node, {
|
||||
/* $FlowExpectedError[incompatible-call] We know `mapStatementList` will
|
||||
not return `ModuleDeclaration` nodes if it is not passed any */
|
||||
consequent
|
||||
});
|
||||
}
|
||||
|
||||
case 'ComponentDeclaration':
|
||||
{
|
||||
var _node$parent;
|
||||
|
||||
throw (0, _createSyntaxError.createSyntaxError)(node, `Components must be defined at the top level of a module or within a ` + `BlockStatement, instead got parent of "${(_node$parent = node.parent) == null ? void 0 : _node$parent.type}".`);
|
||||
}
|
||||
|
||||
case 'HookDeclaration':
|
||||
{
|
||||
var _node$parent2;
|
||||
|
||||
throw (0, _createSyntaxError.createSyntaxError)(node, `Hooks must be defined at the top level of a module or within a ` + `BlockStatement, instead got parent of "${(_node$parent2 = node.parent) == null ? void 0 : _node$parent2.type}".`);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
863
node_modules/hermes-parser/dist/estree/StripComponentSyntax.js.flow
generated
vendored
Normal file
863
node_modules/hermes-parser/dist/estree/StripComponentSyntax.js.flow
generated
vendored
Normal file
@@ -0,0 +1,863 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transforms component syntax (https://flow.org/en/docs/react/component-syntax/)
|
||||
* and hook syntax (https://flow.org/en/docs/react/hook-syntax/).
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ParserOptions} from '../ParserOptions';
|
||||
import type {
|
||||
Program,
|
||||
ESNode,
|
||||
DeclareComponent,
|
||||
DeclareVariable,
|
||||
ComponentDeclaration,
|
||||
FunctionDeclaration,
|
||||
TypeAnnotation,
|
||||
ComponentParameter,
|
||||
SourceLocation,
|
||||
Position,
|
||||
ObjectPattern,
|
||||
Identifier,
|
||||
Range,
|
||||
RestElement,
|
||||
DestructuringObjectProperty,
|
||||
VariableDeclaration,
|
||||
ModuleDeclaration,
|
||||
DeclareHook,
|
||||
DeclareFunction,
|
||||
HookDeclaration,
|
||||
Statement,
|
||||
AssignmentPattern,
|
||||
BindingName,
|
||||
ObjectTypePropertySignature,
|
||||
ObjectTypeSpreadProperty,
|
||||
} from 'hermes-estree';
|
||||
|
||||
import {SimpleTransform} from '../transform/SimpleTransform';
|
||||
import {shallowCloneNode} from '../transform/astNodeMutationHelpers';
|
||||
import {SimpleTraverser} from '../traverse/SimpleTraverser';
|
||||
import {createSyntaxError} from '../utils/createSyntaxError';
|
||||
|
||||
const nodeWith = SimpleTransform.nodeWith;
|
||||
|
||||
// Rely on the mapper to fix up parent relationships.
|
||||
const EMPTY_PARENT: $FlowFixMe = null;
|
||||
|
||||
function createDefaultPosition(): Position {
|
||||
return {
|
||||
line: 1,
|
||||
column: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDeclareComponent(node: DeclareComponent): DeclareVariable {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
}),
|
||||
kind: 'const',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
|
||||
function getComponentParameterName(
|
||||
paramName: ComponentParameter['name'],
|
||||
): string {
|
||||
switch (paramName.type) {
|
||||
case 'Identifier':
|
||||
return paramName.name;
|
||||
case 'Literal':
|
||||
return paramName.value;
|
||||
default:
|
||||
throw createSyntaxError(
|
||||
paramName,
|
||||
`Unknown Component parameter name type of "${paramName.type}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function createPropsTypeAnnotation(
|
||||
propTypes: Array<ObjectTypePropertySignature>,
|
||||
spread: ?ObjectTypeSpreadProperty,
|
||||
loc: ?SourceLocation,
|
||||
range: ?Range,
|
||||
): TypeAnnotation {
|
||||
// Create empty loc for type annotation nodes
|
||||
const createParamsTypeLoc = () => ({
|
||||
loc: {
|
||||
start: loc?.start != null ? loc.start : createDefaultPosition(),
|
||||
end: loc?.end != null ? loc.end : createDefaultPosition(),
|
||||
},
|
||||
range: range ?? [0, 0],
|
||||
parent: EMPTY_PARENT,
|
||||
});
|
||||
|
||||
// Optimize `{...Props}` -> `Props`
|
||||
if (spread != null && propTypes.length === 0) {
|
||||
return {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: spread.argument,
|
||||
...createParamsTypeLoc(),
|
||||
};
|
||||
}
|
||||
|
||||
const typeProperties: Array<
|
||||
ObjectTypePropertySignature | ObjectTypeSpreadProperty,
|
||||
> = [...propTypes];
|
||||
|
||||
if (spread != null) {
|
||||
// Spread needs to be the first type, as inline properties take precedence.
|
||||
typeProperties.unshift(spread);
|
||||
}
|
||||
|
||||
const propTypeObj = {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
callProperties: [],
|
||||
properties: typeProperties,
|
||||
indexers: [],
|
||||
internalSlots: [],
|
||||
exact: false,
|
||||
inexact: false,
|
||||
...createParamsTypeLoc(),
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: '$ReadOnly',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createParamsTypeLoc(),
|
||||
},
|
||||
typeParameters: {
|
||||
type: 'TypeParameterInstantiation',
|
||||
params: [propTypeObj],
|
||||
...createParamsTypeLoc(),
|
||||
},
|
||||
...createParamsTypeLoc(),
|
||||
},
|
||||
...createParamsTypeLoc(),
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameters(
|
||||
params: $ReadOnlyArray<ComponentParameter | RestElement>,
|
||||
options: ParserOptions,
|
||||
): $ReadOnly<{
|
||||
props: ?(ObjectPattern | Identifier),
|
||||
ref: ?(BindingName | AssignmentPattern),
|
||||
}> {
|
||||
if (params.length === 0) {
|
||||
return {props: null, ref: null};
|
||||
}
|
||||
|
||||
// Optimize `component Foo(...props: Props) {}` to `function Foo(props: Props) {}
|
||||
if (
|
||||
params.length === 1 &&
|
||||
params[0].type === 'RestElement' &&
|
||||
params[0].argument.type === 'Identifier'
|
||||
) {
|
||||
const restElementArgument = params[0].argument;
|
||||
return {
|
||||
props: restElementArgument,
|
||||
ref: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Filter out any ref param and capture it's details when targeting React 18.
|
||||
// React 19+ treats ref as a regular prop for function components.
|
||||
let refParam = null;
|
||||
const paramsWithoutRef =
|
||||
(options.reactRuntimeTarget ?? '18') === '18'
|
||||
? params.filter(param => {
|
||||
if (
|
||||
param.type === 'ComponentParameter' &&
|
||||
getComponentParameterName(param.name) === 'ref'
|
||||
) {
|
||||
refParam = param;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
: params;
|
||||
|
||||
const [propTypes, spread] = paramsWithoutRef.reduce<
|
||||
[Array<ObjectTypePropertySignature>, ?ObjectTypeSpreadProperty],
|
||||
>(
|
||||
([propTypes, spread], param) => {
|
||||
switch (param.type) {
|
||||
case 'RestElement': {
|
||||
if (spread != null) {
|
||||
throw createSyntaxError(
|
||||
param,
|
||||
`Invalid state, multiple rest elements found as Component Parameters`,
|
||||
);
|
||||
}
|
||||
return [propTypes, mapComponentParameterRestElementType(param)];
|
||||
}
|
||||
case 'ComponentParameter': {
|
||||
propTypes.push(mapComponentParameterType(param));
|
||||
return [propTypes, spread];
|
||||
}
|
||||
}
|
||||
},
|
||||
[[], null],
|
||||
);
|
||||
|
||||
const propsProperties = paramsWithoutRef.flatMap(mapComponentParameter);
|
||||
|
||||
let props = null;
|
||||
if (propsProperties.length === 0) {
|
||||
if (refParam == null) {
|
||||
throw new Error(
|
||||
'StripComponentSyntax: Invalid state, ref should always be set at this point if props are empty',
|
||||
);
|
||||
}
|
||||
const emptyParamsLoc = {
|
||||
start: refParam.loc.start,
|
||||
end: refParam.loc.start,
|
||||
};
|
||||
const emptyParamsRange = [refParam.range[0], refParam.range[0]];
|
||||
// no properties provided (must have had a single ref)
|
||||
props = {
|
||||
type: 'Identifier',
|
||||
name: '_$$empty_props_placeholder$$',
|
||||
optional: false,
|
||||
typeAnnotation: createPropsTypeAnnotation(
|
||||
[],
|
||||
null,
|
||||
emptyParamsLoc,
|
||||
emptyParamsRange,
|
||||
),
|
||||
loc: emptyParamsLoc,
|
||||
range: emptyParamsRange,
|
||||
parent: EMPTY_PARENT,
|
||||
};
|
||||
} else {
|
||||
const lastPropsProperty = propsProperties[propsProperties.length - 1];
|
||||
props = {
|
||||
type: 'ObjectPattern',
|
||||
properties: propsProperties,
|
||||
typeAnnotation: createPropsTypeAnnotation(
|
||||
propTypes,
|
||||
spread,
|
||||
{
|
||||
start: lastPropsProperty.loc.end,
|
||||
end: lastPropsProperty.loc.end,
|
||||
},
|
||||
[lastPropsProperty.range[1], lastPropsProperty.range[1]],
|
||||
),
|
||||
loc: {
|
||||
start: propsProperties[0].loc.start,
|
||||
end: lastPropsProperty.loc.end,
|
||||
},
|
||||
range: [propsProperties[0].range[0], lastPropsProperty.range[1]],
|
||||
parent: EMPTY_PARENT,
|
||||
};
|
||||
}
|
||||
|
||||
let ref = null;
|
||||
if (refParam != null) {
|
||||
ref = refParam.local;
|
||||
}
|
||||
|
||||
return {
|
||||
props,
|
||||
ref,
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameterType(
|
||||
param: ComponentParameter,
|
||||
): ObjectTypePropertySignature {
|
||||
const typeAnnotation =
|
||||
param.local.type === 'AssignmentPattern'
|
||||
? param.local.left.typeAnnotation
|
||||
: param.local.typeAnnotation;
|
||||
const optional =
|
||||
param.local.type === 'AssignmentPattern'
|
||||
? true
|
||||
: param.local.type === 'Identifier'
|
||||
? param.local.optional
|
||||
: false;
|
||||
|
||||
return {
|
||||
type: 'ObjectTypeProperty',
|
||||
key: shallowCloneNode(param.name),
|
||||
value: typeAnnotation?.typeAnnotation ?? {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: param.local.loc,
|
||||
range: param.local.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
kind: 'init',
|
||||
optional,
|
||||
method: false,
|
||||
static: false,
|
||||
proto: false,
|
||||
variance: null,
|
||||
loc: param.local.loc,
|
||||
range: param.local.range,
|
||||
parent: EMPTY_PARENT,
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameterRestElementType(
|
||||
param: RestElement,
|
||||
): ObjectTypeSpreadProperty {
|
||||
if (
|
||||
param.argument.type !== 'Identifier' &&
|
||||
param.argument.type !== 'ObjectPattern'
|
||||
) {
|
||||
throw createSyntaxError(
|
||||
param,
|
||||
`Invalid ${param.argument.type} encountered in restParameter`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
type: 'ObjectTypeSpreadProperty',
|
||||
argument: param.argument.typeAnnotation?.typeAnnotation ?? {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT,
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentParameter(
|
||||
param: ComponentParameter | RestElement,
|
||||
): Array<DestructuringObjectProperty | RestElement> {
|
||||
switch (param.type) {
|
||||
case 'RestElement': {
|
||||
switch (param.argument.type) {
|
||||
case 'Identifier': {
|
||||
const a = nodeWith(param, {
|
||||
typeAnnotation: null,
|
||||
argument: nodeWith(param.argument, {typeAnnotation: null}),
|
||||
});
|
||||
return [a];
|
||||
}
|
||||
case 'ObjectPattern': {
|
||||
return param.argument.properties.map(property => {
|
||||
return nodeWith(property, {
|
||||
typeAnnotation: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
default: {
|
||||
throw createSyntaxError(
|
||||
param,
|
||||
`Unhandled ${param.argument.type} encountered in restParameter`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'ComponentParameter': {
|
||||
let value;
|
||||
if (param.local.type === 'AssignmentPattern') {
|
||||
value = nodeWith(param.local, {
|
||||
left: nodeWith(param.local.left, {
|
||||
typeAnnotation: null,
|
||||
optional: false,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
value = nodeWith(param.local, {
|
||||
typeAnnotation: null,
|
||||
optional: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Shorthand params
|
||||
if (
|
||||
param.name.type === 'Identifier' &&
|
||||
param.shorthand &&
|
||||
(value.type === 'Identifier' || value.type === 'AssignmentPattern')
|
||||
) {
|
||||
return [
|
||||
{
|
||||
type: 'Property',
|
||||
key: param.name,
|
||||
kind: 'init',
|
||||
value,
|
||||
method: false,
|
||||
shorthand: true,
|
||||
computed: false,
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// Complex params
|
||||
return [
|
||||
{
|
||||
type: 'Property',
|
||||
key: param.name,
|
||||
kind: 'init',
|
||||
value,
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
loc: param.loc,
|
||||
range: param.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
];
|
||||
}
|
||||
default: {
|
||||
throw createSyntaxError(
|
||||
param,
|
||||
`Unknown Component parameter type of "${param.type}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ForwardRefDetails = {
|
||||
forwardRefStatement: VariableDeclaration,
|
||||
internalCompId: Identifier,
|
||||
forwardRefCompId: Identifier,
|
||||
};
|
||||
|
||||
function createForwardRefWrapper(
|
||||
originalComponent: ComponentDeclaration,
|
||||
): ForwardRefDetails {
|
||||
const internalCompId = {
|
||||
type: 'Identifier',
|
||||
name: `${originalComponent.id.name}_withRef`,
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.id.loc,
|
||||
range: originalComponent.id.range,
|
||||
parent: EMPTY_PARENT,
|
||||
};
|
||||
return {
|
||||
forwardRefStatement: {
|
||||
type: 'VariableDeclaration',
|
||||
kind: 'const',
|
||||
declarations: [
|
||||
{
|
||||
type: 'VariableDeclarator',
|
||||
id: shallowCloneNode(originalComponent.id),
|
||||
init: {
|
||||
type: 'CallExpression',
|
||||
callee: {
|
||||
type: 'MemberExpression',
|
||||
object: {
|
||||
type: 'Identifier',
|
||||
name: 'React',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
name: 'forwardRef',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
computed: false,
|
||||
optional: false,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
arguments: [shallowCloneNode(internalCompId)],
|
||||
typeArguments: null,
|
||||
optional: false,
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
],
|
||||
loc: originalComponent.loc,
|
||||
range: originalComponent.range,
|
||||
parent: originalComponent.parent,
|
||||
},
|
||||
internalCompId: internalCompId,
|
||||
forwardRefCompId: originalComponent.id,
|
||||
};
|
||||
}
|
||||
|
||||
function mapComponentDeclaration(
|
||||
node: ComponentDeclaration,
|
||||
options: ParserOptions,
|
||||
): {
|
||||
comp: FunctionDeclaration,
|
||||
forwardRefDetails: ?ForwardRefDetails,
|
||||
} {
|
||||
// Create empty loc for return type annotation nodes
|
||||
const createRendersTypeLoc = () => ({
|
||||
loc: {
|
||||
start: node.body.loc.end,
|
||||
end: node.body.loc.end,
|
||||
},
|
||||
range: [node.body.range[1], node.body.range[1]],
|
||||
parent: EMPTY_PARENT,
|
||||
});
|
||||
const returnType: TypeAnnotation = {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'QualifiedTypeIdentifier',
|
||||
qualification: {
|
||||
type: 'Identifier',
|
||||
name: 'React',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createRendersTypeLoc(),
|
||||
},
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: 'Node',
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
...createRendersTypeLoc(),
|
||||
},
|
||||
...createRendersTypeLoc(),
|
||||
},
|
||||
typeParameters: null,
|
||||
...createRendersTypeLoc(),
|
||||
},
|
||||
...createRendersTypeLoc(),
|
||||
};
|
||||
|
||||
const {props, ref} = mapComponentParameters(node.params, options);
|
||||
|
||||
let forwardRefDetails: ?ForwardRefDetails = null;
|
||||
|
||||
if (ref != null) {
|
||||
forwardRefDetails = createForwardRefWrapper(node);
|
||||
}
|
||||
|
||||
const comp = {
|
||||
type: 'FunctionDeclaration',
|
||||
id:
|
||||
forwardRefDetails != null
|
||||
? shallowCloneNode(forwardRefDetails.internalCompId)
|
||||
: shallowCloneNode(node.id),
|
||||
__componentDeclaration: true,
|
||||
typeParameters: node.typeParameters,
|
||||
params: props == null ? [] : ref == null ? [props] : [props, ref],
|
||||
returnType,
|
||||
body: node.body,
|
||||
async: false,
|
||||
generator: false,
|
||||
predicate: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
|
||||
return {comp, forwardRefDetails};
|
||||
}
|
||||
|
||||
function mapDeclareHook(node: DeclareHook): DeclareFunction {
|
||||
return {
|
||||
type: 'DeclareFunction',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: node.id.name,
|
||||
optional: node.id.optional,
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
this: null,
|
||||
params: node.id.typeAnnotation.typeAnnotation.params,
|
||||
typeParameters: node.id.typeAnnotation.typeAnnotation.typeParameters,
|
||||
rest: node.id.typeAnnotation.typeAnnotation.rest,
|
||||
returnType: node.id.typeAnnotation.typeAnnotation.returnType,
|
||||
loc: node.id.typeAnnotation.typeAnnotation.loc,
|
||||
range: node.id.typeAnnotation.typeAnnotation.range,
|
||||
parent: node.id.typeAnnotation.typeAnnotation.parent,
|
||||
},
|
||||
loc: node.id.typeAnnotation.loc,
|
||||
range: node.id.typeAnnotation.range,
|
||||
parent: node.id.typeAnnotation.parent,
|
||||
},
|
||||
loc: node.id.loc,
|
||||
range: node.id.range,
|
||||
parent: node.id.parent,
|
||||
},
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
predicate: null,
|
||||
};
|
||||
}
|
||||
|
||||
function mapHookDeclaration(node: HookDeclaration): FunctionDeclaration {
|
||||
const comp = {
|
||||
type: 'FunctionDeclaration',
|
||||
id: node.id && shallowCloneNode(node.id),
|
||||
__hookDeclaration: true,
|
||||
typeParameters: node.typeParameters,
|
||||
params: node.params,
|
||||
returnType: node.returnType,
|
||||
body: node.body,
|
||||
async: false,
|
||||
generator: false,
|
||||
predicate: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a list of statements and return the position of the
|
||||
* first statement that contains a reference to a given component
|
||||
* or null of no references were found.
|
||||
*/
|
||||
function scanForFirstComponentReference(
|
||||
compName: string,
|
||||
bodyList: Array<Statement | ModuleDeclaration>,
|
||||
): ?number {
|
||||
for (let i = 0; i < bodyList.length; i++) {
|
||||
const bodyNode = bodyList[i];
|
||||
let referencePos = null;
|
||||
SimpleTraverser.traverse(bodyNode, {
|
||||
enter(node: ESNode) {
|
||||
switch (node.type) {
|
||||
case 'Identifier': {
|
||||
if (node.name === compName) {
|
||||
// We found a reference, record it and stop.
|
||||
referencePos = i;
|
||||
throw SimpleTraverser.Break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
leave(_node: ESNode) {},
|
||||
});
|
||||
if (referencePos != null) {
|
||||
return referencePos;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function mapComponentDeclarationIntoList(
|
||||
node: ComponentDeclaration,
|
||||
newBody: Array<Statement | ModuleDeclaration>,
|
||||
options: ParserOptions,
|
||||
insertExport?: (Identifier | FunctionDeclaration) => ModuleDeclaration,
|
||||
) {
|
||||
const {comp, forwardRefDetails} = mapComponentDeclaration(node, options);
|
||||
if (forwardRefDetails != null) {
|
||||
// Scan for references to our component.
|
||||
const referencePos = scanForFirstComponentReference(
|
||||
forwardRefDetails.forwardRefCompId.name,
|
||||
newBody,
|
||||
);
|
||||
|
||||
// If a reference is found insert the forwardRef statement before it (to simulate function hoisting).
|
||||
if (referencePos != null) {
|
||||
newBody.splice(referencePos, 0, forwardRefDetails.forwardRefStatement);
|
||||
} else {
|
||||
newBody.push(forwardRefDetails.forwardRefStatement);
|
||||
}
|
||||
|
||||
newBody.push(comp);
|
||||
|
||||
if (insertExport != null) {
|
||||
newBody.push(insertExport(forwardRefDetails.forwardRefCompId));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
newBody.push(insertExport != null ? insertExport(comp) : comp);
|
||||
}
|
||||
|
||||
function mapStatementList(
|
||||
stmts: $ReadOnlyArray<Statement | ModuleDeclaration>,
|
||||
options: ParserOptions,
|
||||
) {
|
||||
const newBody: Array<Statement | ModuleDeclaration> = [];
|
||||
for (const node of stmts) {
|
||||
switch (node.type) {
|
||||
case 'ComponentDeclaration': {
|
||||
mapComponentDeclarationIntoList(node, newBody, options);
|
||||
break;
|
||||
}
|
||||
case 'HookDeclaration': {
|
||||
const decl = mapHookDeclaration(node);
|
||||
newBody.push(decl);
|
||||
break;
|
||||
}
|
||||
case 'ExportNamedDeclaration': {
|
||||
if (node.declaration?.type === 'ComponentDeclaration') {
|
||||
mapComponentDeclarationIntoList(
|
||||
node.declaration,
|
||||
newBody,
|
||||
options,
|
||||
componentOrRef => {
|
||||
switch (componentOrRef.type) {
|
||||
case 'FunctionDeclaration': {
|
||||
// No ref, so we can export the component directly.
|
||||
return nodeWith(node, {declaration: componentOrRef});
|
||||
}
|
||||
case 'Identifier': {
|
||||
// If a ref is inserted, we should just export that id.
|
||||
return {
|
||||
type: 'ExportNamedDeclaration',
|
||||
declaration: null,
|
||||
specifiers: [
|
||||
{
|
||||
type: 'ExportSpecifier',
|
||||
exported: shallowCloneNode(componentOrRef),
|
||||
local: shallowCloneNode(componentOrRef),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
],
|
||||
exportKind: 'value',
|
||||
source: null,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (node.declaration?.type === 'HookDeclaration') {
|
||||
const comp = mapHookDeclaration(node.declaration);
|
||||
newBody.push(nodeWith(node, {declaration: comp}));
|
||||
break;
|
||||
}
|
||||
|
||||
newBody.push(node);
|
||||
break;
|
||||
}
|
||||
case 'ExportDefaultDeclaration': {
|
||||
if (node.declaration?.type === 'ComponentDeclaration') {
|
||||
mapComponentDeclarationIntoList(
|
||||
node.declaration,
|
||||
newBody,
|
||||
options,
|
||||
componentOrRef => nodeWith(node, {declaration: componentOrRef}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (node.declaration?.type === 'HookDeclaration') {
|
||||
const comp = mapHookDeclaration(node.declaration);
|
||||
newBody.push(nodeWith(node, {declaration: comp}));
|
||||
break;
|
||||
}
|
||||
|
||||
newBody.push(node);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newBody.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newBody;
|
||||
}
|
||||
|
||||
export function transformProgram(
|
||||
program: Program,
|
||||
options: ParserOptions,
|
||||
): Program {
|
||||
return SimpleTransform.transformProgram(program, {
|
||||
transform(node: ESNode) {
|
||||
switch (node.type) {
|
||||
case 'DeclareComponent': {
|
||||
return mapDeclareComponent(node);
|
||||
}
|
||||
case 'DeclareHook': {
|
||||
return mapDeclareHook(node);
|
||||
}
|
||||
case 'Program':
|
||||
case 'BlockStatement': {
|
||||
return nodeWith(node, {body: mapStatementList(node.body, options)});
|
||||
}
|
||||
case 'SwitchCase': {
|
||||
const consequent = mapStatementList(node.consequent, options);
|
||||
return nodeWith(node, {
|
||||
/* $FlowExpectedError[incompatible-call] We know `mapStatementList` will
|
||||
not return `ModuleDeclaration` nodes if it is not passed any */
|
||||
consequent,
|
||||
});
|
||||
}
|
||||
case 'ComponentDeclaration': {
|
||||
throw createSyntaxError(
|
||||
node,
|
||||
`Components must be defined at the top level of a module or within a ` +
|
||||
`BlockStatement, instead got parent of "${node.parent?.type}".`,
|
||||
);
|
||||
}
|
||||
case 'HookDeclaration': {
|
||||
throw createSyntaxError(
|
||||
node,
|
||||
`Hooks must be defined at the top level of a module or within a ` +
|
||||
`BlockStatement, instead got parent of "${node.parent?.type}".`,
|
||||
);
|
||||
}
|
||||
default: {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
175
node_modules/hermes-parser/dist/estree/StripFlowTypes.js
generated
vendored
Normal file
175
node_modules/hermes-parser/dist/estree/StripFlowTypes.js
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transform strips all Flow types.
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.transformProgram = transformProgram;
|
||||
|
||||
var _SimpleTransform = require("../transform/SimpleTransform");
|
||||
|
||||
const nodeWith = _SimpleTransform.SimpleTransform.nodeWith;
|
||||
|
||||
function transformProgram(program, _options) {
|
||||
return _SimpleTransform.SimpleTransform.transformProgram(program, {
|
||||
transform(node) {
|
||||
switch (node.type) {
|
||||
case 'AsExpression':
|
||||
case 'AsConstExpression':
|
||||
case 'TypeCastExpression':
|
||||
{
|
||||
return node.expression;
|
||||
}
|
||||
|
||||
case 'CallExpression':
|
||||
case 'NewExpression':
|
||||
{
|
||||
if (node.typeArguments != null) {
|
||||
return nodeWith(node, {
|
||||
typeArguments: null
|
||||
});
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
case 'ObjectPattern':
|
||||
case 'ArrayPattern':
|
||||
case 'Identifier':
|
||||
{
|
||||
if (node.typeAnnotation != null) {
|
||||
return nodeWith(node, {
|
||||
typeAnnotation: null
|
||||
});
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
case 'DeclareClass':
|
||||
case 'DeclareFunction':
|
||||
case 'DeclareInterface':
|
||||
case 'DeclareModule':
|
||||
case 'DeclareModuleExports':
|
||||
case 'DeclareNamespace':
|
||||
case 'DeclareOpaqueType':
|
||||
case 'DeclareTypeAlias':
|
||||
case 'DeclareVariable':
|
||||
case 'InterfaceDeclaration':
|
||||
case 'OpaqueType':
|
||||
case 'TypeAlias':
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
case 'FunctionDeclaration':
|
||||
case 'ArrowFunctionExpression':
|
||||
case 'FunctionExpression':
|
||||
{
|
||||
const newParams = [];
|
||||
|
||||
for (let i = 0; i < node.params.length; i++) {
|
||||
if (i === 0 && node.params[0].type === 'Identifier' && node.params[0].name === 'this') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let param = node.params[i];
|
||||
|
||||
if (param.type === 'AssignmentPattern') {
|
||||
param = param.left;
|
||||
}
|
||||
|
||||
if (param.optional === true) {
|
||||
param = nodeWith(param, {
|
||||
optional: false
|
||||
});
|
||||
}
|
||||
|
||||
newParams.push(param);
|
||||
}
|
||||
|
||||
return nodeWith(node, {
|
||||
params: newParams,
|
||||
returnType: null,
|
||||
typeParameters: null,
|
||||
predicate: null
|
||||
});
|
||||
}
|
||||
|
||||
case 'ClassDeclaration':
|
||||
case 'ClassExpression':
|
||||
{
|
||||
return nodeWith(node, {
|
||||
typeParameters: null,
|
||||
superTypeParameters: null,
|
||||
implements: [],
|
||||
decorators: []
|
||||
});
|
||||
}
|
||||
|
||||
case 'PropertyDefinition':
|
||||
{
|
||||
return nodeWith(node, {
|
||||
typeAnnotation: null,
|
||||
variance: null,
|
||||
declare: false,
|
||||
optional: false
|
||||
});
|
||||
}
|
||||
|
||||
case 'ImportDeclaration':
|
||||
{
|
||||
if (node.importKind === 'type' || node.importKind === 'typeof') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nonTypeSpecifiers = node.specifiers.filter(s => s.type !== 'ImportSpecifier' || s.importKind !== 'type' && s.importKind !== 'typeof');
|
||||
|
||||
if (nonTypeSpecifiers.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (nonTypeSpecifiers.length === node.specifiers.length) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return nodeWith(node, {
|
||||
specifiers: nonTypeSpecifiers
|
||||
});
|
||||
}
|
||||
|
||||
case 'ExportAllDeclaration':
|
||||
case 'ExportNamedDeclaration':
|
||||
{
|
||||
if (node.exportKind === 'type') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
158
node_modules/hermes-parser/dist/estree/StripFlowTypes.js.flow
generated
vendored
Normal file
158
node_modules/hermes-parser/dist/estree/StripFlowTypes.js.flow
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transform strips all Flow types.
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ParserOptions} from '../ParserOptions';
|
||||
import type {Program, ESNode} from 'hermes-estree';
|
||||
|
||||
import {SimpleTransform} from '../transform/SimpleTransform';
|
||||
|
||||
const nodeWith = SimpleTransform.nodeWith;
|
||||
|
||||
export function transformProgram(
|
||||
program: Program,
|
||||
_options: ParserOptions,
|
||||
): Program {
|
||||
return SimpleTransform.transformProgram(program, {
|
||||
transform(node: ESNode) {
|
||||
switch (node.type) {
|
||||
case 'AsExpression':
|
||||
case 'AsConstExpression':
|
||||
case 'TypeCastExpression': {
|
||||
return node.expression;
|
||||
}
|
||||
|
||||
case 'CallExpression':
|
||||
case 'NewExpression': {
|
||||
if (node.typeArguments != null) {
|
||||
return nodeWith(node, {typeArguments: null});
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
case 'ObjectPattern':
|
||||
case 'ArrayPattern':
|
||||
case 'Identifier': {
|
||||
if (node.typeAnnotation != null) {
|
||||
return nodeWith(node, {typeAnnotation: null});
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
case 'DeclareClass':
|
||||
case 'DeclareFunction':
|
||||
case 'DeclareInterface':
|
||||
case 'DeclareModule':
|
||||
case 'DeclareModuleExports':
|
||||
case 'DeclareNamespace':
|
||||
case 'DeclareOpaqueType':
|
||||
case 'DeclareTypeAlias':
|
||||
case 'DeclareVariable':
|
||||
case 'InterfaceDeclaration':
|
||||
case 'OpaqueType':
|
||||
case 'TypeAlias': {
|
||||
return null;
|
||||
}
|
||||
|
||||
case 'FunctionDeclaration':
|
||||
case 'ArrowFunctionExpression':
|
||||
case 'FunctionExpression': {
|
||||
const newParams = [];
|
||||
for (let i = 0; i < node.params.length; i++) {
|
||||
if (
|
||||
i === 0 &&
|
||||
node.params[0].type === 'Identifier' &&
|
||||
node.params[0].name === 'this'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let param = node.params[i];
|
||||
if (param.type === 'AssignmentPattern') {
|
||||
param = param.left;
|
||||
}
|
||||
if (param.optional === true) {
|
||||
param = nodeWith(param, {optional: false});
|
||||
}
|
||||
newParams.push(param);
|
||||
}
|
||||
|
||||
return nodeWith(node, {
|
||||
params: newParams,
|
||||
returnType: null,
|
||||
typeParameters: null,
|
||||
predicate: null,
|
||||
});
|
||||
}
|
||||
|
||||
case 'ClassDeclaration':
|
||||
case 'ClassExpression': {
|
||||
return nodeWith(node, {
|
||||
typeParameters: null,
|
||||
superTypeParameters: null,
|
||||
implements: [],
|
||||
decorators: [],
|
||||
});
|
||||
}
|
||||
|
||||
case 'PropertyDefinition': {
|
||||
return nodeWith(node, {
|
||||
typeAnnotation: null,
|
||||
variance: null,
|
||||
declare: false,
|
||||
optional: false,
|
||||
});
|
||||
}
|
||||
|
||||
case 'ImportDeclaration': {
|
||||
if (node.importKind === 'type' || node.importKind === 'typeof') {
|
||||
return null;
|
||||
}
|
||||
const nonTypeSpecifiers = node.specifiers.filter(
|
||||
s =>
|
||||
s.type !== 'ImportSpecifier' ||
|
||||
(s.importKind !== 'type' && s.importKind !== 'typeof'),
|
||||
);
|
||||
if (nonTypeSpecifiers.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (nonTypeSpecifiers.length === node.specifiers.length) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return nodeWith(node, {
|
||||
specifiers: nonTypeSpecifiers,
|
||||
});
|
||||
}
|
||||
|
||||
case 'ExportAllDeclaration':
|
||||
case 'ExportNamedDeclaration': {
|
||||
if (node.exportKind === 'type') {
|
||||
return null;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
default: {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
215
node_modules/hermes-parser/dist/estree/StripFlowTypesForBabel.js
generated
vendored
Normal file
215
node_modules/hermes-parser/dist/estree/StripFlowTypesForBabel.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transform strips Flow types that are not supported past Babel 7.
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.transformProgram = transformProgram;
|
||||
|
||||
var _SimpleTransform = require("../transform/SimpleTransform");
|
||||
|
||||
var _createSyntaxError = require("../utils/createSyntaxError");
|
||||
|
||||
const nodeWith = _SimpleTransform.SimpleTransform.nodeWith; // Rely on the mapper to fix up parent relationships.
|
||||
|
||||
const EMPTY_PARENT = null;
|
||||
|
||||
function createSimpleGenericTypeAnnotation(name, nodeForLoc) {
|
||||
return {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name,
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: nodeForLoc.loc,
|
||||
range: nodeForLoc.range,
|
||||
parent: EMPTY_PARENT
|
||||
},
|
||||
typeParameters: null,
|
||||
loc: nodeForLoc.loc,
|
||||
range: nodeForLoc.range,
|
||||
parent: nodeForLoc.parent
|
||||
};
|
||||
}
|
||||
|
||||
function createAnyTypeAnnotation(node) {
|
||||
return {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert DeclareEnum nodes to DeclareVariable
|
||||
*/
|
||||
|
||||
|
||||
function mapDeclareEnum(node) {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
kind: 'const',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: createAnyTypeAnnotation(node.body),
|
||||
loc: node.body.loc,
|
||||
range: node.body.range,
|
||||
parent: EMPTY_PARENT
|
||||
}
|
||||
}),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert DeclareNamespace nodes to DeclareVariable
|
||||
*/
|
||||
|
||||
|
||||
function mapDeclareNamespace(node) {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
kind: 'const',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: createAnyTypeAnnotation(node.body),
|
||||
loc: node.body.loc,
|
||||
range: node.body.range,
|
||||
parent: EMPTY_PARENT
|
||||
}
|
||||
}),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Remove `this` param from functions.
|
||||
*/
|
||||
|
||||
|
||||
function mapFunction(node) {
|
||||
// Remove the first parameter if it is a this-type annotation,
|
||||
// which is not recognized by Babel.
|
||||
if (node.params.length !== 0 && node.params[0].name === 'this') {
|
||||
return nodeWith(node, {
|
||||
params: node.params.slice(1)
|
||||
});
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Convert to QualifiedTypeIdentifier
|
||||
*/
|
||||
|
||||
|
||||
function mapQualifiedTypeofIdentifier(node) {
|
||||
return {
|
||||
type: 'QualifiedTypeIdentifier',
|
||||
qualification: node.qualification.type === 'QualifiedTypeofIdentifier' ? mapQualifiedTypeofIdentifier(node.qualification) : node.qualification,
|
||||
id: node.id,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent
|
||||
};
|
||||
}
|
||||
|
||||
function transformProgram(program, _options) {
|
||||
return _SimpleTransform.SimpleTransform.transformProgram(program, {
|
||||
transform(node) {
|
||||
switch (node.type) {
|
||||
case 'SymbolTypeAnnotation':
|
||||
{
|
||||
// Convert to simple generic type annotation
|
||||
return createSimpleGenericTypeAnnotation('symbol', node);
|
||||
}
|
||||
|
||||
case 'BigIntTypeAnnotation':
|
||||
{
|
||||
// Convert to simple generic type annotation
|
||||
return createSimpleGenericTypeAnnotation('bigint', node);
|
||||
}
|
||||
|
||||
case 'ObjectTypeAnnotation':
|
||||
{
|
||||
const shouldStrip = node.properties.some(prop => prop.type === 'ObjectTypeMappedTypeProperty');
|
||||
|
||||
if (shouldStrip) {
|
||||
return createAnyTypeAnnotation(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
case 'ObjectTypeMappedTypeProperty':
|
||||
{
|
||||
throw (0, _createSyntaxError.createSyntaxError)(node, `Invalid AST structure, ObjectTypeMappedTypeProperty found outside of an ObjectTypeAnnotation`);
|
||||
}
|
||||
|
||||
case 'IndexedAccessType':
|
||||
case 'OptionalIndexedAccessType':
|
||||
case 'KeyofTypeAnnotation':
|
||||
case 'ConditionalTypeAnnotation':
|
||||
case 'InferTypeAnnotation':
|
||||
case 'TupleTypeLabeledElement':
|
||||
case 'TupleTypeSpreadElement':
|
||||
case 'ComponentTypeAnnotation':
|
||||
case 'HookTypeAnnotation':
|
||||
case 'TypeOperator':
|
||||
case 'TypePredicate':
|
||||
{
|
||||
// Babel does not support these generic types, so convert to any
|
||||
return createAnyTypeAnnotation(node);
|
||||
}
|
||||
|
||||
case 'QualifiedTypeofIdentifier':
|
||||
{
|
||||
return mapQualifiedTypeofIdentifier(node);
|
||||
}
|
||||
|
||||
case 'DeclareEnum':
|
||||
{
|
||||
return mapDeclareEnum(node);
|
||||
}
|
||||
|
||||
case 'DeclareNamespace':
|
||||
{
|
||||
return mapDeclareNamespace(node);
|
||||
}
|
||||
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
{
|
||||
return mapFunction(node);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
216
node_modules/hermes-parser/dist/estree/StripFlowTypesForBabel.js.flow
generated
vendored
Normal file
216
node_modules/hermes-parser/dist/estree/StripFlowTypesForBabel.js.flow
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* This transform strips Flow types that are not supported past Babel 7.
|
||||
*
|
||||
* It is expected that all transforms create valid ESTree AST output. If
|
||||
* the transform requires outputting Babel specific AST nodes then it
|
||||
* should live in `ConvertESTreeToBabel.js`
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ParserOptions} from '../ParserOptions';
|
||||
import type {
|
||||
Program,
|
||||
ESNode,
|
||||
DeclareEnum,
|
||||
DeclareNamespace,
|
||||
DeclareVariable,
|
||||
AnyTypeAnnotation,
|
||||
GenericTypeAnnotation,
|
||||
QualifiedTypeIdentifier,
|
||||
QualifiedTypeofIdentifier,
|
||||
AFunction,
|
||||
} from 'hermes-estree';
|
||||
|
||||
import {SimpleTransform} from '../transform/SimpleTransform';
|
||||
import {createSyntaxError} from '../utils/createSyntaxError';
|
||||
|
||||
const nodeWith = SimpleTransform.nodeWith;
|
||||
|
||||
// Rely on the mapper to fix up parent relationships.
|
||||
const EMPTY_PARENT: $FlowFixMe = null;
|
||||
|
||||
function createSimpleGenericTypeAnnotation(
|
||||
name: string,
|
||||
nodeForLoc: ESNode,
|
||||
): GenericTypeAnnotation {
|
||||
return {
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name,
|
||||
optional: false,
|
||||
typeAnnotation: null,
|
||||
loc: nodeForLoc.loc,
|
||||
range: nodeForLoc.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
typeParameters: null,
|
||||
loc: nodeForLoc.loc,
|
||||
range: nodeForLoc.range,
|
||||
parent: nodeForLoc.parent,
|
||||
};
|
||||
}
|
||||
|
||||
function createAnyTypeAnnotation(node: ESNode): AnyTypeAnnotation {
|
||||
return {
|
||||
type: 'AnyTypeAnnotation',
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert DeclareEnum nodes to DeclareVariable
|
||||
*/
|
||||
function mapDeclareEnum(node: DeclareEnum): DeclareVariable {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
kind: 'const',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: createAnyTypeAnnotation(node.body),
|
||||
loc: node.body.loc,
|
||||
range: node.body.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
}),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert DeclareNamespace nodes to DeclareVariable
|
||||
*/
|
||||
function mapDeclareNamespace(node: DeclareNamespace): DeclareVariable {
|
||||
return {
|
||||
type: 'DeclareVariable',
|
||||
kind: 'const',
|
||||
id: nodeWith(node.id, {
|
||||
typeAnnotation: {
|
||||
type: 'TypeAnnotation',
|
||||
typeAnnotation: createAnyTypeAnnotation(node.body),
|
||||
loc: node.body.loc,
|
||||
range: node.body.range,
|
||||
parent: EMPTY_PARENT,
|
||||
},
|
||||
}),
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove `this` param from functions.
|
||||
*/
|
||||
function mapFunction(node: AFunction): AFunction {
|
||||
// Remove the first parameter if it is a this-type annotation,
|
||||
// which is not recognized by Babel.
|
||||
if (node.params.length !== 0 && node.params[0].name === 'this') {
|
||||
return nodeWith(node, {
|
||||
params: node.params.slice(1),
|
||||
});
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to QualifiedTypeIdentifier
|
||||
*/
|
||||
function mapQualifiedTypeofIdentifier(
|
||||
node: QualifiedTypeofIdentifier,
|
||||
): QualifiedTypeIdentifier {
|
||||
return {
|
||||
type: 'QualifiedTypeIdentifier',
|
||||
qualification:
|
||||
node.qualification.type === 'QualifiedTypeofIdentifier'
|
||||
? mapQualifiedTypeofIdentifier(node.qualification)
|
||||
: node.qualification,
|
||||
id: node.id,
|
||||
loc: node.loc,
|
||||
range: node.range,
|
||||
parent: node.parent,
|
||||
};
|
||||
}
|
||||
|
||||
export function transformProgram(
|
||||
program: Program,
|
||||
_options: ParserOptions,
|
||||
): Program {
|
||||
return SimpleTransform.transformProgram(program, {
|
||||
transform(node: ESNode) {
|
||||
switch (node.type) {
|
||||
case 'SymbolTypeAnnotation': {
|
||||
// Convert to simple generic type annotation
|
||||
return createSimpleGenericTypeAnnotation('symbol', node);
|
||||
}
|
||||
case 'BigIntTypeAnnotation': {
|
||||
// Convert to simple generic type annotation
|
||||
return createSimpleGenericTypeAnnotation('bigint', node);
|
||||
}
|
||||
case 'ObjectTypeAnnotation': {
|
||||
const shouldStrip = node.properties.some(
|
||||
prop => prop.type === 'ObjectTypeMappedTypeProperty',
|
||||
);
|
||||
if (shouldStrip) {
|
||||
return createAnyTypeAnnotation(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
case 'ObjectTypeMappedTypeProperty': {
|
||||
throw createSyntaxError(
|
||||
node,
|
||||
`Invalid AST structure, ObjectTypeMappedTypeProperty found outside of an ObjectTypeAnnotation`,
|
||||
);
|
||||
}
|
||||
case 'IndexedAccessType':
|
||||
case 'OptionalIndexedAccessType':
|
||||
case 'KeyofTypeAnnotation':
|
||||
case 'ConditionalTypeAnnotation':
|
||||
case 'InferTypeAnnotation':
|
||||
case 'TupleTypeLabeledElement':
|
||||
case 'TupleTypeSpreadElement':
|
||||
case 'ComponentTypeAnnotation':
|
||||
case 'HookTypeAnnotation':
|
||||
case 'TypeOperator':
|
||||
case 'TypePredicate': {
|
||||
// Babel does not support these generic types, so convert to any
|
||||
return createAnyTypeAnnotation(node);
|
||||
}
|
||||
case 'QualifiedTypeofIdentifier': {
|
||||
return mapQualifiedTypeofIdentifier(node);
|
||||
}
|
||||
case 'DeclareEnum': {
|
||||
return mapDeclareEnum(node);
|
||||
}
|
||||
case 'DeclareNamespace': {
|
||||
return mapDeclareNamespace(node);
|
||||
}
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression': {
|
||||
return mapFunction(node);
|
||||
}
|
||||
default: {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
203
node_modules/hermes-parser/dist/generated/ESTreeVisitorKeys.js
generated
vendored
Normal file
203
node_modules/hermes-parser/dist/generated/ESTreeVisitorKeys.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
* @generated
|
||||
*/
|
||||
|
||||
/*
|
||||
* !!! GENERATED FILE !!!
|
||||
*
|
||||
* Any manual changes to this file will be overwritten. To regenerate run `yarn build`.
|
||||
*/
|
||||
// lint directives to let us do some basic validation of generated files
|
||||
|
||||
/* eslint no-undef: 'error', no-unused-vars: ['error', {vars: "local"}], no-redeclare: 'error' */
|
||||
|
||||
/* global $NonMaybeType, Partial, $ReadOnly, $ReadOnlyArray, $FlowFixMe */
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
AnyTypeAnnotation: [],
|
||||
ArrayExpression: ['elements'],
|
||||
ArrayPattern: ['elements', 'typeAnnotation'],
|
||||
ArrayTypeAnnotation: ['elementType'],
|
||||
ArrowFunctionExpression: ['id', 'params', 'body', 'typeParameters', 'returnType', 'predicate'],
|
||||
AsConstExpression: ['expression'],
|
||||
AsExpression: ['expression', 'typeAnnotation'],
|
||||
AssignmentExpression: ['left', 'right'],
|
||||
AssignmentPattern: ['left', 'right'],
|
||||
AwaitExpression: ['argument'],
|
||||
BigIntLiteralTypeAnnotation: [],
|
||||
BigIntTypeAnnotation: [],
|
||||
BinaryExpression: ['left', 'right'],
|
||||
BlockStatement: ['body'],
|
||||
BooleanLiteralTypeAnnotation: [],
|
||||
BooleanTypeAnnotation: [],
|
||||
BreakStatement: ['label'],
|
||||
CallExpression: ['callee', 'typeArguments', 'arguments'],
|
||||
CatchClause: ['param', 'body'],
|
||||
ChainExpression: ['expression'],
|
||||
ClassBody: ['body'],
|
||||
ClassDeclaration: ['id', 'typeParameters', 'superClass', 'superTypeParameters', 'implements', 'decorators', 'body'],
|
||||
ClassExpression: ['id', 'typeParameters', 'superClass', 'superTypeParameters', 'implements', 'decorators', 'body'],
|
||||
ClassImplements: ['id', 'typeParameters'],
|
||||
ComponentDeclaration: ['id', 'params', 'body', 'typeParameters', 'rendersType'],
|
||||
ComponentParameter: ['name', 'local'],
|
||||
ComponentTypeAnnotation: ['params', 'rest', 'typeParameters', 'rendersType'],
|
||||
ComponentTypeParameter: ['name', 'typeAnnotation'],
|
||||
ConditionalExpression: ['test', 'consequent', 'alternate'],
|
||||
ConditionalTypeAnnotation: ['checkType', 'extendsType', 'trueType', 'falseType'],
|
||||
ContinueStatement: ['label'],
|
||||
DebuggerStatement: [],
|
||||
DeclareClass: ['id', 'typeParameters', 'extends', 'implements', 'mixins', 'body'],
|
||||
DeclareComponent: ['id', 'params', 'rest', 'typeParameters', 'rendersType'],
|
||||
DeclaredPredicate: ['value'],
|
||||
DeclareEnum: ['id', 'body'],
|
||||
DeclareExportAllDeclaration: ['source'],
|
||||
DeclareExportDeclaration: ['declaration', 'specifiers', 'source'],
|
||||
DeclareFunction: ['id', 'predicate'],
|
||||
DeclareHook: ['id'],
|
||||
DeclareInterface: ['id', 'typeParameters', 'extends', 'body'],
|
||||
DeclareModule: ['id', 'body'],
|
||||
DeclareModuleExports: ['typeAnnotation'],
|
||||
DeclareNamespace: ['id', 'body'],
|
||||
DeclareOpaqueType: ['id', 'typeParameters', 'impltype', 'supertype'],
|
||||
DeclareTypeAlias: ['id', 'typeParameters', 'right'],
|
||||
DeclareVariable: ['id'],
|
||||
DoWhileStatement: ['body', 'test'],
|
||||
EmptyStatement: [],
|
||||
EmptyTypeAnnotation: [],
|
||||
EnumBigIntBody: ['members'],
|
||||
EnumBigIntMember: ['id', 'init'],
|
||||
EnumBooleanBody: ['members'],
|
||||
EnumBooleanMember: ['id', 'init'],
|
||||
EnumDeclaration: ['id', 'body'],
|
||||
EnumDefaultedMember: ['id'],
|
||||
EnumNumberBody: ['members'],
|
||||
EnumNumberMember: ['id', 'init'],
|
||||
EnumStringBody: ['members'],
|
||||
EnumStringMember: ['id', 'init'],
|
||||
EnumSymbolBody: ['members'],
|
||||
ExistsTypeAnnotation: [],
|
||||
ExportAllDeclaration: ['exported', 'source'],
|
||||
ExportDefaultDeclaration: ['declaration'],
|
||||
ExportNamedDeclaration: ['declaration', 'specifiers', 'source'],
|
||||
ExportSpecifier: ['exported', 'local'],
|
||||
ExpressionStatement: ['expression'],
|
||||
ForInStatement: ['left', 'right', 'body'],
|
||||
ForOfStatement: ['left', 'right', 'body'],
|
||||
ForStatement: ['init', 'test', 'update', 'body'],
|
||||
FunctionDeclaration: ['id', 'params', 'body', 'typeParameters', 'returnType', 'predicate'],
|
||||
FunctionExpression: ['id', 'params', 'body', 'typeParameters', 'returnType', 'predicate'],
|
||||
FunctionTypeAnnotation: ['params', 'this', 'returnType', 'rest', 'typeParameters'],
|
||||
FunctionTypeParam: ['name', 'typeAnnotation'],
|
||||
GenericTypeAnnotation: ['id', 'typeParameters'],
|
||||
HookDeclaration: ['id', 'params', 'body', 'typeParameters', 'returnType'],
|
||||
HookTypeAnnotation: ['params', 'returnType', 'rest', 'typeParameters'],
|
||||
Identifier: ['typeAnnotation'],
|
||||
IfStatement: ['test', 'consequent', 'alternate'],
|
||||
ImportAttribute: ['key', 'value'],
|
||||
ImportDeclaration: ['specifiers', 'source', 'assertions'],
|
||||
ImportDefaultSpecifier: ['local'],
|
||||
ImportExpression: ['source', 'attributes'],
|
||||
ImportNamespaceSpecifier: ['local'],
|
||||
ImportSpecifier: ['imported', 'local'],
|
||||
IndexedAccessType: ['objectType', 'indexType'],
|
||||
InferredPredicate: [],
|
||||
InferTypeAnnotation: ['typeParameter'],
|
||||
InterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'],
|
||||
InterfaceExtends: ['id', 'typeParameters'],
|
||||
InterfaceTypeAnnotation: ['extends', 'body'],
|
||||
IntersectionTypeAnnotation: ['types'],
|
||||
JSXAttribute: ['name', 'value'],
|
||||
JSXClosingElement: ['name'],
|
||||
JSXClosingFragment: [],
|
||||
JSXElement: ['openingElement', 'children', 'closingElement'],
|
||||
JSXEmptyExpression: [],
|
||||
JSXExpressionContainer: ['expression'],
|
||||
JSXFragment: ['openingFragment', 'children', 'closingFragment'],
|
||||
JSXIdentifier: [],
|
||||
JSXMemberExpression: ['object', 'property'],
|
||||
JSXNamespacedName: ['namespace', 'name'],
|
||||
JSXOpeningElement: ['name', 'attributes', 'typeArguments'],
|
||||
JSXOpeningFragment: [],
|
||||
JSXSpreadAttribute: ['argument'],
|
||||
JSXSpreadChild: ['expression'],
|
||||
JSXText: [],
|
||||
KeyofTypeAnnotation: ['argument'],
|
||||
LabeledStatement: ['label', 'body'],
|
||||
LogicalExpression: ['left', 'right'],
|
||||
MemberExpression: ['object', 'property'],
|
||||
MetaProperty: ['meta', 'property'],
|
||||
MethodDefinition: ['key', 'value'],
|
||||
MixedTypeAnnotation: [],
|
||||
NewExpression: ['callee', 'typeArguments', 'arguments'],
|
||||
NullableTypeAnnotation: ['typeAnnotation'],
|
||||
NullLiteralTypeAnnotation: [],
|
||||
NumberLiteralTypeAnnotation: [],
|
||||
NumberTypeAnnotation: [],
|
||||
ObjectExpression: ['properties'],
|
||||
ObjectPattern: ['properties', 'typeAnnotation'],
|
||||
ObjectTypeAnnotation: ['properties', 'indexers', 'callProperties', 'internalSlots'],
|
||||
ObjectTypeCallProperty: ['value'],
|
||||
ObjectTypeIndexer: ['id', 'key', 'value', 'variance'],
|
||||
ObjectTypeInternalSlot: ['id', 'value'],
|
||||
ObjectTypeMappedTypeProperty: ['keyTparam', 'propType', 'sourceType', 'variance'],
|
||||
ObjectTypeProperty: ['key', 'value', 'variance'],
|
||||
ObjectTypeSpreadProperty: ['argument'],
|
||||
OpaqueType: ['id', 'typeParameters', 'impltype', 'supertype'],
|
||||
OptionalIndexedAccessType: ['objectType', 'indexType'],
|
||||
PrivateIdentifier: [],
|
||||
Program: ['body'],
|
||||
Property: ['key', 'value'],
|
||||
PropertyDefinition: ['key', 'value', 'variance', 'typeAnnotation'],
|
||||
QualifiedTypeIdentifier: ['qualification', 'id'],
|
||||
QualifiedTypeofIdentifier: ['qualification', 'id'],
|
||||
RestElement: ['argument'],
|
||||
ReturnStatement: ['argument'],
|
||||
SequenceExpression: ['expressions'],
|
||||
SpreadElement: ['argument'],
|
||||
StringLiteralTypeAnnotation: [],
|
||||
StringTypeAnnotation: [],
|
||||
Super: [],
|
||||
SwitchCase: ['test', 'consequent'],
|
||||
SwitchStatement: ['discriminant', 'cases'],
|
||||
SymbolTypeAnnotation: [],
|
||||
TaggedTemplateExpression: ['tag', 'quasi'],
|
||||
TemplateElement: [],
|
||||
TemplateLiteral: ['quasis', 'expressions'],
|
||||
ThisExpression: [],
|
||||
ThisTypeAnnotation: [],
|
||||
ThrowStatement: ['argument'],
|
||||
TryStatement: ['block', 'handler', 'finalizer'],
|
||||
TupleTypeAnnotation: ['types'],
|
||||
TupleTypeLabeledElement: ['label', 'elementType', 'variance'],
|
||||
TupleTypeSpreadElement: ['label', 'typeAnnotation'],
|
||||
TypeAlias: ['id', 'typeParameters', 'right'],
|
||||
TypeAnnotation: ['typeAnnotation'],
|
||||
TypeCastExpression: ['expression', 'typeAnnotation'],
|
||||
TypeofTypeAnnotation: ['argument', 'typeArguments'],
|
||||
TypeOperator: ['typeAnnotation'],
|
||||
TypeParameter: ['bound', 'variance', 'default'],
|
||||
TypeParameterDeclaration: ['params'],
|
||||
TypeParameterInstantiation: ['params'],
|
||||
TypePredicate: ['parameterName', 'typeAnnotation'],
|
||||
UnaryExpression: ['argument'],
|
||||
UnionTypeAnnotation: ['types'],
|
||||
UpdateExpression: ['argument'],
|
||||
VariableDeclaration: ['declarations'],
|
||||
VariableDeclarator: ['id', 'init'],
|
||||
Variance: [],
|
||||
VoidTypeAnnotation: [],
|
||||
WhileStatement: ['test', 'body'],
|
||||
WithStatement: ['object', 'body'],
|
||||
YieldExpression: ['argument'],
|
||||
OptionalMemberExpression: ['object', 'property'],
|
||||
OptionalCallExpression: ['callee', 'typeArguments', 'arguments'],
|
||||
Literal: []
|
||||
};
|
||||
15
node_modules/hermes-parser/dist/generated/ESTreeVisitorKeys.js.flow
generated
vendored
Normal file
15
node_modules/hermes-parser/dist/generated/ESTreeVisitorKeys.js.flow
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type VisitorKeys = $ReadOnly<{[string]: $ReadOnlyArray<string>}>;
|
||||
|
||||
declare module.exports: VisitorKeys;
|
||||
730
node_modules/hermes-parser/dist/generated/ParserVisitorKeys.js
generated
vendored
Normal file
730
node_modules/hermes-parser/dist/generated/ParserVisitorKeys.js
generated
vendored
Normal file
@@ -0,0 +1,730 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
* @generated
|
||||
*/
|
||||
|
||||
/*
|
||||
* !!! GENERATED FILE !!!
|
||||
*
|
||||
* Any manual changes to this file will be overwritten. To regenerate run `yarn build`.
|
||||
*/
|
||||
// lint directives to let us do some basic validation of generated files
|
||||
|
||||
/* eslint no-undef: 'error', no-unused-vars: ['error', {vars: "local"}], no-redeclare: 'error' */
|
||||
|
||||
/* global $NonMaybeType, Partial, $ReadOnly, $ReadOnlyArray, $FlowFixMe */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.NODE_LIST_CHILD = exports.NODE_CHILD = exports.HERMES_AST_VISITOR_KEYS = void 0;
|
||||
const NODE_CHILD = 'Node';
|
||||
exports.NODE_CHILD = NODE_CHILD;
|
||||
const NODE_LIST_CHILD = 'NodeList';
|
||||
exports.NODE_LIST_CHILD = NODE_LIST_CHILD;
|
||||
const HERMES_AST_VISITOR_KEYS = {
|
||||
AnyTypeAnnotation: {},
|
||||
ArrayExpression: {
|
||||
elements: 'NodeList'
|
||||
},
|
||||
ArrayPattern: {
|
||||
elements: 'NodeList',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
ArrayTypeAnnotation: {
|
||||
elementType: 'Node'
|
||||
},
|
||||
ArrowFunctionExpression: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
typeParameters: 'Node',
|
||||
returnType: 'Node',
|
||||
predicate: 'Node'
|
||||
},
|
||||
AsConstExpression: {
|
||||
expression: 'Node'
|
||||
},
|
||||
AsExpression: {
|
||||
expression: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
AssignmentExpression: {
|
||||
left: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
AssignmentPattern: {
|
||||
left: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
AwaitExpression: {
|
||||
argument: 'Node'
|
||||
},
|
||||
BigIntLiteral: {},
|
||||
BigIntLiteralTypeAnnotation: {},
|
||||
BigIntTypeAnnotation: {},
|
||||
BinaryExpression: {
|
||||
left: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
BlockStatement: {
|
||||
body: 'NodeList'
|
||||
},
|
||||
BooleanLiteral: {},
|
||||
BooleanLiteralTypeAnnotation: {},
|
||||
BooleanTypeAnnotation: {},
|
||||
BreakStatement: {
|
||||
label: 'Node'
|
||||
},
|
||||
CallExpression: {
|
||||
callee: 'Node',
|
||||
typeArguments: 'Node',
|
||||
arguments: 'NodeList'
|
||||
},
|
||||
CatchClause: {
|
||||
param: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
ChainExpression: {
|
||||
expression: 'Node'
|
||||
},
|
||||
ClassBody: {
|
||||
body: 'NodeList'
|
||||
},
|
||||
ClassDeclaration: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
superClass: 'Node',
|
||||
superTypeParameters: 'Node',
|
||||
implements: 'NodeList',
|
||||
decorators: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
ClassExpression: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
superClass: 'Node',
|
||||
superTypeParameters: 'Node',
|
||||
implements: 'NodeList',
|
||||
decorators: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
ClassImplements: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node'
|
||||
},
|
||||
ComponentDeclaration: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
typeParameters: 'Node',
|
||||
rendersType: 'Node'
|
||||
},
|
||||
ComponentParameter: {
|
||||
name: 'Node',
|
||||
local: 'Node'
|
||||
},
|
||||
ComponentTypeAnnotation: {
|
||||
params: 'NodeList',
|
||||
rest: 'Node',
|
||||
typeParameters: 'Node',
|
||||
rendersType: 'Node'
|
||||
},
|
||||
ComponentTypeParameter: {
|
||||
name: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
ConditionalExpression: {
|
||||
test: 'Node',
|
||||
alternate: 'Node',
|
||||
consequent: 'Node'
|
||||
},
|
||||
ConditionalTypeAnnotation: {
|
||||
checkType: 'Node',
|
||||
extendsType: 'Node',
|
||||
trueType: 'Node',
|
||||
falseType: 'Node'
|
||||
},
|
||||
ContinueStatement: {
|
||||
label: 'Node'
|
||||
},
|
||||
DebuggerStatement: {},
|
||||
DeclareClass: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
extends: 'NodeList',
|
||||
implements: 'NodeList',
|
||||
mixins: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
DeclareComponent: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
rest: 'Node',
|
||||
typeParameters: 'Node',
|
||||
rendersType: 'Node'
|
||||
},
|
||||
DeclaredPredicate: {
|
||||
value: 'Node'
|
||||
},
|
||||
DeclareEnum: {
|
||||
id: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
DeclareExportAllDeclaration: {
|
||||
source: 'Node'
|
||||
},
|
||||
DeclareExportDeclaration: {
|
||||
declaration: 'Node',
|
||||
specifiers: 'NodeList',
|
||||
source: 'Node'
|
||||
},
|
||||
DeclareFunction: {
|
||||
id: 'Node',
|
||||
predicate: 'Node'
|
||||
},
|
||||
DeclareHook: {
|
||||
id: 'Node'
|
||||
},
|
||||
DeclareInterface: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
extends: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
DeclareModule: {
|
||||
id: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
DeclareModuleExports: {
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
DeclareNamespace: {
|
||||
id: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
DeclareOpaqueType: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
impltype: 'Node',
|
||||
supertype: 'Node'
|
||||
},
|
||||
DeclareTypeAlias: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
DeclareVariable: {
|
||||
id: 'Node'
|
||||
},
|
||||
DoWhileStatement: {
|
||||
body: 'Node',
|
||||
test: 'Node'
|
||||
},
|
||||
EmptyStatement: {},
|
||||
EmptyTypeAnnotation: {},
|
||||
EnumBigIntBody: {
|
||||
members: 'NodeList'
|
||||
},
|
||||
EnumBigIntMember: {
|
||||
id: 'Node',
|
||||
init: 'Node'
|
||||
},
|
||||
EnumBooleanBody: {
|
||||
members: 'NodeList'
|
||||
},
|
||||
EnumBooleanMember: {
|
||||
id: 'Node',
|
||||
init: 'Node'
|
||||
},
|
||||
EnumDeclaration: {
|
||||
id: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
EnumDefaultedMember: {
|
||||
id: 'Node'
|
||||
},
|
||||
EnumNumberBody: {
|
||||
members: 'NodeList'
|
||||
},
|
||||
EnumNumberMember: {
|
||||
id: 'Node',
|
||||
init: 'Node'
|
||||
},
|
||||
EnumStringBody: {
|
||||
members: 'NodeList'
|
||||
},
|
||||
EnumStringMember: {
|
||||
id: 'Node',
|
||||
init: 'Node'
|
||||
},
|
||||
EnumSymbolBody: {
|
||||
members: 'NodeList'
|
||||
},
|
||||
ExistsTypeAnnotation: {},
|
||||
ExportAllDeclaration: {
|
||||
exported: 'Node',
|
||||
source: 'Node'
|
||||
},
|
||||
ExportDefaultDeclaration: {
|
||||
declaration: 'Node'
|
||||
},
|
||||
ExportNamedDeclaration: {
|
||||
declaration: 'Node',
|
||||
specifiers: 'NodeList',
|
||||
source: 'Node'
|
||||
},
|
||||
ExportSpecifier: {
|
||||
exported: 'Node',
|
||||
local: 'Node'
|
||||
},
|
||||
ExpressionStatement: {
|
||||
expression: 'Node'
|
||||
},
|
||||
ForInStatement: {
|
||||
left: 'Node',
|
||||
right: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
ForOfStatement: {
|
||||
left: 'Node',
|
||||
right: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
ForStatement: {
|
||||
init: 'Node',
|
||||
test: 'Node',
|
||||
update: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
FunctionDeclaration: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
typeParameters: 'Node',
|
||||
returnType: 'Node',
|
||||
predicate: 'Node'
|
||||
},
|
||||
FunctionExpression: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
typeParameters: 'Node',
|
||||
returnType: 'Node',
|
||||
predicate: 'Node'
|
||||
},
|
||||
FunctionTypeAnnotation: {
|
||||
params: 'NodeList',
|
||||
this: 'Node',
|
||||
returnType: 'Node',
|
||||
rest: 'Node',
|
||||
typeParameters: 'Node'
|
||||
},
|
||||
FunctionTypeParam: {
|
||||
name: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
GenericTypeAnnotation: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node'
|
||||
},
|
||||
HookDeclaration: {
|
||||
id: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
typeParameters: 'Node',
|
||||
returnType: 'Node'
|
||||
},
|
||||
HookTypeAnnotation: {
|
||||
params: 'NodeList',
|
||||
returnType: 'Node',
|
||||
rest: 'Node',
|
||||
typeParameters: 'Node'
|
||||
},
|
||||
Identifier: {
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
IfStatement: {
|
||||
test: 'Node',
|
||||
consequent: 'Node',
|
||||
alternate: 'Node'
|
||||
},
|
||||
ImportAttribute: {
|
||||
key: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
ImportDeclaration: {
|
||||
specifiers: 'NodeList',
|
||||
source: 'Node',
|
||||
assertions: 'NodeList'
|
||||
},
|
||||
ImportDefaultSpecifier: {
|
||||
local: 'Node'
|
||||
},
|
||||
ImportExpression: {
|
||||
source: 'Node',
|
||||
attributes: 'Node'
|
||||
},
|
||||
ImportNamespaceSpecifier: {
|
||||
local: 'Node'
|
||||
},
|
||||
ImportSpecifier: {
|
||||
imported: 'Node',
|
||||
local: 'Node'
|
||||
},
|
||||
IndexedAccessType: {
|
||||
objectType: 'Node',
|
||||
indexType: 'Node'
|
||||
},
|
||||
InferredPredicate: {},
|
||||
InferTypeAnnotation: {
|
||||
typeParameter: 'Node'
|
||||
},
|
||||
InterfaceDeclaration: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
extends: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
InterfaceExtends: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node'
|
||||
},
|
||||
InterfaceTypeAnnotation: {
|
||||
extends: 'NodeList',
|
||||
body: 'Node'
|
||||
},
|
||||
IntersectionTypeAnnotation: {
|
||||
types: 'NodeList'
|
||||
},
|
||||
JSXAttribute: {
|
||||
name: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
JSXClosingElement: {
|
||||
name: 'Node'
|
||||
},
|
||||
JSXClosingFragment: {},
|
||||
JSXElement: {
|
||||
openingElement: 'Node',
|
||||
children: 'NodeList',
|
||||
closingElement: 'Node'
|
||||
},
|
||||
JSXEmptyExpression: {},
|
||||
JSXExpressionContainer: {
|
||||
expression: 'Node'
|
||||
},
|
||||
JSXFragment: {
|
||||
openingFragment: 'Node',
|
||||
children: 'NodeList',
|
||||
closingFragment: 'Node'
|
||||
},
|
||||
JSXIdentifier: {},
|
||||
JSXMemberExpression: {
|
||||
object: 'Node',
|
||||
property: 'Node'
|
||||
},
|
||||
JSXNamespacedName: {
|
||||
namespace: 'Node',
|
||||
name: 'Node'
|
||||
},
|
||||
JSXOpeningElement: {
|
||||
name: 'Node',
|
||||
attributes: 'NodeList',
|
||||
typeArguments: 'Node'
|
||||
},
|
||||
JSXOpeningFragment: {},
|
||||
JSXSpreadAttribute: {
|
||||
argument: 'Node'
|
||||
},
|
||||
JSXSpreadChild: {
|
||||
expression: 'Node'
|
||||
},
|
||||
JSXText: {},
|
||||
KeyofTypeAnnotation: {
|
||||
argument: 'Node'
|
||||
},
|
||||
LabeledStatement: {
|
||||
label: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
LogicalExpression: {
|
||||
left: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
MemberExpression: {
|
||||
object: 'Node',
|
||||
property: 'Node'
|
||||
},
|
||||
MetaProperty: {
|
||||
meta: 'Node',
|
||||
property: 'Node'
|
||||
},
|
||||
MethodDefinition: {
|
||||
key: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
MixedTypeAnnotation: {},
|
||||
NewExpression: {
|
||||
callee: 'Node',
|
||||
typeArguments: 'Node',
|
||||
arguments: 'NodeList'
|
||||
},
|
||||
NullableTypeAnnotation: {
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
NullLiteral: {},
|
||||
NullLiteralTypeAnnotation: {},
|
||||
NumberLiteralTypeAnnotation: {},
|
||||
NumberTypeAnnotation: {},
|
||||
NumericLiteral: {},
|
||||
ObjectExpression: {
|
||||
properties: 'NodeList'
|
||||
},
|
||||
ObjectPattern: {
|
||||
properties: 'NodeList',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
ObjectTypeAnnotation: {
|
||||
properties: 'NodeList',
|
||||
indexers: 'NodeList',
|
||||
callProperties: 'NodeList',
|
||||
internalSlots: 'NodeList'
|
||||
},
|
||||
ObjectTypeCallProperty: {
|
||||
value: 'Node'
|
||||
},
|
||||
ObjectTypeIndexer: {
|
||||
id: 'Node',
|
||||
key: 'Node',
|
||||
value: 'Node',
|
||||
variance: 'Node'
|
||||
},
|
||||
ObjectTypeInternalSlot: {
|
||||
id: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
ObjectTypeMappedTypeProperty: {
|
||||
keyTparam: 'Node',
|
||||
propType: 'Node',
|
||||
sourceType: 'Node',
|
||||
variance: 'Node'
|
||||
},
|
||||
ObjectTypeProperty: {
|
||||
key: 'Node',
|
||||
value: 'Node',
|
||||
variance: 'Node'
|
||||
},
|
||||
ObjectTypeSpreadProperty: {
|
||||
argument: 'Node'
|
||||
},
|
||||
OpaqueType: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
impltype: 'Node',
|
||||
supertype: 'Node'
|
||||
},
|
||||
OptionalIndexedAccessType: {
|
||||
objectType: 'Node',
|
||||
indexType: 'Node'
|
||||
},
|
||||
PrivateIdentifier: {},
|
||||
Program: {
|
||||
body: 'NodeList'
|
||||
},
|
||||
Property: {
|
||||
key: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
PropertyDefinition: {
|
||||
key: 'Node',
|
||||
value: 'Node',
|
||||
variance: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
QualifiedTypeIdentifier: {
|
||||
qualification: 'Node',
|
||||
id: 'Node'
|
||||
},
|
||||
QualifiedTypeofIdentifier: {
|
||||
qualification: 'Node',
|
||||
id: 'Node'
|
||||
},
|
||||
RegExpLiteral: {},
|
||||
RestElement: {
|
||||
argument: 'Node'
|
||||
},
|
||||
ReturnStatement: {
|
||||
argument: 'Node'
|
||||
},
|
||||
SequenceExpression: {
|
||||
expressions: 'NodeList'
|
||||
},
|
||||
SpreadElement: {
|
||||
argument: 'Node'
|
||||
},
|
||||
StringLiteral: {},
|
||||
StringLiteralTypeAnnotation: {},
|
||||
StringTypeAnnotation: {},
|
||||
Super: {},
|
||||
SwitchCase: {
|
||||
test: 'Node',
|
||||
consequent: 'NodeList'
|
||||
},
|
||||
SwitchStatement: {
|
||||
discriminant: 'Node',
|
||||
cases: 'NodeList'
|
||||
},
|
||||
SymbolTypeAnnotation: {},
|
||||
TaggedTemplateExpression: {
|
||||
tag: 'Node',
|
||||
quasi: 'Node'
|
||||
},
|
||||
TemplateElement: {},
|
||||
TemplateLiteral: {
|
||||
quasis: 'NodeList',
|
||||
expressions: 'NodeList'
|
||||
},
|
||||
ThisExpression: {},
|
||||
ThisTypeAnnotation: {},
|
||||
ThrowStatement: {
|
||||
argument: 'Node'
|
||||
},
|
||||
TryStatement: {
|
||||
block: 'Node',
|
||||
handler: 'Node',
|
||||
finalizer: 'Node'
|
||||
},
|
||||
TupleTypeAnnotation: {
|
||||
types: 'NodeList'
|
||||
},
|
||||
TupleTypeLabeledElement: {
|
||||
label: 'Node',
|
||||
elementType: 'Node',
|
||||
variance: 'Node'
|
||||
},
|
||||
TupleTypeSpreadElement: {
|
||||
label: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
TypeAlias: {
|
||||
id: 'Node',
|
||||
typeParameters: 'Node',
|
||||
right: 'Node'
|
||||
},
|
||||
TypeAnnotation: {
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
TypeCastExpression: {
|
||||
expression: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
TypeofTypeAnnotation: {
|
||||
argument: 'Node',
|
||||
typeArguments: 'Node'
|
||||
},
|
||||
TypeOperator: {
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
TypeParameter: {
|
||||
bound: 'Node',
|
||||
variance: 'Node',
|
||||
default: 'Node'
|
||||
},
|
||||
TypeParameterDeclaration: {
|
||||
params: 'NodeList'
|
||||
},
|
||||
TypeParameterInstantiation: {
|
||||
params: 'NodeList'
|
||||
},
|
||||
TypePredicate: {
|
||||
parameterName: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
UnaryExpression: {
|
||||
argument: 'Node'
|
||||
},
|
||||
UnionTypeAnnotation: {
|
||||
types: 'NodeList'
|
||||
},
|
||||
UpdateExpression: {
|
||||
argument: 'Node'
|
||||
},
|
||||
VariableDeclaration: {
|
||||
declarations: 'NodeList'
|
||||
},
|
||||
VariableDeclarator: {
|
||||
init: 'Node',
|
||||
id: 'Node'
|
||||
},
|
||||
Variance: {},
|
||||
VoidTypeAnnotation: {},
|
||||
WhileStatement: {
|
||||
body: 'Node',
|
||||
test: 'Node'
|
||||
},
|
||||
WithStatement: {
|
||||
object: 'Node',
|
||||
body: 'Node'
|
||||
},
|
||||
YieldExpression: {
|
||||
argument: 'Node'
|
||||
},
|
||||
File: {
|
||||
program: 'Node'
|
||||
},
|
||||
ObjectProperty: {
|
||||
key: 'Node',
|
||||
value: 'Node'
|
||||
},
|
||||
ObjectMethod: {
|
||||
key: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
returnType: 'Node',
|
||||
typeParameters: 'NodeList'
|
||||
},
|
||||
ClassMethod: {
|
||||
key: 'Node',
|
||||
params: 'NodeList',
|
||||
body: 'Node',
|
||||
returnType: 'Node',
|
||||
typeParameters: 'NodeList'
|
||||
},
|
||||
Import: {},
|
||||
ClassProperty: {
|
||||
key: 'Node',
|
||||
value: 'Node',
|
||||
variance: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
ClassPrivateProperty: {
|
||||
key: 'Node',
|
||||
value: 'Node',
|
||||
variance: 'Node',
|
||||
typeAnnotation: 'Node'
|
||||
},
|
||||
PrivateName: {
|
||||
id: 'Node'
|
||||
},
|
||||
OptionalCallExpression: {
|
||||
callee: 'Node',
|
||||
typeArguments: 'Node',
|
||||
arguments: 'NodeList'
|
||||
},
|
||||
OptionalMemberExpression: {
|
||||
object: 'Node',
|
||||
property: 'Node'
|
||||
},
|
||||
ExportNamespaceSpecifier: {
|
||||
exported: 'Node'
|
||||
}
|
||||
};
|
||||
exports.HERMES_AST_VISITOR_KEYS = HERMES_AST_VISITOR_KEYS;
|
||||
17
node_modules/hermes-parser/dist/generated/ParserVisitorKeys.js.flow
generated
vendored
Normal file
17
node_modules/hermes-parser/dist/generated/ParserVisitorKeys.js.flow
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
declare export var NODE_CHILD: 'Node';
|
||||
declare export var NODE_LIST_CHILD: 'NodeList';
|
||||
declare export var HERMES_AST_VISITOR_KEYS: $ReadOnly<{
|
||||
[string]: $ReadOnly<{
|
||||
[string]: 'Node' | 'NodeList',
|
||||
}>,
|
||||
}>;
|
||||
112
node_modules/hermes-parser/dist/getModuleDocblock.js
generated
vendored
Normal file
112
node_modules/hermes-parser/dist/getModuleDocblock.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getModuleDocblock = getModuleDocblock;
|
||||
exports.parseDocblockString = parseDocblockString;
|
||||
const DIRECTIVE_REGEX = /^\s*@([a-zA-Z0-9_-]+)( +.+)?$/;
|
||||
|
||||
function parseDocblockString(docblock) {
|
||||
const directiveLines = docblock.split('\n') // remove the leading " *" from each line
|
||||
.map(line => line.trimStart().replace(/^\* ?/, '').trim()).filter(line => line.startsWith('@'));
|
||||
const directives = // $FlowExpectedError[incompatible-type] - flow types this return as {...}
|
||||
Object.create(null);
|
||||
|
||||
for (const line of directiveLines) {
|
||||
var _match$;
|
||||
|
||||
const match = DIRECTIVE_REGEX.exec(line);
|
||||
|
||||
if (match == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const name = match[1]; // explicitly use an empty string if there's no value
|
||||
// this way the array length tracks how many instances of the directive there was
|
||||
|
||||
const value = ((_match$ = match[2]) != null ? _match$ : '').trim();
|
||||
|
||||
if (directives[name]) {
|
||||
directives[name].push(value);
|
||||
} else {
|
||||
directives[name] = [value];
|
||||
}
|
||||
}
|
||||
|
||||
return directives;
|
||||
}
|
||||
|
||||
function getModuleDocblock(hermesProgram) {
|
||||
const docblockNode = (() => {
|
||||
if (hermesProgram.type !== 'Program') {
|
||||
return null;
|
||||
} // $FlowExpectedError[incompatible-type] - escape out of the unsafe hermes types
|
||||
|
||||
|
||||
const program = hermesProgram;
|
||||
|
||||
if (program.comments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const firstComment = (() => {
|
||||
const first = program.comments[0];
|
||||
|
||||
if (first.type === 'Block') {
|
||||
return first;
|
||||
}
|
||||
|
||||
if (program.comments.length === 1) {
|
||||
return null;
|
||||
} // ESLint will always strip out the shebang comment from the code before passing it to the parser
|
||||
// https://github.com/eslint/eslint/blob/21d647904dc30f9484b22acdd9243a6d0ecfba38/lib/linter/linter.js#L779
|
||||
// this means that we're forced to parse it as a line comment :(
|
||||
// this hacks around it by selecting the second comment in this case
|
||||
|
||||
|
||||
const second = program.comments[1];
|
||||
|
||||
if (first.type === 'Line' && first.range[0] === 0 && second.type === 'Block') {
|
||||
return second;
|
||||
}
|
||||
|
||||
return null;
|
||||
})();
|
||||
|
||||
if (firstComment == null) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
Handle cases like this where the comment isn't actually the first thing in the code:
|
||||
```
|
||||
const x = 1; /* docblock *./
|
||||
```
|
||||
*/
|
||||
|
||||
|
||||
if (program.body.length > 0 && program.body[0].range[0] < firstComment.range[0]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return firstComment;
|
||||
})();
|
||||
|
||||
if (docblockNode == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
directives: parseDocblockString(docblockNode.value),
|
||||
comment: docblockNode
|
||||
};
|
||||
}
|
||||
118
node_modules/hermes-parser/dist/getModuleDocblock.js.flow
generated
vendored
Normal file
118
node_modules/hermes-parser/dist/getModuleDocblock.js.flow
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {HermesNode} from './HermesAST';
|
||||
import type {DocblockDirectives, Program} from 'hermes-estree';
|
||||
|
||||
const DIRECTIVE_REGEX = /^\s*@([a-zA-Z0-9_-]+)( +.+)?$/;
|
||||
|
||||
export function parseDocblockString(docblock: string): DocblockDirectives {
|
||||
const directiveLines = docblock
|
||||
.split('\n')
|
||||
// remove the leading " *" from each line
|
||||
.map(line => line.trimStart().replace(/^\* ?/, '').trim())
|
||||
.filter(line => line.startsWith('@'));
|
||||
|
||||
const directives: {
|
||||
[string]: Array<string>,
|
||||
} =
|
||||
// $FlowExpectedError[incompatible-type] - flow types this return as {...}
|
||||
Object.create(null);
|
||||
|
||||
for (const line of directiveLines) {
|
||||
const match = DIRECTIVE_REGEX.exec(line);
|
||||
if (match == null) {
|
||||
continue;
|
||||
}
|
||||
const name = match[1];
|
||||
// explicitly use an empty string if there's no value
|
||||
// this way the array length tracks how many instances of the directive there was
|
||||
const value = (match[2] ?? '').trim();
|
||||
if (directives[name]) {
|
||||
directives[name].push(value);
|
||||
} else {
|
||||
directives[name] = [value];
|
||||
}
|
||||
}
|
||||
|
||||
return directives;
|
||||
}
|
||||
|
||||
export function getModuleDocblock(
|
||||
hermesProgram: HermesNode,
|
||||
): Program['docblock'] {
|
||||
const docblockNode = (() => {
|
||||
if (hermesProgram.type !== 'Program') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// $FlowExpectedError[incompatible-type] - escape out of the unsafe hermes types
|
||||
const program: Program = hermesProgram;
|
||||
|
||||
if (program.comments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const firstComment = (() => {
|
||||
const first = program.comments[0];
|
||||
if (first.type === 'Block') {
|
||||
return first;
|
||||
}
|
||||
|
||||
if (program.comments.length === 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ESLint will always strip out the shebang comment from the code before passing it to the parser
|
||||
// https://github.com/eslint/eslint/blob/21d647904dc30f9484b22acdd9243a6d0ecfba38/lib/linter/linter.js#L779
|
||||
// this means that we're forced to parse it as a line comment :(
|
||||
// this hacks around it by selecting the second comment in this case
|
||||
const second = program.comments[1];
|
||||
if (
|
||||
first.type === 'Line' &&
|
||||
first.range[0] === 0 &&
|
||||
second.type === 'Block'
|
||||
) {
|
||||
return second;
|
||||
}
|
||||
|
||||
return null;
|
||||
})();
|
||||
if (firstComment == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
Handle cases like this where the comment isn't actually the first thing in the code:
|
||||
```
|
||||
const x = 1; /* docblock *./
|
||||
```
|
||||
*/
|
||||
if (
|
||||
program.body.length > 0 &&
|
||||
program.body[0].range[0] < firstComment.range[0]
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return firstComment;
|
||||
})();
|
||||
|
||||
if (docblockNode == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
directives: parseDocblockString(docblockNode.value),
|
||||
comment: docblockNode,
|
||||
};
|
||||
}
|
||||
146
node_modules/hermes-parser/dist/index.js
generated
vendored
Normal file
146
node_modules/hermes-parser/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var _exportNames = {
|
||||
parse: true,
|
||||
mutateESTreeASTForPrettier: true,
|
||||
Transforms: true,
|
||||
FlowVisitorKeys: true,
|
||||
astArrayMutationHelpers: true,
|
||||
astNodeMutationHelpers: true
|
||||
};
|
||||
exports.mutateESTreeASTForPrettier = exports.astNodeMutationHelpers = exports.astArrayMutationHelpers = exports.Transforms = void 0;
|
||||
exports.parse = parse;
|
||||
|
||||
var HermesParser = _interopRequireWildcard(require("./HermesParser"));
|
||||
|
||||
var _HermesToESTreeAdapter = _interopRequireDefault(require("./HermesToESTreeAdapter"));
|
||||
|
||||
var _ESTreeVisitorKeys = _interopRequireDefault(require("./generated/ESTreeVisitorKeys"));
|
||||
|
||||
exports.FlowVisitorKeys = _ESTreeVisitorKeys.default;
|
||||
|
||||
var StripComponentSyntax = _interopRequireWildcard(require("./estree/StripComponentSyntax"));
|
||||
|
||||
var StripFlowTypesForBabel = _interopRequireWildcard(require("./estree/StripFlowTypesForBabel"));
|
||||
|
||||
var TransformESTreeToBabel = _interopRequireWildcard(require("./babel/TransformESTreeToBabel"));
|
||||
|
||||
var StripFlowTypes = _interopRequireWildcard(require("./estree/StripFlowTypes"));
|
||||
|
||||
var _ParserOptions = require("./ParserOptions");
|
||||
|
||||
Object.keys(_ParserOptions).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
||||
if (key in exports && exports[key] === _ParserOptions[key]) return;
|
||||
exports[key] = _ParserOptions[key];
|
||||
});
|
||||
|
||||
var _SimpleTraverser = require("./traverse/SimpleTraverser");
|
||||
|
||||
Object.keys(_SimpleTraverser).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
||||
if (key in exports && exports[key] === _SimpleTraverser[key]) return;
|
||||
exports[key] = _SimpleTraverser[key];
|
||||
});
|
||||
|
||||
var _SimpleTransform = require("./transform/SimpleTransform");
|
||||
|
||||
Object.keys(_SimpleTransform).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
||||
if (key in exports && exports[key] === _SimpleTransform[key]) return;
|
||||
exports[key] = _SimpleTransform[key];
|
||||
});
|
||||
|
||||
var _getVisitorKeys = require("./traverse/getVisitorKeys");
|
||||
|
||||
Object.keys(_getVisitorKeys).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
||||
if (key in exports && exports[key] === _getVisitorKeys[key]) return;
|
||||
exports[key] = _getVisitorKeys[key];
|
||||
});
|
||||
|
||||
var _astArrayMutationHelpers = _interopRequireWildcard(require("./transform/astArrayMutationHelpers"));
|
||||
|
||||
exports.astArrayMutationHelpers = _astArrayMutationHelpers;
|
||||
|
||||
var _astNodeMutationHelpers = _interopRequireWildcard(require("./transform/astNodeMutationHelpers"));
|
||||
|
||||
exports.astNodeMutationHelpers = _astNodeMutationHelpers;
|
||||
|
||||
var _mutateESTreeASTForPrettier = _interopRequireDefault(require("./utils/mutateESTreeASTForPrettier"));
|
||||
|
||||
exports.mutateESTreeASTForPrettier = _mutateESTreeASTForPrettier.default;
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
const DEFAULTS = {
|
||||
flow: 'detect'
|
||||
};
|
||||
|
||||
function getOptions(options = { ...DEFAULTS
|
||||
}) {
|
||||
// Default to detecting whether to parse Flow syntax by the presence
|
||||
// of an pragma.
|
||||
if (options.flow == null) {
|
||||
options.flow = DEFAULTS.flow;
|
||||
} else if (options.flow !== 'all' && options.flow !== 'detect') {
|
||||
throw new Error('flow option must be "all" or "detect"');
|
||||
}
|
||||
|
||||
if (options.sourceType === 'unambiguous') {
|
||||
// Clear source type so that it will be detected from the contents of the file
|
||||
delete options.sourceType;
|
||||
} else if (options.sourceType != null && options.sourceType !== 'script' && options.sourceType !== 'module') {
|
||||
throw new Error('sourceType option must be "script", "module", or "unambiguous" if set');
|
||||
}
|
||||
|
||||
if (options.enableExperimentalComponentSyntax == null) {
|
||||
options.enableExperimentalComponentSyntax = true; // Enable by default
|
||||
}
|
||||
|
||||
options.tokens = options.tokens === true;
|
||||
options.allowReturnOutsideFunction = options.allowReturnOutsideFunction === true;
|
||||
return options;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-redeclare
|
||||
function parse(code, opts) {
|
||||
const options = getOptions(opts);
|
||||
const ast = HermesParser.parse(code, options);
|
||||
const estreeAdapter = new _HermesToESTreeAdapter.default(options, code);
|
||||
const estreeAST = estreeAdapter.transform(ast);
|
||||
|
||||
if (options.babel !== true) {
|
||||
return estreeAST;
|
||||
}
|
||||
|
||||
const loweredESTreeAST = [StripComponentSyntax.transformProgram, StripFlowTypesForBabel.transformProgram].reduce((ast, transform) => transform(ast, options), estreeAST);
|
||||
return TransformESTreeToBabel.transformProgram(loweredESTreeAST, options);
|
||||
}
|
||||
|
||||
const Transforms = {
|
||||
stripComponentSyntax: StripComponentSyntax.transformProgram,
|
||||
stripFlowTypesForBabel: StripFlowTypesForBabel.transformProgram,
|
||||
stripFlowTypes: StripFlowTypes.transformProgram
|
||||
};
|
||||
exports.Transforms = Transforms;
|
||||
112
node_modules/hermes-parser/dist/index.js.flow
generated
vendored
Normal file
112
node_modules/hermes-parser/dist/index.js.flow
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {Program as ESTreeProgram} from 'hermes-estree';
|
||||
import type {ParserOptions} from './ParserOptions';
|
||||
import type {BabelFile} from './babel/TransformESTreeToBabel';
|
||||
|
||||
import * as HermesParser from './HermesParser';
|
||||
import HermesToESTreeAdapter from './HermesToESTreeAdapter';
|
||||
import FlowVisitorKeys from './generated/ESTreeVisitorKeys';
|
||||
import * as StripComponentSyntax from './estree/StripComponentSyntax';
|
||||
import * as StripFlowTypesForBabel from './estree/StripFlowTypesForBabel';
|
||||
import * as TransformESTreeToBabel from './babel/TransformESTreeToBabel';
|
||||
import * as StripFlowTypes from './estree/StripFlowTypes';
|
||||
|
||||
const DEFAULTS = {
|
||||
flow: 'detect',
|
||||
};
|
||||
|
||||
function getOptions(options?: ParserOptions = {...DEFAULTS}) {
|
||||
// Default to detecting whether to parse Flow syntax by the presence
|
||||
// of an @flow pragma.
|
||||
if (options.flow == null) {
|
||||
options.flow = DEFAULTS.flow;
|
||||
} else if (options.flow !== 'all' && options.flow !== 'detect') {
|
||||
throw new Error('flow option must be "all" or "detect"');
|
||||
}
|
||||
|
||||
if (options.sourceType === 'unambiguous') {
|
||||
// Clear source type so that it will be detected from the contents of the file
|
||||
delete options.sourceType;
|
||||
} else if (
|
||||
options.sourceType != null &&
|
||||
options.sourceType !== 'script' &&
|
||||
options.sourceType !== 'module'
|
||||
) {
|
||||
throw new Error(
|
||||
'sourceType option must be "script", "module", or "unambiguous" if set',
|
||||
);
|
||||
}
|
||||
|
||||
if (options.enableExperimentalComponentSyntax == null) {
|
||||
options.enableExperimentalComponentSyntax = true; // Enable by default
|
||||
}
|
||||
|
||||
options.tokens = options.tokens === true;
|
||||
options.allowReturnOutsideFunction =
|
||||
options.allowReturnOutsideFunction === true;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
declare function parse(
|
||||
code: string,
|
||||
opts: {...ParserOptions, babel: true},
|
||||
): BabelFile;
|
||||
// eslint-disable-next-line no-redeclare
|
||||
declare function parse(
|
||||
code: string,
|
||||
opts?:
|
||||
| {...ParserOptions, babel?: false | void}
|
||||
| {...ParserOptions, babel: false},
|
||||
): ESTreeProgram;
|
||||
|
||||
// eslint-disable-next-line no-redeclare
|
||||
export function parse(
|
||||
code: string,
|
||||
opts?: ParserOptions,
|
||||
): BabelFile | ESTreeProgram {
|
||||
const options = getOptions(opts);
|
||||
const ast = HermesParser.parse(code, options);
|
||||
|
||||
const estreeAdapter = new HermesToESTreeAdapter(options, code);
|
||||
const estreeAST = estreeAdapter.transform(ast);
|
||||
|
||||
if (options.babel !== true) {
|
||||
return estreeAST;
|
||||
}
|
||||
|
||||
const loweredESTreeAST = [
|
||||
StripComponentSyntax.transformProgram,
|
||||
StripFlowTypesForBabel.transformProgram,
|
||||
].reduce((ast, transform) => transform(ast, options), estreeAST);
|
||||
|
||||
return TransformESTreeToBabel.transformProgram(loweredESTreeAST, options);
|
||||
}
|
||||
|
||||
export type {ParserOptions} from './ParserOptions';
|
||||
export * from './ParserOptions';
|
||||
export * from './traverse/SimpleTraverser';
|
||||
export * from './transform/SimpleTransform';
|
||||
export * from './traverse/getVisitorKeys';
|
||||
export {FlowVisitorKeys};
|
||||
export * as astArrayMutationHelpers from './transform/astArrayMutationHelpers';
|
||||
export * as astNodeMutationHelpers from './transform/astNodeMutationHelpers';
|
||||
export {default as mutateESTreeASTForPrettier} from './utils/mutateESTreeASTForPrettier';
|
||||
|
||||
const Transforms = {
|
||||
stripComponentSyntax: StripComponentSyntax.transformProgram,
|
||||
stripFlowTypesForBabel: StripFlowTypesForBabel.transformProgram,
|
||||
stripFlowTypes: StripFlowTypes.transformProgram,
|
||||
};
|
||||
export {Transforms};
|
||||
120
node_modules/hermes-parser/dist/transform/SimpleTransform.js
generated
vendored
Normal file
120
node_modules/hermes-parser/dist/transform/SimpleTransform.js
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.SimpleTransform = void 0;
|
||||
|
||||
var _SimpleTraverser = require("../traverse/SimpleTraverser");
|
||||
|
||||
var _astNodeMutationHelpers = require("./astNodeMutationHelpers");
|
||||
|
||||
function setParentPointer(node, parent) {
|
||||
if (parent != null) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.parent = parent;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A simple class to recursively tranform AST trees.
|
||||
*/
|
||||
|
||||
|
||||
class SimpleTransform {
|
||||
/**
|
||||
* Transform the given AST tree.
|
||||
* @param rootNode The root node to traverse.
|
||||
* @param options The option object.
|
||||
* @return The modified rootNode or a new node if the rootNode was transformed directly.
|
||||
*/
|
||||
transform(rootNode, options) {
|
||||
let resultRootNode = rootNode;
|
||||
|
||||
_SimpleTraverser.SimpleTraverser.traverse(rootNode, {
|
||||
enter: (node, parent) => {
|
||||
// Ensure the parent pointers are correctly set before entering the node.
|
||||
setParentPointer(node, parent);
|
||||
const resultNode = options.transform(node);
|
||||
|
||||
if (resultNode !== node) {
|
||||
let traversedResultNode = null;
|
||||
|
||||
if (resultNode != null) {
|
||||
// Ensure the new node has the correct parent pointers before recursing again.
|
||||
setParentPointer(resultNode, parent);
|
||||
traversedResultNode = this.transform(resultNode, options);
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
if (node !== rootNode) {
|
||||
throw new Error('SimpleTransform infra error: Parent not set on non root node, this should not be possible');
|
||||
}
|
||||
|
||||
resultRootNode = traversedResultNode;
|
||||
} else if (traversedResultNode == null) {
|
||||
(0, _astNodeMutationHelpers.removeNodeOnParent)(node, parent, options.visitorKeys);
|
||||
} else {
|
||||
(0, _astNodeMutationHelpers.replaceNodeOnParent)(node, parent, traversedResultNode, options.visitorKeys);
|
||||
setParentPointer(traversedResultNode, parent);
|
||||
}
|
||||
|
||||
throw _SimpleTraverser.SimpleTraverser.Skip;
|
||||
}
|
||||
},
|
||||
|
||||
leave(_node) {},
|
||||
|
||||
visitorKeys: options.visitorKeys
|
||||
});
|
||||
|
||||
return resultRootNode;
|
||||
}
|
||||
/**
|
||||
* Transform the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
|
||||
|
||||
static transform(node, options) {
|
||||
return new SimpleTransform().transform(node, options);
|
||||
}
|
||||
|
||||
static transformProgram(program, options) {
|
||||
const result = SimpleTransform.transform(program, options);
|
||||
|
||||
if ((result == null ? void 0 : result.type) === 'Program') {
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Error('SimpleTransform.transformProgram: Expected program node.');
|
||||
}
|
||||
/**
|
||||
* Return a new AST node with the given properties overrided if needed.
|
||||
*
|
||||
* This function takes care to only create new nodes when needed. Referential equality of nodes
|
||||
* is important as its used to know if a node should be re-traversed.
|
||||
*
|
||||
* @param node The base AST node.
|
||||
* @param overrideProps New properties to apply to the node.
|
||||
* @return Either the orginal node if the properties matched the existing node or a new node with
|
||||
* the new properties.
|
||||
*/
|
||||
|
||||
|
||||
static nodeWith(node, overrideProps, visitorKeys) {
|
||||
return (0, _astNodeMutationHelpers.nodeWith)(node, overrideProps, visitorKeys);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.SimpleTransform = SimpleTransform;
|
||||
143
node_modules/hermes-parser/dist/transform/SimpleTransform.js.flow
generated
vendored
Normal file
143
node_modules/hermes-parser/dist/transform/SimpleTransform.js.flow
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {VisitorKeysType} from '../traverse/getVisitorKeys';
|
||||
import type {ESNode, Program} from 'hermes-estree';
|
||||
|
||||
import {SimpleTraverser} from '../traverse/SimpleTraverser';
|
||||
import {
|
||||
nodeWith,
|
||||
removeNodeOnParent,
|
||||
replaceNodeOnParent,
|
||||
} from './astNodeMutationHelpers';
|
||||
|
||||
/**
|
||||
* Transform callback
|
||||
* @param node The node we are visiting
|
||||
* @returns
|
||||
* - return input node, signals no changes were made will continue to the next node.
|
||||
* - return new node, the old node will be replaced in the AST. The new node and its
|
||||
* children are then traversed.
|
||||
* - return null, signals the node should be deleted from the AST.
|
||||
*/
|
||||
export type TransformCallback = (node: ESNode) => ESNode | null;
|
||||
|
||||
export type TransformOptions = $ReadOnly<{
|
||||
/** The callback function which is called on entering each node. */
|
||||
transform: TransformCallback,
|
||||
|
||||
/** The set of visitor keys to use for traversal. Defaults to the Flow ESTree visitor keys */
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
}>;
|
||||
|
||||
function setParentPointer(node: ESNode, parent: ?ESNode): void {
|
||||
if (parent != null) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple class to recursively tranform AST trees.
|
||||
*/
|
||||
export class SimpleTransform {
|
||||
/**
|
||||
* Transform the given AST tree.
|
||||
* @param rootNode The root node to traverse.
|
||||
* @param options The option object.
|
||||
* @return The modified rootNode or a new node if the rootNode was transformed directly.
|
||||
*/
|
||||
transform(rootNode: ESNode, options: TransformOptions): ESNode | null {
|
||||
let resultRootNode: ESNode | null = rootNode;
|
||||
SimpleTraverser.traverse(rootNode, {
|
||||
enter: (node: ESNode, parent: ?ESNode) => {
|
||||
// Ensure the parent pointers are correctly set before entering the node.
|
||||
setParentPointer(node, parent);
|
||||
|
||||
const resultNode = options.transform(node);
|
||||
if (resultNode !== node) {
|
||||
let traversedResultNode = null;
|
||||
|
||||
if (resultNode != null) {
|
||||
// Ensure the new node has the correct parent pointers before recursing again.
|
||||
setParentPointer(resultNode, parent);
|
||||
|
||||
traversedResultNode = this.transform(resultNode, options);
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
if (node !== rootNode) {
|
||||
throw new Error(
|
||||
'SimpleTransform infra error: Parent not set on non root node, this should not be possible',
|
||||
);
|
||||
}
|
||||
resultRootNode = traversedResultNode;
|
||||
} else if (traversedResultNode == null) {
|
||||
removeNodeOnParent(node, parent, options.visitorKeys);
|
||||
} else {
|
||||
replaceNodeOnParent(
|
||||
node,
|
||||
parent,
|
||||
traversedResultNode,
|
||||
options.visitorKeys,
|
||||
);
|
||||
setParentPointer(traversedResultNode, parent);
|
||||
}
|
||||
|
||||
throw SimpleTraverser.Skip;
|
||||
}
|
||||
},
|
||||
leave(_node: ESNode) {},
|
||||
visitorKeys: options.visitorKeys,
|
||||
});
|
||||
return resultRootNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
static transform(node: ESNode, options: TransformOptions): ESNode | null {
|
||||
return new SimpleTransform().transform(node, options);
|
||||
}
|
||||
|
||||
static transformProgram(
|
||||
program: Program,
|
||||
options: TransformOptions,
|
||||
): Program {
|
||||
const result = SimpleTransform.transform(program, options);
|
||||
if (result?.type === 'Program') {
|
||||
return result;
|
||||
}
|
||||
throw new Error('SimpleTransform.transformProgram: Expected program node.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new AST node with the given properties overrided if needed.
|
||||
*
|
||||
* This function takes care to only create new nodes when needed. Referential equality of nodes
|
||||
* is important as its used to know if a node should be re-traversed.
|
||||
*
|
||||
* @param node The base AST node.
|
||||
* @param overrideProps New properties to apply to the node.
|
||||
* @return Either the orginal node if the properties matched the existing node or a new node with
|
||||
* the new properties.
|
||||
*/
|
||||
static nodeWith<T: ESNode>(
|
||||
node: T,
|
||||
overrideProps: Partial<T>,
|
||||
visitorKeys?: VisitorKeysType,
|
||||
): T {
|
||||
return nodeWith<T>(node, overrideProps, visitorKeys);
|
||||
}
|
||||
}
|
||||
62
node_modules/hermes-parser/dist/transform/astArrayMutationHelpers.js
generated
vendored
Normal file
62
node_modules/hermes-parser/dist/transform/astArrayMutationHelpers.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.arrayIsEqual = arrayIsEqual;
|
||||
exports.insertInArray = insertInArray;
|
||||
exports.removeFromArray = removeFromArray;
|
||||
exports.replaceInArray = replaceInArray;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
function assertArrayBounds(array, index) {
|
||||
if (index < 0 || index >= array.length) {
|
||||
throw new Error(`Invalid Mutation: Tried to mutate an elements array with an out of bounds index. Index: ${index}, Array Size: ${array.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
function arrayIsEqual(a1, a2) {
|
||||
if (a1 === a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a1.length !== a2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < a1.length; i++) {
|
||||
if (a1[i] !== a2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function insertInArray(array, index, elements) {
|
||||
if (index === array.length) {
|
||||
// Support the insert at end of array case.
|
||||
return array.concat(elements);
|
||||
}
|
||||
|
||||
assertArrayBounds(array, index);
|
||||
return array.slice(0, index).concat(elements).concat(array.slice(index));
|
||||
}
|
||||
|
||||
function removeFromArray(array, index) {
|
||||
assertArrayBounds(array, index);
|
||||
return [...array.slice(0, index), ...array.slice(index + 1)];
|
||||
}
|
||||
|
||||
function replaceInArray(array, index, elements) {
|
||||
assertArrayBounds(array, index);
|
||||
return array.slice(0, index).concat(elements).concat(array.slice(index + 1));
|
||||
}
|
||||
71
node_modules/hermes-parser/dist/transform/astArrayMutationHelpers.js.flow
generated
vendored
Normal file
71
node_modules/hermes-parser/dist/transform/astArrayMutationHelpers.js.flow
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
function assertArrayBounds<T>(array: $ReadOnlyArray<T>, index: number): void {
|
||||
if (index < 0 || index >= array.length) {
|
||||
throw new Error(
|
||||
`Invalid Mutation: Tried to mutate an elements array with an out of bounds index. Index: ${index}, Array Size: ${array.length}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function arrayIsEqual(
|
||||
a1: $ReadOnlyArray<mixed>,
|
||||
a2: $ReadOnlyArray<mixed>,
|
||||
): boolean {
|
||||
if (a1 === a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a1.length !== a2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < a1.length; i++) {
|
||||
if (a1[i] !== a2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function insertInArray<T>(
|
||||
array: $ReadOnlyArray<T>,
|
||||
index: number,
|
||||
elements: $ReadOnlyArray<T>,
|
||||
): Array<T> {
|
||||
if (index === array.length) {
|
||||
// Support the insert at end of array case.
|
||||
return array.concat(elements);
|
||||
}
|
||||
assertArrayBounds(array, index);
|
||||
return array.slice(0, index).concat(elements).concat(array.slice(index));
|
||||
}
|
||||
|
||||
export function removeFromArray<T>(
|
||||
array: $ReadOnlyArray<T>,
|
||||
index: number,
|
||||
): Array<T> {
|
||||
assertArrayBounds(array, index);
|
||||
return [...array.slice(0, index), ...array.slice(index + 1)];
|
||||
}
|
||||
|
||||
export function replaceInArray<T>(
|
||||
array: $ReadOnlyArray<T>,
|
||||
index: number,
|
||||
elements: $ReadOnlyArray<T>,
|
||||
): Array<T> {
|
||||
assertArrayBounds(array, index);
|
||||
return array
|
||||
.slice(0, index)
|
||||
.concat(elements)
|
||||
.concat(array.slice(index + 1));
|
||||
}
|
||||
195
node_modules/hermes-parser/dist/transform/astNodeMutationHelpers.js
generated
vendored
Normal file
195
node_modules/hermes-parser/dist/transform/astNodeMutationHelpers.js
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.deepCloneNode = deepCloneNode;
|
||||
exports.nodeWith = nodeWith;
|
||||
exports.removeNodeOnParent = removeNodeOnParent;
|
||||
exports.replaceNodeOnParent = replaceNodeOnParent;
|
||||
exports.setParentPointersInDirectChildren = setParentPointersInDirectChildren;
|
||||
exports.shallowCloneNode = shallowCloneNode;
|
||||
exports.updateAllParentPointers = updateAllParentPointers;
|
||||
|
||||
var _astArrayMutationHelpers = require("./astArrayMutationHelpers");
|
||||
|
||||
var _getVisitorKeys = require("../traverse/getVisitorKeys");
|
||||
|
||||
var _SimpleTraverser = require("../traverse/SimpleTraverser");
|
||||
|
||||
function getParentKey(target, parent, visitorKeys) {
|
||||
if (parent == null) {
|
||||
throw new Error(`Expected parent node to be set on "${target.type}"`);
|
||||
}
|
||||
|
||||
for (const key of (0, _getVisitorKeys.getVisitorKeys)(parent, visitorKeys)) {
|
||||
if ((0, _getVisitorKeys.isNode)( // $FlowExpectedError[prop-missing]
|
||||
parent[key])) {
|
||||
if (parent[key] === target) {
|
||||
return {
|
||||
type: 'single',
|
||||
node: parent,
|
||||
key
|
||||
};
|
||||
}
|
||||
} else if (Array.isArray(parent[key])) {
|
||||
for (let i = 0; i < parent[key].length; i += 1) {
|
||||
// $FlowExpectedError[invalid-tuple-index]
|
||||
const current = parent[key][i];
|
||||
|
||||
if (current === target) {
|
||||
return {
|
||||
type: 'array',
|
||||
node: parent,
|
||||
key,
|
||||
targetIndex: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // this shouldn't happen ever
|
||||
|
||||
|
||||
throw new Error(`Expected to find the ${target.type} as a direct child of the ${parent.type}.`);
|
||||
}
|
||||
/**
|
||||
* Replace a node with a new node within an AST (via the parent pointer).
|
||||
*/
|
||||
|
||||
|
||||
function replaceNodeOnParent(originalNode, originalNodeParent, nodeToReplaceWith, visitorKeys) {
|
||||
const replacementParent = getParentKey(originalNode, originalNodeParent, visitorKeys);
|
||||
const parent = replacementParent.node;
|
||||
|
||||
if (replacementParent.type === 'array') {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = (0, _astArrayMutationHelpers.replaceInArray)( // $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key], replacementParent.targetIndex, [nodeToReplaceWith]);
|
||||
} else {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = nodeToReplaceWith;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove a node from the AST its connected to (via the parent pointer).
|
||||
*/
|
||||
|
||||
|
||||
function removeNodeOnParent(originalNode, originalNodeParent, visitorKeys) {
|
||||
const replacementParent = getParentKey(originalNode, originalNodeParent, visitorKeys);
|
||||
const parent = replacementParent.node;
|
||||
|
||||
if (replacementParent.type === 'array') {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = (0, _astArrayMutationHelpers.removeFromArray)( // $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key], replacementParent.targetIndex);
|
||||
} else {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Corrects the parent pointers in direct children of the given node.
|
||||
*/
|
||||
|
||||
|
||||
function setParentPointersInDirectChildren(node, visitorKeys) {
|
||||
for (const key of (0, _getVisitorKeys.getVisitorKeys)(node, visitorKeys)) {
|
||||
if ((0, _getVisitorKeys.isNode)(node[key])) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node[key].parent = node;
|
||||
} else if (Array.isArray(node[key])) {
|
||||
for (const child of node[key]) {
|
||||
child.parent = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Traverses the entire subtree to ensure the parent pointers are set correctly.
|
||||
*/
|
||||
|
||||
|
||||
function updateAllParentPointers(node, visitorKeys) {
|
||||
_SimpleTraverser.SimpleTraverser.traverse(node, {
|
||||
enter(node, parent) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.parent = parent;
|
||||
},
|
||||
|
||||
leave() {},
|
||||
|
||||
visitorKeys
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Clone node and add new props.
|
||||
*
|
||||
* This will only create a new object if the overrides actually result in a change.
|
||||
*/
|
||||
|
||||
|
||||
function nodeWith(node, overrideProps, visitorKeys) {
|
||||
// Check if this will actually result in a change, maintaining referential equality is important.
|
||||
const willBeUnchanged = Object.entries(overrideProps).every(([key, value]) => {
|
||||
const node_ = node;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return Array.isArray(node_[key]) ? (0, _astArrayMutationHelpers.arrayIsEqual)(node_[key], value) : false;
|
||||
}
|
||||
|
||||
return node_[key] === value;
|
||||
});
|
||||
|
||||
if (willBeUnchanged) {
|
||||
return node;
|
||||
} // Create new node.
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
|
||||
|
||||
const newNode = { ...node,
|
||||
...overrideProps
|
||||
}; // Ensure parent pointers are correctly set within this nodes children.
|
||||
|
||||
setParentPointersInDirectChildren(newNode, visitorKeys);
|
||||
return newNode;
|
||||
}
|
||||
/**
|
||||
* Shallow clones node, providing a new reference for an existing node.
|
||||
*/
|
||||
|
||||
|
||||
function shallowCloneNode(node, visitorKeys) {
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
const newNode = { ...node
|
||||
}; // Ensure parent pointers are correctly set within this nodes children.
|
||||
|
||||
setParentPointersInDirectChildren(newNode, visitorKeys);
|
||||
return newNode;
|
||||
}
|
||||
/**
|
||||
* Deeply clones node and its entire tree.
|
||||
*/
|
||||
|
||||
|
||||
function deepCloneNode(node, visitorKeys) {
|
||||
const clone = JSON.parse(JSON.stringify(node, (key, value) => {
|
||||
// null out parent pointers
|
||||
if (key === 'parent') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return value;
|
||||
}));
|
||||
updateAllParentPointers(clone, visitorKeys);
|
||||
return clone;
|
||||
}
|
||||
238
node_modules/hermes-parser/dist/transform/astNodeMutationHelpers.js.flow
generated
vendored
Normal file
238
node_modules/hermes-parser/dist/transform/astNodeMutationHelpers.js.flow
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ESNode} from 'hermes-estree';
|
||||
import type {VisitorKeysType} from '../traverse/getVisitorKeys';
|
||||
|
||||
import {
|
||||
arrayIsEqual,
|
||||
removeFromArray,
|
||||
replaceInArray,
|
||||
} from './astArrayMutationHelpers';
|
||||
import {getVisitorKeys, isNode} from '../traverse/getVisitorKeys';
|
||||
import {SimpleTraverser} from '../traverse/SimpleTraverser';
|
||||
|
||||
function getParentKey(
|
||||
target: ESNode,
|
||||
parent: ESNode,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): $ReadOnly<
|
||||
| {
|
||||
type: 'single',
|
||||
node: ESNode,
|
||||
key: string,
|
||||
}
|
||||
| {
|
||||
type: 'array',
|
||||
node: ESNode,
|
||||
key: string,
|
||||
targetIndex: number,
|
||||
},
|
||||
> {
|
||||
if (parent == null) {
|
||||
throw new Error(`Expected parent node to be set on "${target.type}"`);
|
||||
}
|
||||
for (const key of getVisitorKeys(parent, visitorKeys)) {
|
||||
if (
|
||||
isNode(
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[key],
|
||||
)
|
||||
) {
|
||||
if (parent[key] === target) {
|
||||
return {type: 'single', node: parent, key};
|
||||
}
|
||||
} else if (Array.isArray(parent[key])) {
|
||||
for (let i = 0; i < parent[key].length; i += 1) {
|
||||
// $FlowExpectedError[invalid-tuple-index]
|
||||
const current = parent[key][i];
|
||||
if (current === target) {
|
||||
return {type: 'array', node: parent, key, targetIndex: i};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this shouldn't happen ever
|
||||
throw new Error(
|
||||
`Expected to find the ${target.type} as a direct child of the ${parent.type}.`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a node with a new node within an AST (via the parent pointer).
|
||||
*/
|
||||
export function replaceNodeOnParent(
|
||||
originalNode: ESNode,
|
||||
originalNodeParent: ESNode,
|
||||
nodeToReplaceWith: ESNode,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): void {
|
||||
const replacementParent = getParentKey(
|
||||
originalNode,
|
||||
originalNodeParent,
|
||||
visitorKeys,
|
||||
);
|
||||
const parent = replacementParent.node;
|
||||
if (replacementParent.type === 'array') {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = replaceInArray(
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key],
|
||||
replacementParent.targetIndex,
|
||||
[nodeToReplaceWith],
|
||||
);
|
||||
} else {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = nodeToReplaceWith;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a node from the AST its connected to (via the parent pointer).
|
||||
*/
|
||||
export function removeNodeOnParent(
|
||||
originalNode: ESNode,
|
||||
originalNodeParent: ESNode,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): void {
|
||||
const replacementParent = getParentKey(
|
||||
originalNode,
|
||||
originalNodeParent,
|
||||
visitorKeys,
|
||||
);
|
||||
const parent = replacementParent.node;
|
||||
if (replacementParent.type === 'array') {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = removeFromArray(
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key],
|
||||
replacementParent.targetIndex,
|
||||
);
|
||||
} else {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
parent[replacementParent.key] = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrects the parent pointers in direct children of the given node.
|
||||
*/
|
||||
export function setParentPointersInDirectChildren(
|
||||
node: ESNode,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): void {
|
||||
for (const key: $FlowFixMe of getVisitorKeys(node, visitorKeys)) {
|
||||
if (isNode(node[key])) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node[key].parent = node;
|
||||
} else if (Array.isArray(node[key])) {
|
||||
for (const child of node[key]) {
|
||||
child.parent = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the entire subtree to ensure the parent pointers are set correctly.
|
||||
*/
|
||||
export function updateAllParentPointers(
|
||||
node: ESNode,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
) {
|
||||
SimpleTraverser.traverse(node, {
|
||||
enter(node, parent) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.parent = parent;
|
||||
},
|
||||
leave() {},
|
||||
visitorKeys,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone node and add new props.
|
||||
*
|
||||
* This will only create a new object if the overrides actually result in a change.
|
||||
*/
|
||||
export function nodeWith<T: ESNode>(
|
||||
node: T,
|
||||
overrideProps: Partial<T>,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): T {
|
||||
// Check if this will actually result in a change, maintaining referential equality is important.
|
||||
const willBeUnchanged = Object.entries(overrideProps).every(
|
||||
([key, value]) => {
|
||||
const node_: $FlowFixMe = node;
|
||||
if (Array.isArray(value)) {
|
||||
return Array.isArray(node_[key])
|
||||
? arrayIsEqual(node_[key], value)
|
||||
: false;
|
||||
}
|
||||
return node_[key] === value;
|
||||
},
|
||||
);
|
||||
if (willBeUnchanged) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// Create new node.
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
const newNode: T = {
|
||||
...node,
|
||||
...overrideProps,
|
||||
};
|
||||
|
||||
// Ensure parent pointers are correctly set within this nodes children.
|
||||
setParentPointersInDirectChildren(newNode, visitorKeys);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow clones node, providing a new reference for an existing node.
|
||||
*/
|
||||
export function shallowCloneNode<T: ESNode>(
|
||||
node: T,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): T {
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
const newNode: T = {...node};
|
||||
|
||||
// Ensure parent pointers are correctly set within this nodes children.
|
||||
setParentPointersInDirectChildren(newNode, visitorKeys);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deeply clones node and its entire tree.
|
||||
*/
|
||||
export function deepCloneNode<T: ESNode>(
|
||||
node: T,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): T {
|
||||
const clone: T = JSON.parse(
|
||||
JSON.stringify(node, (key, value) => {
|
||||
// null out parent pointers
|
||||
if (key === 'parent') {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}),
|
||||
);
|
||||
|
||||
updateAllParentPointers(clone, visitorKeys);
|
||||
|
||||
return clone;
|
||||
}
|
||||
137
node_modules/hermes-parser/dist/traverse/SimpleTraverser.js
generated
vendored
Normal file
137
node_modules/hermes-parser/dist/traverse/SimpleTraverser.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.SimpleTraverserSkip = exports.SimpleTraverserBreak = exports.SimpleTraverser = void 0;
|
||||
|
||||
var _getVisitorKeys = require("./getVisitorKeys");
|
||||
|
||||
/**
|
||||
* Can be thrown within the traversal "enter" function to prevent the traverser
|
||||
* from traversing the node any further, essentially culling the remainder of the
|
||||
* AST branch
|
||||
*/
|
||||
const SimpleTraverserSkip = new Error();
|
||||
/**
|
||||
* Can be thrown at any point during the traversal to immediately stop traversal
|
||||
* entirely.
|
||||
*/
|
||||
|
||||
exports.SimpleTraverserSkip = SimpleTraverserSkip;
|
||||
const SimpleTraverserBreak = new Error();
|
||||
/**
|
||||
* A very simple traverser class to traverse AST trees.
|
||||
*/
|
||||
|
||||
exports.SimpleTraverserBreak = SimpleTraverserBreak;
|
||||
|
||||
class SimpleTraverser {
|
||||
/**
|
||||
* Traverse the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
traverse(node, options) {
|
||||
try {
|
||||
this._traverse(node, null, options);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserBreak) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Traverse the given AST tree recursively.
|
||||
* @param node The current node.
|
||||
* @param parent The parent node.
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
_traverse(node, parent, options) {
|
||||
if (!(0, _getVisitorKeys.isNode)(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
options.enter(node, parent);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setErrorContext(ex, node);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
|
||||
const keys = (0, _getVisitorKeys.getVisitorKeys)(node, options.visitorKeys);
|
||||
|
||||
for (const key of keys) {
|
||||
const child = node[key];
|
||||
|
||||
if (Array.isArray(child)) {
|
||||
for (let j = 0; j < child.length; ++j) {
|
||||
this._traverse(child[j], node, options);
|
||||
}
|
||||
} else {
|
||||
this._traverse(child, node, options);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
options.leave(node, parent);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setErrorContext(ex, node);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set useful contextual information onto the error object.
|
||||
* @param ex The error object.
|
||||
* @param node The current node.
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
_setErrorContext(ex, node) {
|
||||
// $FlowFixMe[prop-missing]
|
||||
ex.currentNode = {
|
||||
type: node.type,
|
||||
range: node.range,
|
||||
loc: node.loc
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Traverse the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
|
||||
|
||||
static traverse(node, options) {
|
||||
new SimpleTraverser().traverse(node, options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.SimpleTraverser = SimpleTraverser;
|
||||
SimpleTraverser.Break = SimpleTraverserBreak;
|
||||
SimpleTraverser.Skip = SimpleTraverserSkip;
|
||||
133
node_modules/hermes-parser/dist/traverse/SimpleTraverser.js.flow
generated
vendored
Normal file
133
node_modules/hermes-parser/dist/traverse/SimpleTraverser.js.flow
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {VisitorKeysType} from './getVisitorKeys';
|
||||
import type {ESNode} from 'hermes-estree';
|
||||
|
||||
import {getVisitorKeys, isNode} from './getVisitorKeys';
|
||||
|
||||
export type TraverserCallback = (node: ESNode, parent: ?ESNode) => void;
|
||||
export type TraverserOptions = $ReadOnly<{
|
||||
/** The callback function which is called on entering each node. */
|
||||
enter: TraverserCallback,
|
||||
/** The callback function which is called on leaving each node. */
|
||||
leave: TraverserCallback,
|
||||
/** The set of visitor keys to use for traversal. Defaults to the Flow ESTree visitor keys */
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Can be thrown within the traversal "enter" function to prevent the traverser
|
||||
* from traversing the node any further, essentially culling the remainder of the
|
||||
* AST branch
|
||||
*/
|
||||
export const SimpleTraverserSkip: Error = new Error();
|
||||
/**
|
||||
* Can be thrown at any point during the traversal to immediately stop traversal
|
||||
* entirely.
|
||||
*/
|
||||
export const SimpleTraverserBreak: Error = new Error();
|
||||
|
||||
/**
|
||||
* A very simple traverser class to traverse AST trees.
|
||||
*/
|
||||
export class SimpleTraverser {
|
||||
static Break: Error = SimpleTraverserBreak;
|
||||
static Skip: Error = SimpleTraverserSkip;
|
||||
|
||||
/**
|
||||
* Traverse the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
traverse(node: ESNode, options: TraverserOptions): void {
|
||||
try {
|
||||
this._traverse(node, null, options);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserBreak) {
|
||||
return;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the given AST tree recursively.
|
||||
* @param node The current node.
|
||||
* @param parent The parent node.
|
||||
* @private
|
||||
*/
|
||||
_traverse(node: ESNode, parent: ?ESNode, options: TraverserOptions): void {
|
||||
if (!isNode(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
options.enter(node, parent);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserSkip) {
|
||||
return;
|
||||
}
|
||||
this._setErrorContext(ex, node);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
const keys = getVisitorKeys(node, options.visitorKeys);
|
||||
for (const key of keys) {
|
||||
const child: ESNode | $ReadOnlyArray<ESNode> = (node[
|
||||
(key: $FlowFixMe)
|
||||
]: $FlowFixMe);
|
||||
|
||||
if (Array.isArray(child)) {
|
||||
for (let j = 0; j < child.length; ++j) {
|
||||
this._traverse(child[j], node, options);
|
||||
}
|
||||
} else {
|
||||
this._traverse(child, node, options);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
options.leave(node, parent);
|
||||
} catch (ex) {
|
||||
if (ex === SimpleTraverserSkip) {
|
||||
return;
|
||||
}
|
||||
this._setErrorContext(ex, node);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set useful contextual information onto the error object.
|
||||
* @param ex The error object.
|
||||
* @param node The current node.
|
||||
* @private
|
||||
*/
|
||||
_setErrorContext(ex: Error, node: ESNode): void {
|
||||
// $FlowFixMe[prop-missing]
|
||||
ex.currentNode = {
|
||||
type: node.type,
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the given AST tree.
|
||||
* @param node The root node to traverse.
|
||||
* @param options The option object.
|
||||
*/
|
||||
static traverse(node: ESNode, options: TraverserOptions) {
|
||||
new SimpleTraverser().traverse(node, options);
|
||||
}
|
||||
}
|
||||
37
node_modules/hermes-parser/dist/traverse/getVisitorKeys.js
generated
vendored
Normal file
37
node_modules/hermes-parser/dist/traverse/getVisitorKeys.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @noformat
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getVisitorKeys = getVisitorKeys;
|
||||
exports.isNode = isNode;
|
||||
|
||||
var _ESTreeVisitorKeys = _interopRequireDefault(require("../generated/ESTreeVisitorKeys"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function isNode(thing)
|
||||
/*: implies thing is {+[string]: mixed} */
|
||||
{
|
||||
return typeof thing === 'object' && thing != null && typeof thing.type === 'string';
|
||||
}
|
||||
|
||||
function getVisitorKeys(node, visitorKeys) {
|
||||
const keys = (visitorKeys != null ? visitorKeys : _ESTreeVisitorKeys.default)[node.type];
|
||||
|
||||
if (keys == null) {
|
||||
throw new Error(`No visitor keys found for node type "${node.type}".`);
|
||||
} // $FlowExpectedError[prop-missing]
|
||||
|
||||
|
||||
return keys;
|
||||
}
|
||||
36
node_modules/hermes-parser/dist/traverse/getVisitorKeys.js.flow
generated
vendored
Normal file
36
node_modules/hermes-parser/dist/traverse/getVisitorKeys.js.flow
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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
|
||||
* @noformat
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ESNode} from 'hermes-estree';
|
||||
import type {VisitorKeys as VisitorKeysType} from '../generated/ESTreeVisitorKeys';
|
||||
|
||||
import FlowVisitorKeys from '../generated/ESTreeVisitorKeys';
|
||||
|
||||
export function isNode(thing: mixed) /*: implies thing is {+[string]: mixed} */ {
|
||||
return (
|
||||
typeof thing === 'object' && thing != null && typeof thing.type === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
export type {VisitorKeysType};
|
||||
export function getVisitorKeys<T: ESNode>(
|
||||
node: T,
|
||||
visitorKeys?: ?VisitorKeysType,
|
||||
): $ReadOnlyArray<$Keys<T>> {
|
||||
const keys = (visitorKeys ?? FlowVisitorKeys)[node.type];
|
||||
if (keys == null) {
|
||||
throw new Error(`No visitor keys found for node type "${node.type}".`);
|
||||
}
|
||||
|
||||
// $FlowExpectedError[prop-missing]
|
||||
return keys;
|
||||
}
|
||||
25
node_modules/hermes-parser/dist/utils/createSyntaxError.js
generated
vendored
Normal file
25
node_modules/hermes-parser/dist/utils/createSyntaxError.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createSyntaxError = createSyntaxError;
|
||||
|
||||
function createSyntaxError(node, err) {
|
||||
const syntaxError = new SyntaxError(err); // $FlowExpectedError[prop-missing]
|
||||
|
||||
syntaxError.loc = {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column
|
||||
};
|
||||
return syntaxError;
|
||||
}
|
||||
24
node_modules/hermes-parser/dist/utils/createSyntaxError.js.flow
generated
vendored
Normal file
24
node_modules/hermes-parser/dist/utils/createSyntaxError.js.flow
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ESNode} from 'hermes-estree';
|
||||
|
||||
export function createSyntaxError(node: ESNode, err: string): SyntaxError {
|
||||
const syntaxError = new SyntaxError(err);
|
||||
// $FlowExpectedError[prop-missing]
|
||||
syntaxError.loc = {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column,
|
||||
};
|
||||
|
||||
return syntaxError;
|
||||
}
|
||||
127
node_modules/hermes-parser/dist/utils/mutateESTreeASTForPrettier.js
generated
vendored
Normal file
127
node_modules/hermes-parser/dist/utils/mutateESTreeASTForPrettier.js
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = mutate;
|
||||
|
||||
var _SimpleTransform = require("../transform/SimpleTransform");
|
||||
|
||||
// https://github.com/prettier/prettier/blob/d962466a828f8ef51435e3e8840178d90b7ec6cd/src/language-js/parse/postprocess/index.js#L161-L182
|
||||
function transformChainExpression(node, comments) {
|
||||
if (comments != null) {
|
||||
var _node$comments;
|
||||
|
||||
// $FlowExpectedError[prop-missing]
|
||||
const joinedComments = comments.concat((_node$comments = node.comments) != null ? _node$comments : []); // $FlowExpectedError[prop-missing]
|
||||
// $FlowFixMe[cannot-write]
|
||||
|
||||
node.comments = joinedComments;
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
case 'CallExpression':
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
return { ...node,
|
||||
type: 'OptionalCallExpression',
|
||||
callee: transformChainExpression(node.callee)
|
||||
};
|
||||
|
||||
case 'MemberExpression':
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
return { ...node,
|
||||
type: 'OptionalMemberExpression',
|
||||
object: transformChainExpression(node.object)
|
||||
};
|
||||
// No default
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function mutate(rootNode, visitorKeys) {
|
||||
// Since we don't return the result of `transform` we need to be careful not to replace the Program root node.
|
||||
_SimpleTransform.SimpleTransform.transform(rootNode, {
|
||||
transform(node) {
|
||||
// prettier fully expects the parent pointers are NOT set and
|
||||
// certain cases can crash due to prettier infinite-looping
|
||||
// whilst naively traversing the parent property
|
||||
// https://github.com/prettier/prettier/issues/11793
|
||||
// Note: Only needed for prettier V2, this is supported in V3
|
||||
if (node.parent) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
delete node.parent;
|
||||
} // prettier currently relies on the AST being in the old-school, deprecated AST format for optional chaining
|
||||
// so we have to apply their transform to our AST so it can actually format it.
|
||||
// Note: Only needed for prettier V2, this is supported in V3
|
||||
|
||||
|
||||
if (node.type === 'ChainExpression') {
|
||||
// $FlowFixMe[prop-missing]
|
||||
return transformChainExpression(node.expression, node == null ? void 0 : node.comments);
|
||||
} // Prettier currently relies on comparing the `node` vs `node.value` start positions to know if an
|
||||
// `ObjectTypeProperty` is a method or not (instead of using the `node.method` boolean). To correctly print
|
||||
// the node when its not a method we need the start position to be different from the `node.value`s start
|
||||
// position.
|
||||
|
||||
|
||||
if (node.type === 'ObjectTypeProperty') {
|
||||
if (node.method === false && node.kind === 'init' && node.range[0] === 1 && node.value.range[0] === 1) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
node.value = { ...node.value,
|
||||
range: [2, node.value.range[1]]
|
||||
};
|
||||
}
|
||||
|
||||
return node;
|
||||
} // Prettier currently relies on comparing the the start positions to know if the import/export specifier should have a
|
||||
// rename (eg `Name` vs `Name as Name`) when the name is exactly the same
|
||||
// So we need to ensure that the range is always the same to avoid the useless code printing
|
||||
|
||||
|
||||
if (node.type === 'ImportSpecifier') {
|
||||
if (node.local.name === node.imported.name) {
|
||||
if (node.local.range == null) {
|
||||
// for our TS-ast printing which has no locs
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.local.range = [0, 0];
|
||||
} // $FlowExpectedError[cannot-write]
|
||||
|
||||
|
||||
node.imported.range = [...node.local.range];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node.type === 'ExportSpecifier') {
|
||||
if (node.local.name === node.exported.name) {
|
||||
if (node.local.range == null) {
|
||||
// for our TS-ast printing which has no locs
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.local.range = [0, 0];
|
||||
} // $FlowExpectedError[cannot-write]
|
||||
|
||||
|
||||
node.exported.range = [...node.local.range];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
visitorKeys
|
||||
});
|
||||
}
|
||||
130
node_modules/hermes-parser/dist/utils/mutateESTreeASTForPrettier.js.flow
generated
vendored
Normal file
130
node_modules/hermes-parser/dist/utils/mutateESTreeASTForPrettier.js.flow
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ESNode, Program, Comment} from 'hermes-estree';
|
||||
import type {VisitorKeysType} from '../traverse/getVisitorKeys';
|
||||
import {SimpleTransform} from '../transform/SimpleTransform';
|
||||
|
||||
// https://github.com/prettier/prettier/blob/d962466a828f8ef51435e3e8840178d90b7ec6cd/src/language-js/parse/postprocess/index.js#L161-L182
|
||||
function transformChainExpression(
|
||||
node: ESNode,
|
||||
comments: ?$ReadOnlyArray<Comment>,
|
||||
): ESNode {
|
||||
if (comments != null) {
|
||||
// $FlowExpectedError[prop-missing]
|
||||
const joinedComments = comments.concat(node.comments ?? []);
|
||||
// $FlowExpectedError[prop-missing]
|
||||
// $FlowFixMe[cannot-write]
|
||||
node.comments = joinedComments;
|
||||
}
|
||||
switch (node.type) {
|
||||
case 'CallExpression':
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
return {
|
||||
...node,
|
||||
type: 'OptionalCallExpression',
|
||||
callee: transformChainExpression(node.callee),
|
||||
};
|
||||
|
||||
case 'MemberExpression':
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
return {
|
||||
...node,
|
||||
type: 'OptionalMemberExpression',
|
||||
object: transformChainExpression(node.object),
|
||||
};
|
||||
// No default
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export default function mutate(
|
||||
rootNode: Program,
|
||||
visitorKeys: ?VisitorKeysType,
|
||||
): void {
|
||||
// Since we don't return the result of `transform` we need to be careful not to replace the Program root node.
|
||||
SimpleTransform.transform(rootNode, {
|
||||
transform(node): ESNode | null {
|
||||
// prettier fully expects the parent pointers are NOT set and
|
||||
// certain cases can crash due to prettier infinite-looping
|
||||
// whilst naively traversing the parent property
|
||||
// https://github.com/prettier/prettier/issues/11793
|
||||
// Note: Only needed for prettier V2, this is supported in V3
|
||||
if (node.parent) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
delete node.parent;
|
||||
}
|
||||
|
||||
// prettier currently relies on the AST being in the old-school, deprecated AST format for optional chaining
|
||||
// so we have to apply their transform to our AST so it can actually format it.
|
||||
// Note: Only needed for prettier V2, this is supported in V3
|
||||
if (node.type === 'ChainExpression') {
|
||||
// $FlowFixMe[prop-missing]
|
||||
return transformChainExpression(node.expression, node?.comments);
|
||||
}
|
||||
|
||||
// Prettier currently relies on comparing the `node` vs `node.value` start positions to know if an
|
||||
// `ObjectTypeProperty` is a method or not (instead of using the `node.method` boolean). To correctly print
|
||||
// the node when its not a method we need the start position to be different from the `node.value`s start
|
||||
// position.
|
||||
if (node.type === 'ObjectTypeProperty') {
|
||||
if (
|
||||
node.method === false &&
|
||||
node.kind === 'init' &&
|
||||
node.range[0] === 1 &&
|
||||
node.value.range[0] === 1
|
||||
) {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
// $FlowExpectedError[cannot-spread-interface]
|
||||
node.value = {
|
||||
...node.value,
|
||||
range: [2, node.value.range[1]],
|
||||
};
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Prettier currently relies on comparing the the start positions to know if the import/export specifier should have a
|
||||
// rename (eg `Name` vs `Name as Name`) when the name is exactly the same
|
||||
// So we need to ensure that the range is always the same to avoid the useless code printing
|
||||
if (node.type === 'ImportSpecifier') {
|
||||
if (node.local.name === node.imported.name) {
|
||||
if (node.local.range == null) {
|
||||
// for our TS-ast printing which has no locs
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.local.range = [0, 0];
|
||||
}
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.imported.range = [...node.local.range];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node.type === 'ExportSpecifier') {
|
||||
if (node.local.name === node.exported.name) {
|
||||
if (node.local.range == null) {
|
||||
// for our TS-ast printing which has no locs
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.local.range = [0, 0];
|
||||
}
|
||||
// $FlowExpectedError[cannot-write]
|
||||
node.exported.range = [...node.local.range];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
visitorKeys,
|
||||
});
|
||||
}
|
||||
25
node_modules/hermes-parser/package.json
generated
vendored
Normal file
25
node_modules/hermes-parser/package.json
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "hermes-parser",
|
||||
"version": "0.25.1",
|
||||
"description": "A JavaScript parser built from the Hermes engine",
|
||||
"main": "dist/index.js",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/hermes.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"hermes-estree": "0.25.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/parser": "7.7.4",
|
||||
"@babel/generator": "7.7.4",
|
||||
"@babel/types": "7.7.4",
|
||||
"espree": "9.3.2"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"LICENCE",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user