aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.devcontainer/Dockerfile11
-rw-r--r--.devcontainer/devcontainer.json16
-rwxr-xr-x.devcontainer/post-create.sh14
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--etc/config/assembly.amazon.properties59
-rw-r--r--lib/compilers/hlsl.ts20
-rw-r--r--static/modes/cppfront-mode.ts84
-rw-r--r--test/demangler-tests.ts (renamed from test/demangler-tests.js)82
-rw-r--r--test/map-file-tests.ts (renamed from test/map-file-tests.js)70
-rw-r--r--test/options-handler.ts (renamed from test/options-handler.js)222
-rw-r--r--test/packager-tests.ts (renamed from test/packager-tests.js)2
12 files changed, 385 insertions, 200 deletions
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000..688e743f9
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,11 @@
+ARG NODE_MAJOR_VERSION
+
+FROM mcr.microsoft.com/devcontainers/javascript-node:${NODE_MAJOR_VERSION}
+
+ENV EDITOR="code -w" VISUAL="code -w"
+
+# install system dependencies for cypress (https://docs.cypress.io/guides/continuous-integration/introduction)
+RUN apt update && apt install -y libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
+
+# uncomment to install additional npm packages
+# RUN su node -c 'npm i -g cowsay@1.5.0'
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000..1428e6ac2
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,16 @@
+{
+ "name": "compiler-explorer",
+ "dockerFile": "Dockerfile",
+ "build": {
+ "args": {"NODE_MAJOR_VERSION": "20"}
+ },
+ "postCreateCommand": [".devcontainer/post-create.sh"],
+ "portsAttributes": {
+ "10240": {"label": "Compiler Explorer"}
+ },
+ "customizations": {
+ "vscode": {
+ "extensions": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", "esbenp.prettier-vscode"]
+ }
+ }
+}
diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh
new file mode 100755
index 000000000..c7b706cc2
--- /dev/null
+++ b/.devcontainer/post-create.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -eo pipefail
+
+# when in a VS Code or GitHub Codespaces devcontainer
+if [ -n "${REMOTE_CONTAINERS}" ]; then
+ this_dir=$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)
+ workspace_root=$(realpath ${this_dir}/..)
+
+ # perform additional one-time setup just after
+ # the devcontainer is created
+ npm install --prefix "${workspace_root}" # install node dependencies
+
+fi
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d1baecb0a..1c3a21241 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -23,6 +23,10 @@ in the right direction.
**Compiler Explorer** currently targets [Node.js](https://nodejs.org/) version 20, so it's better if you do so as well
when testing your changes locally.
+> Note that this repository is compatible with `GitHub Codespaces` as well as `VS Code Dev Containers`. Opening your
+> cloned project with either of these options will ensure that your development environment is already set up and
+> configured correctly!
+
## In brief
- Make your changes, trying to stick to the style and format where possible.
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 4fcd91f0f..5c6fc4893 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -139,3 +139,4 @@ From oldest to newest contributor, we would like to thank:
- [Seyed Ali Ghasemi](https://github.com/gha3mi)
- [Guo Ci](https://github.com/guoci)
- [Rupert Tombs](https://github.com/Rupt)
+- [Andrew Brey](https://github.com/andrewbrey)
diff --git a/etc/config/assembly.amazon.properties b/etc/config/assembly.amazon.properties
index 055ba2373..2dc7ca81d 100644
--- a/etc/config/assembly.amazon.properties
+++ b/etc/config/assembly.amazon.properties
@@ -1,4 +1,4 @@
-compilers=&nasm:&gnuas:&llvmas:&ptxas:&gnuasarm:&gnuasarm64:&beebasm
+compilers=&nasm:&gnuas:&llvmas:&ptxas:&gnuasarm:&gnuasarm64:&gnuasriscv:&beebasm
compilerType=assembly
objdumper=/opt/compiler-explorer/gcc-12.1.0/bin/objdump
supportsBinary=true
@@ -99,6 +99,63 @@ compiler.gnuasarm64g1020.exe=/opt/compiler-explorer/arm64/gcc-10.2.0/aarch64-unk
compiler.gnuasarm64g1020.name=AArch64 binutils 2.35.1
compiler.gnuasarm64g1020.semver=2.35.1
+# GNU as for RISC-V
+group.gnuasriscv.compilers=&gnuasriscv64:&gnuasriscv32
+group.gnuasriscv.groupName=RISC-V binutils
+group.gnuasriscv.isSemVer=true
+group.gnuasriscv.options=-g
+group.gnuasriscv.supportsExecute=false
+group.gnuasriscv.versionFlag=--version
+
+## GNU as for RISC-V 64-bits
+group.gnuasriscv64.compilers=gnuasriscv64g820:gnuasriscv64g1020:gnuasriscv64g1140:gnuasriscv64g1320
+group.gnuasriscv64.groupName=RISC-V (64-bits) binutils
+group.gnuasriscv64.baseName=RISC-V (64-bits) binutils
+
+compiler.gnuasriscv64g820.exe=/opt/compiler-explorer/riscv64/gcc-8.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-as
+compiler.gnuasriscv64g820.name=RISC-V binutils 2.31.1
+compiler.gnuasriscv64g820.semver=2.31.1
+compiler.gnuasriscv64g820.objdumper=/opt/compiler-explorer/riscv64/gcc-8.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv64g1020.exe=/opt/compiler-explorer/riscv64/gcc-10.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-as
+compiler.gnuasriscv64g1020.name=RISC-V binutils 2.35.1
+compiler.gnuasriscv64g1020.semver=2.35.1
+compiler.gnuasriscv64g1020.objdumper=/opt/compiler-explorer/riscv64/gcc-10.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv64g1140.exe=/opt/compiler-explorer/riscv64/gcc-11.4.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-as
+compiler.gnuasriscv64g1140.name=RISC-V binutils 2.37.0
+compiler.gnuasriscv64g1140.semver=2.37.0
+compiler.gnuasriscv64g1140.objdumper=/opt/compiler-explorer/riscv64/gcc-11.4.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv64g1320.exe=/opt/compiler-explorer/riscv64/gcc-13.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-as
+compiler.gnuasriscv64g1320.name=RISC-V binutils 2.38.0
+compiler.gnuasriscv64g1320.semver=2.38.0
+compiler.gnuasriscv64g1320.objdumper=/opt/compiler-explorer/riscv64/gcc-13.2.0/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-objdump
+
+## GNU as for RISC-V 32-bits
+group.gnuasriscv32.compilers=gnuasriscv32g820:gnuasriscv32g1020:gnuasriscv32g1140:gnuasriscv32g1320
+group.gnuasriscv32.groupName=RISC-V (32-bits) binutils
+group.gnuasriscv32.baseName=RISC-V (32-bits) binutils
+
+compiler.gnuasriscv32g820.exe=/opt/compiler-explorer/riscv32/gcc-8.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-as
+compiler.gnuasriscv32g820.name=RISC-V binutils 2.31.1
+compiler.gnuasriscv32g820.semver=2.31.1
+compiler.gnuasriscv32g820.objdumper=/opt/compiler-explorer/riscv32/gcc-8.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv32g1020.exe=/opt/compiler-explorer/riscv32/gcc-10.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-as
+compiler.gnuasriscv32g1020.name=RISC-V binutils 2.35.1
+compiler.gnuasriscv32g1020.semver=2.35.1
+compiler.gnuasriscv32g1020.objdumper=/opt/compiler-explorer/riscv32/gcc-10.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv32g1140.exe=/opt/compiler-explorer/riscv32/gcc-11.4.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-as
+compiler.gnuasriscv32g1140.name=RISC-V binutils 2.37.0
+compiler.gnuasriscv32g1140.semver=2.37.0
+compiler.gnuasriscv32g1140.objdumper=/opt/compiler-explorer/riscv32/gcc-11.4.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-objdump
+
+compiler.gnuasriscv32g1320.exe=/opt/compiler-explorer/riscv32/gcc-13.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-as
+compiler.gnuasriscv32g1320.name=RISC-V binutils 2.38.0
+compiler.gnuasriscv32g1320.semver=2.38.0
+compiler.gnuasriscv32g1320.objdumper=/opt/compiler-explorer/riscv32/gcc-13.2.0/riscv32-unknown-linux-gnu/bin/riscv32-unknown-linux-gnu-objdump
group.llvmas.compilers=llvmas30:llvmas31:llvmas32:llvmas33:llvmas341:llvmas350:llvmas351:llvmas352:llvmas37x:llvmas36x:llvmas371:llvmas380:llvmas381:llvmas390:llvmas391:llvmas400:llvmas401:llvmas500:llvmas600:llvmas700:llvmas800:llvmas900:llvmas1000:llvmas1001:llvmas1100:llvmas1101:llvmas1200:llvmas1201:llvmas1300:llvmas1400:llvmas1500:llvmas1600:llvmas1701:llvmas_trunk:llvmas_assertions_trunk
group.llvmas.versionFlag=--version
diff --git a/lib/compilers/hlsl.ts b/lib/compilers/hlsl.ts
index 7050355c1..26d5423b1 100644
--- a/lib/compilers/hlsl.ts
+++ b/lib/compilers/hlsl.ts
@@ -23,6 +23,7 @@
// POSSIBILITY OF SUCH DAMAGE.
import path from 'path';
+import _ from 'underscore';
import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
import {BaseCompiler} from '../base-compiler.js';
@@ -41,6 +42,25 @@ export class HLSLCompiler extends BaseCompiler {
this.spirvAsm = new SPIRVAsmParser(this.compilerProps);
}
+ override async generateAST(inputFilename, options) {
+ // These options make DXC produce an AST dump
+ const newOptions = _.filter(options, option => option !== '-Zi' && option !== '-Qembed_debug').concat([
+ '-ast-dump',
+ ]);
+
+ const execOptions = this.getDefaultExecOptions();
+ // A higher max output is needed for when the user includes headers
+ execOptions.maxOutput = 1024 * 1024 * 1024;
+
+ return this.llvmAst.processAst(
+ await this.runCompiler(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions),
+ );
+ }
+
+ override couldSupportASTDump(version: string) {
+ return version.includes('libdxcompiler');
+ }
+
/* eslint-disable no-unused-vars */
override optionsForFilter(
filters: ParseFiltersAndOutputOptions,
diff --git a/static/modes/cppfront-mode.ts b/static/modes/cppfront-mode.ts
index 92372b9a9..d7d01cba7 100644
--- a/static/modes/cppfront-mode.ts
+++ b/static/modes/cppfront-mode.ts
@@ -96,7 +96,12 @@ function definition(): monaco.languages.IMonarchLanguage {
cppfront.at_cpp2_balanced_parentheses = balancedParenthesesRegex(5);
cppfront.at_cpp2_interpolation = /@at_cpp2_balanced_parentheses\$/;
- cppfront.tokenizer.parse_cpp2_interpolation = [[/./, {token: '@rematch', switchTo: 'parse_cpp2_expression'}]];
+ cppfront.tokenizer.parse_cpp2_interpolation = [
+ [/(\()(.)/, ['delimiter.parenthesis', {token: '@rematch', next: 'parse_cpp2_expression'}]],
+ [/:[^)]*/, 'string'],
+ [/\)/, 'delimiter.parenthesis'],
+ [/\$/, 'delimiter.interpolation', '@pop'],
+ ];
cppfront.at_cpp2_string_literal = /@encoding?(?:\$?R)?"/;
cppfront.tokenizer.parse_cpp2_string_literal = [
@@ -195,13 +200,28 @@ function definition(): monaco.languages.IMonarchLanguage {
/@at_cpp2_non_operator_identifier/,
{
cases: {
- '$S2~definition|parameter': {token: 'identifier.definition', next: '@pop'},
+ '$S2~definition|parameter': {
+ token: 'identifier.definition',
+ switchTo: 'parse_cpp2_parameter_ellipsis.$S2',
+ },
'$S2==type': {token: 'type.contextual', next: '@pop'},
'@': {token: 'identifier.use', next: '@pop'},
},
},
],
];
+ cppfront.tokenizer.parse_cpp2_parameter_ellipsis = [
+ [
+ /\.\.\./,
+ {
+ cases: {
+ '$S2==parameter': {token: 'delimiter.ellipsis', next: '@pop'},
+ '@': {token: '@rematch', next: '@pop'},
+ },
+ },
+ ],
+ [/./, '@rematch', '@pop'],
+ ];
cppfront.at_cpp2_type_qualifier = /const\b|\*/;
cppfront.tokenizer.parse_cpp2_type_qualifier_seq = [
@@ -225,9 +245,10 @@ function definition(): monaco.languages.IMonarchLanguage {
[/\(/, {token: '@rematch', switchTo: 'parse_cpp2_function_type'}],
];
- cppfront.at_cpp2_template_argument = /@at_cpp2_expression|@at_cpp2_type_id/;
+ cppfront.at_cpp2_template_argument = /@at_cpp2_string_literal|@at_cpp2_expression|@at_cpp2_type_id/;
cppfront.tokenizer.parse_cpp2_template_argument = [
[/@at_cpp2_keyword_type/, 'keyword.type', '@pop'],
+ [/@at_cpp2_type_qualifier/, {token: '@rematch', switchTo: 'parse_cpp2_type_id'}],
[/@at_cpp2_expression/, {token: '@rematch', switchTo: 'parse_cpp2_expression.template_argument'}],
[/@at_cpp2_type_id/, {token: '@rematch', switchTo: 'parse_cpp2_type_id'}],
];
@@ -251,6 +272,7 @@ function definition(): monaco.languages.IMonarchLanguage {
cppfront.tokenizer.parse_cpp2_id_expression = [
{include: '@whitespace'},
[/::/, ''],
+ [/\.\.\./, '@rematch', '@pop'],
[/\./, 'delimiter'],
[/@at_cpp2_identifier</, {token: '@rematch', switchTo: 'parse_cpp2_template_id.$S2'}],
[/@at_cpp2_non_operator_identifier(?=\s*(?:\.|::))/, '@rematch', 'parse_cpp2_identifier.use'],
@@ -277,17 +299,30 @@ function definition(): monaco.languages.IMonarchLanguage {
];
cppfront.at_cpp2_primary_expression =
- /@at_cpp2_literal|@at_cpp2_id_expression|\(|@at_cpp2_unnamed_declaration_head/;
+ /@at_cpp2_literal|@at_cpp2_id_expression|\.\.\.|\(|@at_cpp2_unnamed_declaration_head/;
// Can't ensure sequential parsing.
cppfront.tokenizer.parse_cpp2_primary_expression = [
[/inspect\b/, '@rematch', 'parse_cpp2_inspect_expression'],
// These two happen to parse UDLs:
- [/@at_cpp2_literal/, '@rematch', 'parse_cpp2_literal'],
- [/@at_cpp2_id_expression/, '@rematch', 'parse_cpp2_primary_expression_id_expression'],
+ [/@at_cpp2_literal/, {token: '@rematch', switchTo: 'parse_cpp2_primary_expression_literal_.$S2.$S3'}],
+ [
+ /@at_cpp2_id_expression/,
+ {token: '@rematch', switchTo: 'parse_cpp2_primary_expression_id_expression_.$S2.$S3'},
+ ],
+ [/\.\.\./, 'delimiter.ellipsis'],
// Handle `(` later to workaround `(0)is` being parsed as two adjacent primary expressions.
[/@at_cpp2_unnamed_declaration_head/, '@rematch', 'parse_cpp2_declaration.expression'],
[/./, {token: '@rematch', switchTo: 'parse_cpp2_postfix_expression.$S2.$S3'}],
];
+ cppfront.tokenizer.parse_cpp2_primary_expression_id_expression_ = [
+ [/@at_cpp2_id_expression/, '@rematch', 'parse_cpp2_primary_expression_id_expression'],
+ [/\.\.\./, 'delimiter.ellipsis'],
+ [/./, {token: '@rematch', switchTo: 'parse_cpp2_postfix_expression.$S2.$S3'}],
+ ];
+ cppfront.tokenizer.parse_cpp2_primary_expression_literal_ = [
+ [/@at_cpp2_literal/, '@rematch', 'parse_cpp2_literal'],
+ [/./, {token: '@rematch', switchTo: 'parse_cpp2_postfix_expression.$S2.$S3'}],
+ ];
cppfront.at_cpp2_postfix_operator = /\+\+|--|~|\$|\*|&/;
cppfront.tokenizer.parse_cpp2_postfix_expression = [
@@ -301,7 +336,9 @@ function definition(): monaco.languages.IMonarchLanguage {
/./,
{
token: '@rematch',
- switchTo: 'parse_cpp2_is_as_expression_target.parse_cpp2_binary_expression_tail.$S2.$S3',
+ switchTo:
+ 'parse_cpp2_is_as_expression_target.parse_cpp2_expression.' +
+ 'parse_cpp2_binary_expression_tail.$S2.$S3',
},
],
];
@@ -321,17 +358,15 @@ function definition(): monaco.languages.IMonarchLanguage {
];
cppfront.tokenizer.parse_cpp2_is_as_expression_target = [
- // `@$S2` is the continuation parser.
+ // `@$S2` is the expression parser.
+ // `@$S3.$S4.$S5` is the continuation parser.
{include: '@whitespace'},
[
/(@at_cpp2_is_as_operator)(\s+)(@at_cpp2_type_id)/,
['keyword', '', {token: '@rematch', switchTo: 'parse_cpp2_type_id'}],
],
- [
- /(is\b)(\s*)(@at_cpp2_expression)/,
- ['keyword', '', {token: '@rematch', switchTo: 'parse_cpp2_expression'}],
- ],
- [/./, {token: '@rematch', switchTo: '@$S2.$S3.$S4'}],
+ [/(is\b)(\s*)(@at_cpp2_expression)/, ['keyword', '', {token: '@rematch', switchTo: '@$S2'}]],
+ [/./, {token: '@rematch', switchTo: '@$S3.$S4.$S5'}],
];
cppfront.at_cpp2_logical_or_operator = /\*|\/|%|\+|-|<<|>>|<=>|<|>|<=|>=|==|!=|&|\^|\||&&|\|\|/;
@@ -399,7 +434,11 @@ function definition(): monaco.languages.IMonarchLanguage {
cppfront.tokenizer.parse_cpp2_alternative = [
{include: '@whitespace'},
- [/@at_cpp2_is_as_operator/, '@rematch', 'parse_cpp2_is_as_expression_target.pop'],
+ [
+ /@at_cpp2_is_as_operator/,
+ '@rematch',
+ 'parse_cpp2_is_as_expression_target.parse_cpp2_logical_or_expression.pop',
+ ],
[/@at_cpp2_non_operator_identifier/, '@rematch', 'parse_cpp2_identifier.definition'],
[/@at_cpp2_unnamed_declaration_head/, 'identifier.definition'],
[/=/, {token: 'delimiter', switchTo: 'parse_cpp2_statement'}],
@@ -645,14 +684,23 @@ function definition(): monaco.languages.IMonarchLanguage {
[/./, '@rematch', '@pop'],
];
- cppfront.tokenizer.parse_cpp2_function_type = [
+ cppfront.tokenizer.parse_cpp2_full_function_type = [
{include: '@whitespace'},
- [/\(/, '@rematch', 'parse_cpp2_parameter_declaration_list'],
[/throws\b/, 'keyword'],
[/->/, '@rematch', 'parse_cpp2_return_list'],
[/\[/, '@rematch', 'parse_cpp2_contract_seq'],
[/./, '@rematch', '@pop'],
];
+ cppfront.tokenizer.parse_cpp2_terse_function = [
+ {include: '@whitespace'},
+ [/\(/, '@rematch', 'parse_cpp2_parameter_declaration_list'],
+ [/throws\b|->|\[/, {token: '@rematch', switchTo: 'parse_cpp2_full_function_type'}],
+ [/requires\b|==?|;/, '@rematch', '@pop'],
+ [/@at_cpp2_expression/, {token: '@rematch', switchTo: 'parse_cpp2_expression'}],
+ ];
+ cppfront.tokenizer.parse_cpp2_function_type = [
+ [/./, {token: '@rematch', switchTo: 'parse_cpp2_terse_function'}],
+ ];
cppfront.tokenizer.parse_cpp2_declaration_initializer = [
[/./, {token: '@rematch', switchTo: 'parse_cpp2_statement.$S2'}],
@@ -684,7 +732,8 @@ function definition(): monaco.languages.IMonarchLanguage {
];
cppfront.at_cpp2_unnamed_declaration_head = /:(?!:)/;
- cppfront.at_cpp2_identifier_definition = /@at_cpp2_identifier\s*@at_cpp2_unnamed_declaration_head/;
+ cppfront.at_cpp2_identifier_definition =
+ /@at_cpp2_identifier\s*(?:\.\.\.)?\s*@at_cpp2_unnamed_declaration_head/;
cppfront.at_cpp2_top_level_declaration_head =
/(?:@at_cpp2_access_specifier\s+)?(?!@at_cpp2_access_specifier)@at_cpp2_identifier_definition/;
cppfront.at_cpp2_declaration_head = /(?:@at_cpp2_access_specifier\s+)?@at_cpp2_identifier_definition/;
@@ -693,6 +742,7 @@ function definition(): monaco.languages.IMonarchLanguage {
{include: '@whitespace'},
[/@at_cpp2_access_specifier/, 'keyword'],
[/@at_cpp2_identifier/, '@rematch', 'parse_cpp2_identifier.$S2'],
+ [/\.\.\./, 'delimiter.ellipsis'],
[
/@at_cpp2_unnamed_declaration_head/,
{token: 'identifier.definition', switchTo: 'parse_cpp2_declaration_signature.$S2'},
diff --git a/test/demangler-tests.js b/test/demangler-tests.ts
index be227e6bb..b7cf981ff 100644
--- a/test/demangler-tests.js
+++ b/test/demangler-tests.ts
@@ -22,22 +22,45 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
+import {unwrap} from '../lib/assert.js';
+import {BaseCompiler} from '../lib/base-compiler.js';
+import {CompilationEnvironment} from '../lib/compilation-env.js';
import {CppDemangler, Win32Demangler} from '../lib/demangler/index.js';
import {PrefixTree} from '../lib/demangler/prefix-tree.js';
import * as exec from '../lib/exec.js';
+import * as properties from '../lib/properties.js';
import {SymbolStore} from '../lib/symbol-store.js';
import * as utils from '../lib/utils.js';
-import {chai, fs, path, resolvePathFromTestRoot} from './utils.js';
+import {chai, fs, makeFakeCompilerInfo, path, resolvePathFromTestRoot} from './utils.js';
const cppfiltpath = 'c++filt';
-class DummyCompiler {
- exec(command, args, options) {
+class DummyCompiler extends BaseCompiler {
+ constructor() {
+ const env = {
+ ceProps: properties.fakeProps({}),
+ compilerProps: () => {},
+ } as unknown as CompilationEnvironment;
+
+ // using c++ as the compiler needs at least one language
+ const compiler = makeFakeCompilerInfo({lang: 'c++'});
+
+ super(compiler, env);
+ }
+ override exec(command, args, options) {
return exec.execute(command, args, options);
}
}
+class DummyCppDemangler extends CppDemangler {
+ public override collectLabels = super.collectLabels;
+}
+
+class DummyWin32Demangler extends Win32Demangler {
+ public override collectLabels = super.collectLabels;
+}
+
const catchCppfiltNonexistence = err => {
if (!err.message.startsWith('spawn c++filt')) {
throw err;
@@ -50,8 +73,7 @@ describe('Basic demangling', function () {
asm: [{text: 'Hello, World!'}],
};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler.process(result).then(output => {
@@ -63,8 +85,7 @@ describe('Basic demangling', function () {
it('One label and some asm', function () {
const result = {asm: [{text: '_Z6squarei:'}, {text: ' ret'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler
@@ -80,8 +101,7 @@ describe('Basic demangling', function () {
it('One label and use of a label', function () {
const result = {asm: [{text: '_Z6squarei:'}, {text: ' mov eax, $_Z6squarei'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler
@@ -109,8 +129,7 @@ describe('Basic demangling', function () {
],
};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return demangler
.process(result)
@@ -125,20 +144,20 @@ describe('Basic demangling', function () {
it('Should ignore comments (CL)', function () {
const result = {asm: [{text: ' call ??3@YAXPEAX_K@Z ; operator delete'}]};
- const demangler = new Win32Demangler(cppfiltpath, new DummyCompiler());
+ const demangler = new DummyWin32Demangler(cppfiltpath, new DummyCompiler());
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
const output = demangler.win32RawSymbols;
- output.should.deep.equal(['??3@YAXPEAX_K@Z']);
+ unwrap(output).should.deep.equal(['??3@YAXPEAX_K@Z']);
});
it('Should ignore comments (CPP)', function () {
const result = {asm: [{text: ' call hello ; operator delete'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
+
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
@@ -150,8 +169,8 @@ describe('Basic demangling', function () {
it('Should also support ARM branch instructions', () => {
const result = {asm: [{text: ' bl _ZN3FooC1Ev'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
+
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
@@ -163,20 +182,20 @@ describe('Basic demangling', function () {
it('Should NOT handle undecorated labels', () => {
const result = {asm: [{text: '$LN3@caller2:'}]};
- const demangler = new Win32Demangler(cppfiltpath, new DummyCompiler());
+ const demangler = new DummyWin32Demangler(cppfiltpath, new DummyCompiler());
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
const output = demangler.win32RawSymbols;
- output.should.deep.equal([]);
+ output?.should.deep.equal([]);
});
it('Should ignore comments after jmps', function () {
const result = {asm: [{text: ' jmp _Z1fP6mytype # TAILCALL'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
+
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
@@ -188,8 +207,8 @@ describe('Basic demangling', function () {
it('Should still work with normal jmps', function () {
const result = {asm: [{text: ' jmp _Z1fP6mytype'}]};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
+
demangler.result = result;
demangler.symbolstore = new SymbolStore();
demangler.collectLabels();
@@ -211,8 +230,7 @@ describe('Basic demangling', function () {
],
};
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler
@@ -244,8 +262,8 @@ async function DoDemangleTest(filename) {
const resultIn = await readResultFile(filename);
const resultOut = await readResultFile(filename + '.demangle');
- const demangler = new CppDemangler(cppfiltpath, new DummyCompiler());
- demangler.demanglerArguments = ['-n'];
+ const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
+
return demangler.process(resultIn).should.eventually.deep.equal(resultOut);
}
@@ -282,7 +300,7 @@ describe('File demangling', () => {
});
describe('Demangler prefix tree', () => {
- const replacements = new PrefixTree();
+ const replacements = new PrefixTree([]);
replacements.add('a', 'short_a');
replacements.add('aa', 'long_a');
replacements.add('aa_shouldnotmatch', 'ERROR');
@@ -299,7 +317,7 @@ describe('Demangler prefix tree', () => {
replacements.replaceAll('a aa a aa').should.eq('short_a long_a short_a long_a');
});
it('should work with empty replacements', () => {
- new PrefixTree().replaceAll('Testing 123').should.eq('Testing 123');
+ new PrefixTree([]).replaceAll('Testing 123').should.eq('Testing 123');
});
it('should leave unmatching text alone', () => {
replacements
@@ -310,9 +328,9 @@ describe('Demangler prefix tree', () => {
replacements.replaceAll('Everyone loves an aardvark').should.eq('Everyone loves short_an long_ardvshort_ark');
});
it('should find exact matches', () => {
- replacements.findExact('a').should.eq('short_a');
- replacements.findExact('aa').should.eq('long_a');
- replacements.findExact('aa_shouldnotmatch').should.eq('ERROR');
+ unwrap(replacements.findExact('a')).should.eq('short_a');
+ unwrap(replacements.findExact('aa')).should.eq('long_a');
+ unwrap(replacements.findExact('aa_shouldnotmatch')).should.eq('ERROR');
});
it('should find not find mismatches', () => {
chai.expect(replacements.findExact('aaa')).to.be.null;
diff --git a/test/map-file-tests.js b/test/map-file-tests.ts
index 4305ae123..9be73d19a 100644
--- a/test/map-file-tests.js
+++ b/test/map-file-tests.ts
@@ -22,6 +22,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
+import {unwrap} from '../lib/assert.js';
import {MapFileReaderDelphi} from '../lib/mapfiles/map-file-delphi.js';
import {MapFileReaderVS} from '../lib/mapfiles/map-file-vs.js';
@@ -49,26 +50,26 @@ describe('Code Segments', function () {
reader.segments.length.should.equal(1);
let info = reader.getSegmentInfoByStartingAddress('0001', 0x2838);
- info.unitName.should.equal('output.pas');
+ expect(unwrap(info).unitName).to.equal('output.pas');
info = reader.getSegmentInfoByStartingAddress(undefined, reader.getSegmentOffset('0001') + 0x2838);
- info.unitName.should.equal('output.pas');
+ expect(unwrap(info).unitName).to.equal('output.pas');
info = reader.getSegmentInfoByStartingAddress('0001', 0x1234);
expect(info, 'Address should not be a Start for any segment').to.be.undefined;
info = reader.getSegmentInfoAddressIsIn('0001', 0x2838 + 0x10);
- info.unitName.should.equal('output.pas');
+ expect(unwrap(info).unitName).to.equal('output.pas');
info = reader.getSegmentInfoAddressIsIn(undefined, reader.getSegmentOffset('0001') + 0x2838 + 0x10);
- info.unitName.should.equal('output.pas');
+ expect(unwrap(info).unitName).to.equal('output.pas');
info = reader.getSegmentInfoAddressIsIn('0001', reader.getSegmentOffset('0001') + 0x2838 + 0x80 + 1);
expect(info, 'Address should not be in any segment').to.be.undefined;
info = reader.getSegmentInfoByUnitName('output.pas');
- info.unitName.should.equal('output.pas');
- info.addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
+ expect(unwrap(info).unitName).to.equal('output.pas');
+ unwrap(info).addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
});
it('Not include this segment', function () {
@@ -89,13 +90,13 @@ describe('Code Segments', function () {
reader.segments.length.should.equal(1);
let info = reader.getSegmentInfoByStartingAddress('0001', 0x2838);
- info.addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
+ unwrap(info).addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
info = reader.getSegmentInfoByStartingAddress(undefined, 0x403838);
- info.addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
+ unwrap(info).addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
info = reader.getSegmentInfoAddressIsIn(undefined, reader.getSegmentOffset('0001') + 0x2838 + 0x10);
- info.addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
+ unwrap(info).addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2838);
info = reader.getSegmentInfoAddressIsIn('0001', reader.getSegmentOffset('0001') + 0x2837);
expect(info).to.be.undefined;
@@ -109,12 +110,12 @@ describe('Code Segments', function () {
);
let info = reader.getSegmentInfoByStartingAddress('0002', 0);
- info.unitName.should.equal('ConsoleApplication1.obj');
+ expect(unwrap(info).unitName).to.equal('ConsoleApplication1.obj');
reader.getSegmentOffset('0002').should.equal(0x411000);
info = reader.getSegmentInfoByStartingAddress(undefined, 0x411000);
- info.unitName.should.equal('ConsoleApplication1.obj');
+ expect(unwrap(info).unitName).to.equal('ConsoleApplication1.obj');
});
});
@@ -125,12 +126,12 @@ describe('Symbol info', function () {
reader.namedAddresses.length.should.equal(1);
let info = reader.getSymbolAt('0001', 0x2838);
- info.should.not.equal(undefined, 'Symbol Square should have been returned 1');
- info.displayName.should.equal('Square');
+ expect(info).to.not.equal(undefined, 'Symbol Square should have been returned 1');
+ expect(unwrap(info).displayName).to.equal('Square');
info = reader.getSymbolAt(undefined, reader.getSegmentOffset('0001') + 0x2838);
- info.should.not.equal(undefined, 'Symbol Square should have been returned 2');
- info.displayName.should.equal('Square');
+ expect(info).to.not.equal(undefined, 'Symbol Square should have been returned 2');
+ expect(unwrap(info).displayName).to.equal('Square');
});
it('Delphi-Map D2009 symbol test', function () {
@@ -139,12 +140,13 @@ describe('Symbol info', function () {
reader.namedAddresses.length.should.equal(1);
let info = reader.getSymbolAt('0001', 0x2c4c);
- info.should.not.equal(undefined, 'Symbol MaxArray should have been returned');
- info.displayName.should.equal('output.MaxArray');
+ expect(info).to.not.equal(undefined, 'Symbol MaxArray should have been returned');
+ expect(unwrap(info).displayName).to.equal('output.MaxArray');
+
//todo should not be undefined
info = reader.getSymbolAt(undefined, reader.getSegmentOffset('0001') + 0x2c4c);
- info.should.not.equal(undefined, 'Symbol MaxArray should have been returned');
- info.displayName.should.equal('output.MaxArray');
+ expect(info).to.not.equal(undefined, 'Symbol MaxArray should have been returned');
+ expect(unwrap(info).displayName).to.equal('output.MaxArray');
});
it('VS-Map symbol test', function () {
@@ -155,12 +157,12 @@ describe('Symbol info', function () {
reader.namedAddresses.length.should.equal(1);
let info = reader.getSymbolAt('0002', 0x6b0);
- info.should.not.equal(undefined, 'Symbol start_verify_argument should have been returned 1');
- info.displayName.should.equal('??$__vcrt_va_start_verify_argument_type@QBD@@YAXXZ');
+ expect(info).to.not.equal(undefined, 'Symbol start_verify_argument should have been returned 1');
+ expect(unwrap(info).displayName).to.equal('??$__vcrt_va_start_verify_argument_type@QBD@@YAXXZ');
info = reader.getSymbolAt(undefined, 0x4116b0);
- info.should.not.equal(undefined, 'Symbol start_verify_argument should have been returned 2');
- info.displayName.should.equal('??$__vcrt_va_start_verify_argument_type@QBD@@YAXXZ');
+ expect(info).to.not.equal(undefined, 'Symbol start_verify_argument should have been returned 2');
+ expect(unwrap(info).displayName).to.equal('??$__vcrt_va_start_verify_argument_type@QBD@@YAXXZ');
});
it('Delphi-Map Duplication prevention', function () {
@@ -184,10 +186,10 @@ describe('Delphi-Map Line number info', function () {
reader.tryReadingLineNumbers(' 17 0001:000028A4').should.equal(true);
let lineInfo = reader.getLineInfoByAddress('0001', 0x28a4);
- lineInfo.lineNumber.should.equal(17);
+ expect(unwrap(lineInfo).lineNumber).to.equal(17);
lineInfo = reader.getLineInfoByAddress(undefined, reader.getSegmentOffset('0001') + 0x28a4);
- lineInfo.lineNumber.should.equal(17);
+ expect(unwrap(lineInfo).lineNumber).to.equal(17);
});
it('Multiple lines', function () {
@@ -197,16 +199,16 @@ describe('Delphi-Map Line number info', function () {
.should.equal(true);
let lineInfo = reader.getLineInfoByAddress('0001', 0x2838);
- lineInfo.lineNumber.should.equal(12);
+ expect(unwrap(lineInfo).lineNumber).to.equal(12);
lineInfo = reader.getLineInfoByAddress('0001', 0x2858);
- lineInfo.lineNumber.should.equal(15);
+ expect(unwrap(lineInfo).lineNumber).to.equal(15);
lineInfo = reader.getLineInfoByAddress('0001', 0x2854);
- lineInfo.lineNumber.should.equal(14);
+ expect(unwrap(lineInfo).lineNumber).to.equal(14);
lineInfo = reader.getLineInfoByAddress('0001', 0x283b);
- lineInfo.lineNumber.should.equal(13);
+ expect(unwrap(lineInfo).lineNumber).to.equal(13);
});
});
@@ -220,12 +222,12 @@ describe('Delphi-Map load test', function () {
reader.namedAddresses.length.should.equal(11);
let info = reader.getSegmentInfoByUnitName('output.pas');
- info.addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2c4c);
+ unwrap(info).addressInt.should.equal(reader.getSegmentOffset('0001') + 0x2c4c);
info = reader.getICodeSegmentInfoByUnitName('output.pas');
- info.segment.should.equal('0002');
- info.addressWithoutOffset.should.equal(0xb0);
- info.addressInt.should.equal(0x4040b0);
+ unwrap(info).segment.should.equal('0002');
+ unwrap(info).addressWithoutOffset.should.equal(0xb0);
+ unwrap(info).addressInt.should.equal(0x4040b0);
});
});
@@ -235,7 +237,7 @@ describe('VS-Map load test', function () {
reader.run();
reader.segments.length.should.equal(1);
- reader.getSegmentInfoByUnitName('ConsoleApplication1.obj').addressInt.should.equal(0x411000);
+ unwrap(reader.getSegmentInfoByUnitName('ConsoleApplication1.obj')).addressInt.should.equal(0x411000);
reader.getSegmentOffset('0001').should.equal(0x401000, 'offset 1');
reader.getSegmentOffset('0002').should.equal(0x411000, 'offset 2');
diff --git a/test/options-handler.js b/test/options-handler.ts
index e77a50639..96e21dfa0 100644
--- a/test/options-handler.js
+++ b/test/options-handler.ts
@@ -26,11 +26,16 @@ import {fileURLToPath} from 'url';
import _ from 'underscore';
+import {AppDefaultArguments} from '../app.js';
import {BaseCompiler} from '../lib/base-compiler.js';
-import {ClientOptionsHandler} from '../lib/options-handler.js';
+import {CompilationEnvironment} from '../lib/compilation-env.js';
+import {ClientOptionsHandler, ClientOptionsType} from '../lib/options-handler.js';
import * as properties from '../lib/properties.js';
+import {BaseTool} from '../lib/tooling/base-tool.js';
+import {CompilerInfo} from '../types/compiler.interfaces.js';
+import {LanguageKey} from '../types/languages.interfaces.js';
-import {should} from './utils.js';
+import {makeFakeCompilerInfo, should} from './utils.js';
const languages = {
fake: {
@@ -122,35 +127,57 @@ const moreLibProps = {
'libs.autolib.versions.autodetect.staticliblink': 'hello',
};
-const makeFakeCompilerInfo = (id, lang, group, semver, isSemver) => {
- return {
+const fakeCompilerInfo = (id: string, lang: string, group: string, semver: string, isSemver: boolean) => {
+ return makeFakeCompilerInfo({
id: id,
exe: '/dev/null',
name: id,
- lang: lang,
+ lang: lang as LanguageKey,
group: group,
isSemVer: isSemver,
semver: semver,
libsArr: [],
- };
+ });
};
+class TestBaseCompiler extends BaseCompiler {
+ public override supportedLibraries = super.supportedLibraries;
+}
+
describe('Options handler', () => {
- let fakeOptionProps;
- let compilerProps;
- let optionsHandler;
- let fakeMoreCompilerProps;
- let moreCompilerProps;
- let moreOptionsHandler;
+ let fakeOptionProps: ReturnType<typeof properties.fakeProps>;
+ let compilerProps: properties.CompilerProps;
+ let optionsHandler: ClientOptionsHandler;
+
+ let fakeMoreCompilerProps: ReturnType<typeof properties.fakeProps>;
+ let moreCompilerProps: properties.CompilerProps;
+ let moreOptionsHandler: ClientOptionsHandler;
+
+ let env: CompilationEnvironment;
+
+ function createClientOptions(libs: ReturnType<ClientOptionsHandler['parseLibraries']>) {
+ return {
+ libs: {
+ 'c++': libs.fake,
+ },
+ } as unknown as ClientOptionsType;
+ }
before(() => {
fakeOptionProps = properties.fakeProps(optionsProps);
compilerProps = new properties.CompilerProps(languages, fakeOptionProps);
- optionsHandler = new ClientOptionsHandler([], compilerProps, {env: ['dev']});
+ optionsHandler = new ClientOptionsHandler([], compilerProps, {env: ['dev']} as unknown as AppDefaultArguments);
fakeMoreCompilerProps = properties.fakeProps(moreLibProps);
moreCompilerProps = new properties.CompilerProps(languages, fakeMoreCompilerProps);
- moreOptionsHandler = new ClientOptionsHandler([], moreCompilerProps, {env: ['dev']});
+ moreOptionsHandler = new ClientOptionsHandler([], moreCompilerProps, {
+ env: ['dev'],
+ } as unknown as AppDefaultArguments);
+
+ env = {
+ ceProps: properties.fakeProps({}),
+ compilerProps: () => {},
+ } as unknown as CompilationEnvironment;
});
it('should always return an array of paths', () => {
@@ -270,32 +297,32 @@ describe('Options handler', () => {
});
it('should order compilers as expected', () => {
const compilers = [
- makeFakeCompilerInfo('a1', languages.fake.id, 'a', '0.0.1', true),
- makeFakeCompilerInfo('a2', languages.fake.id, 'a', '0.2.0', true),
- makeFakeCompilerInfo('a3', languages.fake.id, 'a', '0.2.1', true),
+ fakeCompilerInfo('a1', languages.fake.id, 'a', '0.0.1', true),
+ fakeCompilerInfo('a2', languages.fake.id, 'a', '0.2.0', true),
+ fakeCompilerInfo('a3', languages.fake.id, 'a', '0.2.1', true),
- makeFakeCompilerInfo('b1', languages.fake.id, 'b', 'trunk', true),
- makeFakeCompilerInfo('b2', languages.fake.id, 'b', '1.0.0', true),
- makeFakeCompilerInfo('b3', languages.fake.id, 'b', '0.5.0', true),
+ fakeCompilerInfo('b1', languages.fake.id, 'b', 'trunk', true),
+ fakeCompilerInfo('b2', languages.fake.id, 'b', '1.0.0', true),
+ fakeCompilerInfo('b3', languages.fake.id, 'b', '0.5.0', true),
- makeFakeCompilerInfo('c1', languages.fake.id, 'c', '3.0.0', true),
- makeFakeCompilerInfo('c2', languages.fake.id, 'c', '3.0.0', true),
- makeFakeCompilerInfo('c3', languages.fake.id, 'c', '3.0.0', true),
+ fakeCompilerInfo('c1', languages.fake.id, 'c', '3.0.0', true),
+ fakeCompilerInfo('c2', languages.fake.id, 'c', '3.0.0', true),
+ fakeCompilerInfo('c3', languages.fake.id, 'c', '3.0.0', true),
- makeFakeCompilerInfo('d1', languages.fake.id, 'd', 1, true),
- makeFakeCompilerInfo('d2', languages.fake.id, 'd', '2.0.0', true),
- makeFakeCompilerInfo('d3', languages.fake.id, 'd', '0.0.5', true),
+ fakeCompilerInfo('d1', languages.fake.id, 'd', '1', true),
+ fakeCompilerInfo('d2', languages.fake.id, 'd', '2.0.0', true),
+ fakeCompilerInfo('d3', languages.fake.id, 'd', '0.0.5', true),
- makeFakeCompilerInfo('e1', languages.fake.id, 'e', '0..0', false),
- makeFakeCompilerInfo('e2', languages.fake.id, 'e', undefined, false),
+ fakeCompilerInfo('e1', languages.fake.id, 'e', '0..0', false),
+ fakeCompilerInfo('e2', languages.fake.id, 'e', '', false),
- makeFakeCompilerInfo('f1', languages.fake.id, 'f', '5', true),
- makeFakeCompilerInfo('f2', languages.fake.id, 'f', '5.1', true),
- makeFakeCompilerInfo('f3', languages.fake.id, 'f', '5.2', true),
+ fakeCompilerInfo('f1', languages.fake.id, 'f', '5', true),
+ fakeCompilerInfo('f2', languages.fake.id, 'f', '5.1', true),
+ fakeCompilerInfo('f3', languages.fake.id, 'f', '5.2', true),
- makeFakeCompilerInfo('g1', languages.fake.id, 'g', '5 a', true),
- makeFakeCompilerInfo('g2', languages.fake.id, 'g', '5.1 b d', true),
- makeFakeCompilerInfo('g3', languages.fake.id, 'g', '5.2 ce fg', true),
+ fakeCompilerInfo('g1', languages.fake.id, 'g', '5 a', true),
+ fakeCompilerInfo('g2', languages.fake.id, 'g', '5.1 b d', true),
+ fakeCompilerInfo('g3', languages.fake.id, 'g', '5.2 ce fg', true),
];
const expectedOrder = {
a: {
@@ -337,26 +364,20 @@ describe('Options handler', () => {
_.each(optionsHandler.get().compilers, compiler => {
should.equal(
compiler['$order'],
- expectedOrder[compiler.group][compiler.id],
- `group: ${compiler.group} id: ${compiler.id}`,
+ expectedOrder[(compiler as CompilerInfo).group][(compiler as CompilerInfo).id],
+ `group: ${(compiler as CompilerInfo).group} id: ${(compiler as CompilerInfo).id}`,
);
});
optionsHandler.setCompilers([]);
});
it('should get static libraries', () => {
const libs = optionsHandler.parseLibraries({fake: optionsProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
+
+ const clientOptions = createClientOptions(libs);
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+ compiler.initialiseLibraries(clientOptions);
const staticlinks = compiler.getStaticLibraryLinks([{id: 'fs', version: 'std'}]);
staticlinks.should.deep.equal(['-lc++fs', '-lrt', '-lpthread']);
@@ -366,18 +387,12 @@ describe('Options handler', () => {
});
it('should sort static libraries', () => {
const libs = optionsHandler.parseLibraries({fake: optionsProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
+
+ const clientOptions = createClientOptions(libs);
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+ compiler.initialiseLibraries(clientOptions);
let staticlinks = compiler.getSortedStaticLibraries([{id: 'someotherlib', version: 'trunk'}]);
staticlinks.should.deep.equal(['someotherlib', 'c++fs']);
@@ -390,36 +405,24 @@ describe('Options handler', () => {
});
it('library sort special case 1', () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const staticlinks = compiler.getSortedStaticLibraries([{id: 'fs', version: 'std'}]);
staticlinks.should.deep.equal(['fsextra', 'c++fs', 'rt', 'pthread']);
});
it('library sort special case 2', () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const staticlinks = compiler.getSortedStaticLibraries([
{id: 'yalib', version: 'trunk'},
@@ -430,17 +433,12 @@ describe('Options handler', () => {
});
it('library sort special case 3', () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
+
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const staticlinks = compiler.getSortedStaticLibraries([
{id: 'fourthlib', version: 'trunk'},
@@ -451,38 +449,26 @@ describe('Options handler', () => {
});
it('filtered library list', () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
compilerInfo.libsArr = ['fs.std', 'someotherlib'];
- const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+ const compiler = new TestBaseCompiler(compilerInfo, env);
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const libNames = _.keys(compiler.supportedLibraries);
libNames.should.deep.equal(['fs', 'someotherlib']);
});
it('can detect libraries from options', () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
- const env = {
- ceProps: properties.fakeProps({}),
- compilerProps: () => {},
- };
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const obj = {
libraries: [{id: 'ctre', version: 'trunk'}],
@@ -498,27 +484,33 @@ describe('Options handler', () => {
});
it("server-side library alias support (just in case client doesn't support it)", () => {
const libs = moreOptionsHandler.parseLibraries({fake: moreLibProps.libs});
- const compilerInfo = makeFakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
+ const compilerInfo = fakeCompilerInfo('g82', 'c++', 'cpp', '8.2', true);
const env = {
ceProps: properties.fakeProps({}),
compilerProps: () => {},
- };
+ } as unknown as CompilationEnvironment;
const compiler = new BaseCompiler(compilerInfo, env);
- compiler.initialiseLibraries({
- libs: {
- 'c++': libs.fake,
- },
- });
+
+ const clientOptions = createClientOptions(libs);
+ compiler.initialiseLibraries(clientOptions);
const staticlinks = compiler.getSortedStaticLibraries([{id: 'someotherlib', version: 'master'}]);
staticlinks.should.deep.equal(['someotherlib', 'c++fs']);
});
it('should be able to parse basic tools', () => {
- const tools = optionsHandler.parseTools({fake: optionsProps.tools});
+ class TestBaseTool extends BaseTool {
+ public override env = super.env;
+ }
+ const tools = optionsHandler.parseTools({fake: optionsProps.tools}) as unknown as Record<
+ string,
+ Record<string, Partial<TestBaseTool>>
+ >;
+
_.each(tools.fake, tool => {
delete tool.env;
});
+
tools.should.deep.equal({
fake: {
faketool: {
diff --git a/test/packager-tests.js b/test/packager-tests.ts
index 8544492b6..73fee2fe9 100644
--- a/test/packager-tests.js
+++ b/test/packager-tests.ts
@@ -28,7 +28,7 @@ import {Packager} from '../lib/packager.js';
import {fs, path} from './utils.js';
-function newTempDir() {
+function newTempDir(): Promise<string> {
return new Promise((resolve, reject) => {
temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.tmpDir}, (err, dirPath) => {
if (err) reject(`Unable to open temp file: ${err}`);