compiler: load imports and enforce package exports
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user