build: omit named test source operands
This commit is contained in:
145
cmd/wcc/parse.c
145
cmd/wcc/parse.c
@@ -35,6 +35,17 @@ advance(Parser *p)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
advanceheaderimport(Parser *p)
|
||||
{
|
||||
Tok next;
|
||||
if (!lexheaderimport(p->l, &next))
|
||||
return 0;
|
||||
p->cur = next;
|
||||
p->hasla = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Tok
|
||||
peek(Parser *p)
|
||||
{
|
||||
@@ -1359,6 +1370,140 @@ parseuse(Parser *p)
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Parse one initial import without pulling the declaration that follows it
|
||||
* into the header pass. This intentionally has stricter, single-error
|
||||
* recovery than parseuse: named test-source build loading needs only decide
|
||||
* whether the package/import header itself is valid. */
|
||||
static Node *
|
||||
parseheaderuse(Parser *p)
|
||||
{
|
||||
Pos pp = p->cur.pos;
|
||||
advance(p);
|
||||
Node *n = newnode(p->a, N_USE, pp);
|
||||
n->usefile = p->cur.pos.file;
|
||||
n->useline = p->cur.pos.line;
|
||||
n->usecol = p->cur.pos.col;
|
||||
const char *alias = NULL;
|
||||
const char *first;
|
||||
if (p->cur.kind == TK_UNDER) {
|
||||
n->useblank = 1;
|
||||
advance(p);
|
||||
} else if (p->cur.kind != TK_IDENT) {
|
||||
errorf(p->cur.pos, "expected identifier, got %s",
|
||||
tokname(p->cur.kind));
|
||||
p->errs++;
|
||||
return n;
|
||||
}
|
||||
if (p->cur.kind != TK_IDENT) {
|
||||
errorf(p->cur.pos, "expected identifier, got %s",
|
||||
tokname(p->cur.kind));
|
||||
p->errs++;
|
||||
return n;
|
||||
}
|
||||
first = p->cur.text;
|
||||
advance(p);
|
||||
if (!n->useblank && p->cur.kind == TK_IDENT) {
|
||||
alias = first;
|
||||
first = p->cur.text;
|
||||
advance(p);
|
||||
}
|
||||
const char *leaf = first;
|
||||
const char *path = leaf;
|
||||
while (p->cur.kind == TK_DOT) {
|
||||
advance(p);
|
||||
if (p->cur.kind != TK_IDENT) {
|
||||
errorf(p->cur.pos, "expected identifier, got %s",
|
||||
tokname(p->cur.kind));
|
||||
p->errs++;
|
||||
return n;
|
||||
}
|
||||
leaf = p->cur.text;
|
||||
path = aprintf(p->a, "%s.%s", path, leaf);
|
||||
advance(p);
|
||||
}
|
||||
if (!n->useblank) {
|
||||
n->str = alias ? alias : leaf;
|
||||
n->strlen = strlen(n->str);
|
||||
}
|
||||
n->usesource = path;
|
||||
n->usepath = path;
|
||||
n->usealias = alias;
|
||||
if (p->cur.kind != TK_SEMI) {
|
||||
errorf(p->cur.pos, "expected ';' after import");
|
||||
p->errs++;
|
||||
return n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Go's named-file loader parses a valid source only through its initial
|
||||
* package/import section. Keep the broader parseimports recovery pass for
|
||||
* graph-bearing sources, but give actionless test-source omission a boundary
|
||||
* that cannot diagnose late imports or an invalid ordinary declaration body. */
|
||||
Node *
|
||||
parsepackageheader(Parser *p)
|
||||
{
|
||||
Pos fp = { p->l->file, 1, 1 };
|
||||
Node *file = newnode(p->a, N_FILE, fp);
|
||||
Node *head = NULL, *tail = NULL;
|
||||
|
||||
while (p->cur.kind == TK_MODPATH || p->cur.kind == TK_MODRESET) {
|
||||
if (p->cur.kind == TK_MODPATH) {
|
||||
p->pathmod = p->cur.text;
|
||||
p->curmod = p->cur.text;
|
||||
p->resetmod = NULL;
|
||||
} else {
|
||||
p->pathmod = NULL;
|
||||
p->curmod = p->cur.text;
|
||||
p->resetmod = p->cur.text;
|
||||
}
|
||||
p->sourceid++;
|
||||
advance(p);
|
||||
}
|
||||
if (p->cur.kind != TK_MODULE) {
|
||||
errorf(p->cur.pos, "invalid or missing package clause");
|
||||
p->errs++;
|
||||
return file;
|
||||
}
|
||||
Pos pp = p->cur.pos;
|
||||
advance(p);
|
||||
if (p->cur.kind != TK_IDENT) {
|
||||
errorf(p->cur.pos, "invalid or missing package clause");
|
||||
p->errs++;
|
||||
return file;
|
||||
}
|
||||
const char *name = p->cur.text;
|
||||
advance(p);
|
||||
if (p->cur.kind != TK_SEMI) {
|
||||
errorf(p->cur.pos, "expected ';' after package name");
|
||||
p->errs++;
|
||||
return file;
|
||||
}
|
||||
p->curpkg = name;
|
||||
if (p->pathmod == NULL && p->resetmod == NULL)
|
||||
p->curmod = name;
|
||||
file->module = name;
|
||||
file->pkgname = name;
|
||||
file->sourceid = p->sourceid;
|
||||
file->pos = pp;
|
||||
|
||||
while (advanceheaderimport(p)) {
|
||||
Node *d = parseheaderuse(p);
|
||||
d->module = p->curmod;
|
||||
d->pkgname = p->curpkg;
|
||||
d->sourceid = p->sourceid;
|
||||
if (head == NULL)
|
||||
head = d;
|
||||
else
|
||||
tail->next = d;
|
||||
tail = d;
|
||||
if (p->errs != 0)
|
||||
break;
|
||||
}
|
||||
file->list = head;
|
||||
return file;
|
||||
}
|
||||
|
||||
Node *
|
||||
parseimports(Parser *p)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user