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

// +build go1.5

package pointer

import "go/types"

type constraint interface {
	// For a complex constraint, returns the nodeid of the pointer
	// to which it is attached.   For addr and copy, returns dst.
	ptr() nodeid

	// renumber replaces each nodeid n in the constraint by mapping[n].
	renumber(mapping []nodeid)

	// presolve is a hook for constraint-specific behaviour during
	// pre-solver optimization.  Typical implementations mark as
	// indirect the set of nodes to which the solver will add copy
	// edges or PTS labels.
	presolve(h *hvn)

	// solve is called for complex constraints when the pts for
	// the node to which they are attached has changed.
	solve(a *analysis, delta *nodeset)

	String() string
}

// dst = &src
// pts(dst) ⊇ {src}
// A base constraint used to initialize the solver's pt sets
type addrConstraint struct {
	dst nodeid // (ptr)
	src nodeid
}

func (c *addrConstraint) ptr() nodeid { return c.dst }
func (c *addrConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst = src
// A simple constraint represented directly as a copyTo graph edge.
type copyConstraint struct {
	dst nodeid // (ptr)
	src nodeid
}

func (c *copyConstraint) ptr() nodeid { return c.dst }
func (c *copyConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst = src[offset]
// A complex constraint attached to src (the pointer)
type loadConstraint struct {
	offset uint32
	dst    nodeid
	src    nodeid // (ptr)
}

func (c *loadConstraint) ptr() nodeid { return c.src }
func (c *loadConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst[offset] = src
// A complex constraint attached to dst (the pointer)
type storeConstraint struct {
	offset uint32
	dst    nodeid // (ptr)
	src    nodeid
}

func (c *storeConstraint) ptr() nodeid { return c.dst }
func (c *storeConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst = &src.f  or  dst = &src[0]
// A complex constraint attached to dst (the pointer)
type offsetAddrConstraint struct {
	offset uint32
	dst    nodeid
	src    nodeid // (ptr)
}

func (c *offsetAddrConstraint) ptr() nodeid { return c.src }
func (c *offsetAddrConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst = src.(typ)  where typ is an interface
// A complex constraint attached to src (the interface).
// No representation change: pts(dst) and pts(src) contains tagged objects.
type typeFilterConstraint struct {
	typ types.Type // an interface type
	dst nodeid
	src nodeid // (ptr)
}

func (c *typeFilterConstraint) ptr() nodeid { return c.src }
func (c *typeFilterConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// dst = src.(typ)  where typ is a concrete type
// A complex constraint attached to src (the interface).
//
// If exact, only tagged objects identical to typ are untagged.
// If !exact, tagged objects assignable to typ are untagged too.
// The latter is needed for various reflect operators, e.g. Send.
//
// This entails a representation change:
// pts(src) contains tagged objects,
// pts(dst) contains their payloads.
type untagConstraint struct {
	typ   types.Type // a concrete type
	dst   nodeid
	src   nodeid // (ptr)
	exact bool
}

func (c *untagConstraint) ptr() nodeid { return c.src }
func (c *untagConstraint) renumber(mapping []nodeid) {
	c.dst = mapping[c.dst]
	c.src = mapping[c.src]
}

// src.method(params...)
// A complex constraint attached to iface.
type invokeConstraint struct {
	method *types.Func // the abstract method
	iface  nodeid      // (ptr) the interface
	params nodeid      // the start of the identity/params/results block
}

func (c *invokeConstraint) ptr() nodeid { return c.iface }
func (c *invokeConstraint) renumber(mapping []nodeid) {
	c.iface = mapping[c.iface]
	c.params = mapping[c.params]
}
