Skip to content

Merge oldest parent first #1404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/asc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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. */
Expand Down
31 changes: 19 additions & 12 deletions cli/asc.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ 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;
const opts = optionsUtil.parse(argv, exports.options, false);
let args = optionsUtil.addDefaults(exports.options, opts.options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is happening too early, and is instead intended to be performed as the last step once CLI args and asconfigs have been fully processed. For that, we just need to apply the defaults for target and config early, independently of populating their values. Can either hardcode these or pull them from the config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed addDefaults so that it returns a new object. This way opts.options is untouched. Then at the end of the config it is merged back into args. It was the only way I found that fixed the issues your having in #1406.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I suspect that the underlying issue is that the relative path transform is applied to imported file names, in turn stripping the . from ./a, resulting in the packages test trying to find a, which resolves differently. While the changes in ordering here apparently prevent this, somehow, that doesn't look like a proper fix.

let cliArgs = opts.options;

argv = opts.arguments;
if (args.noColors) {
Expand Down Expand Up @@ -280,11 +281,14 @@ exports.main = function main(argv, options, callback) {
const seenAsconfig = new Set();
seenAsconfig.add(path.join(baseDir, args.config));

// First find all parent configs and add them each to the front
let entries = new Set();
while (asconfig) {
// merge target first, then merge options, then merge extended asconfigs
// First merge targets
if (asconfig.targets && asconfig.targets[target]) {
args = optionsUtil.merge(exports.options, asconfig.targets[target], args);
cliArgs = optionsUtil.merge(exports.options, cliArgs, asconfig.targets[target]);
}

if (asconfig.options) {
if (asconfig.options.transform) {
// ensure that a transform's path is relative to the current config
Expand All @@ -298,22 +302,20 @@ exports.main = function main(argv, options, callback) {
return p;
});
}
args = optionsUtil.merge(exports.options, args, asconfig.options);
cliArgs = optionsUtil.merge(exports.options, cliArgs, asconfig.options);
}

// entries are added to the compilation
if (asconfig.entries) {
for (const entry of asconfig.entries) {
argv.push(
path.isAbsolute(entry)
entries.add(
path.relative(baseDir, path.isAbsolute(entry)
? entry
// the entry is relative to the asconfig directory
: path.join(asconfigDir, entry)
);
));
}
}

// asconfig "extends" another config, merging options of it's parent
if (asconfig.extends) {
asconfigDir = path.isAbsolute(asconfig.extends)
// absolute extension path means we know the exact directory and location
Expand All @@ -329,12 +331,17 @@ exports.main = function main(argv, options, callback) {
asconfig = getAsconfig(fileName, asconfigDir, readFile);
}
} else {
asconfig = null; // finished resolving the configuration chain
break;
}
}
// Merge in cli args
args = optionsUtil.merge(exports.options, cliArgs, args);
// Add entries
argv = argv.concat(Array.from(entries));

// If showConfig print args and exit
if (args.showConfig) {
args.argv = argv;
stderr.write(JSON.stringify(args, null, 2));
return callback(null);
}
Expand Down
17 changes: 12 additions & 5 deletions cli/util/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (option.default != null && propagateDefaults) options[key] = option.default;
});

// iterate over argv
Expand Down Expand Up @@ -87,7 +87,9 @@ function parse(argv, config, propagateDefaults = true) {
} else unknown.push(arg);
}
while (i < k) trailing.push(argv[i++]); // trailing
if (propagateDefaults) addDefaults(config, options);
if (propagateDefaults) {
options = addDefaults(config, options);
}

return { options, unknown, arguments: args, trailing };
}
Expand Down Expand Up @@ -224,12 +226,17 @@ exports.merge = merge;

