mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
added possible infinite loop checker
This commit is contained in:
parent
a34d6e0dfa
commit
d1d0ccf345
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 */
|
||||
scrollbar-width: none; /* for Firefox */
|
||||
}
|
||||
|
||||
.myGlyphMarginClass {
|
||||
background: red;
|
||||
}
|
||||
.myContentClass {
|
||||
background: lightblue;
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
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/material": "^5.0.3",
|
||||
"@mui/styles": "^5.0.1",
|
||||
"@types/acorn": "^4.0.6",
|
||||
"@types/escodegen": "^0.0.7",
|
||||
"@types/numeral": "0.0.25",
|
||||
"@types/react": "^17.0.21",
|
||||
@ -3613,6 +3614,14 @@
|
||||
"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": {
|
||||
"version": "4.2.2",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.3.tgz",
|
||||
@ -24027,6 +24041,14 @@
|
||||
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
|
||||
"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": {
|
||||
"version": "4.2.2",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.0.3",
|
||||
"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/material": "^5.0.3",
|
||||
"@mui/styles": "^5.0.1",
|
||||
"@types/acorn": "^4.0.6",
|
||||
"@types/escodegen": "^0.0.7",
|
||||
"@types/numeral": "0.0.25",
|
||||
"@types/react": "^17.0.21",
|
||||
|
@ -6,7 +6,7 @@
|
||||
* the way
|
||||
*/
|
||||
import * as walk from "acorn-walk";
|
||||
import { parse } from "acorn";
|
||||
import acorn, { parse } from "acorn";
|
||||
|
||||
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,
|
||||
* 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 {
|
||||
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
||||
|
||||
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
||||
// the outermost layer of functions counts.
|
||||
const globalKey = currentModule + memCheckGlobalKey;
|
||||
|
@ -11,7 +11,7 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { isScriptFilename } from "../../Script/isScriptFilename";
|
||||
import { Script } from "../../Script/Script";
|
||||
import { TextFile } from "../../TextFile";
|
||||
import { calculateRamUsage } from "../../Script/RamCalculations";
|
||||
import { calculateRamUsage, checkInfiniteLoop } from "../../Script/RamCalculations";
|
||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { CursorPositions } from "../CursorPositions";
|
||||
@ -90,6 +90,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
||||
const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
|
||||
const [code, setCode] = useState<string>(props.filename ? props.code : lastCode);
|
||||
const [decorations, setDecorations] = useState<string[]>([]);
|
||||
hostname = props.filename ? props.hostname : hostname;
|
||||
if (hostname === "") {
|
||||
hostname = props.player.getCurrentServer().hostname;
|
||||
@ -231,6 +232,30 @@ export function Root(props: IProps): React.ReactElement {
|
||||
lastCode = newCode;
|
||||
if (editorRef.current !== null) {
|
||||
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);
|
||||
updateRAM(newCode);
|
||||
@ -364,7 +389,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
defaultValue={code}
|
||||
onChange={updateCode}
|
||||
theme={options.theme}
|
||||
options={options}
|
||||
options={{ ...options, glyphMargin: true }}
|
||||
/>
|
||||
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
|
||||
<Button onClick={beautify}>Beautify</Button>
|
||||
|
@ -44,7 +44,12 @@
|
||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||
scrollbar-width: none; /* for Firefox */
|
||||
}
|
||||
|
||||
.myGlyphMarginClass {
|
||||
background: red;
|
||||
}
|
||||
.myContentClass {
|
||||
background: lightblue;
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
display: none; /* for Chrome, Safari, and Opera */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user