From cfed3f02136485796b59e59050115d6139fbab6f Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Sun, 23 Jan 2022 15:04:26 -0800 Subject: [PATCH] fix: Add stubs for more missing reflect methods With these methods stubbed out, the text/template package can be imported. These changes also allow code generated by protoc to compile. --- src/reflect/type.go | 88 +++++++++++++++++++++++++++++++++++++++----- src/reflect/value.go | 56 +++++++++++++++++++--------- 2 files changed, 117 insertions(+), 27 deletions(-) diff --git a/src/reflect/type.go b/src/reflect/type.go index 4ead369b..f8aab85a 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -126,6 +126,35 @@ func (k Kind) basicType() rawType { return rawType(k << 1) } +// Copied from reflect/type.go +// https://go.dev/src/reflect/type.go?#L348 + +// ChanDir represents a channel type's direction. +type ChanDir int + +const ( + RecvDir ChanDir = 1 << iota // <-chan + SendDir // chan<- + BothDir = RecvDir | SendDir // chan +) + +// Method represents a single method. +type Method struct { + // Name is the method name. + Name string + + // PkgPath is the package path that qualifies a lower case (unexported) + // method name. It is empty for upper case (exported) method names. + // The combination of PkgPath and Name uniquely identifies a method + // in a method set. + // See https://golang.org/ref/spec#Uniqueness_of_identifiers + PkgPath string + + Type Type // method type + Func Value // func with receiver as first argument + Index int // index for Type.Method +} + // The following Type type has been copied almost entirely from // https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212. // Some methods have been commented out as they haven't yet been implemented. @@ -173,7 +202,7 @@ type Type interface { // // For an interface type, the returned Method's Type field gives the // method signature, without a receiver, and the Func field is nil. - //MethodByName(string) (Method, bool) + MethodByName(string) (Method, bool) // NumMethod returns the number of exported methods in the type's method set. NumMethod() int @@ -187,7 +216,7 @@ type Type interface { // If the type was predeclared (string, error) or not defined (*T, struct{}, // []int, or A where A is an alias for a non-defined type), the package path // will be the empty string. - //PkgPath() string + PkgPath() string // Size returns the number of bytes needed to store // a value of the given type; it is analogous to unsafe.Sizeof. @@ -234,7 +263,7 @@ type Type interface { // ChanDir returns a channel type's direction. // It panics if the type's Kind is not Chan. - //ChanDir() ChanDir + ChanDir() ChanDir // IsVariadic reports whether a function type's final input parameter // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's @@ -248,7 +277,7 @@ type Type interface { // t.IsVariadic() == true // // IsVariadic panics if the type's Kind is not Func. - //IsVariadic() bool + IsVariadic() bool // Elem returns a type's element type. // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. @@ -267,7 +296,7 @@ type Type interface { // FieldByName returns the struct field with the given name // and a boolean indicating if the field was found. - //FieldByName(name string) (StructField, bool) + FieldByName(name string) (StructField, bool) // FieldByNameFunc returns the struct field with a name // that satisfies the match function and a boolean indicating if @@ -286,7 +315,7 @@ type Type interface { // In returns the type of a function type's i'th input parameter. // It panics if the type's Kind is not Func. // It panics if i is not in the range [0, NumIn()). - //In(i int) Type + In(i int) Type // Key returns a map type's key type. // It panics if the type's Kind is not Map. @@ -302,16 +331,16 @@ type Type interface { // NumIn returns a function type's input parameter count. // It panics if the type's Kind is not Func. - //NumIn() int + NumIn() int // NumOut returns a function type's output parameter count. // It panics if the type's Kind is not Func. - //NumOut() int + NumOut() int // Out returns the type of a function type's i'th output parameter. // It panics if the type's Kind is not Func. // It panics if i is not in the range [0, NumOut()). - //Out(i int) Type + Out(i int) Type } // The typecode as used in an interface{}. @@ -675,10 +704,26 @@ func (t rawType) Comparable() bool { } } +func (t rawType) ChanDir() ChanDir { + panic("unimplemented: (reflect.Type).ChanDir()") +} + func (t rawType) ConvertibleTo(u Type) bool { panic("unimplemented: (reflect.Type).ConvertibleTo()") } +func (t rawType) IsVariadic() bool { + panic("unimplemented: (reflect.Type).IsVariadic()") +} + +func (t rawType) NumIn() int { + panic("unimplemented: (reflect.Type).NumIn()") +} + +func (t rawType) NumOut() int { + panic("unimplemented: (reflect.Type).NumOut()") +} + func (t rawType) NumMethod() int { panic("unimplemented: (reflect.Type).NumMethod()") } @@ -691,6 +736,26 @@ func (t rawType) Key() Type { panic("unimplemented: (reflect.Type).Key()") } +func (t rawType) In(i int) Type { + panic("unimplemented: (reflect.Type).In()") +} + +func (t rawType) Out(i int) Type { + panic("unimplemented: (reflect.Type).Out()") +} + +func (t rawType) MethodByName(name string) (Method, bool) { + panic("unimplemented: (reflect.Type).MethodByName()") +} + +func (t rawType) PkgPath() string { + panic("unimplemented: (reflect.Type).PkgPath()") +} + +func (t rawType) FieldByName(name string) (StructField, bool) { + panic("unimplemented: (reflect.Type).FieldByName()") +} + // A StructField describes a single field in a struct. type StructField struct { // Name indicates the field name. @@ -704,6 +769,7 @@ type StructField struct { Tag StructTag // field tag string Anonymous bool Offset uintptr + Index []int // index sequence for Type.FieldByIndex } // IsExported reports whether the field is exported. @@ -800,3 +866,7 @@ func (e *TypeError) Error() string { func align(offset uintptr, alignment uintptr) uintptr { return (offset + alignment - 1) &^ (alignment - 1) } + +func SliceOf(t Type) Type { + panic("unimplemented: reflect.SliceOf()") +} diff --git a/src/reflect/value.go b/src/reflect/value.go index be086e5f..d58ecba6 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -128,7 +128,7 @@ func (v Value) IsNil() bool { _, val := decomposeInterface(*(*interface{})(v.value)) return val == nil default: - panic(&ValueError{"IsNil"}) + panic(&ValueError{Method: "IsNil"}) } } @@ -144,7 +144,7 @@ func (v Value) Pointer() uintptr { case Func: panic("unimplemented: (reflect.Value).Pointer()") default: // not implemented: Func - panic(&ValueError{"Pointer"}) + panic(&ValueError{Method: "Pointer"}) } } @@ -187,7 +187,7 @@ func (v Value) Bool() bool { return uintptr(v.value) != 0 } default: - panic(&ValueError{"Bool"}) + panic(&ValueError{Method: "Bool"}) } } @@ -224,7 +224,7 @@ func (v Value) Int() int64 { return int64(int64(uintptr(v.value))) } default: - panic(&ValueError{"Int"}) + panic(&ValueError{Method: "Int"}) } } @@ -267,7 +267,7 @@ func (v Value) Uint() uint64 { return uint64(uintptr(v.value)) } default: - panic(&ValueError{"Uint"}) + panic(&ValueError{Method: "Uint"}) } } @@ -293,7 +293,7 @@ func (v Value) Float() float64 { return *(*float64)(unsafe.Pointer(&v.value)) } default: - panic(&ValueError{"Float"}) + panic(&ValueError{Method: "Float"}) } } @@ -315,7 +315,7 @@ func (v Value) Complex() complex128 { // architectures with 128-bit pointers, however. return *(*complex128)(v.value) default: - panic(&ValueError{"Complex"}) + panic(&ValueError{Method: "Complex"}) } } @@ -339,6 +339,10 @@ func (v Value) Slice(i, j int) Value { panic("unimplemented: (reflect.Value).Slice()") } +func (v Value) Slice3(i, j, k int) Value { + panic("unimplemented: (reflect.Value).Slice3()") +} + //go:linkname maplen runtime.hashmapLenUnsafePointer func maplen(p unsafe.Pointer) int @@ -360,7 +364,7 @@ func (v Value) Len() int { case String: return int((*stringHeader)(v.value).len) default: - panic(&ValueError{"Len"}) + panic(&ValueError{Method: "Len"}) } } @@ -378,7 +382,7 @@ func (v Value) Cap() int { case Slice: return int((*sliceHeader)(v.value).cap) default: - panic(&ValueError{"Cap"}) + panic(&ValueError{Method: "Cap"}) } } @@ -408,7 +412,7 @@ func (v Value) Elem() Value { flags: v.flags &^ valueFlagIndirect, } default: - panic(&ValueError{"Elem"}) + panic(&ValueError{Method: "Elem"}) } } @@ -552,7 +556,7 @@ func (v Value) Index(i int) Value { value: unsafe.Pointer(value), } default: - panic(&ValueError{"Index"}) + panic(&ValueError{Method: "Index"}) } } @@ -631,7 +635,7 @@ func (v Value) SetBool(x bool) { case Bool: *(*bool)(v.value) = x default: - panic(&ValueError{"SetBool"}) + panic(&ValueError{Method: "SetBool"}) } } @@ -649,7 +653,7 @@ func (v Value) SetInt(x int64) { case Int64: *(*int64)(v.value) = x default: - panic(&ValueError{"SetInt"}) + panic(&ValueError{Method: "SetInt"}) } } @@ -669,7 +673,7 @@ func (v Value) SetUint(x uint64) { case Uintptr: *(*uintptr)(v.value) = uintptr(x) default: - panic(&ValueError{"SetUint"}) + panic(&ValueError{Method: "SetUint"}) } } @@ -681,7 +685,7 @@ func (v Value) SetFloat(x float64) { case Float64: *(*float64)(v.value) = x default: - panic(&ValueError{"SetFloat"}) + panic(&ValueError{Method: "SetFloat"}) } } @@ -693,7 +697,7 @@ func (v Value) SetComplex(x complex128) { case Complex128: *(*complex128)(v.value) = x default: - panic(&ValueError{"SetComplex"}) + panic(&ValueError{Method: "SetComplex"}) } } @@ -703,7 +707,7 @@ func (v Value) SetString(x string) { case String: *(*string)(v.value) = x default: - panic(&ValueError{"SetString"}) + panic(&ValueError{Method: "SetString"}) } } @@ -788,10 +792,14 @@ type stringHeader struct { type ValueError struct { Method string + Kind Kind } func (e *ValueError) Error() string { - return "reflect: call of reflect.Value." + e.Method + " on invalid type" + if e.Kind == 0 { + return "reflect: call of " + e.Method + " on zero Value" + } + return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value" } // Calls to this function are converted to LLVM intrinsic calls such as @@ -865,3 +873,15 @@ func MakeMap(typ Type) Value { func (v Value) Call(in []Value) []Value { panic("unimplemented: (reflect.Value).Call()") } + +func (v Value) MethodByName(name string) Value { + panic("unimplemented: (reflect.Value).MethodByName()") +} + +func (v Value) Recv() (x Value, ok bool) { + panic("unimplemented: (reflect.Value).Recv()") +} + +func NewAt(typ Type, p unsafe.Pointer) Value { + panic("unimplemented: reflect.New()") +}