blob: e0d63c46c6aa73b4248cec6b66cb4be61627f417 [file] [log] [blame]
// Copyright 2025 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 typesinternal
import (
"go/types"
"slices"
)
// IsTypeNamed reports whether t is (or is an alias for) a
// package-level defined type with the given package path and one of
// the given names. It returns false if t is nil.
//
// This function avoids allocating the concatenation of "pkg.Name",
// which is important for the performance of syntax matching.
func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool {
if named, ok := types.Unalias(t).(*types.Named); ok {
tname := named.Obj()
return tname != nil &&
IsPackageLevel(tname) &&
tname.Pkg().Path() == pkgPath &&
slices.Contains(names, tname.Name())
}
return false
}
// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a
// package-level defined type with the given package path and one of the given
// names. It returns false if t is not a pointer type.
func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool {
r := Unpointer(t)
if r == t {
return false
}
return IsTypeNamed(r, pkgPath, names...)
}
// IsFunctionNamed reports whether obj is a package-level function
// defined in the given package and has one of the given names.
// It returns false if obj is nil.
//
// This function avoids allocating the concatenation of "pkg.Name",
// which is important for the performance of syntax matching.
func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool {
f, ok := obj.(*types.Func)
return ok &&
IsPackageLevel(obj) &&
f.Pkg().Path() == pkgPath &&
f.Signature().Recv() == nil &&
slices.Contains(names, f.Name())
}
// IsMethodNamed reports whether obj is a method defined on a
// package-level type with the given package and type name, and has
// one of the given names. It returns false if obj is nil.
//
// This function avoids allocating the concatenation of "pkg.TypeName.Name",
// which is important for the performance of syntax matching.
func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool {
if fn, ok := obj.(*types.Func); ok {
if recv := fn.Signature().Recv(); recv != nil {
_, T := ReceiverNamed(recv)
return T != nil &&
IsTypeNamed(T, pkgPath, typeName) &&
slices.Contains(names, fn.Name())
}
}
return false
}