ww imports: require imports before declarations
This commit is contained in:
@@ -497,12 +497,16 @@ export fn parseimports(p: *parser) *node = {
|
||||
let packages: *node = nil;
|
||||
let packagetail: *node = nil;
|
||||
let sawpackage: bool = false;
|
||||
// One import section precedes ordinary declarations. Keep parsing for
|
||||
// recovery, diagnosing the first import in each later source section.
|
||||
let previmport: bool = true;
|
||||
for (p.curkind != tkind.TK_EOF) {
|
||||
// Compiler/driver bundle markers carry package identity out of
|
||||
// band. They are not source declarations, so keep scanning for
|
||||
// the following package clause and imports.
|
||||
if (p.curkind == tkind.TK_MODPATH) {
|
||||
sawpackage = false;
|
||||
previmport = true;
|
||||
p.sourceid += 1;
|
||||
p.pathmod = p.curtext;
|
||||
p.curmod = p.curtext;
|
||||
@@ -514,6 +518,7 @@ export fn parseimports(p: *parser) *node = {
|
||||
if (p.curkind == tkind.TK_MODRESET) {
|
||||
let rp: str = p.curtext;
|
||||
sawpackage = false;
|
||||
previmport = true;
|
||||
p.sourceid += 1;
|
||||
advance(p);
|
||||
p.pathmod = "";
|
||||
@@ -526,6 +531,7 @@ export fn parseimports(p: *parser) *node = {
|
||||
let pf: str = p.curfile;
|
||||
let pl: i32 = p.curline;
|
||||
let pc: i32 = p.curcol;
|
||||
previmport = true;
|
||||
advance(p);
|
||||
if (p.curkind != tkind.TK_IDENT) {
|
||||
errmsg(p, "invalid or missing package clause");
|
||||
@@ -563,6 +569,10 @@ export fn parseimports(p: *parser) *node = {
|
||||
sawpackage = true;
|
||||
};
|
||||
if (p.curkind == tkind.TK_USE) {
|
||||
if (!previmport) {
|
||||
errmsg(p, "imports must appear before other declarations");
|
||||
};
|
||||
previmport = true;
|
||||
let d: *node = parseuse(p);
|
||||
d.nmod = p.curmod;
|
||||
d.pkgname = p.curpkg;
|
||||
@@ -571,6 +581,7 @@ export fn parseimports(p: *parser) *node = {
|
||||
tail = d;
|
||||
continue;
|
||||
};
|
||||
previmport = false;
|
||||
if (p.curkind == tkind.TK_AT) {
|
||||
skipimportattrs(p);
|
||||
if (p.curkind == tkind.TK_EXPORT) { advance(p); };
|
||||
@@ -618,6 +629,8 @@ export fn parsefile(p: *parser) *node = {
|
||||
let packages: *node = nil;
|
||||
let packagetail: *node = nil;
|
||||
let sawpackage: i32 = 0;
|
||||
// Full/direct parsing is the semantic twin of the imports-only pass.
|
||||
let previmport: bool = true;
|
||||
for (p.curkind != tkind.TK_EOF) {
|
||||
// `package foo;` — directory-as-module declaration. Every
|
||||
// primary section opens with one (`package main;` for an
|
||||
@@ -630,6 +643,7 @@ export fn parsefile(p: *parser) *node = {
|
||||
let pl: i32 = p.curline;
|
||||
let pc: i32 = p.curcol;
|
||||
sawpackage = 1;
|
||||
previmport = true;
|
||||
advance(p);
|
||||
let name: str;
|
||||
expectident(p, &name);
|
||||
@@ -658,6 +672,7 @@ export fn parsefile(p: *parser) *node = {
|
||||
// root-only bare-`main` rule, #32).
|
||||
if (p.curkind == tkind.TK_MODPATH) {
|
||||
sawpackage = 0;
|
||||
previmport = true;
|
||||
p.sourceid += 1;
|
||||
p.pathmod = p.curtext;
|
||||
p.curmod = p.curtext;
|
||||
@@ -677,6 +692,7 @@ export fn parsefile(p: *parser) *node = {
|
||||
// decls to bare — that usage is deliberate-only.
|
||||
if (p.curkind == tkind.TK_MODRESET) {
|
||||
sawpackage = 0;
|
||||
previmport = true;
|
||||
p.sourceid += 1;
|
||||
// #57: a path-carrying reset (sep primary body) mangles decls
|
||||
// on the dotted path so definer == importer, but leaves
|
||||
@@ -714,6 +730,11 @@ export fn parsefile(p: *parser) *node = {
|
||||
errmsg(p, "missing package clause");
|
||||
sawpackage = 1;
|
||||
};
|
||||
let thisimport: bool = p.curkind == tkind.TK_USE;
|
||||
if (thisimport && !previmport) {
|
||||
errmsg(p, "imports must appear before other declarations");
|
||||
};
|
||||
previmport = thisimport;
|
||||
let attrs = parseattrs(p);
|
||||
let exported: i32 = 0;
|
||||
if (p.curkind == tkind.TK_EXPORT) { exported = 1; advance(p); };
|
||||
|
||||
Reference in New Issue
Block a user