ww: unify directory package-test products

This commit is contained in:
2026-08-15 01:27:16 +09:00
parent 9c9bed4e65
commit 8dad2755b3
10 changed files with 1553 additions and 485 deletions

View File

@@ -373,7 +373,7 @@ main(int argc, char **argv)
const char *out = NULL;
const char *wwiout = NULL; /* -I <out.wwi>: M2 export-data producer */
const char *testsupport = NULL;
const char *testtarget = NULL;
const char **testtargets = calloc((size_t)argc, sizeof *testtargets);
const char *packageinit = NULL;
const char *initdispatch = NULL;
int testmode = 0;
@@ -385,14 +385,16 @@ main(int argc, char **argv)
* only; treat `.wwi` deps as external) */
struct importin *imports = calloc((size_t)argc, sizeof *imports);
struct importmap *maps = calloc((size_t)argc, sizeof *maps);
if (imports == NULL || maps == NULL) {
if (imports == NULL || maps == NULL || testtargets == NULL) {
fputs("w6c: out of memory\n", stderr);
free(testtargets);
free(maps);
free(imports);
return 1;
}
int nimports = 0;
int nmaps = 0;
int ntesttargets = 0;
for (int i = 1; i < argc; i++) {
const char *a = argv[i];
if (strcmp(a, "-o") == 0 && i + 1 < argc) {
@@ -430,7 +432,7 @@ main(int argc, char **argv)
fputs("w6c: --test-target-package requires arg\n", stderr);
return 2;
}
testtarget = argv[++i];
testtargets[ntesttargets++] = argv[++i];
} else if (strcmp(a, "-c") == 0) {
sepmode = 1;
} else if (strcmp(a, "--import") == 0) {
@@ -535,12 +537,17 @@ main(int argc, char **argv)
fputs("w6c: invalid --test-support-module\n", stderr);
return 2;
}
if (testtarget != NULL && (!sepmode || !testmode
|| testtarget[0] == '\0')) {
fputs("w6c: invalid --test-target-package\n", stderr);
return 2;
}
if (testtarget != NULL) {
for (int ti = 0; ti < ntesttargets; ti++) {
const char *testtarget = testtargets[ti];
if (!sepmode || !testmode || testtarget[0] == '\0') {
fputs("w6c: invalid --test-target-package\n", stderr);
return 2;
}
if (ti > 0 && strcmp(testtargets[ti - 1], testtarget) >= 0) {
fputs("w6c: --test-target-package paths must be sorted and unique\n",
stderr);
return 2;
}
int direct = 0;
for (int i = 0; i < nimports; i++)
if (strcmp(imports[i].path, testtarget) == 0)
@@ -621,11 +628,11 @@ main(int argc, char **argv)
if (bind_import_names(file->list, imports, nimports, file,
testsupport) < 0)
return 1;
if (testtarget != NULL) {
for (int ti = 0; ti < ntesttargets; ti++) {
int seen = 0;
for (Node *u = file->list; u; u = u->next) {
if (u->kind != N_USE || u->imported || u->usepath == NULL
|| strcmp(u->usepath, testtarget) != 0)
|| strcmp(u->usepath, testtargets[ti]) != 0)
continue;
u->str = u->usepath;
u->strlen = strlen(u->usepath);
@@ -646,7 +653,8 @@ main(int argc, char **argv)
c.is_test = testmode;
c.is_test_package = testpackage;
if (testsupport != NULL) c.test_module = testsupport;
c.test_target = testtarget;
c.test_targets = testtargets;
c.n_test_targets = ntesttargets;
c.sep_mode = sepmode;
c.package_init_symbol = packageinit;
check_file(&c, file);

View File

@@ -2869,7 +2869,8 @@ check_init(Checker *c, Arena *a)
c->is_test = 0; /* #15: caller (w6c main) sets it after init */
c->is_test_package = 0;
c->test_module = "test";
c->test_target = NULL;
c->test_targets = NULL;
c->n_test_targets = 0;
typesinit(a);
c->top = newscope(a, NULL);
c->cur = c->top;
@@ -3995,6 +3996,15 @@ check_import_usage_and_collisions(Checker *c, Node *file)
}
}
static int
check_test_target(const Checker *c, const char *path)
{
if (path == NULL) return 0;
for (int i = 0; i < c->n_test_targets; i++)
if (strcmp(c->test_targets[i], path) == 0) return 1;
return 0;
}
void
check_file(Checker *c, Node *file)
{
@@ -4018,8 +4028,7 @@ check_file(Checker *c, Node *file)
&& !u->imported && u->sourceid == file->sourceid
&& u->usepath
&& (strcmp(u->usepath, c->test_module) == 0
|| (c->test_target != NULL
&& strcmp(u->usepath, c->test_target) == 0)))
|| check_test_target(c, u->usepath)))
u->used = 1;
if (u->kind == N_USE && !u->imported
&& u->sourceid == file->sourceid
@@ -4383,9 +4392,8 @@ check_file(Checker *c, Node *file)
* package as `main`: that would collide with its own entry.
* This is a compiler-owned binding, never source alias syntax;
* use the canonical target path as its private qualifier. */
if (c->test_target != NULL
&& strcmp(d->module, c->test_target) == 0)
alias = c->test_target;
if (check_test_target(c, d->module))
alias = d->module;
id = newnode(c->a, N_DOT, fp);
id->lhs = newnode(c->a, N_IDENT, fp);
id->lhs->str = alias;

View File

@@ -613,8 +613,8 @@ struct Checker {
* bodies and export compiler-private metadata,
* but do not synthesize an entry. */
const char *test_module; /* generated dispatcher support qualifier */
const char *test_target; /* canonical target path used only as the
* compiler-owned generated-main qualifier */
const char **test_targets; /* canonical generated-main target paths */
int n_test_targets;
int sep_mode; /* -c package compilation: imported interfaces are
* present, so absent members are hard export errors. */
Node *synth_test_run; /* exact compiler-generated support.run DOT;

File diff suppressed because it is too large Load Diff