compiler: load imports and enforce package exports

This commit is contained in:
2026-08-11 22:25:59 +09:00
parent 7bc96b4e03
commit db96422f74
14 changed files with 894 additions and 118 deletions

View File

@@ -77,6 +77,29 @@ must_contain(const char *src, const char *needle)
return 1;
}
static char *
imports_to_str(const char *src, int *errs, const char **pkg)
{
Arena *a = newarena();
Lex l;
Parser p;
lexinit(&l, a, "imports.ww", src, strlen(src));
parserinit(&p, a, &l);
Node *n = parseimports(&p);
*errs = p.errs + l.errs;
*pkg = n->module ? strdup(n->module) : NULL;
char *buf = NULL;
size_t len = 0;
FILE *f = open_memstream(&buf, &len);
if (f != NULL) {
astprint(f, n);
fclose(f);
}
freearena(a);
return buf;
}
int
main(void)
{
@@ -179,6 +202,68 @@ main(void)
if (!must_contain("fn f() i32 = { return a + b; };", "(bin +")) fail++;
if (!must_contain("@symbol(\"x\") fn f() void;", "(attr \"symbol\""))fail++;
{
const char *src =
"package main;\n"
"import zed;\n"
"fn f() void = { let s: str = \"import fake;\"; };\n"
"/* import hidden; */\n"
"import alpha;\n";
int errs;
const char *pkg;
char *got = imports_to_str(src, &errs, &pkg);
if (errs != 0 || pkg == NULL || strcmp(pkg, "main") != 0
|| got == NULL || strstr(got, "(use \"zed\"") == NULL
|| strstr(got, "(use \"alpha\"") == NULL
|| strstr(got, "fake") != NULL || strstr(got, "hidden") != NULL) {
fprintf(stderr, "imports-only parse mismatch:\n%s\n",
got ? got : "<null>");
fail++;
}
free((void *)pkg);
free(got);
}
{
int errs;
const char *pkg;
char *got = imports_to_str("package main;\nimport ;\n", &errs,
&pkg);
if (errs == 0) {
fputs("malformed import accepted\n", stderr);
fail++;
}
free((void *)pkg);
free(got);
}
{
int errs;
const char *pkg;
char *got = imports_to_str(
"package main;\n@trace import alpha;\n", &errs, &pkg);
if (errs == 0 || got == NULL
|| strstr(got, "(use \"alpha\"") == NULL) {
fputs("attributed import was not rejected and retained\n",
stderr);
fail++;
}
free((void *)pkg);
free(got);
}
{
int errs;
const char *pkg;
char *got = imports_to_str(
"//ww:module example.main\n"
"package main;\nimport alpha;\n", &errs, &pkg);
if (errs != 0 || pkg == NULL || strcmp(pkg, "main") != 0
|| got == NULL || strstr(got, "(use \"alpha\"") == NULL) {
fputs("imports-only parse rejected module boundary\n", stderr);
fail++;
}
free((void *)pkg);
free(got);
}
if (fail) {
fprintf(stderr, "%d parse tests failed\n", fail);
return 1;