// Copyright 2013 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 pointer

import (
	"fmt"
	"go/token"
	"strings"

	"code.google.com/p/go.tools/call"
	"code.google.com/p/go.tools/go/types"
	"code.google.com/p/go.tools/ssa"
)

// A Label is an entity that may be pointed to by a pointer, map,
// channel, 'func', slice or interface.  Labels include:
//
// Labels include:
// 	- functions
//      - globals
//      - tagged objects, representing interfaces and reflect.Values
//      - arrays created by literals (e.g. []byte("foo")) and conversions ([]byte(s))
// 	- stack- and heap-allocated variables (including composite literals)
// 	- channels, maps and arrays created by make()
//	- instrinsic or reflective operations that allocate (e.g. append, reflect.New)
//	- instrinsic objects, e.g. the initial array behind os.Args.
// 	- and their subelements, e.g. "alloc.y[*].z"
//
// Labels are so varied that they defy good generalizations;
// some have no value, no callgraph node, or no position.
// Many objects have types that are inexpressible in Go:
// maps, channels, functions, tagged objects.
//
// At most one of Value() or ReflectType() may return non-nil.
//
type Label struct {
	obj        *object    // the addressable memory location containing this label
	subelement *fieldInfo // subelement path within obj, e.g. ".a.b[*].c"
}

// Value returns the ssa.Value that allocated this label's object, if any.
func (l Label) Value() ssa.Value {
	val, _ := l.obj.data.(ssa.Value)
	return val
}

// ReflectType returns the type represented by this label if it is an
// reflect.rtype instance object or *reflect.rtype-tagged object.
//
func (l Label) ReflectType() types.Type {
	rtype, _ := l.obj.data.(types.Type)
	return rtype
}

// Context returns the analytic context in which this label's object was allocated,
// or nil for global objects: global, const, and shared contours for functions.
//
func (l Label) Context() call.GraphNode {
	return l.obj.cgn
}

// Path returns the path to the subelement of the object containing
// this label.  For example, ".x[*].y".
//
func (l Label) Path() string {
	return l.subelement.path()
}

// Pos returns the position of this label, if known, zero otherwise.
func (l Label) Pos() token.Pos {
	switch data := l.obj.data.(type) {
	case ssa.Value:
		return data.Pos()
	case types.Type:
		if nt, ok := deref(data).(*types.Named); ok {
			return nt.Obj().Pos()
		}
	}
	if cgn := l.obj.cgn; cgn != nil {
		return cgn.Func().Pos()
	}
	return token.NoPos
}

// String returns the printed form of this label.
//
// Examples:					Object type:
// 	(sync.Mutex).Lock			(a function)
// 	"foo":[]byte				(a slice constant)
//	makemap					(map allocated via make)
//	makechan				(channel allocated via make)
//	makeinterface				(tagged object allocated by makeinterface)
//      <alloc in reflect.Zero>			(allocation in instrinsic)
//      sync.Mutex				(a reflect.rtype instance)
//	<command-line arguments>		(an instrinsic object)
//
// Labels within compound objects have subelement paths:
//	x.y[*].z				(a struct variable, x)
//	append.y[*].z				(array allocated by append)
//	makeslice.y[*].z			(array allocated via make)
//
func (l Label) String() string {
	var s string
	switch v := l.obj.data.(type) {
	case types.Type:
		return v.String()

	case string:
		s = v // an intrinsic object (e.g. os.Args[*])

	case nil:
		if l.obj.cgn != nil {
			// allocation by intrinsic or reflective operation
			s = fmt.Sprintf("<alloc in %s>", l.obj.cgn.Func())
		} else {
			s = "<unknown>" // should be unreachable
		}

	case *ssa.Function:
		s = v.String()

	case *ssa.Global:
		s = v.String()

	case *ssa.Const:
		s = v.Name()

	case *ssa.Alloc:
		s = v.Comment
		if s == "" {
			s = "alloc"
		}

	case *ssa.Call:
		// Currently only calls to append can allocate objects.
		if v.Call.Value.(*ssa.Builtin).Object().Name() != "append" {
			panic("unhandled *ssa.Call label: " + v.Name())
		}
		s = "append"

	case *ssa.MakeMap, *ssa.MakeChan, *ssa.MakeSlice, *ssa.Convert:
		s = strings.ToLower(strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa."))

	case *ssa.MakeInterface:
		// MakeInterface is usually implicit in Go source (so
		// Pos()==0), and tagged objects may be allocated
		// synthetically (so no *MakeInterface data).
		s = "makeinterface:" + v.X.Type().String()

	default:
		panic(fmt.Sprintf("unhandled object data type: %T", v))
	}

	return s + l.subelement.path()
}
