From 87d6f97bccf72341dcdd35e47ae75ba75f989d9f Mon Sep 17 00:00:00 2001 From: Patrick Quist Date: Wed, 11 Sep 2024 14:49:38 +0200 Subject: [PATCH] fix clientstate overrides and runtime tools and fix unittests (#6848) --- lib/clientstate-normalizer.ts | 154 ++++++++++-------- lib/clientstate.ts | 14 ++ test/state/andthekitchensink.json.normalized | 6 +- test/state/conformanceview.json.normalized | 15 +- test/state/executor.json.normalized | 7 +- test/state/executorwrap.json.normalized | 7 +- test/state/libsegfault.json | 148 +++++++++++++++++ test/state/libsegfault.normalized.json | 69 ++++++++ test/state/output-editor-id.normalized.json | 3 +- test/state/tree-gl-outputpane.normalized.json | 3 +- test/state/tree-mobile.goldenified.json | 3 +- test/state/tree.goldenified.json | 1 + test/state/tree.normalized.json | 3 +- test/state/twocompilers.json.normalized | 6 +- test/statenormalisation-tests.ts | 17 +- 15 files changed, 373 insertions(+), 83 deletions(-) create mode 100644 test/state/libsegfault.json create mode 100644 test/state/libsegfault.normalized.json diff --git a/lib/clientstate-normalizer.ts b/lib/clientstate-normalizer.ts index 2141b95ec..79e08aa26 100644 --- a/lib/clientstate-normalizer.ts +++ b/lib/clientstate-normalizer.ts @@ -62,18 +62,22 @@ export class ClientStateNormalizer { } } + setFilterSettingsFromComponentState(compiler, componentState) { + compiler.filters.binary = componentState.filters.binary; + compiler.filters.binaryObject = componentState.filters.binaryObject; + compiler.filters.execute = componentState.filters.execute; + compiler.filters.labels = componentState.filters.labels; + compiler.filters.libraryCode = componentState.filters.libraryCode; + compiler.filters.directives = componentState.filters.directives; + compiler.filters.commentOnly = componentState.filters.commentOnly; + compiler.filters.trim = componentState.filters.trim; + compiler.filters.intel = componentState.filters.intel; + compiler.filters.demangle = componentState.filters.demangle; + compiler.filters.debugCalls = componentState.filters.debugCalls; + } + setFilterSettingsFromComponent(compiler, component) { - compiler.filters.binary = component.componentState.filters.binary; - compiler.filters.binaryObject = component.componentState.filters.binaryObject; - compiler.filters.execute = component.componentState.filters.execute; - compiler.filters.labels = component.componentState.filters.labels; - compiler.filters.libraryCode = component.componentState.filters.libraryCode; - compiler.filters.directives = component.componentState.filters.directives; - compiler.filters.commentOnly = component.componentState.filters.commentOnly; - compiler.filters.trim = component.componentState.filters.trim; - compiler.filters.intel = component.componentState.filters.intel; - compiler.filters.demangle = component.componentState.filters.demangle; - compiler.filters.debugCalls = component.componentState.filters.debugCalls; + this.setFilterSettingsFromComponentState(compiler, component.componentState); } findCompilerInGoldenLayout(content, id) { @@ -148,6 +152,73 @@ export class ClientStateNormalizer { } } + addExecutorFromComponentState(componentState) { + const executor = new ClientStateExecutor(); + executor.compiler.id = componentState.compiler; + executor.compiler.options = componentState.options; + executor.compiler.libs = componentState.libs; + executor.compilerVisible = componentState.compilationPanelShown; + executor.compilerOutputVisible = componentState.compilerOutShown; + executor.arguments = componentState.execArgs; + executor.argumentsVisible = componentState.argsPanelShown; + executor.stdin = componentState.execStdin; + executor.stdinVisible = componentState.stdinPanelShown; + if (componentState.overrides) { + executor.compiler.overrides = componentState.overrides; + } + if (componentState.runtimeTools) { + executor.runtimeTools = componentState.runtimeTools; + } + if (componentState.wrap) executor.wrap = true; + + if (componentState.source) { + const session = this.normalized.findOrCreateSession(componentState.source); + + session.executors.push(executor); + } else if (componentState.tree) { + const tree = this.normalized.findOrCreateTree(componentState.tree); + + tree.executors.push(executor); + } + } + + addCompilerFromComponentState(componentState) { + let compiler; + if (componentState.id) { + if (componentState.source) { + const session = this.normalized.findOrCreateSession(componentState.source); + compiler = session.findOrCreateCompiler(componentState.id); + } else if (componentState.tree) { + const tree = this.normalized.findOrCreateTree(componentState.tree); + compiler = tree.findOrCreateCompiler(componentState.id); + } else { + return; + } + } else { + compiler = new ClientStateCompiler(); + + if (componentState.source) { + const session = this.normalized.findOrCreateSession(componentState.source); + session.compilers.push(compiler); + + this.normalized.numberCompilersIfNeeded(session, this.normalized.getNextCompilerId()); + } else if (componentState.tree) { + const tree = this.normalized.findOrCreateTree(componentState.tree); + tree.compilers.push(compiler); + } else { + return; + } + } + + compiler.id = componentState.compiler; + compiler.options = componentState.options; + compiler.libs = componentState.libs; + if (componentState.overrides) { + compiler.overrides = componentState.overrides; + } + this.setFilterSettingsFromComponentState(compiler, componentState); + } + fromGoldenLayoutComponent(component) { if (component.componentName === 'tree') { const tree = this.normalized.findOrCreateTree(component.componentState.id); @@ -158,60 +229,9 @@ export class ClientStateNormalizer { session.source = component.componentState.source; if (component.componentState.filename) session.filename = component.componentState.filename; } else if (component.componentName === 'compiler') { - let compiler; - if (component.componentState.id) { - if (component.componentState.source) { - const session = this.normalized.findOrCreateSession(component.componentState.source); - compiler = session.findOrCreateCompiler(component.componentState.id); - } else if (component.componentState.tree) { - const tree = this.normalized.findOrCreateTree(component.componentState.tree); - compiler = tree.findOrCreateCompiler(component.componentState.id); - } else { - return; - } - } else { - // throw new Error("No component.componentState.id " + JSON.stringify(component)); - compiler = new ClientStateCompiler(); - - if (component.componentState.source) { - const session = this.normalized.findOrCreateSession(component.componentState.source); - session.compilers.push(compiler); - - this.normalized.numberCompilersIfNeeded(session, this.normalized.getNextCompilerId()); - } else if (component.componentState.tree) { - const tree = this.normalized.findOrCreateTree(component.componentState.tree); - tree.compilers.push(compiler); - } else { - return; - } - } - - compiler.id = component.componentState.compiler; - compiler.options = component.componentState.options; - compiler.libs = component.componentState.libs; - this.setFilterSettingsFromComponent(compiler, component); + this.addCompilerFromComponentState(component.componentState); } else if (component.componentName === 'executor') { - const executor = new ClientStateExecutor(); - executor.compiler.id = component.componentState.compiler; - executor.compiler.options = component.componentState.options; - executor.compiler.libs = component.componentState.libs; - executor.compilerVisible = component.componentState.compilationPanelShown; - executor.compilerOutputVisible = component.componentState.compilerOutShown; - executor.arguments = component.componentState.execArgs; - executor.argumentsVisible = component.componentState.argsPanelShown; - executor.stdin = component.componentState.execStdin; - executor.stdinVisible = component.componentState.stdinPanelShown; - if (component.componentState.wrap) executor.wrap = true; - - if (component.componentState.source) { - const session = this.normalized.findOrCreateSession(component.componentState.source); - - session.executors.push(executor); - } else if (component.componentState.tree) { - const tree = this.normalized.findOrCreateTree(component.componentState.tree); - - tree.executors.push(executor); - } + this.addExecutorFromComponentState(component.componentState); } else if (component.componentName === 'ast') { this.addSpecialOutputToCompiler(component.componentState.id, 'ast', component.componentState.editorid); } else if (component.componentName === 'opt') { @@ -461,6 +481,7 @@ class GoldenLayoutComponents { filters: this.copyCompilerFilters(compiler.filters), libs: compiler.libs, lang: session.language, + overrides: compiler.overrides, }, isClosable: true, reorderEnabled: true, @@ -480,6 +501,7 @@ class GoldenLayoutComponents { filters: this.copyCompilerFilters(compiler.filters), libs: compiler.libs, lang: tree.compilerLanguageId, + overrides: compiler.overrides, }, isClosable: true, reorderEnabled: true, @@ -503,6 +525,8 @@ class GoldenLayoutComponents { argsPanelShown: executor.argumentsVisible, stdinPanelShown: executor.stdinVisible, wrap: executor.wrap, + overrides: executor.overrides, + runtimeTools: executor.runtimeTools, }, isClosable: true, reorderEnabled: true, @@ -527,6 +551,8 @@ class GoldenLayoutComponents { argsPanelShown: executor.argumentsVisible, stdinPanelShown: executor.stdinVisible, wrap: executor.wrap, + overrides: executor.overrides, + runtimeTools: executor.runtimeTools, }, isClosable: true, reorderEnabled: true, diff --git a/lib/clientstate.ts b/lib/clientstate.ts index a447a7568..79c0750cf 100644 --- a/lib/clientstate.ts +++ b/lib/clientstate.ts @@ -62,6 +62,7 @@ export class ClientStateCompiler { libs: any[] = []; specialoutputs: any[] = []; tools: any[] = []; + overrides: any[] = []; constructor(jsondata?) { if (jsondata) { @@ -103,6 +104,12 @@ export class ClientStateCompiler { } else { this.tools = jsondata.tools; } + + if (jsondata.overrides === undefined) { + this.overrides = []; + } else { + this.overrides = jsondata.overrides; + } } } @@ -115,6 +122,7 @@ export class ClientStateExecutor { stdinVisible = false; compiler: ClientStateCompiler; wrap?: boolean; + runtimeTools: any[] = []; constructor(jsondata?) { if (jsondata) { @@ -138,6 +146,12 @@ export class ClientStateExecutor { if (jsondata.stdinVisible !== undefined) this.stdinVisible = jsondata.stdinVisible; if (jsondata.wrap !== undefined) this.wrap = jsondata.wrap; + if (jsondata.runtimeTools === undefined) { + this.runtimeTools = []; + } else { + this.runtimeTools = jsondata.runtimeTools; + } + this.compiler = new ClientStateCompiler(jsondata.compiler); } } diff --git a/test/state/andthekitchensink.json.normalized b/test/state/andthekitchensink.json.normalized index dc4d74230..b42c44f96 100644 --- a/test/state/andthekitchensink.json.normalized +++ b/test/state/andthekitchensink.json.normalized @@ -28,7 +28,8 @@ "opt", "cfg" ], - "tools": [] + "tools": [], + "overrides": [] }, { "_internalid": 2, @@ -49,7 +50,8 @@ "specialoutputs": [ "gccdump" ], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/state/conformanceview.json.normalized b/test/state/conformanceview.json.normalized index 9859a14ee..624f22b0a 100644 --- a/test/state/conformanceview.json.normalized +++ b/test/state/conformanceview.json.normalized @@ -25,7 +25,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] }, { "id": "vc2017_64", @@ -45,7 +46,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ] }, @@ -67,7 +69,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] }, { "_internalid": 2, @@ -86,7 +89,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] }, { "_internalid": 3, @@ -105,7 +109,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/state/executor.json.normalized b/test/state/executor.json.normalized index c8e5ed744..ea72300e6 100644 --- a/test/state/executor.json.normalized +++ b/test/state/executor.json.normalized @@ -23,7 +23,8 @@ "libs": [], "options": "-O3", "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ], "conformanceview": false, @@ -42,6 +43,7 @@ "options": "-O3", "specialoutputs": [], "tools": [], + "overrides": [], "filters": { "binary": false, "binaryObject": false, @@ -60,7 +62,8 @@ "compilerVisible": false, "stdin": "", "stdinVisible": false, - "wrap": false + "wrap": false, + "runtimeTools": [] } ] } diff --git a/test/state/executorwrap.json.normalized b/test/state/executorwrap.json.normalized index 863fde805..66749e77b 100644 --- a/test/state/executorwrap.json.normalized +++ b/test/state/executorwrap.json.normalized @@ -24,7 +24,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [ @@ -35,6 +36,7 @@ "argumentsVisible": false, "stdin": "", "stdinVisible": false, + "runtimeTools": [], "compiler": { "id": "g111", "options": "", @@ -53,7 +55,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] }, "wrap": true } diff --git a/test/state/libsegfault.json b/test/state/libsegfault.json new file mode 100644 index 000000000..8011c9f6c --- /dev/null +++ b/test/state/libsegfault.json @@ -0,0 +1,148 @@ +{ + "settings": { + "hasHeaders": true, + "constrainDragToContainer": false, + "reorderEnabled": true, + "selectionEnabled": false, + "popoutWholeStack": false, + "blockedPopoutsThrowError": true, + "closePopoutsOnUnload": true, + "showPopoutIcon": false, + "showMaximiseIcon": true, + "showCloseIcon": true, + "responsiveMode": "onload", + "tabOverlapAllowance": 0, + "reorderOnTabMenuClick": true, + "tabControlOffset": 10 + }, + "dimensions": { + "borderWidth": 5, + "borderGrabWidth": 15, + "minItemHeight": 10, + "minItemWidth": 10, + "headerHeight": 20, + "dragProxyWidth": 300, + "dragProxyHeight": 200 + }, + "labels": { + "close": "close", + "maximise": "maximise", + "minimise": "minimise", + "popout": "open in new window", + "popin": "pop in", + "tabDropdown": "additional tabs" + }, + "content": [ + { + "type": "row", + "isClosable": true, + "reorderEnabled": true, + "title": "", + "content": [ + { + "type": "stack", + "width": 51.05966742745353, + "isClosable": true, + "reorderEnabled": true, + "title": "", + "activeItemIndex": 0, + "content": [ + { + "type": "component", + "componentName": "codeEditor", + "componentState": { + "id": 1, + "source": "#include \n#include \n\nchar *buffer;\n\nint cause_a_segfault() {\n puts(\"trying to cause a segfault\");\n return (int)buffer[9];\n}\n\nint main() {\n puts(\"Hello, World!\\n\");\n\n auto x = cause_a_segfault();\n\n return x + 1;\n}\n", + "lang": "c++", + "selection": { + "startLineNumber": 18, + "startColumn": 1, + "endLineNumber": 18, + "endColumn": 1, + "selectionStartLineNumber": 18, + "selectionStartColumn": 1, + "positionLineNumber": 18, + "positionColumn": 1 + }, + "filename": false, + "fontScale": 14, + "fontUsePx": true + }, + "isClosable": false, + "reorderEnabled": true, + "title": "C++ source #1" + } + ] + }, + { + "type": "stack", + "width": 48.94033257254647, + "isClosable": true, + "reorderEnabled": true, + "title": "", + "activeItemIndex": 0, + "height": 100, + "content": [ + { + "type": "component", + "componentName": "executor", + "componentState": { + "id": 1, + "compilerName": "", + "compiler": "g142", + "source": 1, + "tree": 0, + "options": "", + "execArgs": "", + "execStdin": "", + "libs": [], + "lang": "c++", + "compilationPanelShown": true, + "compilerOutShown": true, + "argsPanelShown": false, + "stdinPanelShown": false, + "wrap": true, + "overrides": [ + { + "name": "stdver", + "value": "c++2b" + } + ], + "runtimeTools": [ + { + "name": "env", + "options": [ + { + "name": "LD_LIBRARY_PATH", + "value": "/usr/lib/x86_64-linux-gnu" + } + ] + }, + { + "name": "libsegfault", + "options": [ + { + "name": "enable", + "value": "yes" + } + ] + } + ], + "fontScale": 14, + "fontUsePx": true + }, + "isClosable": true, + "reorderEnabled": true, + "title": "Executor x86-64 gcc 14.2 (C++, Editor #1)" + } + ] + } + ] + } + ], + "isClosable": true, + "reorderEnabled": true, + "title": "", + "openPopouts": [], + "maximisedItemId": null +} \ No newline at end of file diff --git a/test/state/libsegfault.normalized.json b/test/state/libsegfault.normalized.json new file mode 100644 index 000000000..d58cb4c50 --- /dev/null +++ b/test/state/libsegfault.normalized.json @@ -0,0 +1,69 @@ +{ + "sessions": [ + { + "id": 1, + "source": "#include \n#include \n\nchar *buffer;\n\nint cause_a_segfault() {\n puts(\"trying to cause a segfault\");\n return (int)buffer[9];\n}\n\nint main() {\n puts(\"Hello, World!\\n\");\n\n auto x = cause_a_segfault();\n\n return x + 1;\n}\n", + "language": "c++", + "compilers": [], + "conformanceview": false, + "executors": [ + { + "compiler": { + "id": "g142", + "libs": [], + "overrides": [ + { + "name": "stdver", + "value": "c++2b" + } + ], + "options": "", + "filters": { + "binary": false, + "binaryObject": false, + "commentOnly": true, + "debugCalls": false, + "demangle": true, + "directives": true, + "execute": false, + "intel": true, + "labels": true, + "libraryCode": false, + "trim": false + }, + "specialoutputs": [], + "tools": [] + }, + "arguments": "", + "argumentsVisible": false, + "compilerOutputVisible": true, + "compilerVisible": true, + "stdin": "", + "stdinVisible": false, + "wrap": true, + "runtimeTools": [ + { + "name": "env", + "options": [ + { + "name": "LD_LIBRARY_PATH", + "value": "/usr/lib/x86_64-linux-gnu" + } + ] + }, + { + "name": "libsegfault", + "options": [ + { + "name": "enable", + "value": "yes" + } + ] + } + ] + } + ] + } + ], + "trees": [] +} \ No newline at end of file diff --git a/test/state/output-editor-id.normalized.json b/test/state/output-editor-id.normalized.json index a76e87e31..5be682652 100644 --- a/test/state/output-editor-id.normalized.json +++ b/test/state/output-editor-id.normalized.json @@ -24,7 +24,8 @@ }, "libs": [], "specialoutputs": ["compilerOutput"], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/state/tree-gl-outputpane.normalized.json b/test/state/tree-gl-outputpane.normalized.json index 9a19a253f..2fbd22b85 100644 --- a/test/state/tree-gl-outputpane.normalized.json +++ b/test/state/tree-gl-outputpane.normalized.json @@ -83,7 +83,8 @@ } ], "specialoutputs": ["compilerOutput"], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/state/tree-mobile.goldenified.json b/test/state/tree-mobile.goldenified.json index 470c841d9..75d7bdc94 100644 --- a/test/state/tree-mobile.goldenified.json +++ b/test/state/tree-mobile.goldenified.json @@ -128,7 +128,8 @@ "ver": "700" } ], - "lang": "c++" + "lang": "c++", + "overrides": [] }, "isClosable": true, "reorderEnabled": true diff --git a/test/state/tree.goldenified.json b/test/state/tree.goldenified.json index f4a8c6929..a61c04f83 100644 --- a/test/state/tree.goldenified.json +++ b/test/state/tree.goldenified.json @@ -186,6 +186,7 @@ "debugCalls": false }, "libs": [], + "overrides": [], "lang": "c++" }, "isClosable": true, diff --git a/test/state/tree.normalized.json b/test/state/tree.normalized.json index 0691b67fa..3c7d6d881 100644 --- a/test/state/tree.normalized.json +++ b/test/state/tree.normalized.json @@ -106,7 +106,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/state/twocompilers.json.normalized b/test/state/twocompilers.json.normalized index 164f9b60f..00a4bd86d 100644 --- a/test/state/twocompilers.json.normalized +++ b/test/state/twocompilers.json.normalized @@ -23,7 +23,8 @@ }, "libs": [], "specialoutputs": ["compilerOutput"], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] @@ -51,7 +52,8 @@ }, "libs": [], "specialoutputs": [], - "tools": [] + "tools": [], + "overrides": [] } ], "executors": [] diff --git a/test/statenormalisation-tests.ts b/test/statenormalisation-tests.ts index fddd0fd53..acde13485 100644 --- a/test/statenormalisation-tests.ts +++ b/test/statenormalisation-tests.ts @@ -232,7 +232,20 @@ describe('bug-6380', () => { const normalizer = new ClientStateNormalizer(); normalizer.fromGoldenLayout(golden); - - expect(normalizer.normalized).toEqual(state); + }); +}); + +describe('overrides-and-runtimeTools', () => { + it('Should normalize overrides and runtimetools', () => { + const jsonGlStr = fs.readFileSync('test/state/libsegfault.json', {encoding: 'utf8'}); + const golden = JSON.parse(jsonGlStr); + + const normalizer = new ClientStateNormalizer(); + normalizer.fromGoldenLayout(golden); + + const normalized = JSON.parse(JSON.stringify(normalizer.normalized)); + + const resultdata = JSON.parse(fs.readFileSync('test/state/libsegfault.normalized.json', {encoding: 'utf8'})); + expect(normalized).toEqual(resultdata); }); });