func fieldsAccessible(s *types.Struct, p *types.Package) bool {
	for i := 0; i < s.NumFields(); i++ {
		f := s.Field(i)
		if f.Exported() || f.Pkg() == p {
			return true
		}
	}
	return false
}
fieldsAccessible returns whether s has at least one field accessible by p.
package completion
import (
	"go/ast"
	"go/token"
	"go/types"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/diff"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/protocol"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/source"
)
func exprAtPos(pos token.Pos, args []ast.Expr) int {
	for i, expr := range args {
		if expr.Pos() <= pos && pos <= expr.End() {
			return i
		}
	}
	return len(args)
}
func eachField(T types.Type, fn func(*types.Var)) {
	var seen map[*types.Struct]bool
	var visit func(T types.Type)
	visit = func(T types.Type) {
		if T, ok := source.Deref(T).Underlying().(*types.Struct); ok {
			if seen[T] {
				return
			}
			for i := 0; i < T.NumFields(); i++ {
				f := T.Field(i)
				fn(f)
				if f.Anonymous() {
					if seen == nil {
						seen = make(map[*types.Struct]bool)
					}
					seen[T] = true
					visit(f.Type())
				}
			}
		}
	}
	visit(T)
}
func typeIsValid(typ types.Type) bool {
	if _, ok := typ.(*types.Named); ok {
		return true
	}
	switch typ := typ.Underlying().(type) {
	case *types.Basic:
		return typ.Kind() != types.Invalid
	case *types.Array:
		return typeIsValid(typ.Elem())
	case *types.Slice:
		return typeIsValid(typ.Elem())
	case *types.Pointer:
		return typeIsValid(typ.Elem())
	case *types.Map:
		return typeIsValid(typ.Key()) && typeIsValid(typ.Elem())
	case *types.Chan:
		return typeIsValid(typ.Elem())
	case *types.Signature:
		return typeIsValid(typ.Params()) && typeIsValid(typ.Results())
	case *types.Tuple:
		for i := 0; i < typ.Len(); i++ {
			if !typeIsValid(typ.At(i).Type()) {
				return false
			}
		}
		return true
	case *types.Struct, *types.Interface:
		return true
	default:
		return false
	}
}
func resolveInvalid(fset *token.FileSet, obj types.Object, node ast.Node, info *types.Info) types.Object {
	var resultExpr ast.Expr
	ast.Inspect(node, func(node ast.Node) bool {
		switch n := node.(type) {
		case *ast.ValueSpec:
			for _, name := range n.Names {
				if info.Defs[name] == obj {
					resultExpr = n.Type
				}
			}
			return false
		case *ast.Field:  
			for _, name := range n.Names {
				if info.Defs[name] == obj {
					resultExpr = n.Type
				}
			}
			return false
		default:
			return true
		}
	})
	typename := source.FormatNode(fset, resultExpr)
	typ := types.NewNamed(types.NewTypeName(token.NoPos, obj.Pkg(), typename, nil), types.Typ[types.Invalid], nil)
	return types.NewVar(obj.Pos(), obj.Pkg(), obj.Name(), typ)
}
func isPointer(T types.Type) bool {
	_, ok := T.(*types.Pointer)
	return ok
}
func isVar(obj types.Object) bool {
	_, ok := obj.(*types.Var)
	return ok
}
func isTypeName(obj types.Object) bool {
	_, ok := obj.(*types.TypeName)
	return ok
}
func isFunc(obj types.Object) bool {
	_, ok := obj.(*types.Func)
	return ok
}
func isEmptyInterface(T types.Type) bool {
	intf, _ := T.(*types.Interface)
	return intf != nil && intf.NumMethods() == 0
}
func isUntyped(T types.Type) bool {
	if basic, ok := T.(*types.Basic); ok {
		return basic.Info()&types.IsUntyped > 0
	}
	return false
}
func isPkgName(obj types.Object) bool {
	_, ok := obj.(*types.PkgName)
	return ok
}
func isASTFile(n ast.Node) bool {
	_, ok := n.(*ast.File)
	return ok
}
func deslice(T types.Type) types.Type {
	if slice, ok := T.Underlying().(*types.Slice); ok {
		return slice.Elem()
	}
	return nil
}
func enclosingSelector(path []ast.Node, pos token.Pos) *ast.SelectorExpr {
	if len(path) == 0 {
		return nil
	}
	if sel, ok := path[0].(*ast.SelectorExpr); ok {
		return sel
	}
	if _, ok := path[0].(*ast.Ident); ok && len(path) > 1 {
		if sel, ok := path[1].(*ast.SelectorExpr); ok && pos >= sel.Sel.Pos() {
			return sel
		}
	}
	return nil
}
func enclosingDeclLHS(path []ast.Node) []*ast.Ident {
	for _, n := range path {
		switch n := n.(type) {
		case *ast.ValueSpec:
			return n.Names
		case *ast.AssignStmt:
			ids := make([]*ast.Ident, 0, len(n.Lhs))
			for _, e := range n.Lhs {
				if id, ok := e.(*ast.Ident); ok {
					ids = append(ids, id)
				}
			}
			return ids
		}
	}
	return nil
}
func exprObj(info *types.Info, e ast.Expr) types.Object {
	var ident *ast.Ident
	switch expr := e.(type) {
	case *ast.Ident:
		ident = expr
	case *ast.SelectorExpr:
		ident = expr.Sel
	default:
		return nil
	}
	return info.ObjectOf(ident)
}
func typeConversion(call *ast.CallExpr, info *types.Info) types.Type {
	if fun, _ := exprObj(info, call.Fun).(*types.TypeName); fun != nil {
		return fun.Type()
	}
	return nil
}