// 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()

	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)
		}
	}
}
