n->op = ONONAME;
s->def = n;
}
+ if(n->oldref < 100)
+ n->oldref++;
if(n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
- // inner func is referring to var
- // in outer func.
+ // inner func is referring to var in outer func.
+ //
+ // TODO(rsc): If there is an outer variable x and we
+ // are parsing x := 5 inside the closure, until we get to
+ // the := it looks like a reference to the outer x so we'll
+ // make x a closure variable unnecessarily.
if(n->closure == N || n->closure->funcdepth != funcdepth) {
// create new closure var.
c = nod(ONAME, N, N);
}
if(n->sym->block == block)
continue;
+
+ // If we created an ONONAME just for this :=,
+ // delete it, to avoid confusion with top-level imports.
+ if(n->op == ONONAME && n->oldref < 100 && --n->oldref == 0)
+ n->sym->def = N;
+
nnew++;
n = newname(n->sym);
declare(n, dclcontext);
pack = nod(OPACK, N, N);
pack->sym = import;
pack->lineno = $1;
- pack->pline = importline;
if(my == S)
my = import;
if(my->name[0] == '_' && my->name[1] == '\0')
break;
- // TODO(rsc): this line is needed for a package
- // which does bytes := in a function, which creates
- // an ONONAME for bytes, but then a different file
- // imports "bytes". more generally we need to figure out
- // what it means if one file imports "bytes" and another
- // declares a top-level name.
- if(my->def && my->def->op == ONONAME)
- my->def = N;
-
+ if(my->def) {
+ lineno = $1;
+ redeclare(my, "as imported package name");
+ }
my->def = pack;
my->lastlineno = $1;
import->block = 1; // at top level
$$ = parserline();
pkgimportname = S;
pkgmyname = $1;
- if($1->def && ($1->name[0] != '_' || $1->name[1] != '\0'))
- redeclare($1, "as imported package name");
importfile(&$2, $$);
}
| '.' LLITERAL
int32 c;
int len;
- // Once we push the new file, we will not be able
- // to print the current lineno correctly with %L.
- // In case that line is the line of the import (likely),
- // save the text for use in error messages.
- importline = smprint("%L", line);
-
-// TODO: don't bother reloading imports more than once
+ // TODO(rsc): don't bother reloading imports more than once
if(f->ctype != CTSTR) {
yyerror("import statement not a string");
// assume .a files move (get installed)
// so don't record the full path.
p = file + len - f->u.sval->len - 2;
- linehist(p, 0, 0);
linehist(p, -1, 1); // acts as #pragma lib
} else {
// assume .6 files don't move around
// so do record the full path
- linehist(file, 0, 0);
linehist(file, -1, 0);
}
void
unimportfile(void)
{
- linehist(nil, 0, 0);
-
if(curio.bin != nil) {
Bterm(curio.bin);
curio.bin = nil;
cannedimports(char *file, char *cp)
{
lexlineno++; // if sys.6 is included on line 1,
- linehist(file, 0, 0); // the debugger gets confused
pushedio = curio;
curio.bin = nil;
if(c != 0) {
curio.peekc = curio.peekc1;
curio.peekc1 = 0;
- if(c == '\n')
+ if(c == '\n' && pushedio.bin == nil)
lexlineno++;
return c;
}
return EOF;
case '\n':
- lexlineno++;
+ if(pushedio.bin == nil)
+ lexlineno++;
break;
}
return c;
{
curio.peekc1 = curio.peekc;
curio.peekc = c;
- if(c == '\n')
+ if(c == '\n' && pushedio.bin == nil)
lexlineno--;
}
// name, so that the name cannot be redeclared
// as a non-package in other files.
if(!s->def->used) {
- print("%s: imported and not used: %s\n", s->def->pline, s->def->sym->name);
+ print("%L: imported and not used: %s\n", s->def->lineno, s->def->sym->name);
nerrors++;
}
s->def = N;
// throw away top-level name left over
// from previous import . "x"
if(s->def->pack != N && !s->def->pack->used) {
- print("%s: imported and not used: %s\n", s->def->pack->pline, s->def->pack->sym->name);
+ print("%L: imported and not used: %s\n", s->def->pack->lineno, s->def->pack->sym->name);
nerrors++;
s->def->pack->used = 1;
}