From b89af45ad5b9eb20c2b92280ec2195184144f9a2 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 22 Jul 2020 16:06:32 +0200 Subject: [PATCH 1/8] Fix asconfig merge order --- cli/asc.js | 241 +++++++++++++++++++++--------------------- cli/asc.json | 6 +- cli/util/options.d.ts | 2 +- cli/util/options.js | 3 +- 4 files changed, 127 insertions(+), 125 deletions(-) diff --git a/cli/asc.js b/cli/asc.js index bf724ff16d..83bcfb25fb 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -193,11 +193,12 @@ exports.main = function main(argv, options, callback) { if (!stdout) throw Error("'options.stdout' must be specified"); if (!stderr) throw Error("'options.stderr' must be specified"); - const opts = optionsUtil.parse(argv, exports.options); - let args = opts.options; + // Parse command line options but do not populate option defaults yet + const optionsResult = optionsUtil.parse(argv, exports.options, false); + let opts = optionsResult.options; + argv = optionsResult.arguments; - argv = opts.arguments; - if (args.noColors) { + if (opts.noColors) { colorsUtil.stdout.supported = colorsUtil.stderr.supported = false; } else { @@ -205,16 +206,18 @@ exports.main = function main(argv, options, callback) { colorsUtil.stderr = colorsUtil.from(stderr); } - // Check for unknown arguments - if (opts.unknown.length) { - opts.unknown.forEach(arg => { + // Check for unknown options + const unknownOpts = optionsResult.unknown; + if (unknownOpts.length) { + unknownOpts.forEach(arg => { stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unknown option '" + arg + "'" + EOL); }); } // Check for trailing arguments - if (opts.trailing.length) { - stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unsupported trailing arguments: " + opts.trailing.join(" ") + EOL); + const trailingArgv = optionsResult.trailing; + if (trailingArgv.length) { + stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unsupported trailing arguments: " + trailingArgv.join(" ") + EOL); } // Use default callback if none is provided @@ -228,24 +231,24 @@ exports.main = function main(argv, options, callback) { }; // Just print the version if requested - if (args.version) { + if (opts.version) { stdout.write("Version " + exports.version + (isDev ? "-dev" : "") + EOL); return callback(null); } // Use another extension if requested - if (typeof args.extension === "string") { - if (/^\.?[0-9a-zA-Z]{1,14}$/.test(args.extension)) { - extension = setupExtension(args.extension); + if (typeof opts.extension === "string") { + if (/^\.?[0-9a-zA-Z]{1,14}$/.test(opts.extension)) { + extension = setupExtension(opts.extension); } else { - return callback(Error("Invalid extension: " + args.extension)); + return callback(Error("Invalid extension: " + opts.extension)); } } // Print the help message if requested or no source files are provided - if (args.help || !argv.length) { - var out = args.help ? stdout : stderr; - var color = args.help ? colorsUtil.stdout : colorsUtil.stderr; + if (opts.help || !argv.length) { + var out = opts.help ? stdout : stderr; + var color = opts.help ? colorsUtil.stdout : colorsUtil.stderr; out.write([ color.white("SYNTAX"), " " + color.cyan("asc") + " [entryFile ...] [options]", @@ -270,24 +273,26 @@ exports.main = function main(argv, options, callback) { } // Set up base directory - const baseDir = args.baseDir ? path.resolve(args.baseDir) : "."; - const target = args.target; + const baseDir = opts.baseDir ? path.resolve(opts.baseDir) : "."; - // Once the baseDir is calculated, we can resolve the config, and its extensions - let asconfig = getAsconfig(args.config, baseDir, readFile); + // Load additional options from asconfig.json + let asconfigFile = opts.config || "asconfig.json"; + let asconfig = getAsconfig(asconfigFile, baseDir, readFile); let asconfigDir = baseDir; const seenAsconfig = new Set(); - seenAsconfig.add(path.join(baseDir, args.config)); + seenAsconfig.add(path.join(baseDir, asconfigFile)); + const target = opts.target || "release"; while (asconfig) { - // merge target first, then merge options, then merge extended asconfigs + // Merge target first if (asconfig.targets && asconfig.targets[target]) { - args = optionsUtil.merge(exports.options, asconfig.targets[target], args); + opts = optionsUtil.merge(exports.options, opts, asconfig.targets[target]); } + // Merge general options if (asconfig.options) { if (asconfig.options.transform) { - // ensure that a transform's path is relative to the current config + // ensure that a transform's path is relative to the current asconfig asconfig.options.transform = asconfig.options.transform.map(p => { if (!path.isAbsolute(p)) { if (p.startsWith(".")) { @@ -298,28 +303,25 @@ exports.main = function main(argv, options, callback) { return p; }); } - args = optionsUtil.merge(exports.options, args, asconfig.options); + opts = optionsUtil.merge(exports.options, opts, asconfig.options); } - // entries are added to the compilation + // Append entries if (asconfig.entries) { for (const entry of asconfig.entries) { argv.push( path.isAbsolute(entry) ? entry - // the entry is relative to the asconfig directory - : path.join(asconfigDir, entry) + : path.join(asconfigDir, entry) // relative to current asconfig ); } } - // asconfig "extends" another config, merging options of it's parent + // Look up extended asconfig and repeat if (asconfig.extends) { asconfigDir = path.isAbsolute(asconfig.extends) - // absolute extension path means we know the exact directory and location ? path.dirname(asconfig.extends) - // relative means we need to calculate a relative asconfigDir - : path.join(asconfigDir, path.dirname(asconfig.extends)); + : path.join(asconfigDir, path.dirname(asconfig.extends)); // relative to current asconfig const fileName = path.basename(asconfig.extends); const filePath = path.join(asconfigDir, fileName); if (seenAsconfig.has(filePath)) { @@ -329,13 +331,16 @@ exports.main = function main(argv, options, callback) { asconfig = getAsconfig(fileName, asconfigDir, readFile); } } else { - asconfig = null; // finished resolving the configuration chain + asconfig = null; } } - // If showConfig print args and exit - if (args.showConfig) { - stderr.write(JSON.stringify(args, null, 2)); + // Populate option defaults once user-defined options are set + optionsUtil.addDefaults(exports.options, opts); + + // If showConfig print options and exit + if (opts.showConfig) { + stderr.write(JSON.stringify(opts, null, 2)); return callback(null); } @@ -360,25 +365,25 @@ exports.main = function main(argv, options, callback) { // Set up options const compilerOptions = assemblyscript.newOptions(); assemblyscript.setTarget(compilerOptions, 0); - assemblyscript.setNoAssert(compilerOptions, args.noAssert); - assemblyscript.setExportMemory(compilerOptions, !args.noExportMemory); - assemblyscript.setImportMemory(compilerOptions, args.importMemory); - assemblyscript.setInitialMemory(compilerOptions, args.initialMemory >>> 0); - assemblyscript.setMaximumMemory(compilerOptions, args.maximumMemory >>> 0); - assemblyscript.setSharedMemory(compilerOptions, args.sharedMemory); - assemblyscript.setImportTable(compilerOptions, args.importTable); - assemblyscript.setExportTable(compilerOptions, args.exportTable); - assemblyscript.setExplicitStart(compilerOptions, args.explicitStart); - assemblyscript.setMemoryBase(compilerOptions, args.memoryBase >>> 0); - assemblyscript.setTableBase(compilerOptions, args.tableBase >>> 0); - assemblyscript.setSourceMap(compilerOptions, args.sourceMap != null); - assemblyscript.setNoUnsafe(compilerOptions, args.noUnsafe); - assemblyscript.setPedantic(compilerOptions, args.pedantic); - assemblyscript.setLowMemoryLimit(compilerOptions, args.lowMemoryLimit >>> 0); + assemblyscript.setNoAssert(compilerOptions, opts.noAssert); + assemblyscript.setExportMemory(compilerOptions, !opts.noExportMemory); + assemblyscript.setImportMemory(compilerOptions, opts.importMemory); + assemblyscript.setInitialMemory(compilerOptions, opts.initialMemory >>> 0); + assemblyscript.setMaximumMemory(compilerOptions, opts.maximumMemory >>> 0); + assemblyscript.setSharedMemory(compilerOptions, opts.sharedMemory); + assemblyscript.setImportTable(compilerOptions, opts.importTable); + assemblyscript.setExportTable(compilerOptions, opts.exportTable); + assemblyscript.setExplicitStart(compilerOptions, opts.explicitStart); + assemblyscript.setMemoryBase(compilerOptions, opts.memoryBase >>> 0); + assemblyscript.setTableBase(compilerOptions, opts.tableBase >>> 0); + assemblyscript.setSourceMap(compilerOptions, opts.sourceMap != null); + assemblyscript.setNoUnsafe(compilerOptions, opts.noUnsafe); + assemblyscript.setPedantic(compilerOptions, opts.pedantic); + assemblyscript.setLowMemoryLimit(compilerOptions, opts.lowMemoryLimit >>> 0); // Add or override aliases if specified - if (args.use) { - let aliases = args.use; + if (opts.use) { + let aliases = opts.use; for (let i = 0, k = aliases.length; i < k; ++i) { let part = aliases[i]; let p = part.indexOf("="); @@ -392,7 +397,7 @@ exports.main = function main(argv, options, callback) { // Disable default features if specified var features; - if ((features = args.disable) != null) { + if ((features = opts.disable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -403,7 +408,7 @@ exports.main = function main(argv, options, callback) { } // Enable experimental features if specified - if ((features = args.enable) != null) { + if ((features = opts.enable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -416,12 +421,12 @@ exports.main = function main(argv, options, callback) { // Set up optimization levels var optimizeLevel = 0; var shrinkLevel = 0; - if (args.optimize) { + if (opts.optimize) { optimizeLevel = exports.defaultOptimizeLevel; shrinkLevel = exports.defaultShrinkLevel; } - if (typeof args.optimizeLevel === "number") optimizeLevel = args.optimizeLevel; - if (typeof args.shrinkLevel === "number") shrinkLevel = args.shrinkLevel; + if (typeof opts.optimizeLevel === "number") optimizeLevel = opts.optimizeLevel; + if (typeof opts.shrinkLevel === "number") shrinkLevel = opts.shrinkLevel; optimizeLevel = Math.min(Math.max(optimizeLevel, 0), 3); shrinkLevel = Math.min(Math.max(shrinkLevel, 0), 2); assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel); @@ -431,9 +436,9 @@ exports.main = function main(argv, options, callback) { // Set up transforms const transforms = []; - if (args.transform) { + if (opts.transform) { let tsNodeRegistered = false; - let transformArgs = unique(args.transform.map(resolveBasedir)); + let transformArgs = unique(opts.transform.map(resolveBasedir)); for (let i = 0, k = transformArgs.length; i < k; ++i) { let filename = transformArgs[i].trim(); if (!tsNodeRegistered && filename.endsWith(".ts")) { // ts-node requires .ts specifically @@ -488,8 +493,8 @@ exports.main = function main(argv, options, callback) { }); }); let customLibDirs = []; - if (args.lib) { - let lib = args.lib; + if (opts.lib) { + let lib = opts.lib; if (typeof lib === "string") lib = lib.trim().split(/\s*,\s*/); customLibDirs.push(...lib.map(resolveBasedir)); customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates @@ -514,7 +519,7 @@ exports.main = function main(argv, options, callback) { } } } - args.path = args.path || []; + opts.path = opts.path || []; // Maps package names to parent directory var packageMains = new Map(); @@ -567,14 +572,14 @@ exports.main = function main(argv, options, callback) { const isPackageRoot = match[2] === undefined; const filePath = isPackageRoot ? "index" : match[2]; const basePath = packageBases.has(dependeePath) ? packageBases.get(dependeePath) : "."; - if (args.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); + if (opts.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); const absBasePath = path.isAbsolute(basePath) ? basePath : path.join(baseDir, basePath); const paths = []; for (let parts = absBasePath.split(SEP), i = parts.length, k = SEP == "/" ? 0 : 1; i >= k; --i) { if (parts[i - 1] !== "node_modules") paths.push(parts.slice(0, i).join(SEP) + SEP + "node_modules"); } - for (const currentPath of paths.concat(...args.path).map(p => path.relative(baseDir, p))) { - if (args.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); + for (const currentPath of paths.concat(...opts.path).map(p => path.relative(baseDir, p))) { + if (opts.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); let mainPath = "assembly"; if (packageMains.has(packageName)) { // use cached mainPath = packageMains.get(packageName); @@ -596,14 +601,14 @@ exports.main = function main(argv, options, callback) { if ((sourceText = readFile(path.join(mainDir, plainName + extension.ext), baseDir)) != null) { sourcePath = libraryPrefix + packageName + "/" + plainName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); + if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); break; } else if (!isPackageRoot) { const indexName = filePath + "/index"; if ((sourceText = readFile(path.join(mainDir, indexName + extension.ext), baseDir)) !== null) { sourcePath = libraryPrefix + packageName + "/" + indexName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); + if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); break; } } @@ -641,7 +646,7 @@ exports.main = function main(argv, options, callback) { // Include runtime template before entry files so its setup runs first { - let runtimeName = String(args.runtime); + let runtimeName = String(opts.runtime); let runtimePath = "rt/index-" + runtimeName; let runtimeText = exports.libraryFiles[runtimePath]; if (runtimeText == null) { @@ -701,7 +706,7 @@ exports.main = function main(argv, options, callback) { } // Print files and exit if listFiles - if (args.listFiles) { + if (opts.listFiles) { // FIXME: not a proper C-like API stderr.write(program.sources.map(s => s.normalizedPath).sort().join(EOL) + EOL); return callback(null); @@ -739,7 +744,7 @@ exports.main = function main(argv, options, callback) { } // Validate the module if requested - if (!args.noValidate) { + if (!opts.noValidate) { stats.validateCount++; let isValid; stats.validateTime += measure(() => { @@ -752,32 +757,32 @@ exports.main = function main(argv, options, callback) { } // Set Binaryen-specific options - if (args.trapMode === "clamp") { + if (opts.trapMode === "clamp") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-clamp"); }); - } else if (args.trapMode === "js") { + } else if (opts.trapMode === "js") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-js"); }); - } else if (args.trapMode !== "allow") { + } else if (opts.trapMode !== "allow") { module.dispose(); return callback(Error("Unsupported trap mode")); } // Optimize the module - const debugInfo = args.debug; - const usesARC = args.runtime == "half" || args.runtime == "full"; - const converge = args.converge; + const debugInfo = opts.debug; + const usesARC = opts.runtime == "half" || opts.runtime == "full"; + const converge = opts.converge; const runPasses = []; - if (args.runPasses) { - if (typeof args.runPasses === "string") { - args.runPasses = args.runPasses.split(","); + if (opts.runPasses) { + if (typeof opts.runPasses === "string") { + opts.runPasses = opts.runPasses.split(","); } - if (args.runPasses.length) { - args.runPasses.forEach(pass => { + if (opts.runPasses.length) { + opts.runPasses.forEach(pass => { if (runPasses.indexOf(pass = pass.trim()) < 0) runPasses.push(pass); }); @@ -807,30 +812,30 @@ exports.main = function main(argv, options, callback) { }); // Prepare output - if (!args.noEmit) { - if (args.outFile != null) { - if (/\.was?t$/.test(args.outFile) && args.textFile == null) { - args.textFile = args.outFile; - } else if (/\.js$/.test(args.outFile) && args.jsFile == null) { - args.jsFile = args.outFile; - } else if (args.binaryFile == null) { - args.binaryFile = args.outFile; + if (!opts.noEmit) { + if (opts.outFile != null) { + if (/\.was?t$/.test(opts.outFile) && opts.textFile == null) { + opts.textFile = opts.outFile; + } else if (/\.js$/.test(opts.outFile) && opts.jsFile == null) { + opts.jsFile = opts.outFile; + } else if (opts.binaryFile == null) { + opts.binaryFile = opts.outFile; } } let hasStdout = false; - let hasOutput = args.textFile != null - || args.binaryFile != null - || args.jsFile != null - || args.tsdFile != null - || args.idlFile != null; + let hasOutput = opts.textFile != null + || opts.binaryFile != null + || opts.jsFile != null + || opts.tsdFile != null + || opts.idlFile != null; // Write binary - if (args.binaryFile != null) { - let basename = path.basename(args.binaryFile); - let sourceMapURL = args.sourceMap != null - ? args.sourceMap.length - ? args.sourceMap + if (opts.binaryFile != null) { + let basename = path.basename(opts.binaryFile); + let sourceMapURL = opts.sourceMap != null + ? opts.sourceMap.length + ? opts.sourceMap : "./" + basename + ".map" : null; @@ -840,8 +845,8 @@ exports.main = function main(argv, options, callback) { wasm = module.toBinary(sourceMapURL); }); - if (args.binaryFile.length) { - writeFile(args.binaryFile, wasm.output, baseDir); + if (opts.binaryFile.length) { + writeFile(opts.binaryFile, wasm.output, baseDir); } else { writeStdout(wasm.output); hasStdout = true; @@ -849,7 +854,7 @@ exports.main = function main(argv, options, callback) { // Post-process source map if (wasm.sourceMap != null) { - if (args.binaryFile.length) { + if (opts.binaryFile.length) { let map = JSON.parse(wasm.sourceMap); map.sourceRoot = "./" + basename; let contents = []; @@ -860,7 +865,7 @@ exports.main = function main(argv, options, callback) { }); map.sourcesContent = contents; writeFile(path.join( - path.dirname(args.binaryFile), + path.dirname(opts.binaryFile), path.basename(sourceMapURL) ).replace(/^\.\//, ""), JSON.stringify(map), baseDir); } else { @@ -870,14 +875,14 @@ exports.main = function main(argv, options, callback) { } // Write text (also fallback) - if (args.textFile != null || !hasOutput) { + if (opts.textFile != null || !hasOutput) { let wat; - if (args.textFile != null && args.textFile.length) { + if (opts.textFile != null && opts.textFile.length) { stats.emitCount++; stats.emitTime += measure(() => { wat = module.toText(); }); - writeFile(args.textFile, wat, baseDir); + writeFile(opts.textFile, wat, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -888,14 +893,14 @@ exports.main = function main(argv, options, callback) { } // Write WebIDL - if (args.idlFile != null) { + if (opts.idlFile != null) { let idl; - if (args.idlFile.length) { + if (opts.idlFile.length) { stats.emitCount++; stats.emitTime += measure(() => { idl = assemblyscript.buildIDL(program); }); - writeFile(args.idlFile, idl, baseDir); + writeFile(opts.idlFile, idl, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -907,14 +912,14 @@ exports.main = function main(argv, options, callback) { } // Write TypeScript definition - if (args.tsdFile != null) { + if (opts.tsdFile != null) { let tsd; - if (args.tsdFile.length) { + if (opts.tsdFile.length) { stats.emitCount++; stats.emitTime += measure(() => { tsd = assemblyscript.buildTSD(program); }); - writeFile(args.tsdFile, tsd, baseDir); + writeFile(opts.tsdFile, tsd, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -926,14 +931,14 @@ exports.main = function main(argv, options, callback) { } // Write JS (modifies the binary, so must be last) - if (args.jsFile != null) { + if (opts.jsFile != null) { let js; - if (args.jsFile.length) { + if (opts.jsFile.length) { stats.emitCount++; stats.emitTime += measure(() => { js = module.toAsmjs(); }); - writeFile(args.jsFile, js, baseDir); + writeFile(opts.jsFile, js, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -945,7 +950,7 @@ exports.main = function main(argv, options, callback) { } module.dispose(); - if (args.measure) { + if (opts.measure) { printStats(stats, stderr); } diff --git a/cli/asc.json b/cli/asc.json index 9b194d7861..79a766639c 100644 --- a/cli/asc.json +++ b/cli/asc.json @@ -20,14 +20,12 @@ "config": { "category": "General", "description": "Configuration file to apply. CLI arguments take precedence.", - "type": "s", - "default": "asconfig.json" + "type": "s" }, "target": { "category": "General", "description": "Target configuration to use. Defaults to 'release'.", - "type": "s", - "default": "release" + "type": "s" }, "optimize": { diff --git a/cli/util/options.d.ts b/cli/util/options.d.ts index e12013fef3..5ec182734c 100644 --- a/cli/util/options.d.ts +++ b/cli/util/options.d.ts @@ -61,4 +61,4 @@ export function help(config: Config, options?: HelpOptions): string; export function merge(config: Config, currentOptions: OptionSet, parentOptions: OptionSet): OptionSet; /** Populates default values on a parsed options result. */ -export function addDefaults(config: Config, options: OptionSet): OptionSet; +export function addDefaults(config: Config, options: OptionSet): void; diff --git a/cli/util/options.js b/cli/util/options.js index 742df4d8cc..2dd9ba7244 100644 --- a/cli/util/options.js +++ b/cli/util/options.js @@ -31,7 +31,7 @@ function parse(argv, config, propagateDefaults = true) { if (typeof option.alias === "string") aliases[option.alias] = key; else if (Array.isArray(option.alias)) option.alias.forEach(alias => aliases[alias] = key); } - if (option.default != null) options[key] = option.default; + if (propagateDefaults && option.default != null) options[key] = option.default; }); // iterate over argv @@ -229,7 +229,6 @@ function addDefaults(config, options) { options[key] = defaultValue; } } - return options; } exports.addDefaults = addDefaults; From b0e15ce80c127c4b25112cda183daf54b73d7cbd Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 22 Jul 2020 16:25:15 +0200 Subject: [PATCH 2/8] revert rename? --- cli/asc.js | 206 ++++++++++++++++++++++++++--------------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/cli/asc.js b/cli/asc.js index 83bcfb25fb..af155faa10 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -194,11 +194,11 @@ exports.main = function main(argv, options, callback) { if (!stderr) throw Error("'options.stderr' must be specified"); // Parse command line options but do not populate option defaults yet - const optionsResult = optionsUtil.parse(argv, exports.options, false); - let opts = optionsResult.options; - argv = optionsResult.arguments; + const opts = optionsUtil.parse(argv, exports.options, false); + let args = opts.options; + argv = opts.arguments; - if (opts.noColors) { + if (args.noColors) { colorsUtil.stdout.supported = colorsUtil.stderr.supported = false; } else { @@ -207,7 +207,7 @@ exports.main = function main(argv, options, callback) { } // Check for unknown options - const unknownOpts = optionsResult.unknown; + const unknownOpts = opts.unknown; if (unknownOpts.length) { unknownOpts.forEach(arg => { stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unknown option '" + arg + "'" + EOL); @@ -215,7 +215,7 @@ exports.main = function main(argv, options, callback) { } // Check for trailing arguments - const trailingArgv = optionsResult.trailing; + const trailingArgv = opts.trailing; if (trailingArgv.length) { stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unsupported trailing arguments: " + trailingArgv.join(" ") + EOL); } @@ -231,24 +231,24 @@ exports.main = function main(argv, options, callback) { }; // Just print the version if requested - if (opts.version) { + if (args.version) { stdout.write("Version " + exports.version + (isDev ? "-dev" : "") + EOL); return callback(null); } // Use another extension if requested - if (typeof opts.extension === "string") { - if (/^\.?[0-9a-zA-Z]{1,14}$/.test(opts.extension)) { - extension = setupExtension(opts.extension); + if (typeof args.extension === "string") { + if (/^\.?[0-9a-zA-Z]{1,14}$/.test(args.extension)) { + extension = setupExtension(args.extension); } else { - return callback(Error("Invalid extension: " + opts.extension)); + return callback(Error("Invalid extension: " + args.extension)); } } // Print the help message if requested or no source files are provided - if (opts.help || !argv.length) { - var out = opts.help ? stdout : stderr; - var color = opts.help ? colorsUtil.stdout : colorsUtil.stderr; + if (args.help || !argv.length) { + var out = args.help ? stdout : stderr; + var color = args.help ? colorsUtil.stdout : colorsUtil.stderr; out.write([ color.white("SYNTAX"), " " + color.cyan("asc") + " [entryFile ...] [options]", @@ -273,21 +273,21 @@ exports.main = function main(argv, options, callback) { } // Set up base directory - const baseDir = opts.baseDir ? path.resolve(opts.baseDir) : "."; + const baseDir = args.baseDir ? path.resolve(args.baseDir) : "."; // Load additional options from asconfig.json - let asconfigFile = opts.config || "asconfig.json"; + let asconfigFile = args.config || "asconfig.json"; let asconfig = getAsconfig(asconfigFile, baseDir, readFile); let asconfigDir = baseDir; const seenAsconfig = new Set(); seenAsconfig.add(path.join(baseDir, asconfigFile)); - const target = opts.target || "release"; + const target = args.target || "release"; while (asconfig) { // Merge target first if (asconfig.targets && asconfig.targets[target]) { - opts = optionsUtil.merge(exports.options, opts, asconfig.targets[target]); + args = optionsUtil.merge(exports.options, args, asconfig.targets[target]); } // Merge general options if (asconfig.options) { @@ -303,7 +303,7 @@ exports.main = function main(argv, options, callback) { return p; }); } - opts = optionsUtil.merge(exports.options, opts, asconfig.options); + args = optionsUtil.merge(exports.options, args, asconfig.options); } // Append entries @@ -336,11 +336,11 @@ exports.main = function main(argv, options, callback) { } // Populate option defaults once user-defined options are set - optionsUtil.addDefaults(exports.options, opts); + optionsUtil.addDefaults(exports.options, args); // If showConfig print options and exit - if (opts.showConfig) { - stderr.write(JSON.stringify(opts, null, 2)); + if (args.showConfig) { + stderr.write(JSON.stringify(args, null, 2)); return callback(null); } @@ -365,25 +365,25 @@ exports.main = function main(argv, options, callback) { // Set up options const compilerOptions = assemblyscript.newOptions(); assemblyscript.setTarget(compilerOptions, 0); - assemblyscript.setNoAssert(compilerOptions, opts.noAssert); - assemblyscript.setExportMemory(compilerOptions, !opts.noExportMemory); - assemblyscript.setImportMemory(compilerOptions, opts.importMemory); - assemblyscript.setInitialMemory(compilerOptions, opts.initialMemory >>> 0); - assemblyscript.setMaximumMemory(compilerOptions, opts.maximumMemory >>> 0); - assemblyscript.setSharedMemory(compilerOptions, opts.sharedMemory); - assemblyscript.setImportTable(compilerOptions, opts.importTable); - assemblyscript.setExportTable(compilerOptions, opts.exportTable); - assemblyscript.setExplicitStart(compilerOptions, opts.explicitStart); - assemblyscript.setMemoryBase(compilerOptions, opts.memoryBase >>> 0); - assemblyscript.setTableBase(compilerOptions, opts.tableBase >>> 0); - assemblyscript.setSourceMap(compilerOptions, opts.sourceMap != null); - assemblyscript.setNoUnsafe(compilerOptions, opts.noUnsafe); - assemblyscript.setPedantic(compilerOptions, opts.pedantic); - assemblyscript.setLowMemoryLimit(compilerOptions, opts.lowMemoryLimit >>> 0); + assemblyscript.setNoAssert(compilerOptions, args.noAssert); + assemblyscript.setExportMemory(compilerOptions, !args.noExportMemory); + assemblyscript.setImportMemory(compilerOptions, args.importMemory); + assemblyscript.setInitialMemory(compilerOptions, args.initialMemory >>> 0); + assemblyscript.setMaximumMemory(compilerOptions, args.maximumMemory >>> 0); + assemblyscript.setSharedMemory(compilerOptions, args.sharedMemory); + assemblyscript.setImportTable(compilerOptions, args.importTable); + assemblyscript.setExportTable(compilerOptions, args.exportTable); + assemblyscript.setExplicitStart(compilerOptions, args.explicitStart); + assemblyscript.setMemoryBase(compilerOptions, args.memoryBase >>> 0); + assemblyscript.setTableBase(compilerOptions, args.tableBase >>> 0); + assemblyscript.setSourceMap(compilerOptions, args.sourceMap != null); + assemblyscript.setNoUnsafe(compilerOptions, args.noUnsafe); + assemblyscript.setPedantic(compilerOptions, args.pedantic); + assemblyscript.setLowMemoryLimit(compilerOptions, args.lowMemoryLimit >>> 0); // Add or override aliases if specified - if (opts.use) { - let aliases = opts.use; + if (args.use) { + let aliases = args.use; for (let i = 0, k = aliases.length; i < k; ++i) { let part = aliases[i]; let p = part.indexOf("="); @@ -397,7 +397,7 @@ exports.main = function main(argv, options, callback) { // Disable default features if specified var features; - if ((features = opts.disable) != null) { + if ((features = args.disable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -408,7 +408,7 @@ exports.main = function main(argv, options, callback) { } // Enable experimental features if specified - if ((features = opts.enable) != null) { + if ((features = args.enable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -421,12 +421,12 @@ exports.main = function main(argv, options, callback) { // Set up optimization levels var optimizeLevel = 0; var shrinkLevel = 0; - if (opts.optimize) { + if (args.optimize) { optimizeLevel = exports.defaultOptimizeLevel; shrinkLevel = exports.defaultShrinkLevel; } - if (typeof opts.optimizeLevel === "number") optimizeLevel = opts.optimizeLevel; - if (typeof opts.shrinkLevel === "number") shrinkLevel = opts.shrinkLevel; + if (typeof args.optimizeLevel === "number") optimizeLevel = args.optimizeLevel; + if (typeof args.shrinkLevel === "number") shrinkLevel = args.shrinkLevel; optimizeLevel = Math.min(Math.max(optimizeLevel, 0), 3); shrinkLevel = Math.min(Math.max(shrinkLevel, 0), 2); assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel); @@ -436,9 +436,9 @@ exports.main = function main(argv, options, callback) { // Set up transforms const transforms = []; - if (opts.transform) { + if (args.transform) { let tsNodeRegistered = false; - let transformArgs = unique(opts.transform.map(resolveBasedir)); + let transformArgs = unique(args.transform.map(resolveBasedir)); for (let i = 0, k = transformArgs.length; i < k; ++i) { let filename = transformArgs[i].trim(); if (!tsNodeRegistered && filename.endsWith(".ts")) { // ts-node requires .ts specifically @@ -493,8 +493,8 @@ exports.main = function main(argv, options, callback) { }); }); let customLibDirs = []; - if (opts.lib) { - let lib = opts.lib; + if (args.lib) { + let lib = args.lib; if (typeof lib === "string") lib = lib.trim().split(/\s*,\s*/); customLibDirs.push(...lib.map(resolveBasedir)); customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates @@ -519,7 +519,7 @@ exports.main = function main(argv, options, callback) { } } } - opts.path = opts.path || []; + args.path = args.path || []; // Maps package names to parent directory var packageMains = new Map(); @@ -572,14 +572,14 @@ exports.main = function main(argv, options, callback) { const isPackageRoot = match[2] === undefined; const filePath = isPackageRoot ? "index" : match[2]; const basePath = packageBases.has(dependeePath) ? packageBases.get(dependeePath) : "."; - if (opts.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); + if (args.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); const absBasePath = path.isAbsolute(basePath) ? basePath : path.join(baseDir, basePath); const paths = []; for (let parts = absBasePath.split(SEP), i = parts.length, k = SEP == "/" ? 0 : 1; i >= k; --i) { if (parts[i - 1] !== "node_modules") paths.push(parts.slice(0, i).join(SEP) + SEP + "node_modules"); } - for (const currentPath of paths.concat(...opts.path).map(p => path.relative(baseDir, p))) { - if (opts.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); + for (const currentPath of paths.concat(...args.path).map(p => path.relative(baseDir, p))) { + if (args.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); let mainPath = "assembly"; if (packageMains.has(packageName)) { // use cached mainPath = packageMains.get(packageName); @@ -601,14 +601,14 @@ exports.main = function main(argv, options, callback) { if ((sourceText = readFile(path.join(mainDir, plainName + extension.ext), baseDir)) != null) { sourcePath = libraryPrefix + packageName + "/" + plainName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); + if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); break; } else if (!isPackageRoot) { const indexName = filePath + "/index"; if ((sourceText = readFile(path.join(mainDir, indexName + extension.ext), baseDir)) !== null) { sourcePath = libraryPrefix + packageName + "/" + indexName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); + if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); break; } } @@ -646,7 +646,7 @@ exports.main = function main(argv, options, callback) { // Include runtime template before entry files so its setup runs first { - let runtimeName = String(opts.runtime); + let runtimeName = String(args.runtime); let runtimePath = "rt/index-" + runtimeName; let runtimeText = exports.libraryFiles[runtimePath]; if (runtimeText == null) { @@ -706,7 +706,7 @@ exports.main = function main(argv, options, callback) { } // Print files and exit if listFiles - if (opts.listFiles) { + if (args.listFiles) { // FIXME: not a proper C-like API stderr.write(program.sources.map(s => s.normalizedPath).sort().join(EOL) + EOL); return callback(null); @@ -744,7 +744,7 @@ exports.main = function main(argv, options, callback) { } // Validate the module if requested - if (!opts.noValidate) { + if (!args.noValidate) { stats.validateCount++; let isValid; stats.validateTime += measure(() => { @@ -757,32 +757,32 @@ exports.main = function main(argv, options, callback) { } // Set Binaryen-specific options - if (opts.trapMode === "clamp") { + if (args.trapMode === "clamp") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-clamp"); }); - } else if (opts.trapMode === "js") { + } else if (args.trapMode === "js") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-js"); }); - } else if (opts.trapMode !== "allow") { + } else if (args.trapMode !== "allow") { module.dispose(); return callback(Error("Unsupported trap mode")); } // Optimize the module - const debugInfo = opts.debug; - const usesARC = opts.runtime == "half" || opts.runtime == "full"; - const converge = opts.converge; + const debugInfo = args.debug; + const usesARC = args.runtime == "half" || args.runtime == "full"; + const converge = args.converge; const runPasses = []; - if (opts.runPasses) { - if (typeof opts.runPasses === "string") { - opts.runPasses = opts.runPasses.split(","); + if (args.runPasses) { + if (typeof args.runPasses === "string") { + args.runPasses = args.runPasses.split(","); } - if (opts.runPasses.length) { - opts.runPasses.forEach(pass => { + if (args.runPasses.length) { + args.runPasses.forEach(pass => { if (runPasses.indexOf(pass = pass.trim()) < 0) runPasses.push(pass); }); @@ -812,30 +812,30 @@ exports.main = function main(argv, options, callback) { }); // Prepare output - if (!opts.noEmit) { - if (opts.outFile != null) { - if (/\.was?t$/.test(opts.outFile) && opts.textFile == null) { - opts.textFile = opts.outFile; - } else if (/\.js$/.test(opts.outFile) && opts.jsFile == null) { - opts.jsFile = opts.outFile; - } else if (opts.binaryFile == null) { - opts.binaryFile = opts.outFile; + if (!args.noEmit) { + if (args.outFile != null) { + if (/\.was?t$/.test(args.outFile) && args.textFile == null) { + args.textFile = args.outFile; + } else if (/\.js$/.test(args.outFile) && args.jsFile == null) { + args.jsFile = args.outFile; + } else if (args.binaryFile == null) { + args.binaryFile = args.outFile; } } let hasStdout = false; - let hasOutput = opts.textFile != null - || opts.binaryFile != null - || opts.jsFile != null - || opts.tsdFile != null - || opts.idlFile != null; + let hasOutput = args.textFile != null + || args.binaryFile != null + || args.jsFile != null + || args.tsdFile != null + || args.idlFile != null; // Write binary - if (opts.binaryFile != null) { - let basename = path.basename(opts.binaryFile); - let sourceMapURL = opts.sourceMap != null - ? opts.sourceMap.length - ? opts.sourceMap + if (args.binaryFile != null) { + let basename = path.basename(args.binaryFile); + let sourceMapURL = args.sourceMap != null + ? args.sourceMap.length + ? args.sourceMap : "./" + basename + ".map" : null; @@ -845,8 +845,8 @@ exports.main = function main(argv, options, callback) { wasm = module.toBinary(sourceMapURL); }); - if (opts.binaryFile.length) { - writeFile(opts.binaryFile, wasm.output, baseDir); + if (args.binaryFile.length) { + writeFile(args.binaryFile, wasm.output, baseDir); } else { writeStdout(wasm.output); hasStdout = true; @@ -854,7 +854,7 @@ exports.main = function main(argv, options, callback) { // Post-process source map if (wasm.sourceMap != null) { - if (opts.binaryFile.length) { + if (args.binaryFile.length) { let map = JSON.parse(wasm.sourceMap); map.sourceRoot = "./" + basename; let contents = []; @@ -865,7 +865,7 @@ exports.main = function main(argv, options, callback) { }); map.sourcesContent = contents; writeFile(path.join( - path.dirname(opts.binaryFile), + path.dirname(args.binaryFile), path.basename(sourceMapURL) ).replace(/^\.\//, ""), JSON.stringify(map), baseDir); } else { @@ -875,14 +875,14 @@ exports.main = function main(argv, options, callback) { } // Write text (also fallback) - if (opts.textFile != null || !hasOutput) { + if (args.textFile != null || !hasOutput) { let wat; - if (opts.textFile != null && opts.textFile.length) { + if (args.textFile != null && args.textFile.length) { stats.emitCount++; stats.emitTime += measure(() => { wat = module.toText(); }); - writeFile(opts.textFile, wat, baseDir); + writeFile(args.textFile, wat, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -893,14 +893,14 @@ exports.main = function main(argv, options, callback) { } // Write WebIDL - if (opts.idlFile != null) { + if (args.idlFile != null) { let idl; - if (opts.idlFile.length) { + if (args.idlFile.length) { stats.emitCount++; stats.emitTime += measure(() => { idl = assemblyscript.buildIDL(program); }); - writeFile(opts.idlFile, idl, baseDir); + writeFile(args.idlFile, idl, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -912,14 +912,14 @@ exports.main = function main(argv, options, callback) { } // Write TypeScript definition - if (opts.tsdFile != null) { + if (args.tsdFile != null) { let tsd; - if (opts.tsdFile.length) { + if (args.tsdFile.length) { stats.emitCount++; stats.emitTime += measure(() => { tsd = assemblyscript.buildTSD(program); }); - writeFile(opts.tsdFile, tsd, baseDir); + writeFile(args.tsdFile, tsd, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -931,14 +931,14 @@ exports.main = function main(argv, options, callback) { } // Write JS (modifies the binary, so must be last) - if (opts.jsFile != null) { + if (args.jsFile != null) { let js; - if (opts.jsFile.length) { + if (args.jsFile.length) { stats.emitCount++; stats.emitTime += measure(() => { js = module.toAsmjs(); }); - writeFile(opts.jsFile, js, baseDir); + writeFile(args.jsFile, js, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -950,7 +950,7 @@ exports.main = function main(argv, options, callback) { } module.dispose(); - if (opts.measure) { + if (args.measure) { printStats(stats, stderr); } From 8c8e08f7d85417939b0db5ae93e59f084d376c15 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 23 Jul 2020 08:14:29 +0200 Subject: [PATCH 3/8] fixes --- cli/asc.js | 287 +++++++++++++++++++----------------------- cli/asc.json | 19 ++- cli/util/options.d.ts | 5 +- cli/util/options.js | 30 ++++- 4 files changed, 175 insertions(+), 166 deletions(-) diff --git a/cli/asc.js b/cli/asc.js index af155faa10..7f9c82bd69 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -41,8 +41,9 @@ const mkdirp = require("./util/mkdirp"); const find = require("./util/find"); const binaryen = global.binaryen || (global.binaryen = require("binaryen")); -const EOL = process.platform === "win32" ? "\r\n" : "\n"; -const SEP = process.platform === "win32" ? "\\" : "/"; +const WIN = process.platform === "win32"; +const EOL = WIN ? "\r\n" : "\n"; +const SEP = WIN ? "\\" : "/"; // Sets up an extension with its definition counterpart and relevant regexes. function setupExtension(extension) { @@ -194,11 +195,11 @@ exports.main = function main(argv, options, callback) { if (!stderr) throw Error("'options.stderr' must be specified"); // Parse command line options but do not populate option defaults yet - const opts = optionsUtil.parse(argv, exports.options, false); - let args = opts.options; - argv = opts.arguments; + const optionsResult = optionsUtil.parse(argv, exports.options, false); + let opts = optionsResult.options; + argv = optionsResult.arguments; - if (args.noColors) { + if (opts.noColors) { colorsUtil.stdout.supported = colorsUtil.stderr.supported = false; } else { @@ -207,7 +208,7 @@ exports.main = function main(argv, options, callback) { } // Check for unknown options - const unknownOpts = opts.unknown; + const unknownOpts = optionsResult.unknown; if (unknownOpts.length) { unknownOpts.forEach(arg => { stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unknown option '" + arg + "'" + EOL); @@ -215,7 +216,7 @@ exports.main = function main(argv, options, callback) { } // Check for trailing arguments - const trailingArgv = opts.trailing; + const trailingArgv = optionsResult.trailing; if (trailingArgv.length) { stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unsupported trailing arguments: " + trailingArgv.join(" ") + EOL); } @@ -231,24 +232,24 @@ exports.main = function main(argv, options, callback) { }; // Just print the version if requested - if (args.version) { + if (opts.version) { stdout.write("Version " + exports.version + (isDev ? "-dev" : "") + EOL); return callback(null); } // Use another extension if requested - if (typeof args.extension === "string") { - if (/^\.?[0-9a-zA-Z]{1,14}$/.test(args.extension)) { - extension = setupExtension(args.extension); + if (typeof opts.extension === "string") { + if (/^\.?[0-9a-zA-Z]{1,14}$/.test(opts.extension)) { + extension = setupExtension(opts.extension); } else { - return callback(Error("Invalid extension: " + args.extension)); + return callback(Error("Invalid extension: " + opts.extension)); } } // Print the help message if requested or no source files are provided - if (args.help || !argv.length) { - var out = args.help ? stdout : stderr; - var color = args.help ? colorsUtil.stdout : colorsUtil.stderr; + if (opts.help || !argv.length) { + var out = opts.help ? stdout : stderr; + var color = opts.help ? colorsUtil.stdout : colorsUtil.stderr; out.write([ color.white("SYNTAX"), " " + color.cyan("asc") + " [entryFile ...] [options]", @@ -273,117 +274,89 @@ exports.main = function main(argv, options, callback) { } // Set up base directory - const baseDir = args.baseDir ? path.resolve(args.baseDir) : "."; + const baseDir = opts.baseDir || "."; // Load additional options from asconfig.json - let asconfigFile = args.config || "asconfig.json"; - let asconfig = getAsconfig(asconfigFile, baseDir, readFile); - let asconfigDir = baseDir; + let asconfigPath = optionsUtil.resolvePath(opts.config || "asconfig.json", baseDir); + let asconfigFile = path.basename(asconfigPath); + let asconfigDir = path.dirname(asconfigPath); + let asconfig = getAsconfig(asconfigFile, asconfigDir, readFile); const seenAsconfig = new Set(); - seenAsconfig.add(path.join(baseDir, asconfigFile)); + seenAsconfig.add(asconfigPath); - const target = args.target || "release"; + const target = opts.target || "release"; while (asconfig) { // Merge target first - if (asconfig.targets && asconfig.targets[target]) { - args = optionsUtil.merge(exports.options, args, asconfig.targets[target]); + if (asconfig.targets) { + const targetOptions = asconfig.targets[target]; + if (targetOptions) { + opts = optionsUtil.merge(exports.options, opts, targetOptions, asconfigDir); + } } // Merge general options - if (asconfig.options) { - if (asconfig.options.transform) { - // ensure that a transform's path is relative to the current asconfig - asconfig.options.transform = asconfig.options.transform.map(p => { - if (!path.isAbsolute(p)) { - if (p.startsWith(".")) { - return path.join(asconfigDir, p); - } - return require.resolve(p); - } - return p; - }); - } - args = optionsUtil.merge(exports.options, args, asconfig.options); + const generalOptions = asconfig.options; + if (generalOptions) { + opts = optionsUtil.merge(exports.options, opts, generalOptions, asconfigDir); } // Append entries if (asconfig.entries) { - for (const entry of asconfig.entries) { - argv.push( - path.isAbsolute(entry) - ? entry - : path.join(asconfigDir, entry) // relative to current asconfig - ); + for (let entry of asconfig.entries) { + argv.push(optionsUtil.resolvePath(entry, asconfigDir)); } } // Look up extended asconfig and repeat if (asconfig.extends) { - asconfigDir = path.isAbsolute(asconfig.extends) - ? path.dirname(asconfig.extends) - : path.join(asconfigDir, path.dirname(asconfig.extends)); // relative to current asconfig - const fileName = path.basename(asconfig.extends); - const filePath = path.join(asconfigDir, fileName); - if (seenAsconfig.has(filePath)) { - asconfig = null; - } else { - seenAsconfig.add(filePath); - asconfig = getAsconfig(fileName, asconfigDir, readFile); - } + asconfigPath = optionsUtil.resolvePath(asconfig.extends, asconfigDir); + asconfigFile = path.basename(asconfigPath); + asconfigDir = path.dirname(asconfigPath); + if (seenAsconfig.has(asconfigPath)) break; + seenAsconfig.add(asconfigPath); + asconfig = getAsconfig(asconfigFile, asconfigDir, readFile); } else { - asconfig = null; + break; } } // Populate option defaults once user-defined options are set - optionsUtil.addDefaults(exports.options, args); + optionsUtil.addDefaults(exports.options, opts); // If showConfig print options and exit - if (args.showConfig) { - stderr.write(JSON.stringify(args, null, 2)); + if (opts.showConfig) { + opts.entries = argv; + stderr.write(JSON.stringify(opts, null, 2)); return callback(null); } - // This method resolves a path relative to the baseDir instead of process.cwd() - function resolveBasedir(arg) { - return path.resolve(baseDir, arg); - } - // create a unique set of values function unique(values) { return [...new Set(values)]; } - // returns a relative path from baseDir - function makeRelative(arg) { - return path.relative(baseDir, arg); - } - - // postprocess we need to get absolute file locations argv - argv = unique(argv.map(resolveBasedir)).map(makeRelative); - // Set up options const compilerOptions = assemblyscript.newOptions(); assemblyscript.setTarget(compilerOptions, 0); - assemblyscript.setNoAssert(compilerOptions, args.noAssert); - assemblyscript.setExportMemory(compilerOptions, !args.noExportMemory); - assemblyscript.setImportMemory(compilerOptions, args.importMemory); - assemblyscript.setInitialMemory(compilerOptions, args.initialMemory >>> 0); - assemblyscript.setMaximumMemory(compilerOptions, args.maximumMemory >>> 0); - assemblyscript.setSharedMemory(compilerOptions, args.sharedMemory); - assemblyscript.setImportTable(compilerOptions, args.importTable); - assemblyscript.setExportTable(compilerOptions, args.exportTable); - assemblyscript.setExplicitStart(compilerOptions, args.explicitStart); - assemblyscript.setMemoryBase(compilerOptions, args.memoryBase >>> 0); - assemblyscript.setTableBase(compilerOptions, args.tableBase >>> 0); - assemblyscript.setSourceMap(compilerOptions, args.sourceMap != null); - assemblyscript.setNoUnsafe(compilerOptions, args.noUnsafe); - assemblyscript.setPedantic(compilerOptions, args.pedantic); - assemblyscript.setLowMemoryLimit(compilerOptions, args.lowMemoryLimit >>> 0); + assemblyscript.setNoAssert(compilerOptions, opts.noAssert); + assemblyscript.setExportMemory(compilerOptions, !opts.noExportMemory); + assemblyscript.setImportMemory(compilerOptions, opts.importMemory); + assemblyscript.setInitialMemory(compilerOptions, opts.initialMemory >>> 0); + assemblyscript.setMaximumMemory(compilerOptions, opts.maximumMemory >>> 0); + assemblyscript.setSharedMemory(compilerOptions, opts.sharedMemory); + assemblyscript.setImportTable(compilerOptions, opts.importTable); + assemblyscript.setExportTable(compilerOptions, opts.exportTable); + assemblyscript.setExplicitStart(compilerOptions, opts.explicitStart); + assemblyscript.setMemoryBase(compilerOptions, opts.memoryBase >>> 0); + assemblyscript.setTableBase(compilerOptions, opts.tableBase >>> 0); + assemblyscript.setSourceMap(compilerOptions, opts.sourceMap != null); + assemblyscript.setNoUnsafe(compilerOptions, opts.noUnsafe); + assemblyscript.setPedantic(compilerOptions, opts.pedantic); + assemblyscript.setLowMemoryLimit(compilerOptions, opts.lowMemoryLimit >>> 0); // Add or override aliases if specified - if (args.use) { - let aliases = args.use; + if (opts.use) { + let aliases = opts.use; for (let i = 0, k = aliases.length; i < k; ++i) { let part = aliases[i]; let p = part.indexOf("="); @@ -397,7 +370,7 @@ exports.main = function main(argv, options, callback) { // Disable default features if specified var features; - if ((features = args.disable) != null) { + if ((features = opts.disable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -408,7 +381,7 @@ exports.main = function main(argv, options, callback) { } // Enable experimental features if specified - if ((features = args.enable) != null) { + if ((features = opts.enable) != null) { if (typeof features === "string") features = features.split(","); for (let i = 0, k = features.length; i < k; ++i) { let name = features[i].trim(); @@ -421,12 +394,12 @@ exports.main = function main(argv, options, callback) { // Set up optimization levels var optimizeLevel = 0; var shrinkLevel = 0; - if (args.optimize) { + if (opts.optimize) { optimizeLevel = exports.defaultOptimizeLevel; shrinkLevel = exports.defaultShrinkLevel; } - if (typeof args.optimizeLevel === "number") optimizeLevel = args.optimizeLevel; - if (typeof args.shrinkLevel === "number") shrinkLevel = args.shrinkLevel; + if (typeof opts.optimizeLevel === "number") optimizeLevel = opts.optimizeLevel; + if (typeof opts.shrinkLevel === "number") shrinkLevel = opts.shrinkLevel; optimizeLevel = Math.min(Math.max(optimizeLevel, 0), 3); shrinkLevel = Math.min(Math.max(shrinkLevel, 0), 2); assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel); @@ -436,9 +409,9 @@ exports.main = function main(argv, options, callback) { // Set up transforms const transforms = []; - if (args.transform) { + if (opts.transform) { let tsNodeRegistered = false; - let transformArgs = unique(args.transform.map(resolveBasedir)); + let transformArgs = unique(opts.transform); for (let i = 0, k = transformArgs.length; i < k; ++i) { let filename = transformArgs[i].trim(); if (!tsNodeRegistered && filename.endsWith(".ts")) { // ts-node requires .ts specifically @@ -493,10 +466,10 @@ exports.main = function main(argv, options, callback) { }); }); let customLibDirs = []; - if (args.lib) { - let lib = args.lib; - if (typeof lib === "string") lib = lib.trim().split(/\s*,\s*/); - customLibDirs.push(...lib.map(resolveBasedir)); + if (opts.lib) { + let lib = opts.lib; + if (typeof lib === "string") lib = lib.split(/\s*,\s*/); + customLibDirs.push(...lib.map(p => p.trim())); customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom let libDir = customLibDirs[i]; @@ -519,7 +492,7 @@ exports.main = function main(argv, options, callback) { } } } - args.path = args.path || []; + opts.path = opts.path || []; // Maps package names to parent directory var packageMains = new Map(); @@ -572,14 +545,14 @@ exports.main = function main(argv, options, callback) { const isPackageRoot = match[2] === undefined; const filePath = isPackageRoot ? "index" : match[2]; const basePath = packageBases.has(dependeePath) ? packageBases.get(dependeePath) : "."; - if (args.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); - const absBasePath = path.isAbsolute(basePath) ? basePath : path.join(baseDir, basePath); + if (opts.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL); const paths = []; - for (let parts = absBasePath.split(SEP), i = parts.length, k = SEP == "/" ? 0 : 1; i >= k; --i) { + const parts = path.resolve(baseDir, basePath).split(SEP); + for (let i = parts.length, k = WIN ? 1 : 0; i >= k; --i) { if (parts[i - 1] !== "node_modules") paths.push(parts.slice(0, i).join(SEP) + SEP + "node_modules"); } - for (const currentPath of paths.concat(...args.path).map(p => path.relative(baseDir, p))) { - if (args.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); + for (const currentPath of paths.concat(...opts.path).map(p => path.relative(baseDir, p))) { + if (opts.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL); let mainPath = "assembly"; if (packageMains.has(packageName)) { // use cached mainPath = packageMains.get(packageName); @@ -601,14 +574,14 @@ exports.main = function main(argv, options, callback) { if ((sourceText = readFile(path.join(mainDir, plainName + extension.ext), baseDir)) != null) { sourcePath = libraryPrefix + packageName + "/" + plainName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); + if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL); break; } else if (!isPackageRoot) { const indexName = filePath + "/index"; if ((sourceText = readFile(path.join(mainDir, indexName + extension.ext), baseDir)) !== null) { sourcePath = libraryPrefix + packageName + "/" + indexName + extension.ext; packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName)); - if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); + if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL); break; } } @@ -646,7 +619,7 @@ exports.main = function main(argv, options, callback) { // Include runtime template before entry files so its setup runs first { - let runtimeName = String(args.runtime); + let runtimeName = String(opts.runtime); let runtimePath = "rt/index-" + runtimeName; let runtimeText = exports.libraryFiles[runtimePath]; if (runtimeText == null) { @@ -706,7 +679,7 @@ exports.main = function main(argv, options, callback) { } // Print files and exit if listFiles - if (args.listFiles) { + if (opts.listFiles) { // FIXME: not a proper C-like API stderr.write(program.sources.map(s => s.normalizedPath).sort().join(EOL) + EOL); return callback(null); @@ -744,7 +717,7 @@ exports.main = function main(argv, options, callback) { } // Validate the module if requested - if (!args.noValidate) { + if (!opts.noValidate) { stats.validateCount++; let isValid; stats.validateTime += measure(() => { @@ -757,32 +730,32 @@ exports.main = function main(argv, options, callback) { } // Set Binaryen-specific options - if (args.trapMode === "clamp") { + if (opts.trapMode === "clamp") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-clamp"); }); - } else if (args.trapMode === "js") { + } else if (opts.trapMode === "js") { stats.optimizeCount++; stats.optimizeTime += measure(() => { module.runPass("trap-mode-js"); }); - } else if (args.trapMode !== "allow") { + } else if (opts.trapMode !== "allow") { module.dispose(); return callback(Error("Unsupported trap mode")); } // Optimize the module - const debugInfo = args.debug; - const usesARC = args.runtime == "half" || args.runtime == "full"; - const converge = args.converge; + const debugInfo = opts.debug; + const usesARC = opts.runtime == "half" || opts.runtime == "full"; + const converge = opts.converge; const runPasses = []; - if (args.runPasses) { - if (typeof args.runPasses === "string") { - args.runPasses = args.runPasses.split(","); + if (opts.runPasses) { + if (typeof opts.runPasses === "string") { + opts.runPasses = opts.runPasses.split(","); } - if (args.runPasses.length) { - args.runPasses.forEach(pass => { + if (opts.runPasses.length) { + opts.runPasses.forEach(pass => { if (runPasses.indexOf(pass = pass.trim()) < 0) runPasses.push(pass); }); @@ -812,30 +785,30 @@ exports.main = function main(argv, options, callback) { }); // Prepare output - if (!args.noEmit) { - if (args.outFile != null) { - if (/\.was?t$/.test(args.outFile) && args.textFile == null) { - args.textFile = args.outFile; - } else if (/\.js$/.test(args.outFile) && args.jsFile == null) { - args.jsFile = args.outFile; - } else if (args.binaryFile == null) { - args.binaryFile = args.outFile; + if (!opts.noEmit) { + if (opts.outFile != null) { + if (/\.was?t$/.test(opts.outFile) && opts.textFile == null) { + opts.textFile = opts.outFile; + } else if (/\.js$/.test(opts.outFile) && opts.jsFile == null) { + opts.jsFile = opts.outFile; + } else if (opts.binaryFile == null) { + opts.binaryFile = opts.outFile; } } let hasStdout = false; - let hasOutput = args.textFile != null - || args.binaryFile != null - || args.jsFile != null - || args.tsdFile != null - || args.idlFile != null; + let hasOutput = opts.textFile != null + || opts.binaryFile != null + || opts.jsFile != null + || opts.tsdFile != null + || opts.idlFile != null; // Write binary - if (args.binaryFile != null) { - let basename = path.basename(args.binaryFile); - let sourceMapURL = args.sourceMap != null - ? args.sourceMap.length - ? args.sourceMap + if (opts.binaryFile != null) { + let basename = path.basename(opts.binaryFile); + let sourceMapURL = opts.sourceMap != null + ? opts.sourceMap.length + ? opts.sourceMap : "./" + basename + ".map" : null; @@ -845,8 +818,8 @@ exports.main = function main(argv, options, callback) { wasm = module.toBinary(sourceMapURL); }); - if (args.binaryFile.length) { - writeFile(args.binaryFile, wasm.output, baseDir); + if (opts.binaryFile.length) { + writeFile(opts.binaryFile, wasm.output, baseDir); } else { writeStdout(wasm.output); hasStdout = true; @@ -854,7 +827,7 @@ exports.main = function main(argv, options, callback) { // Post-process source map if (wasm.sourceMap != null) { - if (args.binaryFile.length) { + if (opts.binaryFile.length) { let map = JSON.parse(wasm.sourceMap); map.sourceRoot = "./" + basename; let contents = []; @@ -865,7 +838,7 @@ exports.main = function main(argv, options, callback) { }); map.sourcesContent = contents; writeFile(path.join( - path.dirname(args.binaryFile), + path.dirname(opts.binaryFile), path.basename(sourceMapURL) ).replace(/^\.\//, ""), JSON.stringify(map), baseDir); } else { @@ -875,14 +848,14 @@ exports.main = function main(argv, options, callback) { } // Write text (also fallback) - if (args.textFile != null || !hasOutput) { + if (opts.textFile != null || !hasOutput) { let wat; - if (args.textFile != null && args.textFile.length) { + if (opts.textFile != null && opts.textFile.length) { stats.emitCount++; stats.emitTime += measure(() => { wat = module.toText(); }); - writeFile(args.textFile, wat, baseDir); + writeFile(opts.textFile, wat, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -893,14 +866,14 @@ exports.main = function main(argv, options, callback) { } // Write WebIDL - if (args.idlFile != null) { + if (opts.idlFile != null) { let idl; - if (args.idlFile.length) { + if (opts.idlFile.length) { stats.emitCount++; stats.emitTime += measure(() => { idl = assemblyscript.buildIDL(program); }); - writeFile(args.idlFile, idl, baseDir); + writeFile(opts.idlFile, idl, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -912,14 +885,14 @@ exports.main = function main(argv, options, callback) { } // Write TypeScript definition - if (args.tsdFile != null) { + if (opts.tsdFile != null) { let tsd; - if (args.tsdFile.length) { + if (opts.tsdFile.length) { stats.emitCount++; stats.emitTime += measure(() => { tsd = assemblyscript.buildTSD(program); }); - writeFile(args.tsdFile, tsd, baseDir); + writeFile(opts.tsdFile, tsd, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -931,14 +904,14 @@ exports.main = function main(argv, options, callback) { } // Write JS (modifies the binary, so must be last) - if (args.jsFile != null) { + if (opts.jsFile != null) { let js; - if (args.jsFile.length) { + if (opts.jsFile.length) { stats.emitCount++; stats.emitTime += measure(() => { js = module.toAsmjs(); }); - writeFile(args.jsFile, js, baseDir); + writeFile(opts.jsFile, js, baseDir); } else if (!hasStdout) { stats.emitCount++; stats.emitTime += measure(() => { @@ -950,7 +923,7 @@ exports.main = function main(argv, options, callback) { } module.dispose(); - if (args.measure) { + if (opts.measure) { printStats(stats, stderr); } diff --git a/cli/asc.json b/cli/asc.json index 79a766639c..b9de41a05a 100644 --- a/cli/asc.json +++ b/cli/asc.json @@ -20,12 +20,14 @@ "config": { "category": "General", "description": "Configuration file to apply. CLI arguments take precedence.", - "type": "s" + "type": "s", + "cliOnly": true }, "target": { "category": "General", "description": "Target configuration to use. Defaults to 'release'.", - "type": "s" + "type": "s", + "cliOnly": true }, "optimize": { @@ -245,7 +247,9 @@ "transform": { "category": "API", "description": "Specifies the path to a custom transform to 'require'.", - "type": "S" + "type": "S", + "isPath": true, + "useNodeResolution": true }, "trapMode": { @@ -283,7 +287,8 @@ }, "extension": { "description": "Specifies an alternative file extension to use.", - "type": "s" + "type": "s", + "cliOnly": true }, "noUnsafe": { "description": [ @@ -318,7 +323,8 @@ "Adds one or multiple paths to custom library components and", "uses exports of all top-level files at this path as globals." ], - "type": "s" + "type": "S", + "isPath": true }, "path": { "description": [ @@ -326,7 +332,8 @@ "to node_modules. Prefers an 'ascMain' entry in a package's", "package.json and falls back to an inner 'assembly/' folder." ], - "type": "S" + "type": "S", + "isPath": true }, "traceResolution": { "description": "Enables tracing of package resolution.", diff --git a/cli/util/options.d.ts b/cli/util/options.d.ts index 5ec182734c..6a727628e9 100644 --- a/cli/util/options.d.ts +++ b/cli/util/options.d.ts @@ -58,7 +58,10 @@ interface HelpOptions { export function help(config: Config, options?: HelpOptions): string; /** Merges two sets of options into one, preferring the current over the parent set. */ -export function merge(config: Config, currentOptions: OptionSet, parentOptions: OptionSet): OptionSet; +export function merge(config: Config, currentOptions: OptionSet, parentOptions: OptionSet, parentBaseDir: string): OptionSet; + +/** Resolves a single relative path. Keeps absolute paths, otherwise prepends baseDir. */ +export function resolvePath(path: string, baseDir: string, useNodeResolution?: boolean): string; /** Populates default values on a parsed options result. */ export function addDefaults(config: Config, options: OptionSet): void; diff --git a/cli/util/options.js b/cli/util/options.js index 2dd9ba7244..1aedac3dc6 100644 --- a/cli/util/options.js +++ b/cli/util/options.js @@ -3,6 +3,7 @@ * @license Apache-2.0 */ +const path = require("path"); const colorsUtil = require("./colors"); // type | meaning @@ -171,22 +172,29 @@ function sanitizeValue(value, type) { } /** Merges two sets of options into one, preferring the current over the parent set. */ -function merge(config, currentOptions, parentOptions) { +function merge(config, currentOptions, parentOptions, parentBaseDir) { const mergedOptions = {}; - for (const [key, { type, mutuallyExclusive }] of Object.entries(config)) { + for (const [key, { type, mutuallyExclusive, isPath, useNodeResolution, cliOnly }] of Object.entries(config)) { let currentValue = sanitizeValue(currentOptions[key], type); let parentValue = sanitizeValue(parentOptions[key], type); if (currentValue == null) { if (parentValue != null) { // only parent value present + if (cliOnly) continue; if (Array.isArray(parentValue)) { let exclude; + if (isPath) { + parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution)); + } if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) { mergedOptions[key] = parentValue.filter(value => !exclude.includes(value)); } else { mergedOptions[key] = parentValue.slice(); } } else { + if (isPath) { + parentValue = resolvePath(parentValue, parentBaseDir, useNodeResolution); + } mergedOptions[key] = parentValue; } } @@ -200,7 +208,14 @@ function merge(config, currentOptions, parentOptions) { } else { // both current and parent values present if (Array.isArray(currentValue)) { + if (cliOnly) { + mergedOptions[key] = currentValue.slice(); + continue; + } let exclude; + if (isPath) { + parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution)); + } if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) { mergedOptions[key] = [ ...currentValue, @@ -222,6 +237,17 @@ function merge(config, currentOptions, parentOptions) { exports.merge = merge; +/** Resolves a single possibly relative path. Keeps absolute paths, otherwise prepends baseDir. */ +function resolvePath(p, baseDir, useNodeResolution = false) { + if (path.isAbsolute(p)) return p; + if (useNodeResolution && !p.startsWith(".")) { + return require.resolve(p, { paths: [ baseDir ] }); + } + return path.join(baseDir, p); +} + +exports.resolvePath = resolvePath; + /** Populates default values on a parsed options result. */ function addDefaults(config, options) { for (const [key, { default: defaultValue }] of Object.entries(config)) { From 7008203e9a36ca15c07b310316621272aa630d13 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 23 Jul 2020 08:22:27 +0200 Subject: [PATCH 4/8] improve showConfig --- cli/asc.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/asc.js b/cli/asc.js index 7f9c82bd69..6ebb9aa440 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -325,8 +325,10 @@ exports.main = function main(argv, options, callback) { // If showConfig print options and exit if (opts.showConfig) { - opts.entries = argv; - stderr.write(JSON.stringify(opts, null, 2)); + stderr.write(JSON.stringify({ + options: opts, + entries: argv + }, null, 2)); return callback(null); } From 25e9ffa96bf65c402232bda840ce1d8715490dc4 Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 24 Jul 2020 17:28:22 +0200 Subject: [PATCH 5/8] make node resolution give us relative paths --- cli/asc.js | 2 +- cli/util/options.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/asc.js b/cli/asc.js index 6ebb9aa440..ccb0f25329 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -274,7 +274,7 @@ exports.main = function main(argv, options, callback) { } // Set up base directory - const baseDir = opts.baseDir || "."; + const baseDir = path.normalize(opts.baseDir || "."); // Load additional options from asconfig.json let asconfigPath = optionsUtil.resolvePath(opts.config || "asconfig.json", baseDir); diff --git a/cli/util/options.js b/cli/util/options.js index 1aedac3dc6..62958fa4be 100644 --- a/cli/util/options.js +++ b/cli/util/options.js @@ -241,7 +241,7 @@ exports.merge = merge; function resolvePath(p, baseDir, useNodeResolution = false) { if (path.isAbsolute(p)) return p; if (useNodeResolution && !p.startsWith(".")) { - return require.resolve(p, { paths: [ baseDir ] }); + return path.relative(baseDir, require.resolve(p, { paths: [ baseDir ] })); } return path.join(baseDir, p); } From 9dd78b7eb9fa17b635853e6cc6181818286b1940 Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 24 Jul 2020 18:47:20 +0200 Subject: [PATCH 6/8] revert to absolute node module paths --- cli/util/options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/util/options.js b/cli/util/options.js index 62958fa4be..1aedac3dc6 100644 --- a/cli/util/options.js +++ b/cli/util/options.js @@ -241,7 +241,7 @@ exports.merge = merge; function resolvePath(p, baseDir, useNodeResolution = false) { if (path.isAbsolute(p)) return p; if (useNodeResolution && !p.startsWith(".")) { - return path.relative(baseDir, require.resolve(p, { paths: [ baseDir ] })); + return require.resolve(p, { paths: [ baseDir ] }); } return path.join(baseDir, p); } From 79403bdba304b4770eb70cdc446c5c609301d504 Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 24 Jul 2020 19:01:10 +0200 Subject: [PATCH 7/8] functional changes from #1408 --- cli/asc.d.ts | 4 ++-- cli/asc.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/asc.d.ts b/cli/asc.d.ts index 3244b4e80b..7957ac7c2f 100644 --- a/cli/asc.d.ts +++ b/cli/asc.d.ts @@ -56,7 +56,7 @@ export interface MemoryStream extends OutputStream { } /** Compiler options. */ -interface CompilerOptions { +export interface CompilerOptions { /** Prints just the compiler's version and exits. */ version?: boolean; /** Prints the help message and exits. */ @@ -146,7 +146,7 @@ interface CompilerOptions { } /** Compiler API options. */ -interface APIOptions { +export interface APIOptions { /** Standard output stream to use. */ stdout?: OutputStream; /** Standard error stream to use. */ diff --git a/cli/asc.js b/cli/asc.js index ccb0f25329..aad61e1749 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -309,7 +309,7 @@ exports.main = function main(argv, options, callback) { // Look up extended asconfig and repeat if (asconfig.extends) { - asconfigPath = optionsUtil.resolvePath(asconfig.extends, asconfigDir); + asconfigPath = optionsUtil.resolvePath(asconfig.extends, asconfigDir, true); asconfigFile = path.basename(asconfigPath); asconfigDir = path.dirname(asconfigPath); if (seenAsconfig.has(asconfigPath)) break; From 8821f7f40a74bbfb15430c0264f014fbb54143e0 Mon Sep 17 00:00:00 2001 From: Daniel Wirtz Date: Fri, 24 Jul 2020 19:03:10 +0200 Subject: [PATCH 8/8] Update cli/asc.js Co-authored-by: Max Graey --- cli/asc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/asc.js b/cli/asc.js index aad61e1749..eba383f20c 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -470,7 +470,7 @@ exports.main = function main(argv, options, callback) { let customLibDirs = []; if (opts.lib) { let lib = opts.lib; - if (typeof lib === "string") lib = lib.split(/\s*,\s*/); + if (typeof lib === "string") lib = lib.split(","); customLibDirs.push(...lib.map(p => p.trim())); customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom