This commit is contained in:
MishaBagger
2023-10-25 09:15:21 +03:00
commit b6c10cc93f
9828 changed files with 1446743 additions and 0 deletions

195
33/node_modules/with/src/globals.ts generated vendored Normal file
View File

@@ -0,0 +1,195 @@
import assertNever from 'assert-never';
import {ancestor as walk} from 'babel-walk';
import * as t from '@babel/types';
import isReferenced from './reference';
const isScope = (node: t.Node) => t.isFunctionParent(node) || t.isProgram(node);
const isBlockScope = (node: t.Node) =>
t.isBlockStatement(node) || isScope(node);
const declaresArguments = (node: t.Node) =>
t.isFunction(node) && !t.isArrowFunctionExpression(node);
const declaresThis = declaresArguments;
const LOCALS_SYMBOL = Symbol('locals');
const getLocals = (node: t.Node): Set<string> | undefined =>
(node as any)[LOCALS_SYMBOL];
const declareLocals = (node: t.Node): Set<string> =>
((node as any)[LOCALS_SYMBOL] = (node as any)[LOCALS_SYMBOL] || new Set());
const setLocal = (node: t.Node, name: string) => declareLocals(node).add(name);
// First pass
function declareFunction(node: t.Function) {
for (const param of node.params) {
declarePattern(param, node);
}
const id = (node as t.FunctionDeclaration).id;
if (id) {
setLocal(node, id.name);
}
}
function declarePattern(node: t.LVal, parent: t.Node) {
switch (node.type) {
case 'Identifier':
setLocal(parent, node.name);
break;
case 'ObjectPattern':
for (const prop of node.properties) {
switch (prop.type) {
case 'RestElement':
declarePattern(prop.argument, parent);
break;
case 'ObjectProperty':
declarePattern(prop.value as t.LVal, parent);
break;
default:
assertNever(prop);
break;
}
}
break;
case 'ArrayPattern':
for (const element of node.elements) {
if (element) declarePattern(element, parent);
}
break;
case 'RestElement':
declarePattern(node.argument, parent);
break;
case 'AssignmentPattern':
declarePattern(node.left, parent);
break;
// istanbul ignore next
default:
throw new Error('Unrecognized pattern type: ' + node.type);
}
}
function declareModuleSpecifier(
node:
| t.ImportSpecifier
| t.ImportDefaultSpecifier
| t.ImportNamespaceSpecifier,
_state: unknown,
parents: t.Node[],
) {
for (let i = parents.length - 2; i >= 0; i--) {
if (isScope(parents[i])) {
setLocal(parents[i], node.local.name);
return;
}
}
}
const firstPass = walk({
VariableDeclaration(node, _state, parents) {
for (let i = parents.length - 2; i >= 0; i--) {
if (
node.kind === 'var'
? t.isFunctionParent(parents[i])
: isBlockScope(parents[i])
) {
for (const declaration of node.declarations) {
declarePattern(declaration.id, parents[i]);
}
return;
}
}
},
FunctionDeclaration(node, _state, parents) {
if (node.id) {
for (let i = parents.length - 2; i >= 0; i--) {
if (isScope(parents[i])) {
setLocal(parents[i], node.id.name);
return;
}
}
}
},
Function: declareFunction,
ClassDeclaration(node, _state, parents) {
for (let i = parents.length - 2; i >= 0; i--) {
if (isScope(parents[i])) {
setLocal(parents[i], node.id.name);
return;
}
}
},
TryStatement(node) {
if (node.handler === null) return;
if (node.handler.param === null) return;
declarePattern(node.handler.param, node.handler);
},
ImportDefaultSpecifier: declareModuleSpecifier,
ImportSpecifier: declareModuleSpecifier,
ImportNamespaceSpecifier: declareModuleSpecifier,
});
// Second pass
const secondPass = walk<{
globals: (t.Identifier | t.ThisExpression)[];
}>({
Identifier(node, state, parents) {
const name = node.name;
if (name === 'undefined') return;
const lastParent = parents[parents.length - 2];
if (lastParent) {
if (!isReferenced(node, lastParent)) return;
for (const parent of parents) {
if (name === 'arguments' && declaresArguments(parent)) {
return;
}
if (getLocals(parent)?.has(name)) {
return;
}
}
}
state.globals.push(node);
},
ThisExpression(node, state, parents) {
for (const parent of parents) {
if (declaresThis(parent)) {
return;
}
}
state.globals.push(node);
},
});
export default function findGlobals(ast: t.Node) {
const globals: (t.Identifier | t.ThisExpression)[] = [];
// istanbul ignore if
if (!t.isNode(ast)) {
throw new TypeError('Source must be a Babylon AST');
}
firstPass(ast, undefined);
secondPass(ast, {globals});
const groupedGlobals = new Map<string, (t.Identifier | t.ThisExpression)[]>();
for (const node of globals) {
const name: string = node.type === 'ThisExpression' ? 'this' : node.name;
const existing = groupedGlobals.get(name);
if (existing) {
existing.push(node);
} else {
groupedGlobals.set(name, [node]);
}
}
return [...groupedGlobals]
.map(([name, nodes]) => ({name, nodes}))
.sort((a, b) => (a.name < b.name ? -1 : 1));
}

154
33/node_modules/with/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,154 @@
import {parse} from '@babel/parser';
import {recursive as walk} from 'babel-walk';
import * as t from '@babel/types';
import detect from './globals';
const parseOptions = {
allowReturnOutsideFunction: true,
allowImportExportEverywhere: true,
};
/**
* Mimic `with` as far as possible but at compile time
*
* @param obj The object part of a with expression
* @param src The body of the with expression
* @param exclude A list of variable names to explicitly exclude
*/
export default function addWith(
obj: string,
src: string,
exclude: string[] = [],
) {
// tslint:disable-next-line: no-parameter-reassignment
obj = obj + '';
// tslint:disable-next-line: no-parameter-reassignment
src = src + '';
let ast;
try {
ast = parse(src, parseOptions);
} catch (e) {
throw Object.assign(
new Error('Error parsing body of the with expression'),
{
component: 'src',
babylonError: e,
},
);
}
let objAst;
try {
objAst = parse(obj, parseOptions);
} catch (e) {
throw Object.assign(
new Error('Error parsing object part of the with expression'),
{
component: 'obj',
babylonError: e,
},
);
}
const excludeSet = new Set([
'undefined',
'this',
...exclude,
...detect(objAst).map((g) => g.name),
]);
const vars = new Set(
detect(ast)
.map((global) => global.name)
.filter((v) => !excludeSet.has(v)),
);
if (vars.size === 0) return src;
let declareLocal = '';
let local = 'locals_for_with';
let result = 'result_of_with';
if (t.isValidIdentifier(obj)) {
local = obj;
} else {
while (vars.has(local) || excludeSet.has(local)) {
local += '_';
}
declareLocal = `var ${local} = (${obj});`;
}
while (vars.has(result) || excludeSet.has(result)) {
result += '_';
}
const args = [
'this',
...Array.from(vars).map(
(v) =>
`${JSON.stringify(v)} in ${local} ?
${local}.${v} :
typeof ${v} !== 'undefined' ? ${v} : undefined`,
),
];
const unwrapped = unwrapReturns(ast, src, result);
return `;
${declareLocal}
${unwrapped.before}
(function (${Array.from(vars).join(', ')}) {
${unwrapped.body}
}.call(${args.join(', ')}));
${unwrapped.after};`;
}
interface UnwrapReturnsState {
hasReturn: boolean;
source(node: t.Node): string;
replace(node: t.Node, str: string): void;
}
const unwrapReturnsVisitors = walk<UnwrapReturnsState>({
Function(_node, _state, _c) {
// returns in these functions are not applicable
},
ReturnStatement(node, state) {
state.hasReturn = true;
let value = '';
if (node.argument) {
value = `value: (${state.source(node.argument)})`;
}
state.replace(node, `return {${value}};`);
},
});
/**
* Take a self calling function, and unwrap it such that return inside the function
* results in return outside the function
*
* @param src Some JavaScript code representing a self-calling function
* @param result A temporary variable to store the result in
*/
function unwrapReturns(ast: t.Node, src: string, result: string) {
const charArray = src.split('');
const state: UnwrapReturnsState = {
hasReturn: false,
source(node) {
return src.slice(node.start!, node.end!);
},
replace(node, str) {
charArray.fill('', node.start!, node.end!);
charArray[node.start!] = str;
},
};
unwrapReturnsVisitors(ast, state);
return {
before: state.hasReturn ? `var ${result} = ` : '',
body: charArray.join(''),
after: state.hasReturn ? `;if (${result}) return ${result}.value` : '',
};
}
module.exports = addWith;
module.exports.default = addWith;

24
33/node_modules/with/src/reference.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import * as t from '@babel/types';
export default function isReferenced(node: t.Node, parent: t.Node) {
switch (parent.type) {
// yes: { [NODE]: '' }
// yes: { NODE }
// no: { NODE: '' }
case 'ObjectProperty':
return parent.value === node || parent.computed;
// no: break NODE;
// no: continue NODE;
case 'BreakStatement':
case 'ContinueStatement':
return false;
// yes: left = NODE;
// yes: NODE = right;
case 'AssignmentExpression':
return true;
}
return t.isReferenced(node, parent);
}