func Walk(tv *types.TypeAndValue, v Visitor) bool { switch { case tv.IsType(): // Anonymous types may have methods too (e.g., // interfaces or structs with embedded fields), but // the Go spec restricts method expressions to named // types and pointers to named types. if namedOf(tv.Type) != nil { walk(tv.Type, false, false, v) } case tv.IsValue(): walk(tv.Type, tv.Addressable(), true, v) default: return false } return true }
// stringVal returns the (unquoted) string value and true if // tv is a string constant; otherwise it returns "" and false. func stringVal(tv types.TypeAndValue) (string, bool) { if tv.IsValue() && tv.Value != nil && tv.Value.Kind() == constant.String { return constant.StringVal(tv.Value), true } return "", false }
// mode returns a string describing the mode of an expression. func mode(tv types.TypeAndValue) string { s := "" if tv.IsVoid() { s += ",void" } if tv.IsType() { s += ",type" } if tv.IsBuiltin() { s += ",builtin" } if tv.IsValue() { s += ",value" } if tv.IsNil() { s += ",nil" } if tv.Addressable() { s += ",addressable" } if tv.Assignable() { s += ",assignable" } if tv.HasOk() { s += ",ok" } return s[1:] }
func mode(tv types.TypeAndValue) string { switch { case tv.IsVoid(): return "void" case tv.IsType(): return "type" case tv.IsBuiltin(): return "builtin" case tv.IsNil(): return "nil" case tv.Assignable(): if tv.Addressable() { return "var" } return "mapindex" case tv.IsValue(): return "value" default: return "unknown" } }