// TODO: show that two-non-empty dotjoin can happen, by using an anon struct as a field type
// TODO: don't report removed/changed methods for both value and pointer method sets?

package apidiff

import (
	
	
	
	
)

// There can be at most one message for each object or part thereof.
// Parts include interface methods and struct fields.
//
// The part thing is necessary. Method (Func) objects have sufficient info, but field
// Vars do not: they just have a field name and a type, without the enclosing struct.
type messageSet map[types.Object]map[string]string

// Add a message for obj and part, overwriting a previous message
// (shouldn't happen).
// obj is required but part can be empty.
func ( messageSet) ( types.Object, ,  string) {
	 := []
	if  == nil {
		 = map[string]string{}
		[] = 
	}
	if ,  := [];  &&  !=  {
		fmt.Printf("! second, different message for obj %s, part %q\n", , )
		fmt.Printf("  first:  %s\n", )
		fmt.Printf("  second: %s\n", )
	}
	[] = 
}

func ( messageSet) () []string {
	var  []string
	for ,  := range  {
		// Format each object name relative to its own package.
		 := objectString()
		for ,  := range  {
			var  string

			if strings.HasPrefix(, ",") {
				 =  + 
			} else {
				 = dotjoin(, )
			}
			 = append(, +": "+)
		}
	}
	sort.Strings()
	return 
}

func ( types.Object) string {
	if ,  := .(*types.Func);  {
		 := .Type().(*types.Signature)
		if  := .Recv();  != nil {
			 := types.TypeString(.Type(), types.RelativeTo(.Pkg()))
			if [0] == '*' {
				 = "(" +  + ")"
			}
			return fmt.Sprintf("%s.%s", , .Name())
		}
	}
	return .Name()
}

func (,  string) string {
	if  == "" {
		return 
	}
	if  == "" {
		return 
	}
	return  + "." + 
}