mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 23:53:48 +01:00
convert to ts
This commit is contained in:
parent
4abc1df840
commit
ad75fa5ebc
@ -68,7 +68,7 @@ export class WorkerScript {
|
|||||||
* Used for static RAM calculation. Stores names of all functions that have
|
* Used for static RAM calculation. Stores names of all functions that have
|
||||||
* already been checked by this script
|
* already been checked by this script
|
||||||
*/
|
*/
|
||||||
loadedFns: IMap<string> = {};
|
loadedFns: IMap<boolean> = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filename of script
|
* Filename of script
|
||||||
|
3
src/Script/RamCalculations.d.ts
vendored
3
src/Script/RamCalculations.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
import { Script } from "./Script";
|
|
||||||
|
|
||||||
export declare function calculateRamUsage(codeCopy: string, otherScripts: Script[]): number;
|
|
@ -11,6 +11,8 @@ import { parse } from "acorn";
|
|||||||
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||||
|
|
||||||
import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
||||||
|
import { Script } from "../Script/Script";
|
||||||
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
|
|
||||||
// These special strings are used to reference the presence of a given logical
|
// These special strings are used to reference the presence of a given logical
|
||||||
// construct within a user script.
|
// construct within a user script.
|
||||||
@ -29,7 +31,11 @@ const memCheckGlobalKey = ".__GLOBAL__";
|
|||||||
* @param {WorkerScript} workerScript - Object containing RAM costs of Netscript functions. Also used to
|
* @param {WorkerScript} workerScript - Object containing RAM costs of Netscript functions. Also used to
|
||||||
* keep track of what functions have/havent been accounted for
|
* keep track of what functions have/havent been accounted for
|
||||||
*/
|
*/
|
||||||
async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
async function parseOnlyRamCalculate(
|
||||||
|
otherScripts: Script[],
|
||||||
|
code: string,
|
||||||
|
workerScript: WorkerScript,
|
||||||
|
): Promise<number | RamCalculationErrorCode> {
|
||||||
try {
|
try {
|
||||||
/**
|
/**
|
||||||
* Maps dependent identifiers to their dependencies.
|
* Maps dependent identifiers to their dependencies.
|
||||||
@ -41,16 +47,16 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
* We walk the dependency graph to calculate RAM usage, given that some identifiers
|
* We walk the dependency graph to calculate RAM usage, given that some identifiers
|
||||||
* reference Netscript functions which have a RAM cost.
|
* reference Netscript functions which have a RAM cost.
|
||||||
*/
|
*/
|
||||||
let dependencyMap = {};
|
let dependencyMap: { [key: string]: string[] } = {};
|
||||||
|
|
||||||
// Scripts we've parsed.
|
// Scripts we've parsed.
|
||||||
const completedParses = new Set();
|
const completedParses = new Set();
|
||||||
|
|
||||||
// Scripts we've discovered that need to be parsed.
|
// Scripts we've discovered that need to be parsed.
|
||||||
const parseQueue = [];
|
const parseQueue: string[] = [];
|
||||||
|
|
||||||
// Parses a chunk of code with a given module name, and updates parseQueue and dependencyMap.
|
// Parses a chunk of code with a given module name, and updates parseQueue and dependencyMap.
|
||||||
function parseCode(code, moduleName) {
|
function parseCode(code: string, moduleName: string): void {
|
||||||
const result = parseOnlyCalculateDeps(code, moduleName);
|
const result = parseOnlyCalculateDeps(code, moduleName);
|
||||||
completedParses.add(moduleName);
|
completedParses.add(moduleName);
|
||||||
|
|
||||||
@ -72,6 +78,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
// Process additional modules, which occurs if the "main" script has any imports
|
// Process additional modules, which occurs if the "main" script has any imports
|
||||||
while (parseQueue.length > 0) {
|
while (parseQueue.length > 0) {
|
||||||
const nextModule = parseQueue.shift();
|
const nextModule = parseQueue.shift();
|
||||||
|
if (nextModule === undefined) throw new Error("nextModule should not be undefined");
|
||||||
|
|
||||||
// Additional modules can either be imported from the web (in which case we use
|
// Additional modules can either be imported from the web (in which case we use
|
||||||
// a dynamic import), or from other in-game scripts
|
// a dynamic import), or from other in-game scripts
|
||||||
@ -122,6 +129,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
const resolvedRefs = new Set();
|
const resolvedRefs = new Set();
|
||||||
while (unresolvedRefs.length > 0) {
|
while (unresolvedRefs.length > 0) {
|
||||||
const ref = unresolvedRefs.shift();
|
const ref = unresolvedRefs.shift();
|
||||||
|
if (ref === undefined) throw new Error("ref should not be undefined");
|
||||||
|
|
||||||
// Check if this is one of the special keys, and add the appropriate ram cost if so.
|
// Check if this is one of the special keys, and add the appropriate ram cost if so.
|
||||||
if (ref === "hacknet" && !resolvedRefs.has("hacknet")) {
|
if (ref === "hacknet" && !resolvedRefs.has("hacknet")) {
|
||||||
@ -154,7 +162,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
// Check if this identifier is a function in the workerScript environment.
|
// Check if this identifier is a function in the workerScript environment.
|
||||||
// If it is, then we need to get its RAM cost.
|
// If it is, then we need to get its RAM cost.
|
||||||
try {
|
try {
|
||||||
function applyFuncRam(func) {
|
function applyFuncRam(func: any) {
|
||||||
if (typeof func === "function") {
|
if (typeof func === "function") {
|
||||||
try {
|
try {
|
||||||
let res;
|
let res;
|
||||||
@ -216,27 +224,28 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
* for RAM usage calculations. It also returns an array of additional modules
|
* for RAM usage calculations. It also returns an array of additional modules
|
||||||
* that need to be parsed (i.e. are 'import'ed scripts).
|
* that need to be parsed (i.e. are 'import'ed scripts).
|
||||||
*/
|
*/
|
||||||
function parseOnlyCalculateDeps(code, currentModule) {
|
function parseOnlyCalculateDeps(code: string, currentModule: string): any {
|
||||||
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
||||||
|
|
||||||
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
||||||
// the outermost layer of functions counts.
|
// the outermost layer of functions counts.
|
||||||
const globalKey = currentModule + memCheckGlobalKey;
|
const globalKey = currentModule + memCheckGlobalKey;
|
||||||
const dependencyMap = {};
|
const dependencyMap: { [key: string]: Set<string> | undefined } = {};
|
||||||
dependencyMap[globalKey] = new Set();
|
dependencyMap[globalKey] = new Set<string>();
|
||||||
|
|
||||||
// If we reference this internal name, we're really referencing that external name.
|
// If we reference this internal name, we're really referencing that external name.
|
||||||
// Filled when we import names from other modules.
|
// Filled when we import names from other modules.
|
||||||
let internalToExternal = {};
|
let internalToExternal: { [key: string]: string | undefined } = {};
|
||||||
|
|
||||||
var additionalModules = [];
|
let additionalModules: string[] = [];
|
||||||
|
|
||||||
// References get added pessimistically. They are added for thisModule.name, name, and for
|
// References get added pessimistically. They are added for thisModule.name, name, and for
|
||||||
// any aliases.
|
// any aliases.
|
||||||
function addRef(key, name) {
|
function addRef(key: string, name: string): void {
|
||||||
const s = dependencyMap[key] || (dependencyMap[key] = new Set());
|
const s = dependencyMap[key] || (dependencyMap[key] = new Set());
|
||||||
if (name in internalToExternal) {
|
const external = internalToExternal[name];
|
||||||
s.add(internalToExternal[name]);
|
if (external !== undefined) {
|
||||||
|
s.add(external);
|
||||||
}
|
}
|
||||||
s.add(currentModule + "." + name);
|
s.add(currentModule + "." + name);
|
||||||
s.add(name); // For builtins like hack.
|
s.add(name); // For builtins like hack.
|
||||||
@ -249,36 +258,36 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
|||||||
// walkDeeper is for doing recursive walks of expressions in composites that we handle.
|
// walkDeeper is for doing recursive walks of expressions in composites that we handle.
|
||||||
function commonVisitors() {
|
function commonVisitors() {
|
||||||
return {
|
return {
|
||||||
Identifier: (node, st) => {
|
Identifier: (node: any, st: any) => {
|
||||||
if (objectPrototypeProperties.includes(node.name)) {
|
if (objectPrototypeProperties.includes(node.name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addRef(st.key, node.name);
|
addRef(st.key, node.name);
|
||||||
},
|
},
|
||||||
WhileStatement: (node, st, walkDeeper) => {
|
WhileStatement: (node: any, st: any, walkDeeper: any) => {
|
||||||
addRef(st.key, specialReferenceWHILE);
|
addRef(st.key, specialReferenceWHILE);
|
||||||
node.test && walkDeeper(node.test, st);
|
node.test && walkDeeper(node.test, st);
|
||||||
node.body && walkDeeper(node.body, st);
|
node.body && walkDeeper(node.body, st);
|
||||||
},
|
},
|
||||||
DoWhileStatement: (node, st, walkDeeper) => {
|
DoWhileStatement: (node: any, st: any, walkDeeper: any) => {
|
||||||
addRef(st.key, specialReferenceWHILE);
|
addRef(st.key, specialReferenceWHILE);
|
||||||
node.test && walkDeeper(node.test, st);
|
node.test && walkDeeper(node.test, st);
|
||||||
node.body && walkDeeper(node.body, st);
|
node.body && walkDeeper(node.body, st);
|
||||||
},
|
},
|
||||||
ForStatement: (node, st, walkDeeper) => {
|
ForStatement: (node: any, st: any, walkDeeper: any) => {
|
||||||
addRef(st.key, specialReferenceFOR);
|
addRef(st.key, specialReferenceFOR);
|
||||||
node.init && walkDeeper(node.init, st);
|
node.init && walkDeeper(node.init, st);
|
||||||
node.test && walkDeeper(node.test, st);
|
node.test && walkDeeper(node.test, st);
|
||||||
node.update && walkDeeper(node.update, st);
|
node.update && walkDeeper(node.update, st);
|
||||||
node.body && walkDeeper(node.body, st);
|
node.body && walkDeeper(node.body, st);
|
||||||
},
|
},
|
||||||
IfStatement: (node, st, walkDeeper) => {
|
IfStatement: (node: any, st: any, walkDeeper: any) => {
|
||||||
addRef(st.key, specialReferenceIF);
|
addRef(st.key, specialReferenceIF);
|
||||||
node.test && walkDeeper(node.test, st);
|
node.test && walkDeeper(node.test, st);
|
||||||
node.consequent && walkDeeper(node.consequent, st);
|
node.consequent && walkDeeper(node.consequent, st);
|
||||||
node.alternate && walkDeeper(node.alternate, st);
|
node.alternate && walkDeeper(node.alternate, st);
|
||||||
},
|
},
|
||||||
MemberExpression: (node, st, walkDeeper) => {
|
MemberExpression: (node: any, st: any, walkDeeper: any) => {
|
||||||
node.object && walkDeeper(node.object, st);
|
node.object && walkDeeper(node.object, st);
|
||||||
node.property && walkDeeper(node.property, st);
|
node.property && walkDeeper(node.property, st);
|
||||||
},
|
},
|
||||||
@ -290,13 +299,15 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
|||||||
{ key: globalKey },
|
{ key: globalKey },
|
||||||
Object.assign(
|
Object.assign(
|
||||||
{
|
{
|
||||||
ImportDeclaration: (node, st) => {
|
ImportDeclaration: (node: any, st: any) => {
|
||||||
const importModuleName = node.source.value;
|
const importModuleName = node.source.value;
|
||||||
additionalModules.push(importModuleName);
|
additionalModules.push(importModuleName);
|
||||||
|
|
||||||
// This module's global scope refers to that module's global scope, no matter how we
|
// This module's global scope refers to that module's global scope, no matter how we
|
||||||
// import it.
|
// import it.
|
||||||
dependencyMap[st.key].add(importModuleName + memCheckGlobalKey);
|
const set = dependencyMap[st.key];
|
||||||
|
if (set === undefined) throw new Error("set should not be undefined");
|
||||||
|
set.add(importModuleName + memCheckGlobalKey);
|
||||||
|
|
||||||
for (let i = 0; i < node.specifiers.length; ++i) {
|
for (let i = 0; i < node.specifiers.length; ++i) {
|
||||||
const spec = node.specifiers[i];
|
const spec = node.specifiers[i];
|
||||||
@ -305,11 +316,13 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
|||||||
internalToExternal[spec.local.name] = importModuleName + "." + spec.imported.name;
|
internalToExternal[spec.local.name] = importModuleName + "." + spec.imported.name;
|
||||||
} else {
|
} else {
|
||||||
// We depend on everything.
|
// We depend on everything.
|
||||||
dependencyMap[st.key].add(importModuleName + ".*");
|
const set = dependencyMap[st.key];
|
||||||
|
if (set === undefined) throw new Error("set should not be undefined");
|
||||||
|
set.add(importModuleName + ".*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FunctionDeclaration: (node) => {
|
FunctionDeclaration: (node: any) => {
|
||||||
const key = currentModule + "." + node.id.name;
|
const key = currentModule + "." + node.id.name;
|
||||||
walk.recursive(node, { key: key }, commonVisitors());
|
walk.recursive(node, { key: key }, commonVisitors());
|
||||||
},
|
},
|
||||||
@ -327,7 +340,10 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
|||||||
* @param {Script[]} otherScripts - All other scripts on the server.
|
* @param {Script[]} otherScripts - All other scripts on the server.
|
||||||
* Used to account for imported scripts
|
* Used to account for imported scripts
|
||||||
*/
|
*/
|
||||||
export async function calculateRamUsage(codeCopy, otherScripts) {
|
export async function calculateRamUsage(
|
||||||
|
codeCopy: string,
|
||||||
|
otherScripts: Script[],
|
||||||
|
): Promise<RamCalculationErrorCode | number> {
|
||||||
// We don't need a real WorkerScript for this. Just an object that keeps
|
// We don't need a real WorkerScript for this. Just an object that keeps
|
||||||
// track of whatever's needed for RAM calculations
|
// track of whatever's needed for RAM calculations
|
||||||
const workerScript = {
|
const workerScript = {
|
||||||
@ -335,7 +351,7 @@ export async function calculateRamUsage(codeCopy, otherScripts) {
|
|||||||
env: {
|
env: {
|
||||||
vars: RamCosts,
|
vars: RamCosts,
|
||||||
},
|
},
|
||||||
};
|
} as WorkerScript;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await parseOnlyRamCalculate(otherScripts, codeCopy, workerScript);
|
return await parseOnlyRamCalculate(otherScripts, codeCopy, workerScript);
|
Loading…
Reference in New Issue
Block a user