/** Populates default values on a parsed options result. */
function addDefaults(config, options) {
const newOptions = {};
for (const [key, { default: defaultValue }] of Object.entries(config)) {
if (options[key] == null && defaultValue != null) {
options[key] = defaultValue;
if (options[key] == null) {
if (defaultValue != null) {
newOptions[key] = defaultValue;
}
} else {
newOptions[key] = options[key];
}
}
return options;
return newOptions;
}

exports.addDefaults = addDefaults;
8 changes: 4 additions & 4 deletions tests/asconfig/complicated/assembly/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
assert(ASC_OPTIMIZE_LEVEL == 3);
assert(ASC_SHRINK_LEVEL == 1);
assert(ASC_FEATURE_SIMD);
assert(ASC_OPTIMIZE_LEVEL == 3, "expected optimize level == 3");
assert(ASC_SHRINK_LEVEL == 1, "expected shrink level == 1");
assert(ASC_FEATURE_SIMD, "expected SIMD enabled");
let size = memory.size();
trace("size", 1, size);
assert(size == 30);
assert(size == 30, "expected 30 got " + size.toString());
4 changes: 3 additions & 1 deletion tests/asconfig/extends/asconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
}
},
"options": {
"enable": ["simd"]
"enable": ["simd"],
"runtime": "half",
"noEmit": false
},
"extends": "./extends.json"
}
6 changes: 6 additions & 0 deletions tests/asconfig/extends/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"runtime": "half",
"noEmit": false,
"noAssert": true,
"enable": ["simd"]
}
4 changes: 3 additions & 1 deletion tests/asconfig/extends/extends.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
}
},
"options": {
"disable": ["simd"]
"disable": ["simd"],
"noEmit": true,
"noAssert": true
}
}
2 changes: 1 addition & 1 deletion tests/asconfig/extends/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"scripts": {
"test": "node ../index.js"
"test": "node ../index.js --showConfig && node ../index.js"
}
}
43 changes: 43 additions & 0 deletions tests/asconfig/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const asc = require("../../cli/asc");
const loader = require("../../lib/loader");
const args = process.argv.slice(2);
const path = require('path');
const fs = require("fs");

/** @type {string} */
let stderr;
/** @type {Uint8Array} */
let binary;
asc.main(["assembly/index.ts", "--outFile", "output.wasm", "--explicitStart", ...args], {
Expand All @@ -11,13 +15,51 @@ asc.main(["assembly/index.ts", "--outFile", "output.wasm", "--explicitStart", ..
} else if (name !== "output.wasm.map") {
throw Error("Unexpected output file: " + name);
}
},
stderr: {
write(s) {
stderr = s;
}
}

}, (err) => {
if (err) {
console.error(err);
console.error(stderr);
process.exit(1);
}

const jsonPath = path.join(process.cwd(), "expected.json");
if (fs.existsSync(jsonPath) && stderr) {
const actual = JSON.parse(stderr);
const expected = require(jsonPath);
let errored = false;
for (let name of Object.getOwnPropertyNames(expected)) {
if (actual[name] !== expected[name]) {
// If object check just first level
if (typeof actual[name] === 'object' && typeof expected[name] === 'object') {
let error = false;
for (let field of Object.getOwnPropertyNames(actual[name])) {
if (actual[name][field] !== expected[name][field]) {
error = true;
break;
}
}
if (!error) {
continue;
}
}
console.error(name + ": " + actual[name] + " expected " + expected[name]);
errored = true;
}
}
if (errored) {
process.exit(1);
}
process.exit(0);
}


if (!binary) {
console.error("No binary was generated for the asconfig test in " + process.cwd());
process.exit(1);
Expand All @@ -29,6 +71,7 @@ asc.main(["assembly/index.ts", "--outFile", "output.wasm", "--explicitStart", ..
theModule.exports._start();
} catch (err) {
console.error("The wasm module _start() function failed in " + process.cwd());
console.error(err);
process.exit(1);
}
return 0;
Expand Down
5 changes: 3 additions & 2 deletions tests/asconfig/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"private": true,
"scripts": {
"test": "npm run test:use-consts && npm run test:target && npm run test:entry-points && npm run test:complicated",
"test": "npm run test:use-consts && npm run test:target && npm run test:entry-points && npm run test:complicated && npm run test:extends",
"test:use-consts": "cd use-consts && npm run test",
"test:entry-points": "cd entry-points && npm run test",
"test:respect-inheritence": "cd respect-inheritence && npm run test",
"test:target": "cd target && npm run test",
"test:cyclical": "cd cyclical && npm run test",
"test:complicated": "cd complicated && npm run test"
"test:complicated": "cd complicated && npm run test",
"test:extends": "cd extends && npm run test"
}
}
4 changes: 3 additions & 1 deletion tests/asconfig/target/asconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@
"debug": true
}
},
"options": {}
"options": {
"runtime": "stub"
}
}
6 changes: 3 additions & 3 deletions tests/asconfig/target/assembly/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
assert(ASC_OPTIMIZE_LEVEL == 3);
assert(ASC_SHRINK_LEVEL == 1);
assert(ASC_FEATURE_SIMD);
assert(ASC_OPTIMIZE_LEVEL == 3, "expected optimize level == 3");
assert(ASC_SHRINK_LEVEL == 1, "expected shrink level == 1");
assert(ASC_FEATURE_SIMD, "expected SIMD enabled");
3 changes: 3 additions & 0 deletions tests/asconfig/target/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"runtime": "none"
}
2 changes: 1 addition & 1 deletion tests/asconfig/target/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"scripts": {
"test": "node ../index.js"
"test": "node ../index.js --target && node ../index.js --showConfig --runtime none"
}
}