// 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", "const", 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
	Enumdef     map[string]int64
	Constdef    map[string]string
	PtrSize     int64
	GccOptions  []string
	OutDefs     map[string]bool
}

// 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
	EnumValues map[string]int64
}

// 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, p *Prog) {
	var err os.Error
	p.AST, err = parser.ParseFile(name, nil, nil, 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.Name()

	// 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 || string(s.Path.Value) != `"C"` {
				d.Specs[ws] = spec
				ws++
				continue
			}
			sawC = true
			if s.Name != nil {
				error(s.Path.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.
	if p.Crefs == nil {
		p.Crefs = make([]*Cref, 0, 8)
	}
	walk(p.AST, p, "prog")
}

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.Name() == "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.Name(),
					Expr:    n,
					Context: context,
				}
				break
			}
		}
		walk(*n, p, context)

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

	case nil:

	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
	case *ast.Field:
		walk(&n.Type, p, "type")
	case *ast.FieldList:
		for _, f := range n.List {
			walk(f, p, context)
		}
	case *ast.BadExpr:
	case *ast.Ident:
	case *ast.Ellipsis:
	case *ast.BasicLit:
	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")
		if n.Results != nil {
			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.Stmt:
		for _, s := range n {
			walk(s, p, context)
		}
	case []ast.Spec:
		for _, s := range n {
			walk(s, p, context)
		}
	}
}
