From 6a6efaefe650c06fd93e0d52e0ae6b6e3b4d4718 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sun, 29 Jan 2023 13:22:30 -0500 Subject: [PATCH] Tsify lib/compilers (#4609) --- lib/base-compiler.ts | 39 ++++++---- lib/compilers/{_all.js => _all.ts} | 0 lib/compilers/ada.ts | 18 +++-- .../{analysis-tool.js => analysis-tool.ts} | 11 ++- lib/compilers/assembly.ts | 17 ++-- lib/compilers/avrgcc6502.ts | 16 +++- lib/compilers/beebasm.ts | 11 ++- lib/compilers/carbon.ts | 2 +- lib/compilers/cc65.ts | 9 ++- lib/compilers/{circle.js => circle.ts} | 6 +- lib/compilers/circt.ts | 9 ++- lib/compilers/cl430.ts | 2 +- lib/compilers/clang.ts | 26 ++++--- lib/compilers/clangcl.ts | 5 +- lib/compilers/{clean.js => clean.ts} | 35 ++++++--- lib/compilers/clspv.ts | 18 +++-- lib/compilers/cppfront.ts | 5 +- lib/compilers/{cproc.js => cproc.ts} | 2 +- lib/compilers/{crystal.js => crystal.ts} | 25 +++--- lib/compilers/{dart.js => dart.ts} | 17 +++- lib/compilers/{default.js => default.ts} | 0 lib/compilers/{dmd.js => dmd.ts} | 18 +++-- lib/compilers/dosbox-compiler.ts | 11 ++- lib/compilers/dotnet.ts | 13 +++- lib/compilers/{ellcc.js => ellcc.ts} | 4 +- lib/compilers/{ewarm.js => ewarm.ts} | 10 ++- lib/compilers/{ewavr.js => ewavr.ts} | 10 ++- lib/compilers/flang.ts | 4 +- lib/compilers/{gccrs.js => gccrs.ts} | 2 +- lib/compilers/golang.ts | 13 ++-- lib/compilers/{haskell.js => haskell.ts} | 12 +-- lib/compilers/{index.js => index.ts} | 0 lib/compilers/{ispc.js => ispc.ts} | 16 ++-- lib/compilers/jakt.ts | 13 ++-- lib/compilers/{java.js => java.ts} | 73 +++++++++++------- lib/compilers/julia.ts | 6 +- lib/compilers/{kotlin.js => kotlin.ts} | 31 +++++--- lib/compilers/{ldc.js => ldc.ts} | 31 ++++---- lib/compilers/{llc.js => llc.ts} | 10 ++- lib/compilers/{llvm-mca.js => llvm-mca.ts} | 12 +-- lib/compilers/llvm-mos.ts | 7 +- lib/compilers/mlir.ts | 11 ++- lib/compilers/{mrustc.js => mrustc.ts} | 15 +++- lib/compilers/{nasm.js => nasm.ts} | 12 ++- lib/compilers/{nim.js => nim.ts} | 34 +++++--- lib/compilers/{nvcc.js => nvcc.ts} | 55 +++++-------- lib/compilers/{ocaml.js => ocaml.ts} | 10 ++- lib/compilers/{opt.js => opt.ts} | 8 +- lib/compilers/{osaca.js => osaca.ts} | 20 +++-- .../{pascal-utils.js => pascal-utils.ts} | 6 +- .../{pascal-win.js => pascal-win.ts} | 53 ++++++++----- lib/compilers/{pascal.js => pascal.ts} | 77 ++++++++++++------- lib/compilers/{ppci.js => ppci.ts} | 10 ++- lib/compilers/{ptxas.js => ptxas.ts} | 42 ++++++---- lib/compilers/python.ts | 6 +- lib/compilers/racket.ts | 3 +- lib/compilers/ruby.ts | 6 +- lib/compilers/rust.ts | 30 ++++---- .../{rustc-cg-gcc.js => rustc-cg-gcc.ts} | 13 ++-- lib/compilers/{scala.js => scala.ts} | 18 +++-- lib/compilers/{sdcc.js => sdcc.ts} | 6 +- lib/compilers/{solidity.js => solidity.ts} | 16 ++-- lib/compilers/spirv.ts | 36 +++++++-- lib/compilers/{swift.js => swift.ts} | 6 +- lib/compilers/{tendra.js => tendra.ts} | 6 +- lib/compilers/{tinyc.js => tinyc.ts} | 10 ++- lib/compilers/toit.ts | 3 +- ...escript-native.js => typescript-native.ts} | 44 ++++++++--- lib/compilers/{win32-vc.js => win32-vc.ts} | 7 +- lib/compilers/{win32-vc6.js => win32-vc6.ts} | 7 +- lib/compilers/{win32.js => win32.ts} | 65 +++++++++------- lib/compilers/{wine-vc.js => wine-vc.ts} | 21 ++--- lib/compilers/{wsl-vc.js => wsl-vc.ts} | 23 +++--- lib/compilers/z88dk.ts | 25 +++--- lib/compilers/zig.ts | 3 +- lib/handlers/compile.ts | 12 +-- lib/parsers/asm-parser-sass.js | 4 +- package-lock.json | 17 ++++ package.json | 1 + types/asmresult/asmresult.interfaces.ts | 3 +- types/compiler.interfaces.ts | 9 +++ 81 files changed, 829 insertions(+), 493 deletions(-) rename lib/compilers/{_all.js => _all.ts} (100%) rename lib/compilers/{analysis-tool.js => analysis-tool.ts} (86%) rename lib/compilers/{circle.js => circle.ts} (92%) rename lib/compilers/{clean.js => clean.ts} (82%) rename lib/compilers/{cproc.js => cproc.ts} (97%) rename lib/compilers/{crystal.js => crystal.ts} (76%) rename lib/compilers/{dart.js => dart.ts} (83%) rename lib/compilers/{default.js => default.ts} (100%) rename lib/compilers/{dmd.js => dmd.ts} (78%) rename lib/compilers/{ellcc.js => ellcc.ts} (95%) rename lib/compilers/{ewarm.js => ewarm.ts} (85%) rename lib/compilers/{ewavr.js => ewavr.ts} (85%) rename lib/compilers/{gccrs.js => gccrs.ts} (97%) rename lib/compilers/{haskell.js => haskell.ts} (86%) rename lib/compilers/{index.js => index.ts} (100%) rename lib/compilers/{ispc.js => ispc.ts} (83%) rename lib/compilers/{java.js => java.ts} (87%) rename lib/compilers/{kotlin.js => kotlin.ts} (84%) rename lib/compilers/{ldc.js => ldc.ts} (81%) rename lib/compilers/{llc.js => llc.ts} (85%) rename lib/compilers/{llvm-mca.js => llvm-mca.ts} (86%) rename lib/compilers/{mrustc.js => mrustc.ts} (84%) rename lib/compilers/{nasm.js => nasm.ts} (86%) rename lib/compilers/{nim.js => nim.ts} (79%) rename lib/compilers/{nvcc.js => nvcc.ts} (80%) rename lib/compilers/{ocaml.js => ocaml.ts} (85%) rename lib/compilers/{opt.js => opt.ts} (86%) rename lib/compilers/{osaca.js => osaca.ts} (79%) rename lib/compilers/{pascal-utils.js => pascal-utils.ts} (94%) rename lib/compilers/{pascal-win.js => pascal-win.ts} (77%) rename lib/compilers/{pascal.js => pascal.ts} (78%) rename lib/compilers/{ppci.js => ppci.ts} (87%) rename lib/compilers/{ptxas.js => ptxas.ts} (73%) rename lib/compilers/{rustc-cg-gcc.js => rustc-cg-gcc.ts} (86%) rename lib/compilers/{scala.js => scala.ts} (82%) rename lib/compilers/{sdcc.js => sdcc.ts} (88%) rename lib/compilers/{solidity.js => solidity.ts} (96%) rename lib/compilers/{swift.js => swift.ts} (92%) rename lib/compilers/{tendra.js => tendra.ts} (88%) rename lib/compilers/{tinyc.js => tinyc.ts} (79%) rename lib/compilers/{typescript-native.js => typescript-native.ts} (70%) rename lib/compilers/{win32-vc.js => win32-vc.ts} (90%) rename lib/compilers/{win32-vc6.js => win32-vc6.ts} (91%) rename lib/compilers/{win32.js => win32.ts} (75%) rename lib/compilers/{wine-vc.js => wine-vc.ts} (81%) rename lib/compilers/{wsl-vc.js => wsl-vc.ts} (81%) diff --git a/lib/base-compiler.ts b/lib/base-compiler.ts index 2ee32dcf6ee..1fa50a01d42 100644 --- a/lib/base-compiler.ts +++ b/lib/base-compiler.ts @@ -60,7 +60,7 @@ import * as cfg from './cfg'; import {CompilationEnvironment} from './compilation-env'; import {CompilerArguments} from './compiler-arguments'; import {ClangParser, GCCParser} from './compilers/argument-parsers'; -import {getDemanglerTypeByKey} from './demangler'; +import {BaseDemangler, getDemanglerTypeByKey} from './demangler'; import {LLVMIRDemangler} from './demangler/llvm'; import * as exec from './exec'; import {getExternalParserByKey} from './external-parsers'; @@ -94,7 +94,7 @@ const executionTimeHistogram = new PromClient.Histogram({ }); export class BaseCompiler implements ICompiler { - protected compiler: CompilerInfo & Record; // TODO: Some missing types still present in Compiler type + protected compiler: CompilerInfo; // TODO: Some missing types still present in Compiler type public lang: Language; protected compileFilename: string; protected env: CompilationEnvironment; @@ -111,7 +111,7 @@ export class BaseCompiler implements ICompiler { protected toolchainPath: any; public possibleArguments: CompilerArguments; protected possibleTools: ITool[]; - protected demanglerClass: any; + protected demanglerClass: typeof BaseDemangler | null = null; protected objdumperClass: any; public outputFilebase: string; protected mtime: Date | null = null; @@ -126,7 +126,7 @@ export class BaseCompiler implements ICompiler { labelNames: [], }); - constructor(compilerInfo: CompilerInfo & Record, env: CompilationEnvironment) { + constructor(compilerInfo: CompilerInfo, env: CompilationEnvironment) { // Information about our compiler this.compiler = compilerInfo; this.lang = languages[compilerInfo.lang]; @@ -300,7 +300,7 @@ export class BaseCompiler implements ICompiler { }); } - optOutputRequested(options) { + optOutputRequested(options: string[]) { return options.includes('-fsave-optimization-record'); } @@ -401,7 +401,7 @@ export class BaseCompiler implements ICompiler { return !!this.objdumperClass; } - getObjdumpOutputFilename(defaultOutputFilename) { + getObjdumpOutputFilename(defaultOutputFilename: string): string { return defaultOutputFilename; } @@ -533,7 +533,7 @@ export class BaseCompiler implements ICompiler { return outputFilename.replace(path.extname(outputFilename), '.dump'); } - getGccDumpOptions(gccDumpOptions, outputFilename) { + getGccDumpOptions(gccDumpOptions, outputFilename: string) { const addOpts = ['-fdump-passes']; // Build dump options to append to the end of the -fdump command-line flag. @@ -756,7 +756,7 @@ export class BaseCompiler implements ICompiler { }) as string[]; } - getSharedLibraryLinks(libraries): string[] { + getSharedLibraryLinks(libraries: any[]): string[] { const linkFlag = this.compiler.linkFlag || '-l'; return _.flatten( @@ -1248,7 +1248,7 @@ export class BaseCompiler implements ICompiler { return [{text: 'Internal error; unable to open output path'}]; } - getIrOutputFilename(inputFilename: string, filters: ParseFiltersAndOutputOptions): string { + getIrOutputFilename(inputFilename: string, filters?: ParseFiltersAndOutputOptions): string { return inputFilename.replace(path.extname(inputFilename), '.ll'); } @@ -1267,7 +1267,7 @@ export class BaseCompiler implements ICompiler { } } - getExecutableFilename(dirPath, outputFilebase, key?) { + getExecutableFilename(dirPath: string, outputFilebase: string, key?) { return this.getOutputFilename(dirPath, outputFilebase, key); } @@ -1436,7 +1436,7 @@ export class BaseCompiler implements ICompiler { result.artifacts.push(artifact); } - protected async writeMultipleFiles(files, dirPath) { + protected async writeMultipleFiles(files: any[], dirPath: string) { const filesToWrite: Promise[] = []; for (const file of files) { @@ -1449,7 +1449,12 @@ export class BaseCompiler implements ICompiler { return Promise.all(filesToWrite); } - protected async writeAllFiles(dirPath, source, files, filters: ParseFiltersAndOutputOptions) { + protected async writeAllFiles( + dirPath: string, + source: string, + files: any[], + filters: ParseFiltersAndOutputOptions, + ) { if (!source) throw new Error(`File ${this.compileFilename} has no content or file is missing`); const inputFilename = path.join(dirPath, this.compileFilename); @@ -1479,7 +1484,7 @@ export class BaseCompiler implements ICompiler { }; } - async buildExecutableInFolder(key, dirPath): Promise { + async buildExecutableInFolder(key, dirPath: string): Promise { const writeSummary = await this.writeAllFiles(dirPath, key.source, key.files, key.filters); const downloads = await this.setupBuildEnvironment(key, dirPath, true); @@ -2237,7 +2242,10 @@ export class BaseCompiler implements ICompiler { if (!bypassCache) { const cacheRetreiveTimeStart = process.hrtime.bigint(); - const result = await this.env.cacheGet(key); + // TODO: We should be able to eliminate this any cast. `key` should be cacheable (if it's not that's a big + // problem) Because key coantains a CompilerInfo which contains a function member it can't be assigned to a + // CacheableValue. + const result = await this.env.cacheGet(key as any); if (result) { const cacheRetreiveTimeEnd = process.hrtime.bigint(); result.retreivedFromCacheTime = ( @@ -2762,7 +2770,7 @@ but nothing was dumped. Possible causes are: return this.compiler; } - getDefaultFilters() { + getDefaultFilters(): ParseFiltersAndOutputOptions { return { binary: false, execute: false, @@ -2774,6 +2782,7 @@ but nothing was dumped. Possible causes are: optOutput: false, libraryCode: false, trim: false, + binaryObject: false, }; } } diff --git a/lib/compilers/_all.js b/lib/compilers/_all.ts similarity index 100% rename from lib/compilers/_all.js rename to lib/compilers/_all.ts diff --git a/lib/compilers/ada.ts b/lib/compilers/ada.ts index 6c867e7abc5..13644a06b74 100644 --- a/lib/compilers/ada.ts +++ b/lib/compilers/ada.ts @@ -25,9 +25,8 @@ import path from 'path'; -import fs from 'fs-extra'; - -import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import * as utils from '../utils'; @@ -36,7 +35,7 @@ export class AdaCompiler extends BaseCompiler { return 'ada'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsGccDump = true; this.compiler.removeEmptyGccDump = true; @@ -45,7 +44,7 @@ export class AdaCompiler extends BaseCompiler { this.compiler.supportsGnatDebugViews = true; } - override getExecutableFilename(dirPath) { + override getExecutableFilename(dirPath: string, outputFilebase: string, key?) { // The name here must match the value used in the pragma Source_File // in the user provided source. return path.join(dirPath, 'example'); @@ -70,7 +69,14 @@ export class AdaCompiler extends BaseCompiler { } } - override prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) { + override prepareArguments( + userOptions: string[], + filters: ParseFiltersAndOutputOptions, + backendOptions: Record, + inputFilename: string, + outputFilename: string, + libraries, + ) { backendOptions = backendOptions || {}; // super call is needed as it handles the GCC Dump files. diff --git a/lib/compilers/analysis-tool.js b/lib/compilers/analysis-tool.ts similarity index 86% rename from lib/compilers/analysis-tool.js rename to lib/compilers/analysis-tool.ts index e6384616edc..dba1ff03718 100644 --- a/lib/compilers/analysis-tool.js +++ b/lib/compilers/analysis-tool.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 {CompilerInfo} from '../../types/compiler.interfaces'; import {BaseCompiler} from '../base-compiler'; // Plain compiler, which just runs the tool and returns whatever the output was @@ -30,13 +31,13 @@ export class AnalysisTool extends BaseCompiler { return 'analysis-tool'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { // Default is to disable all "cosmetic" filters if (!info.disabledFilters) info.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim']; super(info, env); } - getDefaultFilters() { + override getDefaultFilters() { // Disable everything but intel syntax return { intel: true, @@ -44,6 +45,12 @@ export class AnalysisTool extends BaseCompiler { directives: false, labels: false, optOutput: false, + binary: false, + execute: false, + demangle: false, + libraryCode: false, + trim: false, + binaryObject: false, }; } } diff --git a/lib/compilers/assembly.ts b/lib/compilers/assembly.ts index cfe60237ef2..b58365e7335 100644 --- a/lib/compilers/assembly.ts +++ b/lib/compilers/assembly.ts @@ -28,6 +28,7 @@ import path from 'path'; import _ from 'underscore'; import {BuildResult} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AsmRaw} from '../parsers/asm-raw'; @@ -40,7 +41,7 @@ export class AssemblyCompiler extends BaseCompiler { return 'assembly'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new AsmRaw(); } @@ -53,12 +54,12 @@ export class AssemblyCompiler extends BaseCompiler { return BaseParser; } - override optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { filters.binary = true; return []; } - getGeneratedOutputFilename(fn) { + getGeneratedOutputFilename(fn: string) { const outputFolder = path.dirname(fn); const files = fs.readdirSync(outputFolder); @@ -72,7 +73,7 @@ export class AssemblyCompiler extends BaseCompiler { return outputFilename; } - override getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return this.getGeneratedOutputFilename(path.join(dirPath, 'example.asm')); } @@ -126,11 +127,11 @@ export class AssemblyCompiler extends BaseCompiler { return this.doBuildstepAndAddToResult(fullResult, 'ld', this.env.ceProps('ld'), options, execOptions); } - override getExecutableFilename(dirPath) { + override getExecutableFilename(dirPath: string) { return path.join(dirPath, 'ce-asm-executable'); } - override async buildExecutableInFolder(key, dirPath): Promise { + override async buildExecutableInFolder(key, dirPath: string): Promise { const buildEnvironment = this.setupBuildEnvironment(key, dirPath, true); const writeSummary = await this.writeAllFiles(dirPath, key.source, key.files, key.filters); @@ -178,11 +179,11 @@ export class AssemblyCompiler extends BaseCompiler { return fullResult; } - override checkOutputFileAndDoPostProcess(asmResult, outputFilename, filters) { + override checkOutputFileAndDoPostProcess(asmResult, outputFilename, filters: ParseFiltersAndOutputOptions) { return this.postProcess(asmResult, outputFilename, filters); } - override getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string): string { return this.getGeneratedOutputFilename(defaultOutputFilename); } diff --git a/lib/compilers/avrgcc6502.ts b/lib/compilers/avrgcc6502.ts index 42234828848..8734feee5aa 100644 --- a/lib/compilers/avrgcc6502.ts +++ b/lib/compilers/avrgcc6502.ts @@ -24,6 +24,9 @@ import path from 'path'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; export class AvrGcc6502Compiler extends BaseCompiler { @@ -35,7 +38,7 @@ export class AvrGcc6502Compiler extends BaseCompiler { return 'avrgcc6502'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.avrgccpath = this.compilerProps(`compiler.${this.compiler.id}.avrgccpath`); @@ -44,7 +47,7 @@ export class AvrGcc6502Compiler extends BaseCompiler { this.outputFilebase = 'example'; } - public override getOutputFilename(dirPath, outputFilebase, key) { + public override getOutputFilename(dirPath: string, outputFilebase: string, key?: any) { let filename; if (key && key.backendOptions && key.backendOptions.customOutputFilename) { filename = key.backendOptions.customOutputFilename; @@ -59,11 +62,16 @@ export class AvrGcc6502Compiler extends BaseCompiler { } } - protected override optionsForFilter(filters: object, outputFilename: string): string[] { + protected override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string): string[] { return [`-I${this.avrlibstdcpppath}`]; } - public override async runCompiler(compiler, options, inputFilename, execOptions) { + public override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } diff --git a/lib/compilers/beebasm.ts b/lib/compilers/beebasm.ts index e00053ca584..c5b77caa222 100644 --- a/lib/compilers/beebasm.ts +++ b/lib/compilers/beebasm.ts @@ -26,6 +26,8 @@ import path from 'path'; import fs from 'fs-extra'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ArtifactType} from '../../types/tool.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AsmParserBeebAsm} from '../parsers/asm-parser-beebasm'; @@ -36,7 +38,7 @@ export class BeebAsmCompiler extends BaseCompiler { return 'beebasm'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.asm = new AsmParserBeebAsm(this.compilerProps); @@ -50,7 +52,12 @@ export class BeebAsmCompiler extends BaseCompiler { return []; } - override async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } diff --git a/lib/compilers/carbon.ts b/lib/compilers/carbon.ts index 68d9da5eaa4..b53eab1db35 100644 --- a/lib/compilers/carbon.ts +++ b/lib/compilers/carbon.ts @@ -37,7 +37,7 @@ export class CarbonCompiler extends BaseCompiler { return 'carbon'; } - constructor(compilerInfo: CompilerInfo & Record, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.compiler.demangler = ''; this.demanglerClass = null; diff --git a/lib/compilers/cc65.ts b/lib/compilers/cc65.ts index 0c6f4c09b92..13543a02c49 100644 --- a/lib/compilers/cc65.ts +++ b/lib/compilers/cc65.ts @@ -28,6 +28,7 @@ import fs from 'fs-extra'; import _ from 'underscore'; import {CompilationResult} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {ArtifactType} from '../../types/tool.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -39,7 +40,7 @@ export class Cc65Compiler extends BaseCompiler { return 'cc65'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.asm = new CC65AsmParser(this.compilerProps); @@ -60,7 +61,7 @@ export class Cc65Compiler extends BaseCompiler { ) as string[]; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { if (filters.binary) { return ['-g', '-o', this.filename(outputFilename)]; } else { @@ -99,8 +100,8 @@ export class Cc65Compiler extends BaseCompiler { maxSize: number, intelAsm, demangle, - staticReloc, - dynamicReloc, + staticReloc: boolean, + dynamicReloc: boolean, filters: ParseFiltersAndOutputOptions, ) { const res = await super.objdump( diff --git a/lib/compilers/circle.js b/lib/compilers/circle.ts similarity index 92% rename from lib/compilers/circle.js rename to lib/compilers/circle.ts index 58ac17d3b13..ebdb3d8c69f 100644 --- a/lib/compilers/circle.js +++ b/lib/compilers/circle.ts @@ -31,7 +31,7 @@ export class CircleCompiler extends BaseCompiler { return 'circle'; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters, outputFilename) { let options = [`-o=${this.filename(outputFilename)}`]; if (this.compiler.intelAsm && filters.intel && !filters.binary) { options = options.concat(this.compiler.intelAsm.split(' ')); @@ -42,13 +42,13 @@ export class CircleCompiler extends BaseCompiler { return options; } - getOutputFilename(dirPath, outputFilebase) { + override getOutputFilename(dirPath, outputFilebase) { // Do not add '.s' as default implementation does, // because circle emit assembly file instead of executable. return path.join(dirPath, outputFilebase); } - runCompiler(compiler, options, inputFilename, execOptions) { + override runCompiler(compiler, options, inputFilename, execOptions) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } diff --git a/lib/compilers/circt.ts b/lib/compilers/circt.ts index b34fdd45050..ed0515bdefb 100644 --- a/lib/compilers/circt.ts +++ b/lib/compilers/circt.ts @@ -24,6 +24,7 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -34,7 +35,7 @@ export class CIRCTCompiler extends BaseCompiler { return 'circt'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { if (!compilerInfo.disabledFilters) { compilerInfo.disabledFilters = [ 'binary', @@ -51,11 +52,11 @@ export class CIRCTCompiler extends BaseCompiler { super(compilerInfo, env); } - override getOutputFilename(dirPath: string, outputFilebase: string, key?: any): string { + override getOutputFilename(dirPath: string): string { return path.join(dirPath, 'example.out.mlir'); } - override optionsForBackend(backendOptions, outputFilename): string[] { + override optionsForBackend(backendOptions: Record, outputFilename: string): string[] { return ['-o', outputFilename]; } @@ -63,7 +64,7 @@ export class CIRCTCompiler extends BaseCompiler { return BaseParser; } - override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename, userOptions?): any[] { + override optionsForFilter(): any[] { return []; } } diff --git a/lib/compilers/cl430.ts b/lib/compilers/cl430.ts index ead06a90f93..19df01aa910 100644 --- a/lib/compilers/cl430.ts +++ b/lib/compilers/cl430.ts @@ -31,7 +31,7 @@ export class CL430Compiler extends BaseCompiler { return 'cl430'; } - constructor(compilerInfo: CompilerInfo & Record, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); // We need to have the same name for the C/C++ file as we expect for the output file diff --git a/lib/compilers/clang.ts b/lib/compilers/clang.ts index 6a755474952..6ff4ad6e15a 100644 --- a/lib/compilers/clang.ts +++ b/lib/compilers/clang.ts @@ -28,7 +28,9 @@ import path from 'path'; import _ from 'underscore'; import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; -import {UnprocessedExecResult} from '../../types/execution/execution.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ExecutableExecutionOptions, UnprocessedExecResult} from '../../types/execution/execution.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AmdgpuAsmParser} from '../parsers/asm-parser-amdgpu'; import {SassAsmParser} from '../parsers/asm-parser-sass'; @@ -44,7 +46,7 @@ export class ClangCompiler extends BaseCompiler { return 'clang'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsDeviceAsmView = true; @@ -66,7 +68,7 @@ export class ClangCompiler extends BaseCompiler { } } - override runExecutable(executable, executeParameters, homeDir) { + override runExecutable(executable, executeParameters: ExecutableExecutionOptions, homeDir) { if (this.asanSymbolizerPath) { executeParameters.env = { ASAN_SYMBOLIZER_PATH: this.asanSymbolizerPath, @@ -76,7 +78,7 @@ export class ClangCompiler extends BaseCompiler { return super.runExecutable(executable, executeParameters, homeDir); } - forceDwarf4UnlessOverridden(options) { + forceDwarf4UnlessOverridden(options: string[]) { const hasOverride = _.any(options, option => { return option.includes('-gdwarf-') || option.includes('-fdebug-default-version='); }); @@ -86,13 +88,13 @@ export class ClangCompiler extends BaseCompiler { return options; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { const options = super.optionsForFilter(filters, outputFilename); return this.forceDwarf4UnlessOverridden(options); } - override runCompiler(compiler, options, inputFilename, execOptions) { + override runCompiler(compiler: string, options: string[], inputFilename: string, execOptions: ExecutionOptions) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -182,7 +184,7 @@ export class ClangCudaCompiler extends ClangCompiler { return 'clang-cuda'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new SassAsmParser(); @@ -192,7 +194,7 @@ export class ClangCudaCompiler extends ClangCompiler { return 'ptx'; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return ['-o', this.filename(outputFilename), '-g1', filters.binary ? '-c' : '-S']; } @@ -217,13 +219,13 @@ export class ClangHipCompiler extends ClangCompiler { return 'clang-hip'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new AmdgpuAsmParser(); } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return ['-o', this.filename(outputFilename), '-g1', '--no-gpu-bundle-output', filters.binary ? '-c' : '-S']; } } @@ -233,7 +235,7 @@ export class ClangIntelCompiler extends ClangCompiler { return 'clang-intel'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); if (!this.offloadBundlerPath) { @@ -251,7 +253,7 @@ export class ClangIntelCompiler extends ClangCompiler { return opts; } - override runExecutable(executable, executeParameters, homeDir) { + override runExecutable(executable, executeParameters: ExecutableExecutionOptions, homeDir) { executeParameters.env = { OCL_ICD_FILENAMES: path.resolve(path.dirname(this.compiler.exe) + '/../lib/x64/libintelocl.so'), ...executeParameters.env, diff --git a/lib/compilers/clangcl.ts b/lib/compilers/clangcl.ts index 653fd8c2779..e7224c4bc65 100644 --- a/lib/compilers/clangcl.ts +++ b/lib/compilers/clangcl.ts @@ -24,6 +24,7 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {Win32Compiler} from './win32'; @@ -33,7 +34,7 @@ export class ClangCLCompiler extends Win32Compiler { return 'clang-cl'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIrView = true; @@ -64,7 +65,7 @@ export class ClangCLCompiler extends Win32Compiler { return this.filename(path.dirname(inputFilename) + '/output.s.obj'); } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { const options = super.optionsForFilter(filters, outputFilename); // Force the debugging info flag or we can't source locations. diff --git a/lib/compilers/clean.js b/lib/compilers/clean.ts similarity index 82% rename from lib/compilers/clean.js rename to lib/compilers/clean.ts index c159ba1d5e5..e75bd245cd5 100644 --- a/lib/compilers/clean.js +++ b/lib/compilers/clean.ts @@ -26,6 +26,9 @@ import path from 'path'; import fs from 'fs-extra'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {propsFor} from '../properties'; import * as utils from '../utils'; @@ -35,13 +38,15 @@ export class CleanCompiler extends BaseCompiler { return 'clean'; } - constructor(compiler, env) { + executionType: string; + + constructor(compiler: CompilerInfo, env) { super(compiler, env); const execProps = propsFor('execution'); this.executionType = execProps('executionType', 'none'); } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { if (filters.binary) { return []; } else { @@ -49,19 +54,19 @@ export class CleanCompiler extends BaseCompiler { } } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, 'Clean System Files/example.s'); } - getExecutableFilename(dirPath) { + override getExecutableFilename(dirPath: string) { return path.join(dirPath, 'a.out'); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - preprocessOutput(output) { + preprocessOutput(output: string) { const errorRegex = /^error \[.*,(\d*),(.*)]:\s?(.*)/i; const errorLineRegex = /^error \[.*,(\d*)]:\s?(.*)/i; const parseerrorRegex = /^parse error \[.*,(\d*);(\d*),(.*)]:\s?(.*)/i; @@ -97,7 +102,12 @@ export class CleanCompiler extends BaseCompiler { .join('\n'); } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { const tmpDir = path.dirname(inputFilename); const moduleName = path.basename(inputFilename, '.icl'); const compilerPath = path.dirname(compiler); @@ -123,10 +133,13 @@ export class CleanCompiler extends BaseCompiler { execOptions.env.CLEANOPATH = '/app/obj'; } - const result = await this.exec(compiler, options, execOptions); - result.inputFilename = inputFilename; - result.stdout = utils.parseOutput(this.preprocessOutput(result.stdout), inputFilename); - result.stderr = utils.parseOutput(this.preprocessOutput(result.stderr), inputFilename); + const rawResult = await this.exec(compiler, options, execOptions); + const result = { + ...rawResult, + inputFilename, + stdout: utils.parseOutput(this.preprocessOutput(rawResult.stdout), inputFilename), + stderr: utils.parseOutput(this.preprocessOutput(rawResult.stderr), inputFilename), + }; if (options.includes('-S')) { if (await fs.pathExists(this.getOutputFilename(tmpDir))) { diff --git a/lib/compilers/clspv.ts b/lib/compilers/clspv.ts index 12c821783f8..7b12810140d 100644 --- a/lib/compilers/clspv.ts +++ b/lib/compilers/clspv.ts @@ -26,6 +26,9 @@ import path from 'path'; import _ from 'underscore'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {logger} from '../logger'; import {SPIRVAsmParser} from '../parsers/asm-parser-spirv'; @@ -38,7 +41,7 @@ export class CLSPVCompiler extends BaseCompiler { return 'clspv'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.asm = new SPIRVAsmParser(this.compilerProps); @@ -46,22 +49,27 @@ export class CLSPVCompiler extends BaseCompiler { this.disassemblerPath = this.compilerProps('disassemblerPath'); } - getPrimaryOutputFilename(dirPath, outputFilebase) { + getPrimaryOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.spv`); } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { const sourceDir = path.dirname(outputFilename); const spvBinFilename = this.getPrimaryOutputFilename(sourceDir, this.outputFilebase); return ['-o', spvBinFilename, '-g']; } // TODO: Check this to see if it needs key - override getOutputFilename(dirPath, outputFilebase) { + override getOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.spvasm`); } - override async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { const sourceDir = path.dirname(inputFilename); const spvBinFilename = this.getPrimaryOutputFilename(sourceDir, this.outputFilebase); diff --git a/lib/compilers/cppfront.ts b/lib/compilers/cppfront.ts index 38d64daaad0..9e077384584 100644 --- a/lib/compilers/cppfront.ts +++ b/lib/compilers/cppfront.ts @@ -24,6 +24,7 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AsmParserCpp} from '../parsers/asm-parser-cpp'; @@ -33,7 +34,7 @@ export class CppFrontCompiler extends BaseCompiler { return 'cppfront'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new AsmParserCpp(); @@ -52,7 +53,7 @@ export class CppFrontCompiler extends BaseCompiler { return []; } - override getSharedLibraryLinks(libraries): string[] { + override getSharedLibraryLinks(libraries: any[]): string[] { return []; } diff --git a/lib/compilers/cproc.js b/lib/compilers/cproc.ts similarity index 97% rename from lib/compilers/cproc.js rename to lib/compilers/cproc.ts index 50217758ac0..00a8e2f9b95 100644 --- a/lib/compilers/cproc.js +++ b/lib/compilers/cproc.ts @@ -31,7 +31,7 @@ export class CprocCompiler extends BaseCompiler { return 'cproc'; } - getDefaultExecOptions() { + override getDefaultExecOptions() { const execOptions = super.getDefaultExecOptions(); // needed for finding the qbe program diff --git a/lib/compilers/crystal.js b/lib/compilers/crystal.ts similarity index 76% rename from lib/compilers/crystal.js rename to lib/compilers/crystal.ts index d84ab220a20..eabec3efd37 100644 --- a/lib/compilers/crystal.js +++ b/lib/compilers/crystal.ts @@ -26,6 +26,9 @@ import path from 'path'; import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {CrystalAsmParser} from '../parsers/asm-parser-crystal'; @@ -36,19 +39,21 @@ export class CrystalCompiler extends BaseCompiler { return 'crystal'; } - constructor(compiler, env) { + ccPath: string; + + constructor(compiler: CompilerInfo, env) { super(compiler, env); this.asm = new CrystalAsmParser(); this.compiler.supportsIrView = true; this.compiler.irArg = ['--emit', 'llvm-ir']; - this.ccPath = this.compilerProps(`compiler.${this.compiler.id}.cc`); + this.ccPath = this.compilerProps(`compiler.${this.compiler.id}.cc`); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - getDefaultExecOptions() { + override getDefaultExecOptions() { const execOptions = super.getDefaultExecOptions(); if (this.ccPath) { execOptions.env.CC = this.ccPath; @@ -56,11 +61,11 @@ export class CrystalCompiler extends BaseCompiler { return execOptions; } - optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { const output = this.filename(this.getExecutableFilename(path.dirname(outputFilename), this.outputFilebase)); let options = ['build', '-o', output]; - const userRequestedEmit = _.any(userOptions, opt => opt.includes('--emit')); + const userRequestedEmit = _.any(unwrap(userOptions), opt => opt.includes('--emit')); if (!filters.binary) { if (!userRequestedEmit) { options = options.concat('--emit', 'asm'); @@ -70,19 +75,19 @@ export class CrystalCompiler extends BaseCompiler { return options; } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.s`); } - getExecutableFilename(dirPath, outputFilebase) { + override getExecutableFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, outputFilebase); } - getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string) { return this.getExecutableFilename(path.dirname(defaultOutputFilename), this.outputFilebase); } - getArgumentParser() { + override getArgumentParser() { return CrystalParser; } } diff --git a/lib/compilers/dart.js b/lib/compilers/dart.ts similarity index 83% rename from lib/compilers/dart.js rename to lib/compilers/dart.ts index cbcbc73dd76..77bb6e35072 100644 --- a/lib/compilers/dart.js +++ b/lib/compilers/dart.ts @@ -24,6 +24,8 @@ import Semver from 'semver'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {DartAsmParser} from '../parsers/asm-parser-dart'; import * as utils from '../utils'; @@ -31,7 +33,7 @@ import * as utils from '../utils'; import {BaseParser} from './argument-parsers'; export class DartCompiler extends BaseCompiler { - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new DartAsmParser(); } @@ -40,7 +42,14 @@ export class DartCompiler extends BaseCompiler { return 'dart'; } - prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) { + override prepareArguments( + userOptions: string[], + filters: ParseFiltersAndOutputOptions, + backendOptions: Record, + inputFilename: string, + outputFilename: string, + libraries, + ) { let options = this.optionsForFilter(filters, outputFilename, userOptions); if (this.compiler.options) { @@ -54,7 +63,7 @@ export class DartCompiler extends BaseCompiler { return options.concat(libIncludes, libOptions, userOptions, [this.filename(inputFilename)]); } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { // Dart includes way too much of the standard library (even for simple programs) // to show all of it without truncation filters.libraryCode = true; @@ -69,7 +78,7 @@ export class DartCompiler extends BaseCompiler { } } - getArgumentParser() { + override getArgumentParser() { return BaseParser; } } diff --git a/lib/compilers/default.js b/lib/compilers/default.ts similarity index 100% rename from lib/compilers/default.js rename to lib/compilers/default.ts diff --git a/lib/compilers/dmd.js b/lib/compilers/dmd.ts similarity index 78% rename from lib/compilers/dmd.js rename to lib/compilers/dmd.ts index a138276f295..5b039cb080d 100644 --- a/lib/compilers/dmd.js +++ b/lib/compilers/dmd.ts @@ -24,6 +24,8 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {ClangParser} from './argument-parsers'; @@ -33,20 +35,20 @@ export class DMDCompiler extends BaseCompiler { return 'dmd'; } - constructor(compiler, env) { + constructor(compiler: CompilerInfo, env) { super(compiler, env); this.compiler.supportsIntel = true; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return ['-g', '-of' + this.filename(outputFilename)]; } - async execPostProcess(result, postProcesses, outputFilename, maxSize) { + override async execPostProcess(result, postProcesses, outputFilename, maxSize) { const dirPath = path.dirname(outputFilename); const lPath = path.basename(outputFilename); return this.handlePostProcessResult( @@ -55,21 +57,21 @@ export class DMDCompiler extends BaseCompiler { ); } - getOutputFilename(dirPath, outputFilebase) { + override getOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.s`); } - buildExecutable(compiler, options, inputFilename, execOptions) { + override buildExecutable(compiler, options, inputFilename, execOptions) { options = options.filter(param => param !== '-c'); return this.runCompiler(compiler, options, inputFilename, execOptions); } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { return userOptions.filter(option => option !== '-run' && option !== '-man' && !option.startsWith('-Xf')); } } diff --git a/lib/compilers/dosbox-compiler.ts b/lib/compilers/dosbox-compiler.ts index 4a19ea44213..b0719b831d6 100644 --- a/lib/compilers/dosbox-compiler.ts +++ b/lib/compilers/dosbox-compiler.ts @@ -26,6 +26,8 @@ import path from 'path'; import fs from 'fs-extra'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {BaseCompiler} from '../base-compiler'; import * as exec from '../exec'; import {logger} from '../logger'; @@ -35,7 +37,7 @@ export class DosboxCompiler extends BaseCompiler { private readonly dosbox: string; private readonly root: string; - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.dosbox = this.compilerProps(`compiler.${this.compiler.id}.dosbox`); @@ -149,7 +151,12 @@ export class DosboxCompiler extends BaseCompiler { return result; } - public override async runCompiler(compiler, options, inputFilename, execOptions) { + public override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { return super.runCompiler( compiler, options.map(option => { diff --git a/lib/compilers/dotnet.ts b/lib/compilers/dotnet.ts index d59e61a5511..994fee5d507 100644 --- a/lib/compilers/dotnet.ts +++ b/lib/compilers/dotnet.ts @@ -28,6 +28,7 @@ import fs from 'fs-extra'; import _ from 'underscore'; import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import { BasicExecutionResult, ExecutableExecutionOptions, @@ -50,7 +51,7 @@ class DotNetCompiler extends BaseCompiler { private crossgen2VersionString: string; - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.sdkBaseDir = path.join(path.dirname(compilerInfo.exe), 'sdk'); @@ -284,7 +285,7 @@ class DotNetCompiler extends BaseCompiler { } } - async ensureCrossgen2Version(execOptions) { + async ensureCrossgen2Version(execOptions: ExecutionOptions) { if (!this.crossgen2VersionString) { this.crossgen2VersionString = '// crossgen2 '; @@ -301,7 +302,13 @@ class DotNetCompiler extends BaseCompiler { } } - async runCrossgen2(execOptions, bclPath, dllPath, options, outputPath) { + async runCrossgen2( + execOptions: ExecutionOptions, + bclPath: string, + dllPath: string, + options: string[], + outputPath: string, + ) { await this.ensureCrossgen2Version(execOptions); const crossgen2Options = [ diff --git a/lib/compilers/ellcc.js b/lib/compilers/ellcc.ts similarity index 95% rename from lib/compilers/ellcc.js rename to lib/compilers/ellcc.ts index a06e7c84b62..f4641f9e4a4 100644 --- a/lib/compilers/ellcc.js +++ b/lib/compilers/ellcc.ts @@ -25,11 +25,11 @@ import {ClangCompiler} from './clang'; export class EllccCompiler extends ClangCompiler { - static get key() { + static override get key() { return 'ellcc'; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { const pathFlag = this.compiler.rpathFlag || '-Wl,-rpath,'; return this.compiler.ldPath.map(path => pathFlag + path); diff --git a/lib/compilers/ewarm.js b/lib/compilers/ewarm.ts similarity index 85% rename from lib/compilers/ewarm.js rename to lib/compilers/ewarm.ts index e87d5625f0b..544f075824a 100644 --- a/lib/compilers/ewarm.js +++ b/lib/compilers/ewarm.ts @@ -24,6 +24,8 @@ import temp from 'temp'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AsmEWAVRParser} from '../parsers/asm-parser-ewavr'; @@ -32,13 +34,13 @@ export class EWARMCompiler extends BaseCompiler { return 'ewarm'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new AsmEWAVRParser(this.compilerProps); } - newTempDir() { - return new Promise((resolve, reject) => { + override newTempDir() { + return new Promise((resolve, reject) => { temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.TMP}, (err, dirPath) => { if (err) reject(`Unable to open temp file: ${err}`); else resolve(dirPath); @@ -46,7 +48,7 @@ export class EWARMCompiler extends BaseCompiler { }); } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { if (filters.binary) { return []; } diff --git a/lib/compilers/ewavr.js b/lib/compilers/ewavr.ts similarity index 85% rename from lib/compilers/ewavr.js rename to lib/compilers/ewavr.ts index dacdb9d5b3b..8057536e11f 100644 --- a/lib/compilers/ewavr.js +++ b/lib/compilers/ewavr.ts @@ -24,6 +24,8 @@ import temp from 'temp'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {AsmEWAVRParser} from '../parsers/asm-parser-ewavr'; @@ -32,15 +34,15 @@ export class EWAVRCompiler extends BaseCompiler { return 'ewavr'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { info.supportsDemangle = false; info.supportsLibraryCodeFilter = false; super(info, env); this.asm = new AsmEWAVRParser(this.compilerProps); } - newTempDir() { - return new Promise((resolve, reject) => { + override newTempDir() { + return new Promise((resolve, reject) => { temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.TMP}, (err, dirPath) => { if (err) reject(`Unable to open temp file: ${err}`); else resolve(dirPath); @@ -48,7 +50,7 @@ export class EWAVRCompiler extends BaseCompiler { }); } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { if (filters.binary) { return []; } diff --git a/lib/compilers/flang.ts b/lib/compilers/flang.ts index 9ff8fc22657..ebcde09d442 100644 --- a/lib/compilers/flang.ts +++ b/lib/compilers/flang.ts @@ -24,6 +24,8 @@ import path from 'path'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {FortranCompiler} from './fortran'; export class FlangCompiler extends FortranCompiler { @@ -31,7 +33,7 @@ export class FlangCompiler extends FortranCompiler { return 'flang'; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = ['-o', this.filename(outputFilename)]; if (this.compiler.intelAsm && filters.intel && !filters.binary) { options = options.concat(this.compiler.intelAsm.split(' ')); diff --git a/lib/compilers/gccrs.js b/lib/compilers/gccrs.ts similarity index 97% rename from lib/compilers/gccrs.js rename to lib/compilers/gccrs.ts index 6a288c2db2d..f798fd42aec 100644 --- a/lib/compilers/gccrs.js +++ b/lib/compilers/gccrs.ts @@ -25,7 +25,7 @@ import {GCCCompiler} from './gcc'; export class GCCRSCompiler extends GCCCompiler { - static get key() { + static override get key() { return 'gccrs'; } } diff --git a/lib/compilers/golang.ts b/lib/compilers/golang.ts index b1de6688472..7db2d87e215 100644 --- a/lib/compilers/golang.ts +++ b/lib/compilers/golang.ts @@ -24,7 +24,10 @@ import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {ResultLine} from '../../types/resultline/resultline.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import * as utils from '../utils'; @@ -55,7 +58,7 @@ export class GolangCompiler extends BaseCompiler { return 'golang'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); const goroot = this.compilerProps(`compiler.${this.compiler.id}.goroot`); const goarch = this.compilerProps(`compiler.${this.compiler.id}.goarch`); @@ -219,21 +222,21 @@ export class GolangCompiler extends BaseCompiler { return []; } - override optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { // If we're dealing with an older version... if (this.compiler.id === '6g141') { return ['tool', '6g', '-g', '-o', outputFilename, '-S']; } if (filters.binary) { - return ['build', '-o', outputFilename, '-gcflags=' + userOptions.join(' ')]; + return ['build', '-o', outputFilename, '-gcflags=' + unwrap(userOptions).join(' ')]; } else { // Add userOptions to -gcflags to preserve previous behavior. - return ['build', '-o', outputFilename, '-gcflags=-S ' + userOptions.join(' ')]; + return ['build', '-o', outputFilename, '-gcflags=-S ' + unwrap(userOptions).join(' ')]; } } - override filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { if (this.compiler.id === '6g141') { return userOptions; } diff --git a/lib/compilers/haskell.js b/lib/compilers/haskell.ts similarity index 86% rename from lib/compilers/haskell.js rename to lib/compilers/haskell.ts index a6c1a8f6bdf..c4cf6003ec5 100644 --- a/lib/compilers/haskell.js +++ b/lib/compilers/haskell.ts @@ -24,6 +24,8 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {ClangParser} from './argument-parsers'; @@ -33,14 +35,14 @@ export class HaskellCompiler extends BaseCompiler { return 'haskell'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsHaskellCoreView = true; this.compiler.supportsHaskellStgView = true; this.compiler.supportsHaskellCmmView = true; } - optionsForBackend(backendOptions, outputFilename) { + override optionsForBackend(backendOptions: Record, outputFilename: string) { const opts = super.optionsForBackend(backendOptions, outputFilename); const anydump = @@ -63,18 +65,18 @@ export class HaskellCompiler extends BaseCompiler { return opts; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { const options = ['-g', '-o', this.filename(outputFilename)]; if (!filters.binary) options.unshift('-S'); return options; } - getSharedLibraryPathsAsArguments(libraries) { + override getSharedLibraryPathsAsArguments(libraries) { const libPathFlag = this.compiler.libpathFlag || '-L'; return [libPathFlag + '.', ...this.getSharedLibraryPaths(libraries).map(path => libPathFlag + path)]; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } } diff --git a/lib/compilers/index.js b/lib/compilers/index.ts similarity index 100% rename from lib/compilers/index.js rename to lib/compilers/index.ts diff --git a/lib/compilers/ispc.js b/lib/compilers/ispc.ts similarity index 83% rename from lib/compilers/ispc.js rename to lib/compilers/ispc.ts index 897c0976f3d..d6eb0382454 100644 --- a/lib/compilers/ispc.js +++ b/lib/compilers/ispc.ts @@ -25,6 +25,8 @@ import Semver from 'semver'; import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {asSafeVer} from '../utils'; @@ -35,17 +37,17 @@ export class ISPCCompiler extends BaseCompiler { return 'ispc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIrView = true; this.compiler.irArg = ['--emit-llvm-text']; } - couldSupportASTDump(version) { + override couldSupportASTDump(version: string) { return Semver.gte(asSafeVer(this.compiler.semver), '1.18.0', true); } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = ['--target=avx2-i32x8', '--emit-asm', '-g', '-o', this.filename(outputFilename)]; if (this.compiler.intelAsm && filters.intel && !filters.binary) { options = options.concat(this.compiler.intelAsm.split(' ')); @@ -53,16 +55,16 @@ export class ISPCCompiler extends BaseCompiler { return options; } - async generateIR(inputFilename, options, filters) { + override async generateIR(inputFilename: string, options: string[], filters: ParseFiltersAndOutputOptions) { const newOptions = [...options, ...this.compiler.irArg, '-o', this.getIrOutputFilename(inputFilename)]; return super.generateIR(inputFilename, newOptions, filters); } - getArgumentParser() { + override getArgumentParser() { return ISPCParser; } - async generateAST(inputFilename, options) { + override async generateAST(inputFilename, options) { // These options make Clang produce an AST dump const newOptions = _.filter(options, option => option !== '--colored-output').concat(['--ast-dump']); @@ -75,7 +77,7 @@ export class ISPCCompiler extends BaseCompiler { ); } - isCfgCompiler(/*compilerVersion*/) { + override isCfgCompiler(/*compilerVersion*/) { return true; } } diff --git a/lib/compilers/jakt.ts b/lib/compilers/jakt.ts index a9ef1e3e5c9..d480dea88e0 100644 --- a/lib/compilers/jakt.ts +++ b/lib/compilers/jakt.ts @@ -25,6 +25,7 @@ import path from 'path'; import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -33,7 +34,7 @@ export class JaktCompiler extends BaseCompiler { return 'jakt'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.outputFilebase = 'example'; @@ -49,8 +50,8 @@ export class JaktCompiler extends BaseCompiler { maxSize: number, intelAsm, demangle, - staticReloc, - dynamicReloc, + staticReloc: boolean, + dynamicReloc: boolean, filters: ParseFiltersAndOutputOptions, ) { const objdumpResult = await super.objdump( @@ -72,13 +73,13 @@ export class JaktCompiler extends BaseCompiler { return ['--binary-dir', path.dirname(outputFilename)]; } - override getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string) { const parsed_path = path.parse(defaultOutputFilename); return path.join(parsed_path.dir, this.outputFilebase); } - override getExecutableFilename(dirPath, outputFilebase, key?) { + override getExecutableFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, outputFilebase); } @@ -88,7 +89,7 @@ export class JaktCompiler extends BaseCompiler { } // We have no dynamic linking in Jakt - override getSharedLibraryLinks(libraries): string[] { + override getSharedLibraryLinks(libraries: any[]): string[] { return []; } diff --git a/lib/compilers/java.js b/lib/compilers/java.ts similarity index 87% rename from lib/compilers/java.js rename to lib/compilers/java.ts index 5d83e01b16d..46820fad02e 100644 --- a/lib/compilers/java.js +++ b/lib/compilers/java.ts @@ -26,6 +26,10 @@ import path from 'path'; import fs from 'fs-extra'; +import {ParsedAsmResult, ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {logger} from '../logger'; import * as utils from '../utils'; @@ -37,21 +41,24 @@ export class JavaCompiler extends BaseCompiler { return 'java'; } - constructor(compilerInfo, env) { + javaRuntime: string; + mainRegex: RegExp; + + constructor(compilerInfo: CompilerInfo, env) { // Default is to disable all "cosmetic" filters if (!compilerInfo.disabledFilters) { compilerInfo.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim']; } super(compilerInfo, env); - this.javaRuntime = this.compilerProps(`compiler.${this.compiler.id}.runtime`); + this.javaRuntime = this.compilerProps(`compiler.${this.compiler.id}.runtime`); this.mainRegex = /public static ?(.*?) void main\(java\.lang\.String\[]\)/; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - async objdump(outputFilename, result, maxSize) { + override async objdump(outputFilename, result: any, maxSize: number) { const dirPath = path.dirname(outputFilename); const files = await fs.readdir(dirPath); logger.verbose('Class files: ', files); @@ -77,20 +84,28 @@ export class JavaCompiler extends BaseCompiler { maxOutput: maxSize, customCwd: dirPath, }); - const oneResult = { - asm: objResult.stdout, + const oneResult: ParsedAsmResult = { + asm: [ + { + text: objResult.stdout, + }, + ], }; if (objResult.code === 0) { oneResult.objdumpTime = objResult.execTime; } else { - oneResult.asm = ''; + oneResult.asm = [ + { + text: ``, + }, + ]; } return oneResult; }), ); - const merged = {asm: []}; + const merged = {asm: [] as ParsedAsmResultLine[][]}; for (const result of results) { const asmBackup = merged.asm; Object.assign(merged, result); @@ -102,14 +117,14 @@ export class JavaCompiler extends BaseCompiler { return result; } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { // Forcibly enable javap filters.binary = true; return ['-Xlint:all', '-encoding', 'utf8']; } - async handleInterpreting(key, executeParameters) { + override async handleInterpreting(key, executeParameters) { const compileResult = await this.getOrBuildExecutable(key); if (compileResult.code === 0) { executeParameters.args = [ @@ -124,9 +139,11 @@ export class JavaCompiler extends BaseCompiler { ...executeParameters.args, ]; const result = await this.runExecutable(this.javaRuntime, executeParameters, compileResult.dirPath); - result.didExecute = true; - result.buildResult = compileResult; - return result; + return { + ...result, + didExecute: true, + buildResult: compileResult, + }; } else { return { stdout: compileResult.stdout, @@ -134,11 +151,12 @@ export class JavaCompiler extends BaseCompiler { code: compileResult.code, didExecute: false, buildResult: compileResult, + timedOut: false, }; } } - async getMainClassName(dirPath) { + async getMainClassName(dirPath: string) { const maxSize = this.env.ceProps('max-asm-size', 64 * 1024 * 1024); const files = await fs.readdir(dirPath); const results = await Promise.all( @@ -164,23 +182,23 @@ export class JavaCompiler extends BaseCompiler { const candidates = results.filter(file => file !== null); if (candidates.length > 0) { // In case of multiple candidates, we'll just take the first one. - const fileName = candidates[0]; + const fileName = unwrap(candidates[0]); return fileName.substring(0, fileName.lastIndexOf('.')); } // We were unable to find a main method, let's error out assuming "Main" return 'Main'; } - getArgumentParser() { + override getArgumentParser() { return JavaParser; } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.class`); } - filterUserOptionsWithArg(userOptions, oneArgForbiddenList) { - const filteredOptions = []; + filterUserOptionsWithArg(userOptions: string[], oneArgForbiddenList: Set) { + const filteredOptions: string[] = []; let toSkip = 0; for (const userOption of userOptions) { @@ -199,7 +217,7 @@ export class JavaCompiler extends BaseCompiler { return filteredOptions; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { const oneArgForbiddenList = new Set([ // -d directory // Sets the destination directory for class files. @@ -216,7 +234,7 @@ export class JavaCompiler extends BaseCompiler { return this.filterUserOptionsWithArg(userOptions, oneArgForbiddenList); } - processAsm(result) { + override processAsm(result) { // Handle "error" documents. if (!result.asm.includes('\n') && result.asm[0] === '<') { return [{text: result.asm, source: null}]; @@ -227,7 +245,7 @@ export class JavaCompiler extends BaseCompiler { // Sort class file outputs according to first source line they reference parseds.sort((o1, o2) => o1.firstSourceLine - o2.firstSourceLine); - const segments = []; + const segments: ParsedAsmResultLine[] = []; for (const [classNumber, parsed] of parseds.entries()) { if (classNumber > 0) { // Separate classes with two line breaks @@ -261,8 +279,8 @@ export class JavaCompiler extends BaseCompiler { } parseAsmForClass(javapOut) { - const textsBeforeMethod = []; - const methods = []; + const textsBeforeMethod: string[] = []; + const methods: {instructions: any[]; startLine?: number}[] = []; // javap output puts ` Code:` after every signature. (Line will not be shown to user) // We use this to find the individual methods. // Before the first `Code:` occurrence, there is the method signature as well as the name of the class. @@ -275,7 +293,7 @@ export class JavaCompiler extends BaseCompiler { for (const codeAndLineNumberTable of codeAndLineNumberTables) { const method = { instructions: [], - }; + } as typeof methods[0]; methods.push(method); for (const codeLineCandidate of utils.splitLines(codeAndLineNumberTable)) { @@ -365,7 +383,10 @@ export class JavaCompiler extends BaseCompiler { } return { // Used for sorting - firstSourceLine: methods.reduce((p, m) => (p === -1 ? m.startLine : Math.min(p, m.startLine)), -1), + firstSourceLine: methods.reduce( + (p, m) => (p === -1 ? unwrap(m.startLine) : Math.min(p, unwrap(m.startLine))), + -1, + ), methods: methods, textsBeforeMethod, }; diff --git a/lib/compilers/julia.ts b/lib/compilers/julia.ts index 83a2d14d758..dee1674361a 100644 --- a/lib/compilers/julia.ts +++ b/lib/compilers/julia.ts @@ -26,6 +26,8 @@ import path from 'path'; import {ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces'; import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import * as utils from '../utils'; @@ -38,7 +40,7 @@ export class JuliaCompiler extends BaseCompiler { return 'julia'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.demangler = ''; this.demanglerClass = null; @@ -89,7 +91,7 @@ export class JuliaCompiler extends BaseCompiler { return {asm: bytecodeResult}; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return []; } diff --git a/lib/compilers/kotlin.js b/lib/compilers/kotlin.ts similarity index 84% rename from lib/compilers/kotlin.js rename to lib/compilers/kotlin.ts index 7936acef246..1a9adc258f7 100644 --- a/lib/compilers/kotlin.js +++ b/lib/compilers/kotlin.ts @@ -22,20 +22,25 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {KotlinParser} from './argument-parsers'; import {JavaCompiler} from './java'; export class KotlinCompiler extends JavaCompiler { - static get key() { + static override get key() { return 'kotlin'; } - constructor(compilerInfo, env) { + javaHome: string; + + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); - this.javaHome = this.compilerProps(`compiler.${this.compiler.id}.java_home`); + this.javaHome = this.compilerProps(`compiler.${this.compiler.id}.java_home`); } - getDefaultExecOptions() { + override getDefaultExecOptions() { const execOptions = super.getDefaultExecOptions(); if (this.javaHome) { execOptions.env.JAVA_HOME = this.javaHome; @@ -44,11 +49,11 @@ export class KotlinCompiler extends JavaCompiler { return execOptions; } - getMainClassName() { + override async getMainClassName() { return 'ExampleKt'; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { // filter options without extra arguments userOptions = (userOptions || []).filter( option => option !== '-script' && option !== '-progressive' && !option.startsWith('-Xjavac'), @@ -69,7 +74,7 @@ export class KotlinCompiler extends JavaCompiler { return super.filterUserOptionsWithArg(userOptions, oneArgForbiddenList); } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { // Forcibly enable javap filters.binary = true; @@ -88,7 +93,7 @@ export class KotlinCompiler extends JavaCompiler { * * TODO(supergrecko): Find a better fix than this bandaid for execution */ - async handleInterpreting(key, executeParameters) { + override async handleInterpreting(key, executeParameters) { const alteredKey = { ...key, options: ['-include-runtime', '-d', 'example.jar'], @@ -109,12 +114,14 @@ export class KotlinCompiler extends JavaCompiler { ...executeParameters.args, ]; const result = await this.runExecutable(this.javaRuntime, executeParameters, compileResult.dirPath); - result.didExecute = true; - result.buildResult = compileResult; - return result; + return { + ...result, + didExecute: true, + buildResult: compileResult, + }; } - getArgumentParser() { + override getArgumentParser() { return KotlinParser; } } diff --git a/lib/compilers/ldc.js b/lib/compilers/ldc.ts similarity index 81% rename from lib/compilers/ldc.js rename to lib/compilers/ldc.ts index 277d2979bac..88932416ef2 100644 --- a/lib/compilers/ldc.js +++ b/lib/compilers/ldc.ts @@ -27,6 +27,7 @@ import path from 'path'; import fs from 'fs-extra'; import semverParser from 'semver'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {BaseCompiler} from '../base-compiler'; import {logger} from '../logger'; @@ -37,16 +38,18 @@ export class LDCCompiler extends BaseCompiler { return 'ldc'; } - constructor(info, env) { + asanSymbolizerPath: string; + + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; this.compiler.supportsIrView = true; this.compiler.irArg = ['-output-ll']; - this.asanSymbolizerPath = this.compilerProps('llvmSymbolizer'); + this.asanSymbolizerPath = this.compilerProps('llvmSymbolizer'); } - runExecutable(executable, executeParameters, homeDir) { + override runExecutable(executable, executeParameters, homeDir) { if (this.asanSymbolizerPath) { executeParameters.env = { ASAN_SYMBOLIZER_PATH: this.asanSymbolizerPath, @@ -56,42 +59,43 @@ export class LDCCompiler extends BaseCompiler { return super.runExecutable(executable, executeParameters, homeDir); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters, outputFilename) { let options = ['-gline-tables-only', '-of', this.filename(outputFilename)]; if (filters.intel && !filters.binary) options = options.concat('-x86-asm-syntax=intel'); if (!filters.binary) options = options.concat('-output-s'); return options; } - getArgumentParser() { + override getArgumentParser() { return LDCParser; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions) { return userOptions.filter(option => option !== '-run'); } - isCfgCompiler() { + override isCfgCompiler() { return true; } - couldSupportASTDump(version) { + override couldSupportASTDump(version) { const versionRegex = /\((\d\.\d+)\.\d+/; const versionMatch = versionRegex.exec(version); return versionMatch ? semverParser.compare(versionMatch[1] + '.0', '1.4.0', true) >= 0 : false; } - async generateAST(inputFilename, options) { + override async generateAST(inputFilename, options) { // These options make LDC produce an AST dump in a separate file `.cg`. const newOptions = options.concat('-vcg-ast'); const execOptions = this.getDefaultExecOptions(); + // TODO(#4654) generateAST expects to return a ResultLine[] not a string return this.loadASTOutput( await this.runCompiler(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions), - ); + ) as any; } async loadASTOutput(output) { @@ -104,7 +108,8 @@ export class LDCCompiler extends BaseCompiler { try { return await fs.readFile(astFilename, 'utf8'); } catch (e) { - if (e instanceof Error && e.code === 'ENOENT') { + // TODO(jeremy-rifkin) why does e have .code here + if (e instanceof Error && (e as any).code === 'ENOENT') { logger.warn(`LDC AST file ${astFilename} requested but it does not exist`); return ''; } @@ -113,7 +118,7 @@ export class LDCCompiler extends BaseCompiler { } // Override the IR file name method for LDC because the output file is different from clang. - getIrOutputFilename(inputFilename) { + override getIrOutputFilename(inputFilename) { return this.getOutputFilename(path.dirname(inputFilename), this.outputFilebase).replace('.s', '.ll'); } } diff --git a/lib/compilers/llc.js b/lib/compilers/llc.ts similarity index 85% rename from lib/compilers/llc.js rename to lib/compilers/llc.ts index 45688398dcc..5a79bca49ed 100644 --- a/lib/compilers/llc.js +++ b/lib/compilers/llc.ts @@ -22,6 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {ClangParser} from './argument-parsers'; @@ -31,7 +33,7 @@ export class LLCCompiler extends BaseCompiler { return 'llc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; this.compiler.supportsLLVMOptPipelineView = true; @@ -40,18 +42,18 @@ export class LLCCompiler extends BaseCompiler { this.compiler.llvmOptNoDiscardValueNamesArg = []; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = ['-o', this.filename(outputFilename)]; if (filters.intel && !filters.binary) options = options.concat('-x86-asm-syntax=intel'); if (filters.binary) options = options.concat('-filetype=obj'); return options; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } } diff --git a/lib/compilers/llvm-mca.js b/lib/compilers/llvm-mca.ts similarity index 86% rename from lib/compilers/llvm-mca.js rename to lib/compilers/llvm-mca.ts index 9fd419cbf8d..b0b30925c73 100644 --- a/lib/compilers/llvm-mca.js +++ b/lib/compilers/llvm-mca.ts @@ -22,32 +22,34 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {AnalysisTool} from './analysis-tool'; import {ClangParser} from './argument-parsers'; // Plain compiler, which just runs the tool and returns whatever the output was export class LLVMmcaTool extends AnalysisTool { - static get key() { + static override get key() { return 'llvm-mca'; } - supportsObjdump() { + override supportsObjdump() { return false; } - getOutputFilenameArgs(filename) { + getOutputFilenameArgs(filename: string) { // TODO: Some tools might require an argument of the form -arg=filename return ['-o', filename]; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = this.getOutputFilenameArgs(outputFilename); // Some tools might require more than one arg, so split(' ') if (filters.intel) options = options.concat(this.compiler.intelAsm.split(' ')); return options; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } } diff --git a/lib/compilers/llvm-mos.ts b/lib/compilers/llvm-mos.ts index e1057ef70dd..8fded073e0e 100644 --- a/lib/compilers/llvm-mos.ts +++ b/lib/compilers/llvm-mos.ts @@ -27,6 +27,7 @@ import path from 'path'; import _ from 'underscore'; import {CompilationResult} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {ArtifactType} from '../../types/tool.interfaces'; import * as utils from '../utils'; @@ -38,7 +39,7 @@ export class LLVMMOSCompiler extends ClangCompiler { return 'llvmmos'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.externalparser = null; this.toolchainPath = path.normalize(path.join(path.dirname(this.compiler.exe), '..')); @@ -62,8 +63,8 @@ export class LLVMMOSCompiler extends ClangCompiler { maxSize: number, intelAsm, demangle, - staticReloc, - dynamicReloc, + staticReloc: boolean, + dynamicReloc: boolean, filters: ParseFiltersAndOutputOptions, ) { if (!outputFilename.endsWith('.elf') && (await utils.fileExists(outputFilename + '.elf'))) { diff --git a/lib/compilers/mlir.ts b/lib/compilers/mlir.ts index 8332a1ace30..3cd9ea1f47f 100644 --- a/lib/compilers/mlir.ts +++ b/lib/compilers/mlir.ts @@ -24,6 +24,7 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -34,7 +35,7 @@ export class MLIRCompiler extends BaseCompiler { return 'mlir'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { if (!compilerInfo.disabledFilters) { compilerInfo.disabledFilters = [ 'binary', @@ -59,7 +60,7 @@ export class MLIRCompiler extends BaseCompiler { return path.join(dirPath, 'example.out.mlir'); } - override optionsForBackend(backendOptions, outputFilename): string[] { + override optionsForBackend(backendOptions: Record, outputFilename: string): string[] { return ['-o', outputFilename]; } @@ -67,7 +68,11 @@ export class MLIRCompiler extends BaseCompiler { return BaseParser; } - override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename, userOptions?): any[] { + override optionsForFilter( + filters: ParseFiltersAndOutputOptions, + outputFilename: string, + userOptions?: string[], + ): any[] { return []; } } diff --git a/lib/compilers/mrustc.js b/lib/compilers/mrustc.ts similarity index 84% rename from lib/compilers/mrustc.js rename to lib/compilers/mrustc.ts index 12228d46e47..13980568e13 100644 --- a/lib/compilers/mrustc.js +++ b/lib/compilers/mrustc.ts @@ -24,6 +24,8 @@ import path from 'path'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {MrustcParser} from './argument-parsers'; @@ -33,7 +35,7 @@ export class MrustcCompiler extends BaseCompiler { return 'mrustc'; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { // mrustc always dumps the C code for target in the .c file. // In our case, the actual file in -o is not even created because we are // faking the last step (C compilation). @@ -54,7 +56,12 @@ export class MrustcCompiler extends BaseCompiler { ]; } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { // mrustc will always invoke a C compiler on its C output to create a final exec/object. // There's no easy way to disable this last step, so simply faking it with 'true' works. execOptions.env.CC = 'true'; @@ -62,11 +69,11 @@ export class MrustcCompiler extends BaseCompiler { return super.runCompiler(compiler, options, inputFilename, execOptions); } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.c`); } - getArgumentParser() { + override getArgumentParser() { return MrustcParser; } } diff --git a/lib/compilers/nasm.js b/lib/compilers/nasm.ts similarity index 86% rename from lib/compilers/nasm.js rename to lib/compilers/nasm.ts index 09cd6b5eedf..7c105af2107 100644 --- a/lib/compilers/nasm.js +++ b/lib/compilers/nasm.ts @@ -24,16 +24,24 @@ import path from 'path'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import * as utils from '../utils'; import {AssemblyCompiler} from './assembly'; export class NasmCompiler extends AssemblyCompiler { - static get key() { + static override get key() { return 'nasm'; } - prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) { + override prepareArguments( + userOptions: string[], + filters: ParseFiltersAndOutputOptions, + backendOptions: Record, + inputFilename: string, + outputFilename: string, + libraries, + ) { let options = super.prepareArguments( userOptions, filters, diff --git a/lib/compilers/nim.js b/lib/compilers/nim.ts similarity index 79% rename from lib/compilers/nim.js rename to lib/compilers/nim.ts index 21b582f9b1b..6c1df68f78d 100644 --- a/lib/compilers/nim.js +++ b/lib/compilers/nim.ts @@ -27,6 +27,9 @@ import path from 'path'; import fs from 'fs-extra'; import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {NimParser} from './argument-parsers'; @@ -38,7 +41,7 @@ export class NimCompiler extends BaseCompiler { return 'nim'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; } @@ -47,7 +50,7 @@ export class NimCompiler extends BaseCompiler { return outputFilename + '.cache'; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return [ '--debugger:native', // debugging info '-o:' + outputFilename, //output file, only for js mode @@ -56,7 +59,7 @@ export class NimCompiler extends BaseCompiler { ]; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { //If none of the allowed commands is present in userOptions add 'compile' command if (_.intersection(userOptions, NimCommands).length === 0) { userOptions.unshift('compile'); @@ -65,7 +68,7 @@ export class NimCompiler extends BaseCompiler { return userOptions.filter(option => !['--run', '-r'].includes(option)); } - expectedExtensionFromCommand(command) { + expectedExtensionFromCommand(command: string) { const isC = ['compile', 'compileToC', 'c'], isCpp = ['compileToCpp', 'cpp', 'cc'], isObjC = ['compileToOC', 'objc']; @@ -76,7 +79,7 @@ export class NimCompiler extends BaseCompiler { else return null; } - getCacheFile(options, inputFilename, cacheDir) { + getCacheFile(options: string[], inputFilename: string, cacheDir: string) { const commandsInOptions = _.intersection(options, NimCommands); if (commandsInOptions.length === 0) return null; const command = commandsInOptions[0]; @@ -87,7 +90,7 @@ export class NimCompiler extends BaseCompiler { return path.join(cacheDir, resultName); } - async postProcess(result, outputFilename, filters) { + override async postProcess(result, outputFilename: string, filters: ParseFiltersAndOutputOptions) { const options = result.compilationOptions; const cacheDir = this.cacheDir(outputFilename); try { @@ -95,7 +98,7 @@ export class NimCompiler extends BaseCompiler { else { filters.binary = true; const objFile = this.getCacheFile(options, result.inputFilename, cacheDir); - await fs.move(objFile, outputFilename); + await fs.move(unwrap(objFile), outputFilename); } return super.postProcess(result, outputFilename, filters); } finally { @@ -103,19 +106,28 @@ export class NimCompiler extends BaseCompiler { } } - getSharedLibraryPathsAsArguments(/*libraries*/) { + override getSharedLibraryPathsAsArguments(/*libraries*/) { return []; } - getArgumentParser() { + override getArgumentParser() { return NimParser; } - isCfgCompiler(/*compilerVersion*/) { + override isCfgCompiler(/*compilerVersion*/) { return true; } - orderArguments(options, inputFilename, libIncludes, libOptions, libPaths, libLinks, userOptions, staticLibLinks) { + override orderArguments( + options: string[], + inputFilename: string, + libIncludes: string[], + libOptions: string[], + libPaths: string[], + libLinks: string[], + userOptions: string[], + staticLibLinks: string[], + ) { return options.concat( libIncludes, libOptions, diff --git a/lib/compilers/nvcc.js b/lib/compilers/nvcc.ts similarity index 80% rename from lib/compilers/nvcc.js rename to lib/compilers/nvcc.ts index d87e4a8b4c7..00dcc7c0a26 100644 --- a/lib/compilers/nvcc.js +++ b/lib/compilers/nvcc.ts @@ -27,6 +27,10 @@ import Path from 'path'; import Semver from 'semver'; +import {CompilationInfo} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {SassAsmParser} from '../parsers/asm-parser-sass'; import {asSafeVer} from '../utils'; @@ -38,7 +42,9 @@ export class NvccCompiler extends BaseCompiler { return 'nvcc'; } - constructor(info, env) { + deviceAsmParser: SassAsmParser; + + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsOptOutput = true; this.compiler.supportsDeviceAsmView = true; @@ -49,14 +55,7 @@ export class NvccCompiler extends BaseCompiler { // * lots of whitespace from nvcc // * would be nice to try and filter unused `.func`s from e.g. clang output - /** - * - * @param {import('../../types/features/filters.interfaces').ParseFiltersAndOutputOptions} filters - * @param {string} outputFilename - * @param {string[]?} userOptions - * @returns {string[]} - */ - optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { const opts = ['-o', this.filename(outputFilename), '-g', '-lineinfo']; if (!filters.execute) { opts.push('-c', '-keep', '-keep-dir', Path.dirname(outputFilename)); @@ -67,11 +66,11 @@ export class NvccCompiler extends BaseCompiler { return opts; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } - optOutputRequested(options) { + override optOutputRequested(options: string[]) { return ( super.optOutputRequested(options) || options.includes('--optimization-info') || @@ -79,42 +78,33 @@ export class NvccCompiler extends BaseCompiler { ); } - /** - * - * @param {string} outputFilename - * @param {*} result - * @param {number} maxOutput - */ - async nvdisasm(outputFilename, result, maxOutput) { + async nvdisasm(outputFilename: string, result: any, maxOutput: number) { const {nvdisasm, semver} = this.compiler; const args = Semver.lt(asSafeVer(semver), '11.0.0', true) ? [outputFilename, '-c', '-g'] : [outputFilename, '-c', '-g', '-hex']; - const {code, execTime, stdout} = await this.exec(nvdisasm, args, {maxOutput, customCwd: result.dirPath}); + const {code, execTime, stdout} = await this.exec(unwrap(nvdisasm), args, { + maxOutput, + customCwd: result.dirPath, + }); if (code === 0) { result.objdumpTime = execTime; result.asm = this.postProcessObjdumpOutput(stdout); } else { - result.asm = ``; + result.asm = ``; } return result; } - /** - * - * @param {*} result - * @param {string} outputFilename - * @param {import('../../types/features/filters.interfaces').ParseFiltersAndOutputOptions} filters - */ - async postProcess(result, outputFilename, filters) { + override async postProcess(result, outputFilename: string, filters: ParseFiltersAndOutputOptions) { const maxSize = this.env.ceProps('max-asm-size', 64 * 1024 * 1024); const optPromise = result.hasOptOutput ? this.processOptOutput(result.optPath) : Promise.resolve(''); const asmPromise = ( filters.binary - ? this.objdump(outputFilename, {}, maxSize, filters.intel, filters.demangle, filters) + ? this.objdump(outputFilename, {}, maxSize, filters.intel, filters.demangle, false, false, filters) : fs.readFile(outputFilename, {encoding: 'utf8'}) ).then(asm => { result.asm = typeof asm === 'string' ? asm : asm.asm; @@ -123,14 +113,7 @@ export class NvccCompiler extends BaseCompiler { return Promise.all([asmPromise, optPromise]); } - /** - * - * @param {*} result - * @param {*} filters - * @param {import('../../types/compilation/compilation.interfaces').CompilationInfo} compilationInfo - * @returns - */ - async extractDeviceCode(result, filters, compilationInfo) { + override async extractDeviceCode(result, filters, compilationInfo: CompilationInfo) { const {dirPath} = result; const {demangle} = filters; const devices = {...result.devices}; diff --git a/lib/compilers/ocaml.js b/lib/compilers/ocaml.ts similarity index 85% rename from lib/compilers/ocaml.js rename to lib/compilers/ocaml.ts index cae0e34c3e5..6635760ed1f 100644 --- a/lib/compilers/ocaml.js +++ b/lib/compilers/ocaml.ts @@ -22,6 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {PascalParser} from './argument-parsers'; @@ -31,7 +33,7 @@ export class OCamlCompiler extends BaseCompiler { return 'ocaml'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); // override output base because ocaml's -S -o has different semantics. // namely, it outputs a full binary exe to the supposed asm dump. @@ -40,11 +42,11 @@ export class OCamlCompiler extends BaseCompiler { this.outputFilebase = 'example'; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFileName) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFileName: string) { const options = ['-g']; if (filters.binary) { options.unshift('-o', outputFileName); @@ -54,7 +56,7 @@ export class OCamlCompiler extends BaseCompiler { return options; } - getArgumentParser() { + override getArgumentParser() { return PascalParser; } } diff --git a/lib/compilers/opt.js b/lib/compilers/opt.ts similarity index 86% rename from lib/compilers/opt.js rename to lib/compilers/opt.ts index 9f902b65b32..459e3502f59 100644 --- a/lib/compilers/opt.js +++ b/lib/compilers/opt.ts @@ -22,6 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {ClangParser} from './argument-parsers'; @@ -31,7 +33,7 @@ export class OptCompiler extends BaseCompiler { return 'opt'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsLLVMOptPipelineView = true; this.compiler.llvmOptArg = ['-print-after-all', '-print-before-all']; @@ -39,11 +41,11 @@ export class OptCompiler extends BaseCompiler { this.compiler.llvmOptNoDiscardValueNamesArg = []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return ['-o', this.filename(outputFilename), '-S']; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } } diff --git a/lib/compilers/osaca.js b/lib/compilers/osaca.ts similarity index 79% rename from lib/compilers/osaca.js rename to lib/compilers/osaca.ts index 70487cd3567..80fbf701fd4 100644 --- a/lib/compilers/osaca.js +++ b/lib/compilers/osaca.ts @@ -22,28 +22,30 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {AnalysisTool} from './analysis-tool'; import {BaseParser} from './argument-parsers'; // Plain compiler, which just runs the tool and returns whatever the output was export class OSACATool extends AnalysisTool { - static get key() { + static override get key() { return 'osaca'; } - supportsObjdump() { + override supportsObjdump() { return false; } - getOutputFilenameArgs(filename) { + getOutputFilenameArgs(filename: string) { return ['-o', filename]; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return this.getOutputFilenameArgs(outputFilename); } - getDefaultFilters() { + override getDefaultFilters() { // Disable everything, also intel syntax return { intel: false, @@ -51,10 +53,16 @@ export class OSACATool extends AnalysisTool { directives: false, labels: false, optOutput: false, + binary: false, + execute: false, + demangle: false, + libraryCode: false, + trim: false, + binaryObject: false, }; } - getArgumentParser() { + override getArgumentParser() { return BaseParser; } } diff --git a/lib/compilers/pascal-utils.js b/lib/compilers/pascal-utils.ts similarity index 94% rename from lib/compilers/pascal-utils.js rename to lib/compilers/pascal-utils.ts index d1f354bc1fc..564ce9d786d 100644 --- a/lib/compilers/pascal-utils.js +++ b/lib/compilers/pascal-utils.ts @@ -23,17 +23,17 @@ // POSSIBILITY OF SUCH DAMAGE. export class PascalUtils { - isProgram(source) { + isProgram(source: string) { const re = /\s?program\s+([\w.-]*);/i; return !!re.test(source); } - isUnit(source) { + isUnit(source: string) { const re = /\s?unit\s+([\w.-]*);/i; return !!re.test(source); } - getUnitname(source) { + getUnitname(source: string) { const re = /\s?unit\s+([\w.-]*);/i; const match = source.match(re); if (match) { diff --git a/lib/compilers/pascal-win.js b/lib/compilers/pascal-win.ts similarity index 77% rename from lib/compilers/pascal-win.js rename to lib/compilers/pascal-win.ts index 2c51bb47e72..3d4ef81ebbe 100644 --- a/lib/compilers/pascal-win.js +++ b/lib/compilers/pascal-win.ts @@ -26,6 +26,10 @@ import path from 'path'; import fs from 'fs-extra'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {MapFileReaderDelphi} from '../mapfiles/map-file-delphi'; import {PELabelReconstructor} from '../pe32-support'; @@ -38,23 +42,27 @@ export class PascalWinCompiler extends BaseCompiler { return 'pascal-win'; } - constructor(info, env) { + mapFilename: string | null; + dprFilename: string; + pasUtils: PascalUtils; + + constructor(info: CompilerInfo, env) { super(info, env); info.supportsFiltersInBinary = true; - this.mapFilename = false; + this.mapFilename = null; this.compileFilename = 'output.pas'; this.dprFilename = 'prog.dpr'; this.pasUtils = new PascalUtils(); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - exec(command, args, options) { + override exec(command: string, args: string[], options: ExecutionOptions) { if (process.platform === 'linux' || process.platform === 'darwin') { - const wine = this.env.gccProps('wine'); + const wine = this.env.ceProps('wine'); args = args.slice(0); if (command.toLowerCase().endsWith('.exe')) { @@ -66,15 +74,15 @@ export class PascalWinCompiler extends BaseCompiler { return super.exec(command, args, options); } - getExecutableFilename(dirPath) { + override getExecutableFilename(dirPath: string) { return path.join(dirPath, 'prog.exe'); } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, 'prog.exe'); } - filename(fn) { + override filename(fn) { if (process.platform === 'linux' || process.platform === 'darwin') { return 'Z:' + fn; } else { @@ -82,7 +90,7 @@ export class PascalWinCompiler extends BaseCompiler { } } - async objdump(outputFilename, result, maxSize, intelAsm) { + override async objdump(outputFilename, result, maxSize: number, intelAsm) { const dirPath = path.dirname(outputFilename); const execBinary = this.getExecutableFilename(dirPath); if (await utils.fileExists(execBinary)) { @@ -104,7 +112,7 @@ export class PascalWinCompiler extends BaseCompiler { }); } - async saveDummyProjectFile(filename, unitName, unitPath) { + async saveDummyProjectFile(filename: string, unitName: string, unitPath: string) { await fs.writeFile( filename, // prettier-ignore @@ -115,7 +123,7 @@ export class PascalWinCompiler extends BaseCompiler { ); } - async writeAllFiles(dirPath, source, files, filters) { + override async writeAllFiles(dirPath: string, source: string, files: any[], filters: ParseFiltersAndOutputOptions) { let inputFilename; if (this.pasUtils.isProgram(source)) { inputFilename = path.join(dirPath, this.dprFilename); @@ -139,7 +147,12 @@ export class PascalWinCompiler extends BaseCompiler { }; } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -167,18 +180,20 @@ export class PascalWinCompiler extends BaseCompiler { execOptions.customCwd = tempPath; return this.exec(compiler, options, execOptions).then(result => { - result.inputFilename = inputFilename; - result.stdout = utils.parseOutput(result.stdout, inputFilename); - result.stderr = utils.parseOutput(result.stderr, inputFilename); - return result; + return { + ...result, + inputFilename, + stdout: utils.parseOutput(result.stdout, inputFilename), + stderr: utils.parseOutput(result.stderr, inputFilename), + }; }); } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { filters.binary = true; filters.dontMaskFilenames = true; - filters.preProcessBinaryAsmLines = asmLines => { - const mapFileReader = new MapFileReaderDelphi(this.mapFilename); + (filters as any).preProcessBinaryAsmLines = asmLines => { + const mapFileReader = new MapFileReaderDelphi(unwrap(this.mapFilename)); const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader, false); reconstructor.run('output'); diff --git a/lib/compilers/pascal.js b/lib/compilers/pascal.ts similarity index 78% rename from lib/compilers/pascal.js rename to lib/compilers/pascal.ts index 157755398c5..9e2418dc6d2 100644 --- a/lib/compilers/pascal.js +++ b/lib/compilers/pascal.ts @@ -27,6 +27,10 @@ import path from 'path'; import fs from 'fs-extra'; import _ from 'underscore'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import * as utils from '../utils'; @@ -38,29 +42,36 @@ export class FPCCompiler extends BaseCompiler { return 'pascal'; } - constructor(info, env) { + dprFilename: string; + supportsOptOutput: boolean; + nasmPath: string; + pasUtils: PascalUtils; + demangler: any | null = null; + + constructor(info: CompilerInfo, env) { super(info, env); this.compileFilename = 'output.pas'; this.dprFilename = 'prog.dpr'; this.supportsOptOutput = false; - this.nasmPath = this.compilerProps('nasmpath'); + this.nasmPath = this.compilerProps('nasmpath'); this.pasUtils = new PascalUtils(); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - processAsm(result, filters) { - this.demangler = new this.demanglerClass(null, this); + override processAsm(result, filters) { + // TODO: Pascal doesn't have a demangler exe, it's the only compiler that's weird like this + this.demangler = new (unwrap(this.demanglerClass))(null as any, this); return this.asm.process(result.asm, filters); } - postProcessAsm(result, filters) { + override postProcessAsm(result, filters?: ParseFiltersAndOutputOptions) { if (!result.okToCache) return result; - if (filters.binary) { + if (unwrap(filters).binary) { for (let j = 0; j < result.asm.length; ++j) { this.demangler.addDemangleToCache(result.asm[j].text); } @@ -72,7 +83,7 @@ export class FPCCompiler extends BaseCompiler { return result; } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { let options = ['-g', '-al']; if (this.compiler.intelAsm && filters.intel && !filters.binary) { @@ -88,25 +99,34 @@ export class FPCCompiler extends BaseCompiler { return options; } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.s`); } - getExecutableFilename(dirPath) { + override getExecutableFilename(dirPath: string) { return path.join(dirPath, 'prog'); } - async objdump(outputFilename, result, maxSize, intelAsm, demangle) { + override async objdump( + outputFilename, + result: any, + maxSize: number, + intelAsm, + demangle, + staticReloc: boolean, + dynamicReloc: boolean, + filters: ParseFiltersAndOutputOptions, + ) { const dirPath = path.dirname(outputFilename); const execBinary = this.getExecutableFilename(dirPath); if (await utils.fileExists(execBinary)) { - return super.objdump(execBinary, result, maxSize, intelAsm, demangle); + return super.objdump(execBinary, result, maxSize, intelAsm, demangle, staticReloc, dynamicReloc, filters); } - return super.objdump(outputFilename, result, maxSize, intelAsm, demangle); + return super.objdump(outputFilename, result, maxSize, intelAsm, demangle, staticReloc, dynamicReloc, filters); } - static preProcessBinaryAsm(input) { + static preProcessBinaryAsm(input: string) { const systemInitOffset = input.indexOf(''); const relevantAsmStartsAt = input.indexOf('...', systemInitOffset); if (relevantAsmStartsAt !== -1) { @@ -121,11 +141,11 @@ export class FPCCompiler extends BaseCompiler { return input; } - postProcessObjdumpOutput(output) { + override postProcessObjdumpOutput(output) { return FPCCompiler.preProcessBinaryAsm(output); } - async saveDummyProjectFile(filename, unitName, unitPath) { + async saveDummyProjectFile(filename: string, unitName: string, unitPath: string) { await fs.writeFile( filename, // prettier-ignore @@ -136,7 +156,7 @@ export class FPCCompiler extends BaseCompiler { ); } - async writeAllFiles(dirPath, source, files, filters) { + override async writeAllFiles(dirPath: string, source: string, files: any[], filters: ParseFiltersAndOutputOptions) { let inputFilename; if (this.pasUtils.isProgram(source)) { inputFilename = path.join(dirPath, this.dprFilename); @@ -162,7 +182,12 @@ export class FPCCompiler extends BaseCompiler { }; } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -189,7 +214,7 @@ export class FPCCompiler extends BaseCompiler { return this.parseOutput(await this.exec(compiler, options, execOptions), inputFilename, dirPath); } - parseOutput(result, inputFilename, tempPath) { + parseOutput(result, inputFilename: string, tempPath: string) { const fileWithoutPath = path.basename(inputFilename); result.inputFilename = fileWithoutPath; result.stdout = utils.parseOutput(result.stdout, fileWithoutPath, tempPath); @@ -197,11 +222,11 @@ export class FPCCompiler extends BaseCompiler { return result; } - getArgumentParser() { + override getArgumentParser() { return PascalParser; } - getExtraAsmHint(asm, currentFileId) { + getExtraAsmHint(asm: string, currentFileId: number) { if (asm.startsWith('# [')) { const bracketEndPos = asm.indexOf(']', 3); let valueInBrackets = asm.substr(3, bracketEndPos - 3); @@ -214,7 +239,7 @@ export class FPCCompiler extends BaseCompiler { valueInBrackets = valueInBrackets.substr(1); } - if (isNaN(valueInBrackets)) { + if (Number.isNaN(Number(valueInBrackets))) { return ` .file ${currentFileId} "${valueInBrackets}"`; } else { return ` .loc ${currentFileId} ${valueInBrackets} 0`; @@ -226,7 +251,7 @@ export class FPCCompiler extends BaseCompiler { } } - tryGetFilenumber(asm, files) { + tryGetFilenumber(asm: string, files: Record) { if (asm.startsWith('# [')) { const bracketEndPos = asm.indexOf(']', 3); let valueInBrackets = asm.substr(3, bracketEndPos - 3); @@ -239,7 +264,7 @@ export class FPCCompiler extends BaseCompiler { valueInBrackets = valueInBrackets.substr(1); } - if (isNaN(valueInBrackets)) { + if (Number.isNaN(Number(valueInBrackets))) { if (!files[valueInBrackets]) { let maxFileId = _.max(files); if (maxFileId === -Infinity) { @@ -255,9 +280,9 @@ export class FPCCompiler extends BaseCompiler { return false; } - preProcessLines(asmLines) { + preProcessLines(asmLines: string[]) { let i = 0; - const files = {}; + const files: Record = {}; let currentFileId = 1; while (i < asmLines.length) { diff --git a/lib/compilers/ppci.js b/lib/compilers/ppci.ts similarity index 87% rename from lib/compilers/ppci.js rename to lib/compilers/ppci.ts index 5eac3317d0a..f334f92dad5 100644 --- a/lib/compilers/ppci.js +++ b/lib/compilers/ppci.ts @@ -22,6 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {assert} from '../assert'; import {BaseCompiler} from '../base-compiler'; import * as exec from '../exec'; import {logger} from '../logger'; @@ -33,7 +35,7 @@ export class PPCICompiler extends BaseCompiler { return 'ppci'; } - filterUserOptions(args) { + override filterUserOptions(args: string[]) { return args.filter(item => { if (typeof item !== 'string') return true; @@ -41,9 +43,9 @@ export class PPCICompiler extends BaseCompiler { }); } - exec(compiler, args, options) { + override exec(compiler: string, args: string[], options: ExecutionOptions) { if (compiler.endsWith('.py')) { - const python = this.env.ceProps('python3'); + const python = this.env.ceProps('python3'); options = options || {}; const matches = compiler.match(/^(.*)(\/ppci\/)(.*).py/); @@ -54,7 +56,7 @@ export class PPCICompiler extends BaseCompiler { const python_args = ['-m', ppciName].concat(args); return exec.execute(python, python_args, options); } - logger.error(`Invalid ppci path ${compiler}`); + assert(false, `Invalid ppci path ${compiler}`); } else { return super.exec(compiler, args, options); } diff --git a/lib/compilers/ptxas.js b/lib/compilers/ptxas.ts similarity index 73% rename from lib/compilers/ptxas.js rename to lib/compilers/ptxas.ts index 47a4f80ee06..36aad025200 100644 --- a/lib/compilers/ptxas.js +++ b/lib/compilers/ptxas.ts @@ -24,6 +24,10 @@ import path from 'path'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {ResultLine} from '../../types/resultline/resultline.interfaces'; import {BaseCompiler} from '../base-compiler'; import {SassAsmParser} from '../parsers/asm-parser-sass'; import * as utils from '../utils'; @@ -35,15 +39,15 @@ export class PtxAssembler extends BaseCompiler { return 'ptxas'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compileFilename = 'example.ptxas'; this.asm = new SassAsmParser(); } - parsePtxOutput(lines, inputFilename, pathPrefix) { + parsePtxOutput(lines: string, inputFilename: string, pathPrefix: string) { const re = /^ptxas\s*, line (\d+);(.*)/; - const result = []; + const result: ResultLine[] = []; utils.eachLine(lines, function (line) { if (pathPrefix) line = line.replace(pathPrefix, ''); if (inputFilename) { @@ -55,11 +59,12 @@ export class PtxAssembler extends BaseCompiler { } } if (line !== null) { - const lineObj = {text: line}; + const lineObj: ResultLine = {text: line}; const match = line.replace(/\x1B\[[\d;]*[Km]/g, '').match(re); if (match) { lineObj.text = `:${match[1]} ${match[2].trim()}`; lineObj.tag = { + severity: 0, line: parseInt(match[1]), column: 0, text: match[2].trim(), @@ -71,20 +76,25 @@ export class PtxAssembler extends BaseCompiler { return result; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - getArgumentParser() { + override getArgumentParser() { return BaseParser; } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { filters.binary = true; return []; } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -93,21 +103,23 @@ export class PtxAssembler extends BaseCompiler { execOptions.customCwd = path.dirname(inputFilename); const result = await this.exec(compiler, options, execOptions); - result.inputFilename = inputFilename; - result.stdout = this.parsePtxOutput(result.stdout, './' + this.compileFilename); - result.stderr = this.parsePtxOutput(result.stderr, './' + this.compileFilename); - return result; + return { + ...result, + inputFilename, + stdout: this.parsePtxOutput(result.stdout, './' + this.compileFilename, 'no idea what to put here'), + stderr: this.parsePtxOutput(result.stderr, './' + this.compileFilename, 'no idea what to put here'), + }; } - getOutputFilename(dirPath, outputFilebase) { + override getOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.cubin`); } - checkOutputFileAndDoPostProcess(asmResult, outputFilename, filters) { + override checkOutputFileAndDoPostProcess(asmResult, outputFilename, filters: ParseFiltersAndOutputOptions) { return this.postProcess(asmResult, outputFilename, filters); } - async objdump(outputFilename, result, maxSize) { + override async objdump(outputFilename, result: any, maxSize: number) { const dirPath = path.dirname(outputFilename); const args = ['-c', '-g', '-hex', outputFilename]; const objResult = await this.exec(this.compiler.objdumper, args, {maxOutput: maxSize, customCwd: dirPath}); diff --git a/lib/compilers/python.ts b/lib/compilers/python.ts index eaf1092d715..ebfca451f44 100644 --- a/lib/compilers/python.ts +++ b/lib/compilers/python.ts @@ -23,6 +23,8 @@ // POSSIBILITY OF SUCH DAMAGE. import {AsmResultSource, ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {resolvePathFromAppRoot} from '../utils'; @@ -35,7 +37,7 @@ export class PythonCompiler extends BaseCompiler { return 'python'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.compiler.demangler = ''; this.demanglerClass = null; @@ -73,7 +75,7 @@ export class PythonCompiler extends BaseCompiler { return {asm: bytecodeResult}; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return ['-I', this.disasmScriptPath, '--outputfile', outputFilename, '--inputfile']; } diff --git a/lib/compilers/racket.ts b/lib/compilers/racket.ts index f67275eb45f..6ef9c8ad502 100644 --- a/lib/compilers/racket.ts +++ b/lib/compilers/racket.ts @@ -25,6 +25,7 @@ import path from 'path'; import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {logger} from '../logger'; @@ -36,7 +37,7 @@ export class RacketCompiler extends BaseCompiler { return 'racket'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { // Disable output filters, as they currently don't do anything if (!info.disabledFilters) { info.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim']; diff --git a/lib/compilers/ruby.ts b/lib/compilers/ruby.ts index d84f6025acb..99f54931866 100644 --- a/lib/compilers/ruby.ts +++ b/lib/compilers/ruby.ts @@ -24,6 +24,8 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {resolvePathFromAppRoot} from '../utils'; @@ -36,7 +38,7 @@ export class RubyCompiler extends BaseCompiler { return 'ruby'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.disasmScriptPath = this.compilerProps('disasmScript') || resolvePathFromAppRoot('etc', 'scripts', 'disasms', 'disasm.rb'); @@ -81,7 +83,7 @@ export class RubyCompiler extends BaseCompiler { return {asm: bytecodeResult}; } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return [ this.disasmScriptPath, '--outputfile', diff --git a/lib/compilers/rust.ts b/lib/compilers/rust.ts index 0fbce4e0c2e..1507fcc4049 100644 --- a/lib/compilers/rust.ts +++ b/lib/compilers/rust.ts @@ -26,8 +26,10 @@ import path from 'path'; import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {BasicExecutionResult, UnprocessedExecResult} from '../../types/execution/execution.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; import {BuildEnvDownloadInfo} from '../buildenvsetup/buildenv.interfaces'; import {parseRustOutput} from '../utils'; @@ -41,7 +43,7 @@ export class RustCompiler extends BaseCompiler { return 'rust'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; this.compiler.supportsIrView = true; @@ -65,7 +67,7 @@ export class RustCompiler extends BaseCompiler { return []; } - override getSharedLibraryLinks(libraries): string[] { + override getSharedLibraryLinks(libraries: any[]): string[] { return []; } @@ -87,21 +89,21 @@ export class RustCompiler extends BaseCompiler { } override orderArguments( - options, - inputFilename, - libIncludes, - libOptions, - libPaths, - libLinks, - userOptions, - staticLibLinks, + options: string[], + inputFilename: string, + libIncludes: string[], + libOptions: string[], + libPaths: string[], + libLinks: string[], + userOptions: string[], + staticLibLinks: string[], ) { return options.concat(userOptions, libIncludes, libOptions, libPaths, libLinks, staticLibLinks, [ this.filename(inputFilename), ]); } - override async setupBuildEnvironment(key, dirPath): Promise { + override async setupBuildEnvironment(key: any, dirPath: string): Promise { if (this.buildenvsetup) { const libraryDetails = await this.getRequiredLibraryVersions(key.libraries); return this.buildenvsetup.setup(key, dirPath, libraryDetails); @@ -117,7 +119,7 @@ export class RustCompiler extends BaseCompiler { return options; } - override optionsForBackend(backendOptions, outputFilename) { + override optionsForBackend(backendOptions: Record, outputFilename: string) { // The super class handles the GCC dump files that may be needed by // rustc-cg-gcc subclass. const opts = super.optionsForBackend(backendOptions, outputFilename); @@ -129,10 +131,10 @@ export class RustCompiler extends BaseCompiler { return opts; } - override optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { let options = ['-C', 'debuginfo=1', '-o', this.filename(outputFilename)]; - const userRequestedEmit = _.any(userOptions, opt => opt.includes('--emit')); + const userRequestedEmit = _.any(unwrap(userOptions), opt => opt.includes('--emit')); if (filters.binary) { options = options.concat(['--crate-type', 'bin']); if (this.linker) { diff --git a/lib/compilers/rustc-cg-gcc.js b/lib/compilers/rustc-cg-gcc.ts similarity index 86% rename from lib/compilers/rustc-cg-gcc.js rename to lib/compilers/rustc-cg-gcc.ts index ed2d3e6d82c..6c01408d764 100644 --- a/lib/compilers/rustc-cg-gcc.js +++ b/lib/compilers/rustc-cg-gcc.ts @@ -24,14 +24,17 @@ import path from 'path'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {RustCompiler} from './rust'; export class RustcCgGCCCompiler extends RustCompiler { - static get key() { + static override get key() { return 'rustc-cg-gcc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIrView = false; @@ -47,11 +50,11 @@ export class RustcCgGCCCompiler extends RustCompiler { this.compiler.removeEmptyGccDump = false; } - getGccDumpOptions(gccDumpOptions, removeEmptyPasses) { - return ['-C', 'llvm-args=' + super.getGccDumpOptions(gccDumpOptions, removeEmptyPasses).join(' ')]; + override getGccDumpOptions(gccDumpOptions, outputFilename: string) { + return ['-C', 'llvm-args=' + super.getGccDumpOptions(gccDumpOptions, outputFilename).join(' ')]; } - optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { // these options are direcly taken from rustc_codegen_gcc doc. // See https://github.com/antoyo/rustc_codegen_gcc const toolroot = path.resolve(path.dirname(this.compiler.exe), '..'); diff --git a/lib/compilers/scala.js b/lib/compilers/scala.ts similarity index 82% rename from lib/compilers/scala.js rename to lib/compilers/scala.ts index d7acbf3019d..ce2ac3b29fa 100644 --- a/lib/compilers/scala.js +++ b/lib/compilers/scala.ts @@ -24,22 +24,26 @@ import Semver from 'semver'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {asSafeVer} from '../utils'; import {ScalaParser} from './argument-parsers'; import {JavaCompiler} from './java'; export class ScalaCompiler extends JavaCompiler { - static get key() { + static override get key() { return 'scala'; } - constructor(compilerInfo, env) { + javaHome: string; + + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); - this.javaHome = this.compilerProps(`compiler.${this.compiler.id}.java_home`); + this.javaHome = this.compilerProps(`compiler.${this.compiler.id}.java_home`); } - getDefaultExecOptions() { + override getDefaultExecOptions() { const execOptions = super.getDefaultExecOptions(); if (this.javaHome) { execOptions.env.JAVA_HOME = this.javaHome; @@ -48,7 +52,7 @@ export class ScalaCompiler extends JavaCompiler { return execOptions; } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions: string[]) { // filter options without extra arguments userOptions = userOptions.filter(option => option !== '-Xscript'); @@ -62,7 +66,7 @@ export class ScalaCompiler extends JavaCompiler { return super.filterUserOptionsWithArg(userOptions, oneArgForbiddenList); } - optionsForFilter(filters) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions) { // Forcibly enable javap filters.binary = true; @@ -73,7 +77,7 @@ export class ScalaCompiler extends JavaCompiler { return Semver.gte(asSafeVer(this.compiler.semver), '3.0.0', true) ? scala3Opts : scala2Opts; } - getArgumentParser() { + override getArgumentParser() { return ScalaParser; } } diff --git a/lib/compilers/sdcc.js b/lib/compilers/sdcc.ts similarity index 88% rename from lib/compilers/sdcc.js rename to lib/compilers/sdcc.ts index ba0ddfc8451..8b9ca3343a8 100644 --- a/lib/compilers/sdcc.js +++ b/lib/compilers/sdcc.ts @@ -22,14 +22,16 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {GCCCompiler} from './gcc'; export class SdccCompiler extends GCCCompiler { - static get key() { + static override get key() { return 'sdcc'; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = ['-o', this.filename(outputFilename)]; if (!filters.binary) options = options.concat('-S'); return options; diff --git a/lib/compilers/solidity.js b/lib/compilers/solidity.ts similarity index 96% rename from lib/compilers/solidity.js rename to lib/compilers/solidity.ts index 8577bfca829..09d32a748e0 100644 --- a/lib/compilers/solidity.js +++ b/lib/compilers/solidity.ts @@ -37,15 +37,15 @@ export class SolidityCompiler extends BaseCompiler { return 'solidity'; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } - optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter() { return [ // We use --combined-json instead of `--asm-json` to have compacted json '--combined-json', @@ -57,15 +57,15 @@ export class SolidityCompiler extends BaseCompiler { ]; } - isCfgCompiler(/*compilerVersion*/) { + override isCfgCompiler(/*compilerVersion*/) { return false; } - getOutputFilename(dirPath) { + override getOutputFilename(dirPath: string) { return path.join(dirPath, 'contracts/combined.json'); } - processAsm(result) { + override processAsm(result) { // Handle "error" documents. if (!result.asm.includes('\n') && result.asm[0] === '<') { return {asm: [{text: result.asm}]}; @@ -88,7 +88,7 @@ export class SolidityCompiler extends BaseCompiler { const asm = JSON.parse(result.asm); return { - asm: Object.entries(asm.contracts) + asm: (Object.entries(asm.contracts) as [string, any][]) .sort(([_name1, data1], [_name2, data2]) => data1.asm['.code'][0].begin - data2.asm['.code'][0].begin) .map(([name, data]) => { // name is in the format of file:contract @@ -264,7 +264,7 @@ export class SolidityCompiler extends BaseCompiler { {text: ''}, // .data section is deployed bytecode - everything else {text: '.data'}, - Object.entries(data.asm['.data']).map(([id, {'.code': code}]) => [ + (Object.entries(data.asm['.data']) as [string, any][]).map(([id, {'.code': code}]) => [ {text: `\t${id}:`}, processOpcodes(code, '\t', generatedSourcesRuntime), ]), diff --git a/lib/compilers/spirv.ts b/lib/compilers/spirv.ts index b94fd638d69..24d0f946bdc 100644 --- a/lib/compilers/spirv.ts +++ b/lib/compilers/spirv.ts @@ -26,6 +26,9 @@ import path from 'path'; import _ from 'underscore'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {logger} from '../logger'; import {SPIRVAsmParser} from '../parsers/asm-parser-spirv'; @@ -39,7 +42,7 @@ export class SPIRVCompiler extends BaseCompiler { return 'spirv'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.asm = new SPIRVAsmParser(this.compilerProps); @@ -48,7 +51,14 @@ export class SPIRVCompiler extends BaseCompiler { this.disassemblerPath = this.compilerProps('disassemblerPath'); } - override prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) { + override prepareArguments( + userOptions: string[], + filters: ParseFiltersAndOutputOptions, + backendOptions: Record, + inputFilename: string, + outputFilename: string, + libraries, + ) { let options = this.optionsForFilter(filters, outputFilename); backendOptions = backendOptions || {}; @@ -89,21 +99,26 @@ export class SPIRVCompiler extends BaseCompiler { ); } - override optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { const sourceDir = path.dirname(outputFilename); const bitcodeFilename = path.join(sourceDir, this.outputFilebase + '.bc'); return ['-cc1', '-debug-info-kind=limited', '-dwarf-version=5', '-debugger-tuning=gdb', '-o', bitcodeFilename]; } - getPrimaryOutputFilename(dirPath, outputFilebase) { + getPrimaryOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.bc`); } - override getOutputFilename(dirPath, outputFilebase) { + override getOutputFilename(dirPath: string, outputFilebase: string) { return path.join(dirPath, `${outputFilebase}.spvasm`); } - override async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { const sourceDir = path.dirname(inputFilename); const bitcodeFilename = path.join(sourceDir, this.outputFilebase + '.bc'); @@ -146,7 +161,12 @@ export class SPIRVCompiler extends BaseCompiler { return result; } - async runCompilerForASTOrIR(compiler, options, inputFilename, execOptions) { + async runCompilerForASTOrIR( + compiler: string, + options: any[], + inputFilename: string, + execOptions: ExecutionOptions, + ) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -178,7 +198,7 @@ export class SPIRVCompiler extends BaseCompiler { ); } - override async generateIR(inputFilename, options, filters) { + override async generateIR(inputFilename: string, options: string[], filters: ParseFiltersAndOutputOptions) { const newOptions = _.filter(options, option => option !== '-fcolor-diagnostics').concat('-emit-llvm'); const execOptions = this.getDefaultExecOptions(); diff --git a/lib/compilers/swift.js b/lib/compilers/swift.ts similarity index 92% rename from lib/compilers/swift.js rename to lib/compilers/swift.ts index 437099b2bc6..6baced4ff43 100644 --- a/lib/compilers/swift.js +++ b/lib/compilers/swift.ts @@ -31,15 +31,15 @@ export class SwiftCompiler extends BaseCompiler { return 'swift'; } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } - isCfgCompiler(/*compilerVersion*/) { + override isCfgCompiler(/*compilerVersion*/) { return true; } } diff --git a/lib/compilers/tendra.js b/lib/compilers/tendra.ts similarity index 88% rename from lib/compilers/tendra.js rename to lib/compilers/tendra.ts index 46ba97c3e02..ab0d8b3e3ae 100644 --- a/lib/compilers/tendra.js +++ b/lib/compilers/tendra.ts @@ -22,14 +22,16 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; + import {GCCCompiler} from './gcc'; export class TenDRACompiler extends GCCCompiler { - static get key() { + static override get key() { return 'tendra'; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { let options = ['-o', this.filename(outputFilename)]; if (!filters.binary) options = options.concat('-S'); return options; diff --git a/lib/compilers/tinyc.js b/lib/compilers/tinyc.ts similarity index 79% rename from lib/compilers/tinyc.js rename to lib/compilers/tinyc.ts index f92733b087a..c5fcdfb6cba 100644 --- a/lib/compilers/tinyc.js +++ b/lib/compilers/tinyc.ts @@ -24,6 +24,8 @@ import _ from 'underscore'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; +import {unwrap} from '../assert'; import {BaseCompiler} from '../base-compiler'; export class TinyCCompiler extends BaseCompiler { @@ -31,18 +33,18 @@ export class TinyCCompiler extends BaseCompiler { return 'tinyc'; } - optionsForFilter(filters, outputFilename, userOptions) { - if (_.some(userOptions, opt => opt === '--help' || opt === '-h' || opt === '-hh')) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { + if (_.some(unwrap(userOptions), opt => opt === '--help' || opt === '-h' || opt === '-hh')) { return []; } else { - if (!_.some(userOptions, opt => opt === '-E')) { + if (!_.some(unwrap(userOptions), opt => opt === '-E')) { filters.binary = true; } return ['-g', '-o', this.filename(outputFilename)]; } } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions) { return _.filter(userOptions, opt => opt !== '-run'); } } diff --git a/lib/compilers/toit.ts b/lib/compilers/toit.ts index 84b1f231422..258f4e50049 100644 --- a/lib/compilers/toit.ts +++ b/lib/compilers/toit.ts @@ -24,6 +24,7 @@ import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -34,7 +35,7 @@ export class ToitCompiler extends BaseCompiler { return 'toit'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; } diff --git a/lib/compilers/typescript-native.js b/lib/compilers/typescript-native.ts similarity index 70% rename from lib/compilers/typescript-native.js rename to lib/compilers/typescript-native.ts index 4dd239c1c20..4debc288c0e 100644 --- a/lib/compilers/typescript-native.js +++ b/lib/compilers/typescript-native.ts @@ -22,6 +22,9 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {TypeScriptNativeParser} from './argument-parsers'; @@ -31,25 +34,28 @@ export class TypeScriptNativeCompiler extends BaseCompiler { return 'typescript'; } - constructor(compilerInfo, env) { + tscJit: string; + tscSharedLib: string; + + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.compiler.supportsIntel = false; this.compiler.supportsIrView = true; - this.tscJit = this.compilerProps(`compiler.${this.compiler.id}.exe`); - this.tscSharedLib = this.compilerProps(`compiler.${this.compiler.id}.sharedlibs`); + this.tscJit = this.compilerProps(`compiler.${this.compiler.id}.exe`); + this.tscSharedLib = this.compilerProps(`compiler.${this.compiler.id}.sharedlibs`); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { return [this.filename(outputFilename)]; } - async handleInterpreting(key, executeParameters) { + override async handleInterpreting(key, executeParameters) { executeParameters.args = [ '--emit=jit', this.tscSharedLib ? '--shared-libs=' + this.tscSharedLib : '-nogc', @@ -59,7 +65,12 @@ export class TypeScriptNativeCompiler extends BaseCompiler { return await super.handleInterpreting(key, executeParameters); } - async runCompiler(compiler, options, inputFilename, execOptions) { + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ): Promise { // These options make Clang produce an IR const newOptions = ['--emit=mlir-llvm', inputFilename]; @@ -74,13 +85,22 @@ export class TypeScriptNativeCompiler extends BaseCompiler { execOptions, ); if (output.code !== 0) { - return [{text: 'Failed to run compiler to get MLIR code'}]; + return { + code: output.code, + timedOut: false, + stdout: [], + stderr: [ + { + text: 'Failed to run compiler to get MLIR code', + }, + ], + }; } - return {code: 0}; + return {code: 0, timedOut: false, stdout: [], stderr: []}; } - async generateIR(inputFilename, options, filters) { + override async generateIR(inputFilename: string, options: string[], filters: ParseFiltersAndOutputOptions) { // These options make Clang produce an IR const newOptions = ['--emit=llvm', inputFilename]; @@ -110,11 +130,11 @@ export class TypeScriptNativeCompiler extends BaseCompiler { return ir.asm; } - isCfgCompiler() { + override isCfgCompiler() { return true; } - getArgumentParser() { + override getArgumentParser() { return TypeScriptNativeParser; } } diff --git a/lib/compilers/win32-vc.js b/lib/compilers/win32-vc.ts similarity index 90% rename from lib/compilers/win32-vc.js rename to lib/compilers/win32-vc.ts index e5d13662e15..be16a2875e6 100644 --- a/lib/compilers/win32-vc.js +++ b/lib/compilers/win32-vc.ts @@ -22,22 +22,23 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; import {VcAsmParser} from '../parsers/asm-parser-vc'; import {VCParser} from './argument-parsers'; import {Win32Compiler} from './win32'; export class Win32VcCompiler extends Win32Compiler { - static get key() { + static override get key() { return 'win32-vc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new VcAsmParser(this.compilerProps); } - getArgumentParser() { + override getArgumentParser() { return VCParser; } } diff --git a/lib/compilers/win32-vc6.js b/lib/compilers/win32-vc6.ts similarity index 91% rename from lib/compilers/win32-vc6.js rename to lib/compilers/win32-vc6.ts index c835394d1a4..1f07c7aebae 100644 --- a/lib/compilers/win32-vc6.js +++ b/lib/compilers/win32-vc6.ts @@ -22,22 +22,23 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import {CompilerInfo} from '../../types/compiler.interfaces'; import {Vc6AsmParser} from '../parsers/asm-parser-vc6'; import {VCParser} from './argument-parsers'; import {Win32Compiler} from './win32'; export class Win32Vc6Compiler extends Win32Compiler { - static get key() { + static override get key() { return 'win32-vc6'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new Vc6AsmParser(this.compilerProps); } - getArgumentParser() { + override getArgumentParser() { return VCParser; } } diff --git a/lib/compilers/win32.js b/lib/compilers/win32.ts similarity index 75% rename from lib/compilers/win32.js rename to lib/compilers/win32.ts index dca1508541c..42bf2f67a94 100644 --- a/lib/compilers/win32.js +++ b/lib/compilers/win32.ts @@ -27,6 +27,9 @@ import path from 'path'; import temp from 'temp'; import _ from 'underscore'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {MapFileReaderVS} from '../mapfiles/map-file-vs'; import {AsmParser} from '../parsers/asm-parser'; @@ -38,14 +41,16 @@ export class Win32Compiler extends BaseCompiler { return 'win32'; } - constructor(compilerInfo, env) { + binaryAsmParser: AsmParser; + + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.binaryAsmParser = new AsmParser(this.compilerProps); } - newTempDir() { - return new Promise((resolve, reject) => { + override newTempDir() { + return new Promise((resolve, reject) => { temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.TMP}, (err, dirPath) => { if (err) reject(`Unable to open temp file: ${err}`); else resolve(dirPath); @@ -53,44 +58,46 @@ export class Win32Compiler extends BaseCompiler { }); } - getExecutableFilename(dirPath, outputFilebase) { + override getExecutableFilename(dirPath: string, outputFilebase: string) { return this.getOutputFilename(dirPath, outputFilebase) + '.exe'; } - getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string) { return this.getExecutableFilename(path.dirname(defaultOutputFilename), 'output'); } - getSharedLibraryPathsAsArguments(libraries) { + override getSharedLibraryPathsAsArguments(libraries) { const libPathFlag = this.compiler.libpathFlag || '/LIBPATH:'; return this.getSharedLibraryPaths(libraries).map(path => libPathFlag + path); } - getSharedLibraryLinks(libraries) { + override getSharedLibraryLinks(libraries: any[]): string[] { return _.flatten( - _.map(libraries, selectedLib => { - const foundVersion = this.findLibVersion(selectedLib); - if (!foundVersion) return false; - - return _.map(foundVersion.liblink, lib => { - if (lib) { - return '"' + lib + '.lib"'; - } else { - return false; - } - }); - }), + libraries + .map(selectedLib => [selectedLib, this.findLibVersion(selectedLib)]) + .filter(([selectedLib, foundVersion]) => !!foundVersion) + .map(([selectedLib, foundVersion]) => { + return foundVersion.liblink.filter(Boolean).map(lib => `"${lib}.lib"`); + }) + .map(([selectedLib, foundVersion]) => selectedLib), ); } - getStaticLibraryLinks(libraries) { + override getStaticLibraryLinks(libraries) { return _.map(super.getSortedStaticLibraries(libraries), lib => { return '"' + lib + '.lib"'; }); } - prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) { + override prepareArguments( + userOptions: string[], + filters: ParseFiltersAndOutputOptions, + backendOptions: Record, + inputFilename: string, + outputFilename: string, + libraries, + ) { let options = this.optionsForFilter(filters, outputFilename, userOptions); backendOptions = backendOptions || {}; @@ -104,10 +111,10 @@ export class Win32Compiler extends BaseCompiler { const libIncludes = this.getIncludeArguments(libraries); const libOptions = this.getLibraryOptions(libraries); - let libLinks = []; - let libPaths = []; - let preLink = []; - let staticlibLinks = []; + let libLinks: any[] = []; + let libPaths: string[] = []; + let preLink: string[] = []; + let staticlibLinks: string[] = []; if (filters.binary) { preLink = ['/link']; @@ -129,12 +136,12 @@ export class Win32Compiler extends BaseCompiler { ); } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) { if (filters.binary) { const mapFilename = outputFilename + '.map'; const mapFileReader = new MapFileReaderVS(mapFilename); - filters.preProcessBinaryAsmLines = asmLines => { + (filters as any).preProcessBinaryAsmLines = asmLines => { const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader); reconstructor.run('output.s.obj'); @@ -160,7 +167,7 @@ export class Win32Compiler extends BaseCompiler { } } - processAsm(result, filters /*, options*/) { + override processAsm(result, filters /*, options*/) { if (filters.binary) { filters.dontMaskFilenames = true; return this.binaryAsmParser.process(result.asm, filters); @@ -169,7 +176,7 @@ export class Win32Compiler extends BaseCompiler { } } - exec(compiler, args, options_) { + override exec(compiler: string, args: string[], options_: ExecutionOptions) { const options = Object.assign({}, options_); options.env = Object.assign({}, options.env); diff --git a/lib/compilers/wine-vc.js b/lib/compilers/wine-vc.ts similarity index 81% rename from lib/compilers/wine-vc.js rename to lib/compilers/wine-vc.ts index be60b94d7ed..6623a6bd754 100644 --- a/lib/compilers/wine-vc.js +++ b/lib/compilers/wine-vc.ts @@ -24,6 +24,9 @@ import path from 'path'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {MapFileReaderVS} from '../mapfiles/map-file-vs'; import {VcAsmParser} from '../parsers/asm-parser-vc'; @@ -36,17 +39,17 @@ export class WineVcCompiler extends BaseCompiler { return 'wine-vc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { info.supportsFiltersInBinary = true; super(info, env); this.asm = new VcAsmParser(); } - filename(fn) { + override filename(fn: string) { return 'Z:' + fn; } - runCompiler(compiler, options, inputFilename, execOptions) { + override runCompiler(compiler: string, options: string[], inputFilename: string, execOptions: ExecutionOptions) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } @@ -59,28 +62,28 @@ export class WineVcCompiler extends BaseCompiler { return super.runCompiler(compiler, options, inputFilename, execOptions); } - getArgumentParser() { + override getArgumentParser() { return VCParser; } - getExecutableFilename(dirPath, outputFilebase) { + override getExecutableFilename(dirPath: string, outputFilebase: string) { return this.getOutputFilename(dirPath, outputFilebase) + '.exe'; } - getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string) { return this.getExecutableFilename(path.dirname(defaultOutputFilename), 'output'); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename) { + override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) { if (filters.binary) { const mapFilename = outputFilename + '.map'; const mapFileReader = new MapFileReaderVS(mapFilename); - filters.preProcessBinaryAsmLines = asmLines => { + (filters as any).preProcessBinaryAsmLines = asmLines => { const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader); reconstructor.run('output.s.obj'); diff --git a/lib/compilers/wsl-vc.js b/lib/compilers/wsl-vc.ts similarity index 81% rename from lib/compilers/wsl-vc.js rename to lib/compilers/wsl-vc.ts index aeed39143be..2ef9a746246 100644 --- a/lib/compilers/wsl-vc.js +++ b/lib/compilers/wsl-vc.ts @@ -29,34 +29,37 @@ import path from 'path'; import temp from 'temp'; +import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; +import {unwrap} from '../assert'; import {VcAsmParser} from '../parsers/asm-parser-vc'; import {Win32VcCompiler} from './win32-vc'; export class WslVcCompiler extends Win32VcCompiler { - static get key() { + static override get key() { return 'wsl-vc'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.asm = new VcAsmParser(); } - filename(fn) { + override filename(fn: string) { // AP: Need to translate compiler paths from what the Node.js process sees // on a Unix mounted volume (/mnt/c/tmp) to what CL sees on Windows (c:/tmp) // We know process.env.tmpDir is of format /mnt/X/dir where X is drive letter. - const driveLetter = process.env.winTmp.substring(5, 6); - const directoryPath = process.env.winTmp.substring(7); + const driveLetter = unwrap(process.env.winTmp).substring(5, 6); + const directoryPath = unwrap(process.env.winTmp).substring(7); const windowsStyle = driveLetter.concat(':/', directoryPath); - return fn.replace(process.env.winTmp, windowsStyle); + return fn.replace(unwrap(process.env.winTmp), windowsStyle); } // AP: Create CE temp directory in winTmp directory instead of the tmpDir directory. // NPM temp package: https://www.npmjs.com/package/temp, see Affixes - newTempDir() { - return new Promise((resolve, reject) => { + override newTempDir() { + return new Promise((resolve, reject) => { temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.winTmp}, (err, dirPath) => { if (err) reject(`Unable to open temp file: ${err}`); else resolve(dirPath); @@ -64,7 +67,7 @@ export class WslVcCompiler extends Win32VcCompiler { }); } - exec(compiler, args, options_) { + override exec(compiler: string, args: string[], options_: ExecutionOptions) { const options = Object.assign({}, options_); options.env = Object.assign({}, options.env); @@ -79,7 +82,7 @@ export class WslVcCompiler extends Win32VcCompiler { return super.exec(compiler, args, options); } - runCompiler(compiler, options, inputFilename, execOptions) { + override runCompiler(compiler: string, options: string[], inputFilename: string, execOptions: ExecutionOptions) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } diff --git a/lib/compilers/z88dk.ts b/lib/compilers/z88dk.ts index 15f438d55cc..0459193815a 100644 --- a/lib/compilers/z88dk.ts +++ b/lib/compilers/z88dk.ts @@ -27,6 +27,7 @@ import path from 'path'; import fs from 'fs-extra'; import {ExecutionOptions} from '../../types/compilation/compilation.interfaces'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {ArtifactType} from '../../types/tool.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -39,7 +40,7 @@ export class z88dkCompiler extends BaseCompiler { return 'z88dk'; } - constructor(compilerInfo, env) { + constructor(compilerInfo: CompilerInfo, env) { super(compilerInfo, env); this.outputFilebase = 'example'; this.asm = new AsmParserZ88dk(this.compilerProps); @@ -63,14 +64,14 @@ export class z88dkCompiler extends BaseCompiler { } public override orderArguments( - options, - inputFilename, - libIncludes, - libOptions, - libPaths, - libLinks, - userOptions, - staticLibLinks, + options: string[], + inputFilename: string, + libIncludes: string[], + libOptions: string[], + libPaths: string[], + libLinks: string[], + userOptions: string[], + staticLibLinks: string[], ) { return userOptions.concat( options, @@ -99,7 +100,7 @@ export class z88dkCompiler extends BaseCompiler { return opts; } - override getObjdumpOutputFilename(defaultOutputFilename) { + override getObjdumpOutputFilename(defaultOutputFilename: string) { return defaultOutputFilename; } @@ -117,8 +118,8 @@ export class z88dkCompiler extends BaseCompiler { maxSize: number, intelAsm, demangle, - staticReloc, - dynamicReloc, + staticReloc: boolean, + dynamicReloc: boolean, filters: ParseFiltersAndOutputOptions, ) { outputFilename = this.getObjdumpOutputFilename(outputFilename); diff --git a/lib/compilers/zig.ts b/lib/compilers/zig.ts index 4862e8c87f4..abd304f5bb4 100644 --- a/lib/compilers/zig.ts +++ b/lib/compilers/zig.ts @@ -27,6 +27,7 @@ import path from 'path'; import Semver from 'semver'; import _ from 'underscore'; +import {CompilerInfo} from '../../types/compiler.interfaces'; import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {SelectedLibraryVersion} from '../../types/libraries/libraries.interfaces'; import {BaseCompiler} from '../base-compiler'; @@ -39,7 +40,7 @@ export class ZigCompiler extends BaseCompiler { return 'zig'; } - constructor(info, env) { + constructor(info: CompilerInfo, env) { super(info, env); this.compiler.supportsIntel = true; this.compiler.supportsIrView = true; diff --git a/lib/handlers/compile.ts b/lib/handlers/compile.ts index 517a5325654..8ae81243d81 100644 --- a/lib/handlers/compile.ts +++ b/lib/handlers/compile.ts @@ -34,6 +34,7 @@ import _ from 'underscore'; import which from 'which'; import {ICompiler} from '../../types/compiler.interfaces'; +import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; import {CompilationEnvironment} from '../compilation-env'; import {getCompilerTypeByKey} from '../compilers'; @@ -86,7 +87,7 @@ type ParsedRequest = { source: string; options: string[]; backendOptions: Record; - filters: Record; + filters: ParseFiltersAndOutputOptions; bypassCache: boolean; tools: any; executionParameters: ExecutionParams; @@ -335,7 +336,7 @@ export class CompileHandler { let source: string, options: string, backendOptions: Record = {}, - filters: Record, + filters: ParseFiltersAndOutputOptions, bypassCache = false, tools; const execReqParams: ExecutionRequestParams = {}; @@ -378,10 +379,9 @@ export class CompileHandler { filters = compiler.getDefaultFilters(); // If specified exactly, we'll take that with ?filters=a,b,c if (query.filters) { - filters = _.object(_.map(query.filters.split(','), filter => [filter, true])) as Record< - string, - boolean - >; + filters = _.object( + _.map(query.filters.split(','), filter => [filter, true]), + ) as any as ParseFiltersAndOutputOptions; } // Add a filter. ?addFilters=binary _.each((query.addFilters || '').split(','), filter => { diff --git a/lib/parsers/asm-parser-sass.js b/lib/parsers/asm-parser-sass.js index e970a0d0266..1bf5ac33301 100644 --- a/lib/parsers/asm-parser-sass.js +++ b/lib/parsers/asm-parser-sass.js @@ -25,8 +25,8 @@ import {AsmParser} from './asm-parser'; export class SassAsmParser extends AsmParser { - constructor() { - super(); + constructor(compilerProps) { + super(compilerProps); // These are for parsing the output of nvdisasm. this.asmOpcodeRe = diff --git a/package-lock.json b/package-lock.json index 20e789d3a4e..41e4ac4fa04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@types/http-proxy": "^1.17.9", "@types/js-cookie": "^3.0.2", "@types/request": "^2.48.8", + "@types/temp": "^0.9.1", "aws-sdk": "^2.1048.0", "big-integer": "^1.6.51", "body-parser": "^1.19.1", @@ -1999,6 +2000,14 @@ "@types/node": "*" } }, + "node_modules/@types/temp": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/temp/-/temp-0.9.1.tgz", + "integrity": "sha512-yDQ8Y+oQi9V7VkexwE6NBSVyNuyNFeGI275yWXASc2DjmxNicMi9O50KxDpNlST1kBbV9jKYBHGXhgNYFMPqtA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", @@ -17019,6 +17028,14 @@ "@types/node": "*" } }, + "@types/temp": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/temp/-/temp-0.9.1.tgz", + "integrity": "sha512-yDQ8Y+oQi9V7VkexwE6NBSVyNuyNFeGI275yWXASc2DjmxNicMi9O50KxDpNlST1kBbV9jKYBHGXhgNYFMPqtA==", + "requires": { + "@types/node": "*" + } + }, "@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", diff --git a/package.json b/package.json index 3461bf74d85..b1d14b2f37d 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@types/http-proxy": "^1.17.9", "@types/js-cookie": "^3.0.2", "@types/request": "^2.48.8", + "@types/temp": "^0.9.1", "aws-sdk": "^2.1048.0", "big-integer": "^1.6.51", "body-parser": "^1.19.1", diff --git a/types/asmresult/asmresult.interfaces.ts b/types/asmresult/asmresult.interfaces.ts index 908f212ad0b..36036783177 100644 --- a/types/asmresult/asmresult.interfaces.ts +++ b/types/asmresult/asmresult.interfaces.ts @@ -37,7 +37,8 @@ export type ParsedAsmResult = { parsingTime?: string; filteredCount?: number; externalParserUsed?: boolean; - objdumpTime?: number; + // TODO(#4655) A few compilers seem to assign strings here. It might be ok but we should look into it more. + objdumpTime?: number | string; execTime?: string; languageId?: string; }; diff --git a/types/compiler.interfaces.ts b/types/compiler.interfaces.ts index 1d856b4dbbe..f1f0891861c 100644 --- a/types/compiler.interfaces.ts +++ b/types/compiler.interfaces.ts @@ -108,6 +108,15 @@ export type CompilerInfo = { }; remote: any; disabledFilters: string[]; + optArg: string; + externalparser: any; + removeEmptyGccDump: boolean; + irArg: string[]; + llvmOptArg: string[]; + llvmOptModuleScopeArg: string[]; + llvmOptNoDiscardValueNamesArg: string[]; + cachedPossibleArguments?: any; + nvdisasm?: string; }; export interface ICompiler {