mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-13 11:04:03 +08:00
chore: upgrade coredns version (#550)
This commit is contained in:
261
vendor/github.com/expr-lang/expr/checker/nature/nature.go
generated
vendored
Normal file
261
vendor/github.com/expr-lang/expr/checker/nature/nature.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
package nature
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/expr-lang/expr/builtin"
|
||||
"github.com/expr-lang/expr/internal/deref"
|
||||
)
|
||||
|
||||
var (
|
||||
unknown = Nature{}
|
||||
)
|
||||
|
||||
type Nature struct {
|
||||
Type reflect.Type // Type of the value. If nil, then value is unknown.
|
||||
Func *builtin.Function // Used to pass function type from callee to CallNode.
|
||||
ArrayOf *Nature // Elem nature of array type (usually Type is []any, but ArrayOf can be any nature).
|
||||
PredicateOut *Nature // Out nature of predicate.
|
||||
Fields map[string]Nature // Fields of map type.
|
||||
DefaultMapValue *Nature // Default value of map type.
|
||||
Strict bool // If map is types.StrictMap.
|
||||
Nil bool // If value is nil.
|
||||
Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
|
||||
MethodIndex int // Index of method in type.
|
||||
FieldIndex []int // Index of field in type.
|
||||
}
|
||||
|
||||
func (n Nature) IsAny() bool {
|
||||
return n.Kind() == reflect.Interface && n.NumMethods() == 0
|
||||
}
|
||||
|
||||
func (n Nature) IsUnknown() bool {
|
||||
switch {
|
||||
case n.Type == nil && !n.Nil:
|
||||
return true
|
||||
case n.IsAny():
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n Nature) String() string {
|
||||
if n.Type != nil {
|
||||
return n.Type.String()
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func (n Nature) Deref() Nature {
|
||||
if n.Type != nil {
|
||||
n.Type = deref.Type(n.Type)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (n Nature) Kind() reflect.Kind {
|
||||
if n.Type != nil {
|
||||
return n.Type.Kind()
|
||||
}
|
||||
return reflect.Invalid
|
||||
}
|
||||
|
||||
func (n Nature) Key() Nature {
|
||||
if n.Kind() == reflect.Map {
|
||||
return Nature{Type: n.Type.Key()}
|
||||
}
|
||||
return unknown
|
||||
}
|
||||
|
||||
func (n Nature) Elem() Nature {
|
||||
switch n.Kind() {
|
||||
case reflect.Ptr:
|
||||
return Nature{Type: n.Type.Elem()}
|
||||
case reflect.Map:
|
||||
if n.DefaultMapValue != nil {
|
||||
return *n.DefaultMapValue
|
||||
}
|
||||
return Nature{Type: n.Type.Elem()}
|
||||
case reflect.Array, reflect.Slice:
|
||||
if n.ArrayOf != nil {
|
||||
return *n.ArrayOf
|
||||
}
|
||||
return Nature{Type: n.Type.Elem()}
|
||||
}
|
||||
return unknown
|
||||
}
|
||||
|
||||
func (n Nature) AssignableTo(nt Nature) bool {
|
||||
if n.Nil {
|
||||
// Untyped nil is assignable to any interface, but implements only the empty interface.
|
||||
if nt.IsAny() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if n.Type == nil || nt.Type == nil {
|
||||
return false
|
||||
}
|
||||
return n.Type.AssignableTo(nt.Type)
|
||||
}
|
||||
|
||||
func (n Nature) NumMethods() int {
|
||||
if n.Type == nil {
|
||||
return 0
|
||||
}
|
||||
return n.Type.NumMethod()
|
||||
}
|
||||
|
||||
func (n Nature) MethodByName(name string) (Nature, bool) {
|
||||
if n.Type == nil {
|
||||
return unknown, false
|
||||
}
|
||||
method, ok := n.Type.MethodByName(name)
|
||||
if !ok {
|
||||
return unknown, false
|
||||
}
|
||||
|
||||
if n.Type.Kind() == reflect.Interface {
|
||||
// In case of interface type method will not have a receiver,
|
||||
// and to prevent checker decreasing numbers of in arguments
|
||||
// return method type as not method (second argument is false).
|
||||
|
||||
// Also, we can not use m.Index here, because it will be
|
||||
// different indexes for different types which implement
|
||||
// the same interface.
|
||||
return Nature{Type: method.Type}, true
|
||||
} else {
|
||||
return Nature{
|
||||
Type: method.Type,
|
||||
Method: true,
|
||||
MethodIndex: method.Index,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
func (n Nature) NumIn() int {
|
||||
if n.Type == nil {
|
||||
return 0
|
||||
}
|
||||
return n.Type.NumIn()
|
||||
}
|
||||
|
||||
func (n Nature) In(i int) Nature {
|
||||
if n.Type == nil {
|
||||
return unknown
|
||||
}
|
||||
return Nature{Type: n.Type.In(i)}
|
||||
}
|
||||
|
||||
func (n Nature) NumOut() int {
|
||||
if n.Type == nil {
|
||||
return 0
|
||||
}
|
||||
return n.Type.NumOut()
|
||||
}
|
||||
|
||||
func (n Nature) Out(i int) Nature {
|
||||
if n.Type == nil {
|
||||
return unknown
|
||||
}
|
||||
return Nature{Type: n.Type.Out(i)}
|
||||
}
|
||||
|
||||
func (n Nature) IsVariadic() bool {
|
||||
if n.Type == nil {
|
||||
return false
|
||||
}
|
||||
return n.Type.IsVariadic()
|
||||
}
|
||||
|
||||
func (n Nature) FieldByName(name string) (Nature, bool) {
|
||||
if n.Type == nil {
|
||||
return unknown, false
|
||||
}
|
||||
field, ok := fetchField(n.Type, name)
|
||||
return Nature{Type: field.Type, FieldIndex: field.Index}, ok
|
||||
}
|
||||
|
||||
func (n Nature) PkgPath() string {
|
||||
if n.Type == nil {
|
||||
return ""
|
||||
}
|
||||
return n.Type.PkgPath()
|
||||
}
|
||||
|
||||
func (n Nature) IsFastMap() bool {
|
||||
if n.Type == nil {
|
||||
return false
|
||||
}
|
||||
if n.Type.Kind() == reflect.Map &&
|
||||
n.Type.Key().Kind() == reflect.String &&
|
||||
n.Type.Elem().Kind() == reflect.Interface {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n Nature) Get(name string) (Nature, bool) {
|
||||
if n.Type == nil {
|
||||
return unknown, false
|
||||
}
|
||||
|
||||
if m, ok := n.MethodByName(name); ok {
|
||||
return m, true
|
||||
}
|
||||
|
||||
t := deref.Type(n.Type)
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
if f, ok := fetchField(t, name); ok {
|
||||
return Nature{
|
||||
Type: f.Type,
|
||||
FieldIndex: f.Index,
|
||||
}, true
|
||||
}
|
||||
case reflect.Map:
|
||||
if f, ok := n.Fields[name]; ok {
|
||||
return f, true
|
||||
}
|
||||
}
|
||||
return unknown, false
|
||||
}
|
||||
|
||||
func (n Nature) All() map[string]Nature {
|
||||
table := make(map[string]Nature)
|
||||
|
||||
if n.Type == nil {
|
||||
return table
|
||||
}
|
||||
|
||||
for i := 0; i < n.Type.NumMethod(); i++ {
|
||||
method := n.Type.Method(i)
|
||||
table[method.Name] = Nature{
|
||||
Type: method.Type,
|
||||
Method: true,
|
||||
MethodIndex: method.Index,
|
||||
}
|
||||
}
|
||||
|
||||
t := deref.Type(n.Type)
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
for name, nt := range StructFields(t) {
|
||||
if _, ok := table[name]; ok {
|
||||
continue
|
||||
}
|
||||
table[name] = nt
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for key, nt := range n.Fields {
|
||||
if _, ok := table[key]; ok {
|
||||
continue
|
||||
}
|
||||
table[key] = nt
|
||||
}
|
||||
}
|
||||
|
||||
return table
|
||||
}
|
76
vendor/github.com/expr-lang/expr/checker/nature/utils.go
generated
vendored
Normal file
76
vendor/github.com/expr-lang/expr/checker/nature/utils.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package nature
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/expr-lang/expr/internal/deref"
|
||||
)
|
||||
|
||||
func fieldName(field reflect.StructField) string {
|
||||
if taggedName := field.Tag.Get("expr"); taggedName != "" {
|
||||
return taggedName
|
||||
}
|
||||
return field.Name
|
||||
}
|
||||
|
||||
func fetchField(t reflect.Type, name string) (reflect.StructField, bool) {
|
||||
// First check all structs fields.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
// Search all fields, even embedded structs.
|
||||
if fieldName(field) == name {
|
||||
return field, true
|
||||
}
|
||||
}
|
||||
|
||||
// Second check fields of embedded structs.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
anon := t.Field(i)
|
||||
if anon.Anonymous {
|
||||
anonType := anon.Type
|
||||
if anonType.Kind() == reflect.Pointer {
|
||||
anonType = anonType.Elem()
|
||||
}
|
||||
if field, ok := fetchField(anonType, name); ok {
|
||||
field.Index = append(anon.Index, field.Index...)
|
||||
return field, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.StructField{}, false
|
||||
}
|
||||
|
||||
func StructFields(t reflect.Type) map[string]Nature {
|
||||
table := make(map[string]Nature)
|
||||
|
||||
t = deref.Type(t)
|
||||
if t == nil {
|
||||
return table
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
|
||||
if f.Anonymous {
|
||||
for name, typ := range StructFields(f.Type) {
|
||||
if _, ok := table[name]; ok {
|
||||
continue
|
||||
}
|
||||
typ.FieldIndex = append(f.Index, typ.FieldIndex...)
|
||||
table[name] = typ
|
||||
}
|
||||
}
|
||||
|
||||
table[fieldName(f)] = Nature{
|
||||
Type: f.Type,
|
||||
FieldIndex: f.Index,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return table
|
||||
}
|
Reference in New Issue
Block a user