first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

192
node_modules/hermes-parser/dist/src/HermesASTAdapter.js generated vendored Normal file
View File

@@ -0,0 +1,192 @@
"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-type] 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) {
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
.replaceAll('_', '');
return {
bigint,
// coerce the string to a bigint value if supported by the environment
value: typeof BigInt === 'function' ? BigInt(bigint) : null
};
}
}
exports.default = HermesASTAdapter;

108
node_modules/hermes-parser/dist/src/HermesParser.js generated vendored Normal file
View 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', '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.enableExperimentalFlowMatchSyntax, 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);
}
}

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

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

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,439 @@
"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 '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);
case 'BlockStatement':
return this.mapBlockStatement(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);
}
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;
}
mapBlockStatement(node) {
if (node.implicit && node.body.length) {
return this.mapNode(node.body[0]);
}
delete node.implicit;
return this.mapNodeDefault(node);
}
}
exports.default = HermesToESTreeAdapter;

18
node_modules/hermes-parser/dist/src/ParserOptions.js generated vendored Normal file
View 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', 'enableExperimentalFlowMatchSyntax', 'reactRuntimeTarget', 'sourceFilename', 'sourceType', 'tokens']);
exports.ParserOptionsKeys = ParserOptionsKeys;

File diff suppressed because it is too large Load Diff

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

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

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
/**
* 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', 'lowerBound', 'upperBound', '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', 'options'],
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'],
MatchArrayPattern: ['elements', 'rest'],
MatchAsPattern: ['pattern', 'target'],
MatchBindingPattern: ['id'],
MatchExpression: ['argument', 'cases'],
MatchExpressionCase: ['pattern', 'body', 'guard'],
MatchIdentifierPattern: ['id'],
MatchLiteralPattern: ['literal'],
MatchMemberPattern: ['base', 'property'],
MatchObjectPattern: ['properties', 'rest'],
MatchObjectPatternProperty: ['key', 'pattern'],
MatchOrPattern: ['patterns'],
MatchRestPattern: ['argument'],
MatchStatement: ['argument', 'cases'],
MatchStatementCase: ['pattern', 'body', 'guard'],
MatchUnaryPattern: ['argument'],
MatchWildcardPattern: [],
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', 'lowerBound', 'upperBound', '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'],
StaticBlock: ['body'],
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: []
};

View File

@@ -0,0 +1,794 @@
/**
* 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',
lowerBound: 'Node',
upperBound: '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',
options: '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'
},
MatchArrayPattern: {
elements: 'NodeList',
rest: 'Node'
},
MatchAsPattern: {
pattern: 'Node',
target: 'Node'
},
MatchBindingPattern: {
id: 'Node'
},
MatchExpression: {
argument: 'Node',
cases: 'NodeList'
},
MatchExpressionCase: {
pattern: 'Node',
body: 'Node',
guard: 'Node'
},
MatchIdentifierPattern: {
id: 'Node'
},
MatchLiteralPattern: {
literal: 'Node'
},
MatchMemberPattern: {
base: 'Node',
property: 'Node'
},
MatchObjectPattern: {
properties: 'NodeList',
rest: 'Node'
},
MatchObjectPatternProperty: {
key: 'Node',
pattern: 'Node'
},
MatchOrPattern: {
patterns: 'NodeList'
},
MatchRestPattern: {
argument: 'Node'
},
MatchStatement: {
argument: 'Node',
cases: 'NodeList'
},
MatchStatementCase: {
pattern: 'Node',
body: 'Node',
guard: 'Node'
},
MatchUnaryPattern: {
argument: 'Node'
},
MatchWildcardPattern: {},
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',
lowerBound: 'Node',
upperBound: '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'
},
StaticBlock: {
body: 'NodeList'
},
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;

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

153
node_modules/hermes-parser/dist/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,153 @@
/**
* 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 TransformMatchSyntax = _interopRequireWildcard(require("./estree/TransformMatchSyntax"));
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
}
if (options.enableExperimentalFlowMatchSyntax == null) {
options.enableExperimentalFlowMatchSyntax = 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 = [TransformMatchSyntax.transformProgram, StripComponentSyntax.transformProgram, StripFlowTypesForBabel.transformProgram].reduce((ast, transform) => transform(ast, options), estreeAST);
return TransformESTreeToBabel.transformProgram(loweredESTreeAST, options);
}
const Transforms = {
transformMatchSyntax: TransformMatchSyntax.transformProgram,
stripComponentSyntax: StripComponentSyntax.transformProgram,
stripFlowTypesForBabel: StripFlowTypesForBabel.transformProgram,
stripFlowTypes: StripFlowTypes.transformProgram
};
exports.Transforms = Transforms;

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

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

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

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

191
node_modules/hermes-parser/dist/src/utils/Builders.js generated vendored Normal file
View File

@@ -0,0 +1,191 @@
/**
* 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.EMPTY_PARENT = void 0;
exports.callExpression = callExpression;
exports.conjunction = conjunction;
exports.createDefaultPosition = createDefaultPosition;
exports.disjunction = disjunction;
exports.etc = etc;
exports.ident = ident;
exports.iife = iife;
exports.nullLiteral = nullLiteral;
exports.numberLiteral = numberLiteral;
exports.stringLiteral = stringLiteral;
exports.throwStatement = throwStatement;
exports.typeofExpression = typeofExpression;
exports.variableDeclaration = variableDeclaration;
// Rely on the mapper to fix up parent relationships.
const EMPTY_PARENT = null;
exports.EMPTY_PARENT = EMPTY_PARENT;
function createDefaultPosition() {
return {
line: 1,
column: 0
};
}
function etc({
loc,
range,
parent
} = {}) {
return {
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: parent != null ? parent : EMPTY_PARENT
};
}
function ident(name, info) {
return {
type: 'Identifier',
name,
optional: false,
typeAnnotation: null,
...etc(info)
};
}
function stringLiteral(value, info) {
return {
type: 'Literal',
value,
raw: `"${value}"`,
literalType: 'string',
...etc(info)
};
}
function numberLiteral(value, info) {
return {
type: 'Literal',
value,
raw: String(value),
literalType: 'numeric',
...etc(info)
};
}
function nullLiteral(info) {
return {
type: 'Literal',
value: null,
raw: 'null',
literalType: 'null',
...etc(info)
};
}
function conjunction(tests) {
if (tests.length === 0) {
throw new Error('Must have at least one test.');
}
return tests.reduce((acc, test) => ({
type: 'LogicalExpression',
left: acc,
right: test,
operator: '&&',
...etc()
}));
}
function disjunction(tests) {
if (tests.length === 0) {
throw new Error('Must have at least one test.');
}
return tests.reduce((acc, test) => ({
type: 'LogicalExpression',
left: acc,
right: test,
operator: '||',
...etc()
}));
}
function variableDeclaration(kind, id, init, info) {
return {
type: 'VariableDeclaration',
kind,
declarations: [{
type: 'VariableDeclarator',
init,
id,
...etc(),
parent: EMPTY_PARENT
}],
...etc(info)
};
}
function callExpression(callee, args, info) {
return {
type: 'CallExpression',
callee,
arguments: args,
typeArguments: null,
optional: false,
...etc(info)
};
}
function throwStatement(arg, info) {
return {
type: 'ThrowStatement',
argument: callExpression(ident('Error'), [arg]),
...etc(info)
};
}
function iife(statements, params = [], args = []) {
const callee = {
type: 'ArrowFunctionExpression',
params,
expression: false,
async: false,
predicate: null,
returnType: null,
typeParameters: null,
id: null,
body: {
type: 'BlockStatement',
body: statements,
...etc()
},
...etc()
};
return callExpression(callee, args);
}
function typeofExpression(arg, kind) {
return {
type: 'BinaryExpression',
left: {
type: 'UnaryExpression',
operator: 'typeof',
argument: arg,
prefix: true,
...etc()
},
right: stringLiteral(kind),
operator: '===',
...etc()
};
}

41
node_modules/hermes-parser/dist/src/utils/GenID.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* 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.createGenID = createGenID;
const genPrefix = '$$gen$';
function createGenID(uniqueTransformPrefix) {
let genN = 0;
const used = new Set();
return {
genID() {
let name;
do {
name = `${genPrefix}${uniqueTransformPrefix}${genN}`;
genN++;
} while (used.has(name));
used.add(name);
return name;
},
addUsage(name) {
if (name.startsWith(genPrefix)) {
used.add(name);
}
}
};
}

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

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