merge new into master

This commit is contained in:
2026-02-05 17:31:20 +00:00
16267 changed files with 2194867 additions and 0 deletions

View 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;

View 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);
}
}

View 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;
}

View 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;
}