// 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.

// Parse input AST and prepare Prog structure.

package main

import (
	"fmt";
	"go/ast";
	"go/doc";
	"go/parser";
	"go/scanner";
	"os";
)

// A Cref refers to an expression of the form C.xxx in the AST.
type Cref struct {
	Name		string;
	Expr		*ast.Expr;
	Context		string;	// "type", "expr", or "call"
	TypeName	bool;	// whether xxx is a C type name
	Type		*Type;	// the type of xxx
	FuncType	*FuncType;
}

// A Prog collects information about a cgo program.
type Prog struct {
	AST		*ast.File;	// parsed AST
	Preamble	string;		// C preamble (doc comment on import "C")
	PackagePath	string;
	Package		string;
	Crefs		[]*Cref;
	Typedef		map[string]ast.Expr;
	Vardef		map[string]*Type;
	Funcdef		map[string]*FuncType;
	PtrSize		int64;
	GccOptions	[]string;
}

// A Type collects information about a type in both the C and Go worlds.
type Type struct {
	Size	int64;
	Align	int64;
	C	string;
	Go	ast.Expr;
}

// A FuncType collects information about a function type in both the C and Go worlds.
type FuncType struct {
	Params	[]*Type;
	Result	*Type;
	Go	*ast.FuncType;
}

func openProg(name string) *Prog {
	p := new(Prog);
	var err os.Error;
	p.AST, err = parser.ParsePkgFile("", name, parser.ParseComments);
	if err != nil {
		if list, ok := err.(scanner.ErrorList); ok {
			// If err is a scanner.ErrorList, its String will print just
			// the first error and then (+n more errors).
			// Instead, turn it into a new Error that will return
			// details for all the errors.
			for _, e := range list {
				fmt.Fprintln(os.Stderr, e)
			}
			os.Exit(2);
		}
		fatal("parsing %s: %s", name, err);
	}
	p.Package = p.AST.Name.Value;

	// Find the import "C" line and get any extra C preamble.
	// Delete the import "C" line along the way.
	sawC := false;
	w := 0;
	for _, decl := range p.AST.Decls {
		d, ok := decl.(*ast.GenDecl);
		if !ok {
			p.AST.Decls[w] = decl;
			w++;
			continue;
		}
		ws := 0;
		for _, spec := range d.Specs {
			s, ok := spec.(*ast.ImportSpec);
			if !ok || len(s.Path) != 1 || string(s.Path[0].Value) != `"C"` {
				d.Specs[ws] = spec;
				ws++;
				continue;
			}
			sawC = true;
			if s.Name != nil {
				error(s.Path[0].Pos(), `cannot rename import "C"`)
			}
			if s.Doc != nil {
				p.Preamble += doc.CommentText(s.Doc) + "\n"
			} else if len(d.Specs) == 1 && d.Doc != nil {
				p.Preamble += doc.CommentText(d.Doc) + "\n"
			}
		}
		if ws == 0 {
			continue
		}
		d.Specs = d.Specs[0:ws];
		p.AST.Decls[w] = d;
		w++;
	}
	p.AST.Decls = p.AST.Decls[0:w];

	if !sawC {
		error(noPos, `cannot find import "C"`)
	}

	// Accumulate pointers to uses of C.x.
	p.Crefs = make([]*Cref, 0, 8);
	walk(p.AST, p, "prog");
	return p;
}

func walk(x interface{}, p *Prog, context string) {
	switch n := x.(type) {
	case *ast.Expr:
		if sel, ok := (*n).(*ast.SelectorExpr); ok {
			// For now, assume that the only instance of capital C is
			// when used as the imported package identifier.
			// The parser should take care of scoping in the future,
			// so that we will be able to distinguish a "top-level C"
			// from a local C.
			if l, ok := sel.X.(*ast.Ident); ok && l.Value == "C" {
				i := len(p.Crefs);
				if i >= cap(p.Crefs) {
					new := make([]*Cref, 2*i);
					for j, v := range p.Crefs {
						new[j] = v
					}
					p.Crefs = new;
				}
				p.Crefs = p.Crefs[0 : i+1];
				p.Crefs[i] = &Cref{
					Name: sel.Sel.Value,
					Expr: n,
					Context: context,
				};
				break;
			}
		}
		walk(*n, p, context);

	// everything else just recurs
	default:
		error(noPos, "unexpected type %T in walk", x);
		panic();

	case nil:

	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
	case *ast.Field:
		walk(&n.Type, p, "type")
	case *ast.BadExpr:
	case *ast.Ident:
	case *ast.Ellipsis:
	case *ast.BasicLit:
	case *ast.StringList:
	case *ast.FuncLit:
		walk(n.Type, p, "type");
		walk(n.Body, p, "stmt");
	case *ast.CompositeLit:
		walk(&n.Type, p, "type");
		walk(n.Elts, p, "expr");
	case *ast.ParenExpr:
		walk(&n.X, p, context)
	case *ast.SelectorExpr:
		walk(&n.X, p, "selector")
	case *ast.IndexExpr:
		walk(&n.X, p, "expr");
		walk(&n.Index, p, "expr");
	case *ast.SliceExpr:
		walk(&n.X, p, "expr");
		walk(&n.Index, p, "expr");
		if n.End != nil {
			walk(&n.End, p, "expr")
		}
	case *ast.TypeAssertExpr:
		walk(&n.X, p, "expr");
		walk(&n.Type, p, "type");
	case *ast.CallExpr:
		walk(&n.Fun, p, "call");
		walk(n.Args, p, "expr");
	case *ast.StarExpr:
		walk(&n.X, p, context)
	case *ast.UnaryExpr:
		walk(&n.X, p, "expr")
	case *ast.BinaryExpr:
		walk(&n.X, p, "expr");
		walk(&n.Y, p, "expr");
	case *ast.KeyValueExpr:
		walk(&n.Key, p, "expr");
		walk(&n.Value, p, "expr");

	case *ast.ArrayType:
		walk(&n.Len, p, "expr");
		walk(&n.Elt, p, "type");
	case *ast.StructType:
		walk(n.Fields, p, "field")
	case *ast.FuncType:
		walk(n.Params, p, "field");
		walk(n.Results, p, "field");
	case *ast.InterfaceType:
		walk(n.Methods, p, "field")
	case *ast.MapType:
		walk(&n.Key, p, "type");
		walk(&n.Value, p, "type");
	case *ast.ChanType:
		walk(&n.Value, p, "type")

	case *ast.BadStmt:
	case *ast.DeclStmt:
		walk(n.Decl, p, "decl")
	case *ast.EmptyStmt:
	case *ast.LabeledStmt:
		walk(n.Stmt, p, "stmt")
	case *ast.ExprStmt:
		walk(&n.X, p, "expr")
	case *ast.IncDecStmt:
		walk(&n.X, p, "expr")
	case *ast.AssignStmt:
		walk(n.Lhs, p, "expr");
		walk(n.Rhs, p, "expr");
	case *ast.GoStmt:
		walk(n.Call, p, "expr")
	case *ast.DeferStmt:
		walk(n.Call, p, "expr")
	case *ast.ReturnStmt:
		walk(n.Results, p, "expr")
	case *ast.BranchStmt:
	case *ast.BlockStmt:
		walk(n.List, p, "stmt")
	case *ast.IfStmt:
		walk(n.Init, p, "stmt");
		walk(&n.Cond, p, "expr");
		walk(n.Body, p, "stmt");
		walk(n.Else, p, "stmt");
	case *ast.CaseClause:
		walk(n.Values, p, "expr");
		walk(n.Body, p, "stmt");
	case *ast.SwitchStmt:
		walk(n.Init, p, "stmt");
		walk(&n.Tag, p, "expr");
		walk(n.Body, p, "stmt");
	case *ast.TypeCaseClause:
		walk(n.Types, p, "type");
		walk(n.Body, p, "stmt");
	case *ast.TypeSwitchStmt:
		walk(n.Init, p, "stmt");
		walk(n.Assign, p, "stmt");
		walk(n.Body, p, "stmt");
	case *ast.CommClause:
		walk(n.Lhs, p, "expr");
		walk(n.Rhs, p, "expr");
		walk(n.Body, p, "stmt");
	case *ast.SelectStmt:
		walk(n.Body, p, "stmt")
	case *ast.ForStmt:
		walk(n.Init, p, "stmt");
		walk(&n.Cond, p, "expr");
		walk(n.Post, p, "stmt");
		walk(n.Body, p, "stmt");
	case *ast.RangeStmt:
		walk(&n.Key, p, "expr");
		walk(&n.Value, p, "expr");
		walk(&n.X, p, "expr");
		walk(n.Body, p, "stmt");

	case *ast.ImportSpec:
	case *ast.ValueSpec:
		walk(&n.Type, p, "type");
		walk(n.Values, p, "expr");
	case *ast.TypeSpec:
		walk(&n.Type, p, "type")

	case *ast.BadDecl:
	case *ast.GenDecl:
		walk(n.Specs, p, "spec")
	case *ast.FuncDecl:
		if n.Recv != nil {
			walk(n.Recv, p, "field")
		}
		walk(n.Type, p, "type");
		if n.Body != nil {
			walk(n.Body, p, "stmt")
		}

	case *ast.File:
		walk(n.Decls, p, "decl")

	case *ast.Package:
		for _, f := range n.Files {
			walk(f, p, "file")
		}

	case []ast.Decl:
		for _, d := range n {
			walk(d, p, context)
		}
	case []ast.Expr:
		for i := range n {
			walk(&n[i], p, context)
		}
	case []*ast.Field:
		for _, f := range n {
			walk(f, p, context)
		}
	case []ast.Stmt:
		for _, s := range n {
			walk(s, p, context)
		}
	case []ast.Spec:
		for _, s := range n {
			walk(s, p, context)
		}
	}
}
