// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include	<u.h>
#include	<libc.h>
#include	"go.h"
#include	"y.tab.h"

static NodeList *asmlist;

static void	dumpexporttype(Type *t);

// Mark n's symbol as exported
void
exportsym(Node *n)
{
	if(n == N || n->sym == S)
		return;
	if(n->sym->flags & (SymExport|SymPackage)) {
		if(n->sym->flags & SymPackage)
			yyerror("export/package mismatch: %S", n->sym);
		return;
	}
	n->sym->flags |= SymExport;

	if(debug['E'])
		print("export symbol %S\n", n->sym);
	exportlist = list(exportlist, n);
}

int
exportname(char *s)
{
	Rune r;

	if((uchar)s[0] < Runeself)
		return 'A' <= s[0] && s[0] <= 'Z';
	chartorune(&r, s);
	return isupperrune(r);
}

static int
initname(char *s)
{
	return strcmp(s, "init") == 0;
}

// exportedsym reports whether a symbol will be visible
// to files that import our package.
static int
exportedsym(Sym *sym)
{
	// Builtins are visible everywhere.
	if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg)
		return 1;

	return sym->pkg == localpkg && exportname(sym->name);
}

void
autoexport(Node *n, int ctxt)
{
	if(n == N || n->sym == S)
		return;
	if((ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN)
		return;
	if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left)	// method
		return;
	// -A is for cmd/gc/mkbuiltin script, so export everything
	if(debug['A'] || exportname(n->sym->name) || initname(n->sym->name))
		exportsym(n);
	if(asmhdr && n->sym->pkg == localpkg && !(n->sym->flags & SymAsm)) {
		n->sym->flags |= SymAsm;
		asmlist = list(asmlist, n);
	}
		
}

static void
dumppkg(Pkg *p)
{
	char *suffix;

	if(p == nil || p == localpkg || p->exported || p == builtinpkg)
		return;
	p->exported = 1;
	suffix = "";
	if(!p->direct)
		suffix = " // indirect";
	Bprint(bout, "\timport %s \"%Z\"%s\n", p->name, p->path, suffix);
}

// Look for anything we need for the inline body
static void reexportdep(Node *n);
static void
reexportdeplist(NodeList *ll)
{
	for(; ll ;ll=ll->next)
		reexportdep(ll->n);
}

static void
reexportdep(Node *n)
{
	Type *t;

	if(!n)
		return;

	//print("reexportdep %+hN\n", n);
	switch(n->op) {
	case ONAME:
		switch(n->class&~PHEAP) {
		case PFUNC:
			// methods will be printed along with their type
			// nodes for T.Method expressions
			if(n->left && n->left->op == OTYPE)
				break;
			// nodes for method calls.
			if(!n->type || n->type->thistuple > 0)
				break;
			// fallthrough
		case PEXTERN:
			if(n->sym && !exportedsym(n->sym)) {
				if(debug['E'])
					print("reexport name %S\n", n->sym);
				exportlist = list(exportlist, n);
			}
		}
		break;

	case ODCL:
		// Local variables in the bodies need their type.
		t = n->left->type;
		if(t != types[t->etype] && t != idealbool && t != idealstring) {
			if(isptr[t->etype])
				t = t->type;
			if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
				if(debug['E'])
					print("reexport type %S from declaration\n", t->sym);
				exportlist = list(exportlist, t->sym->def);
			}
		}
		break;

	case OLITERAL:
		t = n->type;
		if(t != types[n->type->etype] && t != idealbool && t != idealstring) {
			if(isptr[t->etype])
				t = t->type;
			if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
				if(debug['E'])
					print("reexport literal type %S\n", t->sym);
				exportlist = list(exportlist, t->sym->def);
			}
		}
		// fallthrough
	case OTYPE:
		if(n->sym && !exportedsym(n->sym)) {
			if(debug['E'])
				print("reexport literal/type %S\n", n->sym);
			exportlist = list(exportlist, n);
		}
		break;

	// for operations that need a type when rendered, put the type on the export list.
	case OCONV:
	case OCONVIFACE:
	case OCONVNOP:
	case ORUNESTR:
	case OARRAYBYTESTR:
	case OARRAYRUNESTR:
	case OSTRARRAYBYTE:
	case OSTRARRAYRUNE:
	case ODOTTYPE:
	case ODOTTYPE2:
	case OSTRUCTLIT:
	case OARRAYLIT:
	case OPTRLIT:
	case OMAKEMAP:
	case OMAKESLICE:
	case OMAKECHAN:
		t = n->type;
		if(!t->sym && t->type)
			t = t->type;
		if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
			if(debug['E'])
				print("reexport type for expression %S\n", t->sym);
			exportlist = list(exportlist, t->sym->def);
		}
		break;
	}

	reexportdep(n->left);
	reexportdep(n->right);
	reexportdeplist(n->list);
	reexportdeplist(n->rlist);
	reexportdeplist(n->ninit);
	reexportdep(n->ntest);
	reexportdep(n->nincr);
	reexportdeplist(n->nbody);
	reexportdeplist(n->nelse);
}


static void
dumpexportconst(Sym *s)
{
	Node *n;
	Type *t;

	n = s->def;
	typecheck(&n, Erv);
	if(n == N || n->op != OLITERAL)
		fatal("dumpexportconst: oconst nil: %S", s);

	t = n->type;	// may or may not be specified
	dumpexporttype(t);

	if(t != T && !isideal(t))
		Bprint(bout, "\tconst %#S %#T = %#V\n", s, t, &n->val);
	else
		Bprint(bout, "\tconst %#S = %#V\n", s, &n->val);
}

static void
dumpexportvar(Sym *s)
{
	Node *n;
	Type *t;

	n = s->def;
	typecheck(&n, Erv|Ecall);
	if(n == N || n->type == T) {
		yyerror("variable exported but not defined: %S", s);
		return;
	}

	t = n->type;
	dumpexporttype(t);

	if(t->etype == TFUNC && n->class == PFUNC) {
		if (n->inl) {
			// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
			// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
			if(debug['l'] < 2)
				typecheckinl(n);
			// NOTE: The space after %#S here is necessary for ld's export data parser.
			Bprint(bout, "\tfunc %#S %#hT { %#H }\n", s, t, n->inl);
			reexportdeplist(n->inl);
		} else
			Bprint(bout, "\tfunc %#S %#hT\n", s, t);
	} else
		Bprint(bout, "\tvar %#S %#T\n", s, t);
}

static int
methodbyname(const void *va, const void *vb)
{
	Type *a, *b;
	
	a = *(Type**)va;
	b = *(Type**)vb;
	return strcmp(a->sym->name, b->sym->name);
}

static void
dumpexporttype(Type *t)
{
	Type *f;
	Type **m;
	int i, n;

	if(t == T)
		return;
	if(t->printed || t == types[t->etype] || t == bytetype || t == runetype || t == errortype)
		return;
	t->printed = 1;

	if(t->sym != S && t->etype != TFIELD)
		dumppkg(t->sym->pkg);

	dumpexporttype(t->type);
	dumpexporttype(t->down);

	if (t->sym == S || t->etype == TFIELD)
		return;

	n = 0;
	for(f=t->method; f!=T; f=f->down) {	
		dumpexporttype(f);
		n++;
	}

	m = mal(n*sizeof m[0]);
	i = 0;
	for(f=t->method; f!=T; f=f->down)
		m[i++] = f;
	qsort(m, n, sizeof m[0], methodbyname);

	Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
	for(i=0; i<n; i++) {
		f = m[i];
		if(f->nointerface)
			Bprint(bout, "\t//go:nointerface\n");
		if (f->type->nname && f->type->nname->inl) { // nname was set by caninl
			// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
			// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
			if(debug['l'] < 2)
				typecheckinl(f->type->nname);
			Bprint(bout, "\tfunc (%#T) %#hhS %#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
			reexportdeplist(f->type->nname->inl);
		} else
			Bprint(bout, "\tfunc (%#T) %#hhS %#hT\n", getthisx(f->type)->type, f->sym, f->type);
	}
}

static void
dumpsym(Sym *s)
{
	if(s->flags & SymExported)
		return;
	s->flags |= SymExported;

	if(s->def == N) {
		yyerror("unknown export symbol: %S", s);
		return;
	}
//	print("dumpsym %O %+S\n", s->def->op, s);
	dumppkg(s->pkg);

	switch(s->def->op) {
	default:
		yyerror("unexpected export symbol: %O %S", s->def->op, s);
		break;

	case OLITERAL:
		dumpexportconst(s);
		break;

	case OTYPE:
		if(s->def->type->etype == TFORW)
			yyerror("export of incomplete type %S", s);
		else
			dumpexporttype(s->def->type);
		break;

	case ONAME:
		dumpexportvar(s);
		break;
	}
}

void
dumpexport(void)
{
	NodeList *l;
	int32 i, lno;
	Pkg *p;

	lno = lineno;

	Bprint(bout, "\n$$\npackage %s", localpkg->name);
	if(safemode)
		Bprint(bout, " safe");
	Bprint(bout, "\n");

	for(i=0; i<nelem(phash); i++)
		for(p=phash[i]; p; p=p->link)
			if(p->direct)
				dumppkg(p);

	for(l=exportlist; l; l=l->next) {
		lineno = l->n->lineno;
		dumpsym(l->n->sym);
	}

	Bprint(bout, "\n$$\n");
	lineno = lno;
}

/*
 * import
 */

/*
 * return the sym for ss, which should match lexical
 */
Sym*
importsym(Sym *s, int op)
{
	char *pkgstr;

	if(s->def != N && s->def->op != op) {
		pkgstr = smprint("during import \"%Z\"", importpkg->path);
		redeclare(s, pkgstr);
	}

	// mark the symbol so it is not reexported
	if(s->def == N) {
		if(exportname(s->name) || initname(s->name))
			s->flags |= SymExport;
		else
			s->flags |= SymPackage;	// package scope
	}
	return s;
}

/*
 * return the type pkg.name, forward declaring if needed
 */
Type*
pkgtype(Sym *s)
{
	Type *t;

	importsym(s, OTYPE);
	if(s->def == N || s->def->op != OTYPE) {
		t = typ(TFORW);
		t->sym = s;
		s->def = typenod(t);
	}
	if(s->def->type == T)
		yyerror("pkgtype %S", s);
	return s->def->type;
}

void
importimport(Sym *s, Strlit *z)
{
	// Informational: record package name
	// associated with import path, for use in
	// human-readable messages.
	Pkg *p;

	if(isbadimport(z))
		errorexit();
	p = mkpkg(z);
	if(p->name == nil) {
		p->name = s->name;
		pkglookup(s->name, nil)->npkg++;
	} else if(strcmp(p->name, s->name) != 0)
		yyerror("conflicting names %s and %s for package \"%Z\"", p->name, s->name, p->path);
	
	if(!incannedimport && myimportpath != nil && strcmp(z->s, myimportpath) == 0) {
		yyerror("import \"%Z\": package depends on \"%Z\" (import cycle)", importpkg->path, z);
		errorexit();
	}
}

void
importconst(Sym *s, Type *t, Node *n)
{
	Node *n1;

	importsym(s, OLITERAL);
	convlit(&n, t);

	if(s->def != N)	 // TODO: check if already the same.
		return;

	if(n->op != OLITERAL) {
		yyerror("expression must be a constant");
		return;
	}

	if(n->sym != S) {
		n1 = nod(OXXX, N, N);
		*n1 = *n;
		n = n1;
	}
	n->orig = newname(s);
	n->sym = s;
	declare(n, PEXTERN);

	if(debug['E'])
		print("import const %S\n", s);
}

void
importvar(Sym *s, Type *t)
{
	Node *n;

	importsym(s, ONAME);
	if(s->def != N && s->def->op == ONAME) {
		if(eqtype(t, s->def->type))
			return;
		yyerror("inconsistent definition for var %S during import\n\t%T (in \"%Z\")\n\t%T (in \"%Z\")", s, s->def->type, s->importdef->path, t, importpkg->path);
	}
	n = newname(s);
	s->importdef = importpkg;
	n->type = t;
	declare(n, PEXTERN);

	if(debug['E'])
		print("import var %S %lT\n", s, t);
}

void
importtype(Type *pt, Type *t)
{
	Node *n;

	// override declaration in unsafe.go for Pointer.
	// there is no way in Go code to define unsafe.Pointer
	// so we have to supply it.
	if(incannedimport &&
	   strcmp(importpkg->name, "unsafe") == 0 &&
	   strcmp(pt->nod->sym->name, "Pointer") == 0) {
		t = types[TUNSAFEPTR];
	}

	if(pt->etype == TFORW) {
		n = pt->nod;
		copytype(pt->nod, t);
		pt->nod = n;		// unzero nod
		pt->sym->importdef = importpkg;
		pt->sym->lastlineno = parserline();
		declare(n, PEXTERN);
		checkwidth(pt);
	} else if(!eqtype(pt->orig, t))
		yyerror("inconsistent definition for type %S during import\n\t%lT (in \"%Z\")\n\t%lT (in \"%Z\")", pt->sym, pt, pt->sym->importdef->path, t, importpkg->path);

	if(debug['E'])
		print("import type %T %lT\n", pt, t);
}

void
dumpasmhdr(void)
{
	Biobuf *b;
	NodeList *l;
	Node *n;
	Type *t;

	b = Bopen(asmhdr, OWRITE);
	if(b == nil)
		fatal("open %s: %r", asmhdr);
	Bprint(b, "// generated by %cg -asmhdr from package %s\n\n", thearch.thechar, localpkg->name);
	for(l=asmlist; l; l=l->next) {
		n = l->n;
		if(isblanksym(n->sym))
			continue;
		switch(n->op) {
		case OLITERAL:
			Bprint(b, "#define const_%s %#V\n", n->sym->name, &n->val);
			break;
		case OTYPE:
			t = n->type;
			if(t->etype != TSTRUCT || t->map != T || t->funarg)
				break;
			Bprint(b, "#define %s__size %d\n", t->sym->name, (int)t->width);
			for(t=t->type; t != T; t=t->down)
				if(!isblanksym(t->sym))
					Bprint(b, "#define %s_%s %d\n", n->sym->name, t->sym->name, (int)t->width);
			break;
		}
	}
	
	Bterm(b);
}
