mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-11 10:13:52 +01:00
Merge pull request #1628 from danielyxie/dev
Few bugfix and infinite loop checker.
This commit is contained in:
commit
331d267082
28
dist/vendor.bundle.js
vendored
28
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -44,7 +44,12 @@
|
|||||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||||
scrollbar-width: none; /* for Firefox */
|
scrollbar-width: none; /* for Firefox */
|
||||||
}
|
}
|
||||||
|
.myGlyphMarginClass {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
.myContentClass {
|
||||||
|
background: lightblue;
|
||||||
|
}
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
display: none; /* for Chrome, Safari, and Opera */
|
display: none; /* for Chrome, Safari, and Opera */
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
27
package-lock.json
generated
27
package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"@mui/icons-material": "^5.0.3",
|
"@mui/icons-material": "^5.0.3",
|
||||||
"@mui/material": "^5.0.3",
|
"@mui/material": "^5.0.3",
|
||||||
"@mui/styles": "^5.0.1",
|
"@mui/styles": "^5.0.1",
|
||||||
|
"@types/acorn": "^4.0.6",
|
||||||
"@types/escodegen": "^0.0.7",
|
"@types/escodegen": "^0.0.7",
|
||||||
"@types/numeral": "0.0.25",
|
"@types/numeral": "0.0.25",
|
||||||
"@types/react": "^17.0.21",
|
"@types/react": "^17.0.21",
|
||||||
@ -3613,6 +3614,14 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/acorn": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/estree": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/aria-query": {
|
"node_modules/@types/aria-query": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
|
||||||
@ -3665,6 +3674,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
||||||
"integrity": "sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ=="
|
"integrity": "sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/estree": {
|
||||||
|
"version": "0.0.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
|
||||||
|
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
|
||||||
|
},
|
||||||
"node_modules/@types/file-saver": {
|
"node_modules/@types/file-saver": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.3.tgz",
|
||||||
@ -24027,6 +24041,14 @@
|
|||||||
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
|
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/acorn": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/estree": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/aria-query": {
|
"@types/aria-query": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
|
||||||
@ -24079,6 +24101,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
||||||
"integrity": "sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ=="
|
"integrity": "sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ=="
|
||||||
},
|
},
|
||||||
|
"@types/estree": {
|
||||||
|
"version": "0.0.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
|
||||||
|
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
|
||||||
|
},
|
||||||
"@types/file-saver": {
|
"@types/file-saver": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.3.tgz",
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"@mui/icons-material": "^5.0.3",
|
"@mui/icons-material": "^5.0.3",
|
||||||
"@mui/material": "^5.0.3",
|
"@mui/material": "^5.0.3",
|
||||||
"@mui/styles": "^5.0.1",
|
"@mui/styles": "^5.0.1",
|
||||||
|
"@types/acorn": "^4.0.6",
|
||||||
"@types/escodegen": "^0.0.7",
|
"@types/escodegen": "^0.0.7",
|
||||||
"@types/numeral": "0.0.25",
|
"@types/numeral": "0.0.25",
|
||||||
"@types/react": "^17.0.21",
|
"@types/react": "^17.0.21",
|
||||||
|
@ -44,7 +44,7 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
|||||||
<MoneyCost money={cost} corp={corp} />
|
<MoneyCost money={cost} corp={corp} />
|
||||||
</Button>
|
</Button>
|
||||||
<Tooltip title={tooltip}>
|
<Tooltip title={tooltip}>
|
||||||
<Typography>{data[4]} </Typography>
|
<Typography>{data[4]} - lvl {level}</Typography>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -25,15 +25,15 @@ function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
|
|||||||
const maxAmount = (props.warehouse.size - props.warehouse.sizeUsed) / matSize;
|
const maxAmount = (props.warehouse.size - props.warehouse.sizeUsed) / matSize;
|
||||||
|
|
||||||
if (parsedAmt * matSize > maxAmount) {
|
if (parsedAmt * matSize > maxAmount) {
|
||||||
return <>Not enough warehouse space to purchase this amount</>;
|
return <><Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography></>;
|
||||||
} else if (isNaN(cost)) {
|
} else if (isNaN(cost)) {
|
||||||
return <>Invalid put for Bulk Purchase amount</>;
|
return <><Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography></>;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<><Typography>
|
||||||
Purchasing {numeralWrapper.format(parsedAmt, "0,0.00")} of {props.mat.name} will cost{" "}
|
Purchasing {numeralWrapper.format(parsedAmt, "0,0.00")} of {props.mat.name} will cost{" "}
|
||||||
{numeralWrapper.formatMoney(cost)}
|
{numeralWrapper.formatMoney(cost)}</Typography>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* the way
|
* the way
|
||||||
*/
|
*/
|
||||||
import * as walk from "acorn-walk";
|
import * as walk from "acorn-walk";
|
||||||
import { parse } from "acorn";
|
import acorn, { parse } from "acorn";
|
||||||
|
|
||||||
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||||
|
|
||||||
@ -206,6 +206,46 @@ async function parseOnlyRamCalculate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function checkInfiniteLoop(code: string): number {
|
||||||
|
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
||||||
|
|
||||||
|
function nodeHasTrueTest(node: acorn.Node): boolean {
|
||||||
|
return node.type === "Literal" && (node as any).raw === "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasAwait(ast: acorn.Node): boolean {
|
||||||
|
let hasAwait = false;
|
||||||
|
walk.recursive(
|
||||||
|
ast,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
AwaitExpression: () => {
|
||||||
|
hasAwait = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return hasAwait;
|
||||||
|
}
|
||||||
|
|
||||||
|
let missingAwaitLine = -1;
|
||||||
|
walk.recursive(
|
||||||
|
ast,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
WhileStatement: (node: acorn.Node, st: any, walkDeeper: walk.WalkerCallback<any>) => {
|
||||||
|
if (nodeHasTrueTest((node as any).test) && !hasAwait(node)) {
|
||||||
|
console.log(node);
|
||||||
|
missingAwaitLine = (code.slice(0, node.start).match(/\n/g) || []).length + 1;
|
||||||
|
} else {
|
||||||
|
(node as any).body && walkDeeper((node as any).body, st);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return missingAwaitLine;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function that parses a single script. It returns a map of all dependencies,
|
* Helper function that parses a single script. It returns a map of all dependencies,
|
||||||
* which are items in the code's AST that potentially need to be evaluated
|
* which are items in the code's AST that potentially need to be evaluated
|
||||||
@ -214,7 +254,6 @@ async function parseOnlyRamCalculate(
|
|||||||
*/
|
*/
|
||||||
function parseOnlyCalculateDeps(code: string, currentModule: string): any {
|
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;
|
||||||
|
@ -11,7 +11,7 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
|||||||
import { isScriptFilename } from "../../Script/isScriptFilename";
|
import { isScriptFilename } from "../../Script/isScriptFilename";
|
||||||
import { Script } from "../../Script/Script";
|
import { Script } from "../../Script/Script";
|
||||||
import { TextFile } from "../../TextFile";
|
import { TextFile } from "../../TextFile";
|
||||||
import { calculateRamUsage } from "../../Script/RamCalculations";
|
import { calculateRamUsage, checkInfiniteLoop } from "../../Script/RamCalculations";
|
||||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { CursorPositions } from "../CursorPositions";
|
import { CursorPositions } from "../CursorPositions";
|
||||||
@ -90,6 +90,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
||||||
const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
|
const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
|
||||||
const [code, setCode] = useState<string>(props.filename ? props.code : lastCode);
|
const [code, setCode] = useState<string>(props.filename ? props.code : lastCode);
|
||||||
|
const [decorations, setDecorations] = useState<string[]>([]);
|
||||||
hostname = props.filename ? props.hostname : hostname;
|
hostname = props.filename ? props.hostname : hostname;
|
||||||
if (hostname === "") {
|
if (hostname === "") {
|
||||||
hostname = props.player.getCurrentServer().hostname;
|
hostname = props.player.getCurrentServer().hostname;
|
||||||
@ -231,6 +232,30 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
lastCode = newCode;
|
lastCode = newCode;
|
||||||
if (editorRef.current !== null) {
|
if (editorRef.current !== null) {
|
||||||
lastPosition = editorRef.current.getPosition();
|
lastPosition = editorRef.current.getPosition();
|
||||||
|
const awaitWarning = checkInfiniteLoop(newCode);
|
||||||
|
if (awaitWarning !== -1) {
|
||||||
|
const newDecorations = editorRef.current.deltaDecorations(decorations, [
|
||||||
|
{
|
||||||
|
range: {
|
||||||
|
startLineNumber: awaitWarning,
|
||||||
|
startColumn: 1,
|
||||||
|
endLineNumber: awaitWarning,
|
||||||
|
endColumn: 10,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
isWholeLine: true,
|
||||||
|
glyphMarginClassName: "myGlyphMarginClass",
|
||||||
|
glyphMarginHoverMessage: {
|
||||||
|
value: "Possible infinite loop, await something.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setDecorations(newDecorations);
|
||||||
|
} else {
|
||||||
|
const newDecorations = editorRef.current.deltaDecorations(decorations, []);
|
||||||
|
setDecorations(newDecorations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setCode(newCode);
|
setCode(newCode);
|
||||||
updateRAM(newCode);
|
updateRAM(newCode);
|
||||||
@ -364,7 +389,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
defaultValue={code}
|
defaultValue={code}
|
||||||
onChange={updateCode}
|
onChange={updateCode}
|
||||||
theme={options.theme}
|
theme={options.theme}
|
||||||
options={options}
|
options={{ ...options, glyphMargin: true }}
|
||||||
/>
|
/>
|
||||||
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
|
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
|
||||||
<Button onClick={beautify}>Beautify</Button>
|
<Button onClick={beautify}>Beautify</Button>
|
||||||
|
@ -44,7 +44,12 @@
|
|||||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||||
scrollbar-width: none; /* for Firefox */
|
scrollbar-width: none; /* for Firefox */
|
||||||
}
|
}
|
||||||
|
.myGlyphMarginClass {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
.myContentClass {
|
||||||
|
background: lightblue;
|
||||||
|
}
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
display: none; /* for Chrome, Safari, and Opera */
|
display: none; /* for Chrome, Safari, and Opera */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user