typeutil

package
v0.0.1-2019.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2019 License: MIT Imports: 7 Imported by: 35

Documentation

Overview

Package typeutil defines various utilities for types, such as Map, a mapping from types.Type to interface{} values.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Callee

func Callee(info *types.Info, call *ast.CallExpr) types.Object

Callee returns the named target of a function call, if any: a function, method, builtin, or variable.

func Dependencies

func Dependencies(pkgs ...*types.Package) []*types.Package

Dependencies returns all dependencies of the specified packages.

Dependent packages appear in topological order: if package P imports package Q, Q appears earlier than P in the result. The algorithm follows import statements in the order they appear in the source code, so the result is a total order.

func Identical

func Identical(x, y types.Type) (ret bool)

Identical reports whether x and y are identical types. Unlike types.Identical, receivers of Signature types are not ignored. Unlike types.Identical, interfaces are compared via pointer equality (except for the empty interface, which gets deduplicated). Unlike types.Identical, structs are compared via pointer equality.

func IntuitiveMethodSet

func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection

IntuitiveMethodSet returns the intuitive method set of a type T, which is the set of methods you can call on an addressable value of that type.

The result always contains MethodSet(T), and is exactly MethodSet(T) for interface types and for pointer-to-concrete types. For all other concrete types T, the result additionally contains each method belonging to *T if there is no identically named method on T itself.

This corresponds to user intuition about method sets; this function is intended only for user interfaces.

The order of the result is as for types.MethodSet(T).

func StaticCallee

func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func

StaticCallee returns the target (function or method) of a static function call, if any. It returns nil for calls to builtins.

Types

type Hasher added in v0.2.0

type Hasher struct {
	// contains filtered or unexported fields
}

A Hasher maps each type to its hash value. For efficiency, a hasher uses memoization; thus its memory footprint grows monotonically over time. Hashers are not thread-safe. Hashers have reference semantics. Call MakeHasher to create a Hasher.

func MakeHasher added in v0.2.0

func MakeHasher() Hasher

MakeHasher returns a new Hasher instance.

func (Hasher) Hash

func (h Hasher) Hash(t types.Type) uint32

Hash computes a hash value for the given type t such that Identical(t, t') => Hash(t) == Hash(t').

type Map added in v0.2.0

type Map struct {
	// contains filtered or unexported fields
}

Map is a hash-table-based mapping from types (types.Type) to arbitrary interface{} values. The concrete types that implement the Type interface are pointers. Since they are not canonicalized, == cannot be used to check for equivalence, and thus we cannot simply use a Go map.

Just as with map[K]V, a nil *Map is a valid empty map.

Not thread-safe.

This fork handles Signatures correctly, respecting method receivers. Furthermore, it doesn't deduplicate interfaces or structs. Interfaces aren't deduplicated as not to conflate implicit and explicit methods. Structs aren't deduplicated because we track fields of each type separately.

Example
package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"go/types"
	"sort"

	"honnef.co/go/tools/go/types/typeutil"
)

func main() {
	const source = `package P

var X []string
var Y []string

const p, q = 1.0, 2.0

func f(offset int32) (value byte, ok bool)
func g(rune) (uint8, bool)
`

	// Parse and type-check the package.
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "P.go", source, 0)
	if err != nil {
		panic(err)
	}
	pkg, err := new(types.Config).Check("P", fset, []*ast.File{f}, nil)
	if err != nil {
		panic(err)
	}

	scope := pkg.Scope()

	// Group names of package-level objects by their type.
	var namesByType typeutil.Map // value is []string
	for _, name := range scope.Names() {
		T := scope.Lookup(name).Type()

		names, _ := namesByType.At(T).([]string)
		names = append(names, name)
		namesByType.Set(T, names)
	}

	// Format, sort, and print the map entries.
	var lines []string
	namesByType.Iterate(func(T types.Type, names interface{}) {
		lines = append(lines, fmt.Sprintf("%s   %s", names, T))
	})
	sort.Strings(lines)
	for _, line := range lines {
		fmt.Println(line)
	}

}
Output:

[X Y]   []string
[f g]   func(offset int32) (value byte, ok bool)
[p q]   untyped float

func (*Map) At added in v0.4.0

func (m *Map) At(key types.Type) interface{}

At returns the map entry for the given key. The result is nil if the entry is not present.

func (*Map) Delete added in v0.4.0

func (m *Map) Delete(key types.Type) bool

Delete removes the entry with the given key, if any. It returns true if the entry was found.

func (*Map) Iterate added in v0.4.0

func (m *Map) Iterate(f func(key types.Type, value interface{}))

Iterate calls function f on each entry in the map in unspecified order.

If f should mutate the map, Iterate provides the same guarantees as Go maps: if f deletes a map entry that Iterate has not yet reached, f will not be invoked for it, but if f inserts a map entry that Iterate has not yet reached, whether or not f will be invoked for it is unspecified.

func (*Map) Keys added in v0.4.0

func (m *Map) Keys() []types.Type

Keys returns a new slice containing the set of map keys. The order is unspecified.

func (*Map) KeysString added in v0.4.0

func (m *Map) KeysString() string

KeysString returns a string representation of the map's key set. Order is unspecified.

func (*Map) Len added in v0.4.0

func (m *Map) Len() int

Len returns the number of map entries.

func (*Map) Set added in v0.4.0

func (m *Map) Set(key types.Type, value interface{}) (prev interface{})

Set sets the map entry for key to val, and returns the previous entry, if any.

func (*Map) SetHasher added in v0.4.0

func (m *Map) SetHasher(hasher Hasher)

SetHasher sets the hasher used by Map.

All Hashers are functionally equivalent but contain internal state used to cache the results of hashing previously seen types.

A single Hasher created by MakeHasher() may be shared among many Maps. This is recommended if the instances have many keys in common, as it will amortize the cost of hash computation.

A Hasher may grow without bound as new types are seen. Even when a type is deleted from the map, the Hasher never shrinks, since other types in the map may reference the deleted type indirectly.

Hashers are not thread-safe, and read-only operations such as Map.Lookup require updates to the hasher, so a full Mutex lock (not a read-lock) is require around all Map operations if a shared hasher is accessed from multiple threads.

If SetHasher is not called, the Map will create a private hasher at the first call to Insert.

func (*Map) String added in v0.4.0

func (m *Map) String() string

String returns a string representation of the map's entries. Values are printed using fmt.Sprintf("%v", v). Order is unspecified.

type MethodSetCache

type MethodSetCache struct {
	// contains filtered or unexported fields
}

A MethodSetCache records the method set of each type T for which MethodSet(T) is called so that repeat queries are fast. The zero value is a ready-to-use cache instance.

func (*MethodSetCache) MethodSet

func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet

MethodSet returns the method set of type T. It is thread-safe.

If cache is nil, this function is equivalent to types.NewMethodSet(T). Utility functions can thus expose an optional *MethodSetCache parameter to clients that care about performance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL