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

package ast

import "go/token"


func filterIdentList(list []*Ident) []*Ident {
	j := 0;
	for _, x := range list {
		if x.IsExported() {
			list[j] = x;
			j++;
		}
	}
	return list[0:j];
}


// isExportedType assumes that typ is a correct type.
func isExportedType(typ Expr) bool {
	switch t := typ.(type) {
	case *Ident:
		return t.IsExported()
	case *ParenExpr:
		return isExportedType(t.X)
	case *SelectorExpr:
		// assume t.X is a typename
		return t.Sel.IsExported()
	case *StarExpr:
		return isExportedType(t.X)
	}
	return false;
}


func filterFieldList(list []*Field, incomplete *bool) []*Field {
	j := 0;
	for _, f := range list {
		exported := false;
		if len(f.Names) == 0 {
			// anonymous field
			// (Note that a non-exported anonymous field
			// may still refer to a type with exported
			// fields, so this is not absolutely correct.
			// However, this cannot be done w/o complete
			// type information.)
			exported = isExportedType(f.Type)
		} else {
			n := len(f.Names);
			f.Names = filterIdentList(f.Names);
			if len(f.Names) < n {
				*incomplete = true
			}
			exported = len(f.Names) > 0;
		}
		if exported {
			filterType(f.Type);
			list[j] = f;
			j++;
		}
	}
	if j < len(list) {
		*incomplete = true
	}
	return list[0:j];
}


func filterParamList(list []*Field) {
	for _, f := range list {
		filterType(f.Type)
	}
}


var noPos token.Position

func filterType(typ Expr) {
	switch t := typ.(type) {
	case *ArrayType:
		filterType(t.Elt)
	case *StructType:
		t.Fields = filterFieldList(t.Fields, &t.Incomplete)
	case *FuncType:
		filterParamList(t.Params);
		filterParamList(t.Results);
	case *InterfaceType:
		t.Methods = filterFieldList(t.Methods, &t.Incomplete)
	case *MapType:
		filterType(t.Key);
		filterType(t.Value);
	case *ChanType:
		filterType(t.Value)
	}
}


func filterSpec(spec Spec) bool {
	switch s := spec.(type) {
	case *ValueSpec:
		s.Names = filterIdentList(s.Names);
		if len(s.Names) > 0 {
			filterType(s.Type);
			return true;
		}
	case *TypeSpec:
		// TODO(gri) consider stripping forward declarations
		//           of structs, interfaces, functions, and methods
		if s.Name.IsExported() {
			filterType(s.Type);
			return true;
		}
	}
	return false;
}


func filterSpecList(list []Spec) []Spec {
	j := 0;
	for _, s := range list {
		if filterSpec(s) {
			list[j] = s;
			j++;
		}
	}
	return list[0:j];
}


func filterDecl(decl Decl) bool {
	switch d := decl.(type) {
	case *GenDecl:
		d.Specs = filterSpecList(d.Specs);
		return len(d.Specs) > 0;
	case *FuncDecl:
		// TODO consider removing function declaration altogether if
		//      forward declaration (i.e., if d.Body == nil) because
		//      in that case the actual declaration will come later.
		d.Body = nil;	// strip body
		return d.Name.IsExported();
	}
	return false;
}


// FileExports trims the AST for a Go source file in place such that only
// exported nodes remain: all top-level identifiers which are not exported
// and their associated information (such as type, initial value, or function
// body) are removed. Non-exported fields and methods of exported types are
// stripped, and the function bodies of exported functions are set to nil.
// The File.comments list is not changed.
//
// FileExports returns true if there is an exported declaration; it returns
// false otherwise.
//
func FileExports(src *File) bool {
	j := 0;
	for _, d := range src.Decls {
		if filterDecl(d) {
			src.Decls[j] = d;
			j++;
		}
	}
	src.Decls = src.Decls[0:j];
	return j > 0;
}


// PackageExports trims the AST for a Go package in place such that only
// exported nodes remain. The pkg.Files list is not changed, so that file
// names and top-level package comments don't get lost.
//
// PackageExports returns true if there is an exported declaration; it
// returns false otherwise.
//
func PackageExports(pkg *Package) bool {
	hasExports := false;
	for _, f := range pkg.Files {
		if FileExports(f) {
			hasExports = true
		}
	}
	return hasExports;
}


// separator is an empty //-style comment that is interspersed between
// different comment groups when they are concatenated into a single group
//
var separator = &Comment{noPos, []byte{'/', '/'}}


// MergePackageFiles creates a file AST by merging the ASTs of the
// files belonging to a package.
//
func MergePackageFiles(pkg *Package) *File {
	// Count the number of package comments and declarations across
	// all package files.
	ncomments := 0;
	ndecls := 0;
	for _, f := range pkg.Files {
		if f.Doc != nil {
			ncomments += len(f.Doc.List) + 1	// +1 for separator
		}
		ndecls += len(f.Decls);
	}

	// Collect package comments from all package files into a single
	// CommentGroup - the collected package documentation. The order
	// is unspecified. In general there should be only one file with
	// a package comment; but it's better to collect extra comments
	// than drop them on the floor.
	var doc *CommentGroup;
	if ncomments > 0 {
		list := make([]*Comment, ncomments-1);	// -1: no separator before first group
		i := 0;
		for _, f := range pkg.Files {
			if f.Doc != nil {
				if i > 0 {
					// not the first group - add separator
					list[i] = separator;
					i++;
				}
				for _, c := range f.Doc.List {
					list[i] = c;
					i++;
				}
			}
		}
		doc = &CommentGroup{list, nil};
	}

	// Collect declarations from all package files.
	var decls []Decl;
	if ndecls > 0 {
		decls = make([]Decl, ndecls);
		i := 0;
		for _, f := range pkg.Files {
			for _, d := range f.Decls {
				decls[i] = d;
				i++;
			}
		}
	}

	// TODO(gri) Should collect comments as well. For that the comment
	//           list should be changed back into a []*CommentGroup,
	//           otherwise need to modify the existing linked list.
	return &File{doc, noPos, &Ident{noPos, pkg.Name}, decls, nil};
}
