diff --git a/unexported/testdata/src/a/a.go b/unexported/testdata/src/a/a.go deleted file mode 100644 index e214fb4..0000000 --- a/unexported/testdata/src/a/a.go +++ /dev/null @@ -1,239 +0,0 @@ -package a - -import ( - "io" -) - -// unexportedReader is an unexported interface. -type unexportedReader interface { - Read([]byte) (int, error) -} - -// ExportedWriter is an exported interface. -type ExportedWriter interface { - Write([]byte) (int, error) -} - -// 1. Function with unexported arg type interface -func ReadAll(r unexportedReader) ([]byte, error) { // want "unexported interface 'unexportedReader' used as parameter in exported function 'ReadAll'" - buf := make([]byte, 1024) - _, err := r.Read(buf) - return buf, err -} - -//iface:ignore=unexported -func ReadAllIgnored(r unexportedReader) ([]byte, error) { - buf := make([]byte, 1024) - _, err := r.Read(buf) - return buf, err -} - -// 2. Function with exported arg type interface -func WriteHello(w ExportedWriter) error { - _, err := w.Write([]byte("hello")) - return err -} - -// 3. Function with unexported return type interface -func NewUnexportedReader() unexportedReader { // want "unexported interface 'unexportedReader' used as return value in exported function 'NewUnexportedReader'" - return nil // stub -} - -//iface:ignore=unexported -func NewUnexportedReaderIgnored() unexportedReader { - return nil // stub -} - -// 4. Function with exported return type interface -func NewWriter() ExportedWriter { - return nil // stub -} - -// 5. Function with both unexported arg and return type interface -func WrapReader(r unexportedReader) unexportedReader { // want "unexported interface 'unexportedReader' used as parameter in exported function 'WrapReader'" "unexported interface 'unexportedReader' used as return value in exported function 'WrapReader'" - return r -} - -// 6. Function with both exported arg and return type interface -func WrapWriter(w ExportedWriter) ExportedWriter { - return w -} - -// 7. Function with unexported arg type interface and exported return type interface -func PromoteReader(r unexportedReader) ExportedWriter { // want "unexported interface 'unexportedReader' used as parameter in exported function 'PromoteReader'" - return nil // stub -} - -// 8. Function with exported arg type interface and unexported return type interface -func DemoteWriter(w ExportedWriter) unexportedReader { // want "unexported interface 'unexportedReader' used as return value in exported function 'DemoteWriter'" - return nil // stub -} - -// 9. Function with external arg type interface (io.Writer) -func WriteToExternal(w io.Writer) error { - _, err := w.Write([]byte("external")) - return err -} - -// 10. Function with external return type interface (io.Writer) -func NewExternalWriter() io.Writer { - return nil // stub -} - -// 11. Function with both external arg and return type interface (io.Writer) -func WrapExternalWriter(w io.Writer) io.Writer { - return w -} - -// 12. Function with any arg type -func Print(a any) { -} - -// 13. Function witn interface{} arg type -func Write(i interface{}) { -} - -// 14. Function with error arg type -func Capture(err error) {} - -// 15. Function with no arg and no return type interface -func Ping() {} - -// 16. Function with primitive arg type -func AddOne(x int) int { - return x + 1 -} - -// 17. Function with primitive return type -func GetZero() int { - return 0 -} - -// 18. Function with both primitive arg and return type -func Double(x int) int { - return x * 2 -} - -// 19. Function with pointer to unexported interface parameter -func ReadPtr(r *unexportedReader) ([]byte, error) { // want `unexported interface '\*unexportedReader' used as parameter in exported function 'ReadPtr'` - return nil, nil -} - -// 20. Function with pointer to unexported interface return value -func NewReaderPtr() *unexportedReader { // want `unexported interface '\*unexportedReader' used as return value in exported function 'NewReaderPtr'` - return nil -} - -// 21. Function with pointer to unexported interface both param and return -func WrapReaderPtr(r *unexportedReader) *unexportedReader { // want `unexported interface '\*unexportedReader' used as parameter in exported function 'WrapReaderPtr'` `unexported interface '\*unexportedReader' used as return value in exported function 'WrapReaderPtr'` - return r -} - -// 22. Function with pointer to pointer to unexported interface -func ReadPtrPtr(r **unexportedReader) { // want `unexported interface '\*\*unexportedReader' used as parameter in exported function 'ReadPtrPtr'` -} - -// 23. Function with pointer to exported interface — no diagnostic -func ReadExportedPtr(r *ExportedWriter) {} - -// 24. Function with pointer to external interface — no diagnostic -func ReadExtPtr(r *io.Writer) {} - -// 25. Function with variadic unexported interface parameter -func ServeClient(h ...unexportedReader) {} // want `unexported interface '...unexportedReader' used as parameter in exported function 'ServeClient'` - -// 26. Function with variadic exported interface — no diagnostic -func ServeExportedVariadic(w ...ExportedWriter) {} - -// 27. Function with variadic any — no diagnostic -func ServeOK(h ...any) {} - -// 28. Function with variadic error — no diagnostic -func ServeErr(h ...error) {} - -// 29. Function with variadic pointer to unexported interface (nested wrapping) -func ServeVariadicPtr(h ...*unexportedReader) {} // want `unexported interface '...\*unexportedReader' used as parameter in exported function 'ServeVariadicPtr'` - -// 30. Function with slice of unexported interface parameter -func ReadMany(r []unexportedReader) {} // want `unexported interface '\[\]unexportedReader' used as parameter in exported function 'ReadMany'` - -// 31. Function with slice of unexported interface return value -func NewReaderSlice() []unexportedReader { return nil } // want `unexported interface '\[\]unexportedReader' used as return value in exported function 'NewReaderSlice'` - -// 32. Function with slice of unexported interface both param and return -func TransformReaders(r []unexportedReader) []unexportedReader { return r } // want `unexported interface '\[\]unexportedReader' used as parameter in exported function 'TransformReaders'` `unexported interface '\[\]unexportedReader' used as return value in exported function 'TransformReaders'` - -// 33. Function with slice of exported interface — no diagnostic -func ReadSliceExported(r []ExportedWriter) {} - -// 34. Function with slice of external interface — no diagnostic -func ReadSliceExt(r []io.Writer) {} - -// 35. Function with array of unexported interface parameter -func ReadFixed(r [4]unexportedReader) {} // want `unexported interface '\[4\]unexportedReader' used as parameter in exported function 'ReadFixed'` - -// 36. Function with array of unexported interface return value -func NewReaderArray() [2]unexportedReader { return [2]unexportedReader{} } // want `unexported interface '\[2\]unexportedReader' used as return value in exported function 'NewReaderArray'` - -// 37. Function with array of exported interface — no diagnostic -func ReadArrayExported(r [4]ExportedWriter) {} - -// 38. Function with array of external interface — no diagnostic -func ReadArrayExt(r [4]io.Writer) {} - -// 39. Function with receive-only channel of unexported interface parameter -func ReadChan(r <-chan unexportedReader) {} // want `unexported interface '<-chan unexportedReader' used as parameter in exported function 'ReadChan'` - -// 40. Function with send-only channel of unexported interface parameter -func WriteChan(r chan<- unexportedReader) {} // want `unexported interface 'chan<- unexportedReader' used as parameter in exported function 'WriteChan'` - -// 41. Function with bidirectional channel of unexported interface parameter -func BidiChan(r chan unexportedReader) {} // want `unexported interface 'chan unexportedReader' used as parameter in exported function 'BidiChan'` - -// 42. Function with receive-only channel of unexported interface return value -func NewReaderChan() <-chan unexportedReader { return nil } // want `unexported interface '<-chan unexportedReader' used as return value in exported function 'NewReaderChan'` - -// 43. Function with send-only channel of unexported interface return value -func NewReaderChanSend() chan<- unexportedReader { return nil } // want `unexported interface 'chan<- unexportedReader' used as return value in exported function 'NewReaderChanSend'` - -// 44. Function with channel of exported interface — no diagnostic -func ReadChanExported(r <-chan ExportedWriter) {} - -// 45. Function with channel of external interface — no diagnostic -func ReadChanExt(r <-chan io.Writer) {} - -// 46. Function with map value is unexported interface parameter -func ReadMapVal(r map[string]unexportedReader) {} // want `unexported interface 'map\[string\]unexportedReader' used as parameter in exported function 'ReadMapVal'` - -// 47. Function with map value is unexported interface return value -func NewReaderMapVal() map[string]unexportedReader { return nil } // want `unexported interface 'map\[string\]unexportedReader' used as return value in exported function 'NewReaderMapVal'` - -// 48. Function with map of exported interface — no diagnostic -func ReadMapExported(r map[string]ExportedWriter) {} - -// 49. Function with map of external interface — no diagnostic -func ReadMapExt(r map[string]io.Writer) {} - -// 50. Function with pointer to slice of unexported interface (nested wrapping) -func ReadPtrSlice(r *[]unexportedReader) {} // want `unexported interface '\*\[\]unexportedReader' used as parameter in exported function 'ReadPtrSlice'` - -// 51. Function with pointer to pointer to slice of unexported interface (nested wrapping) -func ReadPtrPtrSlice(r **[]unexportedReader) {} // want `unexported interface '\*\*\[\]unexportedReader' used as parameter in exported function 'ReadPtrPtrSlice'` - -// 52. Function with pointer to slice of unexported interface as return value -func NewReaderPtrSlice() *[]unexportedReader { return nil } // want `unexported interface '\*\[\]unexportedReader' used as return value in exported function 'NewReaderPtrSlice'` - -// 53. Function with slice of pointer to unexported interface -func ReadSlicePtr(r []*unexportedReader) {} // want `unexported interface '\[\]\*unexportedReader' used as parameter in exported function 'ReadSlicePtr'` - -// 54. Function with pointer to slice of external interface — no diagnostic -func ReadPtrSliceExt(r *[]io.Writer) {} - -// 55. Function with pointer to slice of exported interface — no diagnostic -func ReadPtrSliceExported(r *[]ExportedWriter) {} - -// 56. Function with slice of pointer to external interface — no diagnostic -func ReadSlicePtrExt(r []*io.Writer) {} - -// 57. Function with slice of pointer to exported interface — no diagnostic -func ReadSlicePtrExported(r []*ExportedWriter) {} diff --git a/unexported/testdata/src/b/b.go b/unexported/testdata/src/b/b.go deleted file mode 100644 index fa6d67f..0000000 --- a/unexported/testdata/src/b/b.go +++ /dev/null @@ -1,253 +0,0 @@ -package b - -import "io" - -// unexportedReader is an unexported interface. -type unexportedReader interface { - Read([]byte) (int, error) -} - -// ExportedWriter is an exported interface. -type ExportedWriter interface { - Write([]byte) (int, error) -} - -// ExportedType is an exported struct type. -type ExportedType struct{} - -// 1. Method with unexported arg type interface -func (e *ExportedType) ReadAll(r unexportedReader) ([]byte, error) { // want "unexported interface 'unexportedReader' used as parameter in exported method 'ExportedType.ReadAll'" - buf := make([]byte, 1024) - _, err := r.Read(buf) - return buf, err -} - -//iface:ignore=unexported -func (e *ExportedType) ReadAllIgnored(r unexportedReader) ([]byte, error) { - buf := make([]byte, 1024) - _, err := r.Read(buf) - return buf, err -} - -// 2. Method with exported arg type interface -func (e *ExportedType) WriteHello(w ExportedWriter) error { - _, err := w.Write([]byte("hello")) - return err -} - -// 3. Method with unexported return type interface -func (e *ExportedType) NewUnexportedReader() unexportedReader { // want "unexported interface 'unexportedReader' used as return value in exported method 'ExportedType.NewUnexportedReader'" - return nil // stub -} - -//iface:ignore=unexported -func (e *ExportedType) NewUnexportedReaderIgnored() unexportedReader { - return nil // stub -} - -// 4. Method with exported return type interface -func (e *ExportedType) NewWriter() ExportedWriter { - return nil // stub -} - -// 5. Method with both unexported arg and return type interface -func (e *ExportedType) WrapReader(r unexportedReader) unexportedReader { // want "unexported interface 'unexportedReader' used as parameter in exported method 'ExportedType.WrapReader'" "unexported interface 'unexportedReader' used as return value in exported method 'ExportedType.WrapReader'" - return r -} - -// 6. Method with both exported arg and return type interface -func (e *ExportedType) WrapWriter(w ExportedWriter) ExportedWriter { - return w -} - -// 7. Method with unexported arg type interface and exported return type interface -func (e *ExportedType) PromoteReader(r unexportedReader) ExportedWriter { // want "unexported interface 'unexportedReader' used as parameter in exported method 'ExportedType.PromoteReader'" - return nil // stub -} - -// 8. Method with exported arg type interface and unexported return type interface -func (e *ExportedType) DemoteWriter(w ExportedWriter) unexportedReader { // want "unexported interface 'unexportedReader' used as return value in exported method 'ExportedType.DemoteWriter'" - return nil // stub -} - -// 9. Method with external arg type interface (io.Writer) -func (e *ExportedType) WriteToExternal(w io.Writer) error { - _, err := w.Write([]byte("external")) - return err -} - -// 10. Method with external return type interface (io.Writer) -func (e *ExportedType) NewExternalWriter() io.Writer { - return nil // stub -} - -// 11. Method with both external arg and return type interface (io.Writer) -func (e *ExportedType) WrapExternalWriter(w io.Writer) io.Writer { - return w -} - -// 13. Method with any arg type -func (e *ExportedType) Print(a any) { -} - -// 14. Method with interface{} arg type -func (e *ExportedType) Write(i interface{}) { -} - -// 15. Method with error arg type -func (e *ExportedType) Capture(err error) {} - -// 16. Method with no arg and no return type interface -func (e *ExportedType) Ping() {} - -// 17. Method with primitive arg type -func (e *ExportedType) AddOne(x int) int { - return x + 1 -} - -// 18. Method with primitive return type -func (e *ExportedType) GetZero() int { - return 0 -} - -// 19. Method with both primitive arg and return type -func (e *ExportedType) Double(x int) int { - return x * 2 -} - -// 20. Method with pointer to unexported interface parameter -func (e *ExportedType) ReadPtr(r *unexportedReader) ([]byte, error) { // want `unexported interface '\*unexportedReader' used as parameter in exported method 'ExportedType.ReadPtr'` - return nil, nil -} - -// 21. Method with pointer to unexported interface return value -func (e *ExportedType) NewReaderPtr() *unexportedReader { // want `unexported interface '\*unexportedReader' used as return value in exported method 'ExportedType.NewReaderPtr'` - return nil -} - -// 22. Method with pointer to unexported interface both param and return -func (e *ExportedType) WrapReaderPtr(r *unexportedReader) *unexportedReader { // want `unexported interface '\*unexportedReader' used as parameter in exported method 'ExportedType.WrapReaderPtr'` `unexported interface '\*unexportedReader' used as return value in exported method 'ExportedType.WrapReaderPtr'` - return r -} - -// 23. Method with pointer to pointer to unexported interface -func (e *ExportedType) ReadPtrPtr(r **unexportedReader) { // want `unexported interface '\*\*unexportedReader' used as parameter in exported method 'ExportedType.ReadPtrPtr'` -} - -// 24. Method with pointer to exported interface — no diagnostic -func (e *ExportedType) ReadExportedPtr(r *ExportedWriter) {} - -// 25. Method with pointer to external interface — no diagnostic -func (e *ExportedType) ReadExtPtr(r *io.Writer) {} - -// 26. Method with variadic unexported interface parameter -func (e *ExportedType) ServeClient(h ...unexportedReader) {} // want `unexported interface '...unexportedReader' used as parameter in exported method 'ExportedType.ServeClient'` - -// 27. Method with variadic exported interface — no diagnostic -func (e *ExportedType) ServeExportedVariadic(w ...ExportedWriter) {} - -// 28. Method with variadic pointer to unexported interface (nested wrapping) -func (e *ExportedType) ServeVariadicPtr(h ...*unexportedReader) {} // want `unexported interface '...\*unexportedReader' used as parameter in exported method 'ExportedType.ServeVariadicPtr'` - -// 29. Method with slice of unexported interface parameter -func (e *ExportedType) ReadMany(r []unexportedReader) {} // want `unexported interface '\[\]unexportedReader' used as parameter in exported method 'ExportedType.ReadMany'` - -// 30. Method with slice of unexported interface return value -func (e *ExportedType) NewReaderSlice() []unexportedReader { return nil } // want `unexported interface '\[\]unexportedReader' used as return value in exported method 'ExportedType.NewReaderSlice'` - -// 31. Method with slice of unexported interface both param and return -func (e *ExportedType) TransformReaders(r []unexportedReader) []unexportedReader { return r } // want `unexported interface '\[\]unexportedReader' used as parameter in exported method 'ExportedType.TransformReaders'` `unexported interface '\[\]unexportedReader' used as return value in exported method 'ExportedType.TransformReaders'` - -// 32. Method with slice of exported interface — no diagnostic -func (e *ExportedType) ReadSliceExported(r []ExportedWriter) {} - -// 33. Method with slice of external interface — no diagnostic -func (e *ExportedType) ReadSliceExt(r []io.Writer) {} - -// 34. Method with array of unexported interface parameter -func (e *ExportedType) ReadFixed(r [4]unexportedReader) {} // want `unexported interface '\[4\]unexportedReader' used as parameter in exported method 'ExportedType.ReadFixed'` - -// 35. Method with array of unexported interface return value -func (e *ExportedType) NewReaderArray() [2]unexportedReader { return [2]unexportedReader{} } // want `unexported interface '\[2\]unexportedReader' used as return value in exported method 'ExportedType.NewReaderArray'` - -// 36. Method with array of exported interface — no diagnostic -func (e *ExportedType) ReadArrayExported(r [4]ExportedWriter) {} - -// 37. Method with array of external interface — no diagnostic -func (e *ExportedType) ReadArrayExt(r [4]io.Writer) {} - -// 38. Method with receive-only channel of unexported interface parameter -func (e *ExportedType) ReadChan(r <-chan unexportedReader) {} // want `unexported interface '<-chan unexportedReader' used as parameter in exported method 'ExportedType.ReadChan'` - -// 39. Method with send-only channel of unexported interface parameter -func (e *ExportedType) WriteChan(r chan<- unexportedReader) {} // want `unexported interface 'chan<- unexportedReader' used as parameter in exported method 'ExportedType.WriteChan'` - -// 40. Method with bidirectional channel of unexported interface parameter -func (e *ExportedType) BidiChan(r chan unexportedReader) {} // want `unexported interface 'chan unexportedReader' used as parameter in exported method 'ExportedType.BidiChan'` - -// 41. Method with receive-only channel of unexported interface return value -func (e *ExportedType) NewReaderChan() <-chan unexportedReader { return nil } // want `unexported interface '<-chan unexportedReader' used as return value in exported method 'ExportedType.NewReaderChan'` - -// 42. Method with send-only channel of unexported interface return value -func (e *ExportedType) NewReaderChanSend() chan<- unexportedReader { return nil } // want `unexported interface 'chan<- unexportedReader' used as return value in exported method 'ExportedType.NewReaderChanSend'` - -// 43. Method with channel of exported interface — no diagnostic -func (e *ExportedType) ReadChanExported(r <-chan ExportedWriter) {} - -// 44. Method with channel of external interface — no diagnostic -func (e *ExportedType) ReadChanExt(r <-chan io.Writer) {} - -// 45. Method with map value is unexported interface parameter -func (e *ExportedType) ReadMapVal(r map[string]unexportedReader) {} // want `unexported interface 'map\[string\]unexportedReader' used as parameter in exported method 'ExportedType.ReadMapVal'` - -// 46. Method with map value is unexported interface return value -func (e *ExportedType) NewReaderMapVal() map[string]unexportedReader { return nil } // want `unexported interface 'map\[string\]unexportedReader' used as return value in exported method 'ExportedType.NewReaderMapVal'` - -// 47. Method with map of exported interface — no diagnostic -func (e *ExportedType) ReadMapExported(r map[string]ExportedWriter) {} - -// 48. Method with map of external interface — no diagnostic -func (e *ExportedType) ReadMapExt(r map[string]io.Writer) {} - -// 49. Method with pointer to slice of unexported interface (nested wrapping) -func (e *ExportedType) ReadPtrSlice(r *[]unexportedReader) {} // want `unexported interface '\*\[\]unexportedReader' used as parameter in exported method 'ExportedType.ReadPtrSlice'` - -// 50. Method with pointer to pointer to slice of unexported interface (nested wrapping) -func (e *ExportedType) ReadPtrPtrSlice(r **[]unexportedReader) {} // want `unexported interface '\*\*\[\]unexportedReader' used as parameter in exported method 'ExportedType.ReadPtrPtrSlice'` - -// 51. Method with pointer to slice of unexported interface as return value -func (e *ExportedType) NewReaderPtrSlice() *[]unexportedReader { return nil } // want `unexported interface '\*\[\]unexportedReader' used as return value in exported method 'ExportedType.NewReaderPtrSlice'` - -// 52. Method with slice of pointer to unexported interface -func (e *ExportedType) ReadSlicePtr(r []*unexportedReader) {} // want `unexported interface '\[\]\*unexportedReader' used as parameter in exported method 'ExportedType.ReadSlicePtr'` - -// 53. Method with pointer to slice of external interface — no diagnostic -func (e *ExportedType) ReadPtrSliceExt(r *[]io.Writer) {} - -// 54. Method with pointer to slice of exported interface — no diagnostic -func (e *ExportedType) ReadPtrSliceExported(r *[]ExportedWriter) {} - -// 55. Method with slice of pointer to external interface — no diagnostic -func (e *ExportedType) ReadSlicePtrExt(r []*io.Writer) {} - -// 56. Method with slice of pointer to exported interface — no diagnostic -func (e *ExportedType) ReadSlicePtrExported(r []*ExportedWriter) {} - -// 57. Generic receiver with unexported interface parameter -type GenericType[T any] struct{} - -func (g *GenericType[T]) Process(r unexportedReader) {} // want "unexported interface 'unexportedReader' used as parameter in exported method 'GenericType\\[T\\].Process'" - -// 58. Generic receiver with unexported interface return value -func (g *GenericType[T]) NewReader() unexportedReader { return nil } // want "unexported interface 'unexportedReader' used as return value in exported method 'GenericType\\[T\\].NewReader'" - -// 59. Generic receiver with both unexported interface param and return -func (g *GenericType[T]) WrapReader(r unexportedReader) unexportedReader { return r } // want "unexported interface 'unexportedReader' used as parameter in exported method 'GenericType\\[T\\].WrapReader'" "unexported interface 'unexportedReader' used as return value in exported method 'GenericType\\[T\\].WrapReader'" - -// 60. Pointer to generic receiver with unexported interface parameter -func (g *GenericType[T]) ProcessPtr(r unexportedReader) {} // want "unexported interface 'unexportedReader' used as parameter in exported method 'GenericType\\[T\\].ProcessPtr'" - -// 61. Multi-param generic receiver with unexported interface parameter -type MultiGenericType[T, U any] struct{} - -func (m *MultiGenericType[T, U]) Handle(r unexportedReader) {} // want "unexported interface 'unexportedReader' used as parameter in exported method 'MultiGenericType\\[T, U\\].Handle'" diff --git a/unexported/testdata/src/fun/fun.go b/unexported/testdata/src/fun/fun.go new file mode 100644 index 0000000..e063dbd --- /dev/null +++ b/unexported/testdata/src/fun/fun.go @@ -0,0 +1,123 @@ +package fun + +import ( + "fmt" + "io" + "os" +) + +type execer interface { + Exec() (any, error) +} + +type Caller interface { + Call() (any, error) +} + +type AddTask struct { + a int + b int +} + +func (t *AddTask) Exec() (any, error) { + return t.a + t.b, nil +} + +type CallFunc func() (any, error) + +func (cf CallFunc) Call() (any, error) { + return cf() +} + +func ExecAdd(a, b int) execer { // want "^unexported interface 'execer' used as return value in exported function 'ExecAdd'$" + return &AddTask{a, b} +} + +func CallAdd(a, b int) Caller { + return CallFunc(ExecAdd(a, b).Exec) +} + +func NewAddTask(a, b int) *AddTask { + return &AddTask{a, b} +} + +func Exec(e execer) (any, error) { // want "^unexported interface 'execer' used as parameter in exported function 'Exec'$" + return e.Exec() +} + +func ExecPtr(e *execer) (any, error) { // want "^unexported interface '\\*execer' used as parameter in exported function 'ExecPtr'$" + return (*e).Exec() +} + +func exe(c execer) (any, error) { + return Exec(c) +} + +func DumpExec(w io.Writer, c execer) { // want "^unexported interface 'execer' used as parameter in exported function 'DumpExec'$" + out, err := Exec(c) + if err != nil { + fmt.Fprintf(w, "err: %v\n", err) + return + } + fmt.Fprintf(w, "out: %v\n", out) +} + +func Call(c Caller) (any, error) { + return c.Call() +} + +func ExecAll(execs []execer) (any, error) { // want "^unexported interface '\\[\\]execer' used as parameter in exported function 'ExecAll'$" + var out []any + for _, e := range execs { + res, err := e.Exec() + if err != nil { + return nil, err + } + out = append(out, res) + } + return out, nil +} + +func CallAll(calls []Caller) (any, error) { + var out []any + for _, c := range calls { + res, err := c.Call() + if err != nil { + return nil, err + } + out = append(out, res) + } + return out, nil +} + +func Execs(a ...execer) (any, error) { // want "^unexported interface '...execer' used as parameter in exported function 'Execs'$" + return ExecAll(a) +} + +func Calls(a ...Caller) (any, error) { + return CallAll(a) +} + +func ExecChan(ch <-chan execer) chan<- any { // want "^unexported interface '<-chan execer' used as parameter in exported function 'ExecChan'$" + out := make(chan any) + go func() { + for v := range ch { + res, err := v.Exec() + if err != nil { + continue + } + + out <- res + } + }() + return out +} + +func LogError(msg string, err error) { + fmt.Fprintf(os.Stderr, "ERROR: %s err: %v\n", msg, err) +} + +func LogInfo(format string, a ...any) { + msg := fmt.Sprintf(format, a...) + fmt.Fprintf(os.Stderr, "INFO: %s\n", msg) +} diff --git a/unexported/testdata/src/ignoredirective/ignoredirective.go b/unexported/testdata/src/ignoredirective/ignoredirective.go new file mode 100644 index 0000000..085b7dc --- /dev/null +++ b/unexported/testdata/src/ignoredirective/ignoredirective.go @@ -0,0 +1,10 @@ +package ignoredirective + +type execer interface { + Exec() (any, error) +} + +//iface:ignore=unexported +func Exec(e execer) (any, error) { + return e.Exec() +} diff --git a/unexported/testdata/src/method/method.go b/unexported/testdata/src/method/method.go new file mode 100644 index 0000000..b0b2d5f --- /dev/null +++ b/unexported/testdata/src/method/method.go @@ -0,0 +1,27 @@ +package method + +type User struct { + ID string + Name string + Role string + Terminated bool +} + +type matcher interface { + Match(*User) bool +} + +type UserRepository struct { + users []*User +} + +func (ur *UserRepository) Query(m matcher) ([]*User, error) { // want "^unexported interface 'matcher' used as parameter in exported method 'UserRepository.Query'$" + var res []*User + for _, u := range ur.users { + if !m.Match(u) { + continue + } + res = append(res, u) + } + return res, nil +} diff --git a/unexported/testdata/src/typeparams/typeparams.go b/unexported/testdata/src/typeparams/typeparams.go new file mode 100644 index 0000000..492864f --- /dev/null +++ b/unexported/testdata/src/typeparams/typeparams.go @@ -0,0 +1,38 @@ +package typeparams + +import ( + "fmt" +) + +type execer[T any] interface { + Exec() (T, error) +} + +func Exec[T any](name string, reg map[string]execer[T]) (T, error) { // want "^unexported interface 'map\\[string\\]execer\\[T\\]' used as parameter in exported function 'Exec'$" + exe, ok := reg[name] + if !ok { + var zero T + return zero, fmt.Errorf("no %q on reg", name) + } + + return exe.Exec() +} + +type matcher[T any] interface { + Match(T) bool +} + +type Repository[T any] struct { + entries []T +} + +func (r *Repository[T]) Query(m matcher[T]) ([]T, error) { // want "^unexported interface 'matcher\\[T\\]' used as parameter in exported method 'Repository\\[T\\].Query'$" + var res []T + for _, e := range r.entries { + if ok := m.Match(e); !ok { + continue + } + res = append(res, e) + } + return res, nil +} diff --git a/unexported/unexported.go b/unexported/unexported.go index d9496b9..5e0c5c7 100644 --- a/unexported/unexported.go +++ b/unexported/unexported.go @@ -108,6 +108,7 @@ func findIdent(expr ast.Expr) ast.Expr { case *ast.Ident, *ast.SelectorExpr: return e default: + // should not happen return nil } } diff --git a/unexported/unexported_test.go b/unexported/unexported_test.go index d583c2d..72e3acd 100644 --- a/unexported/unexported_test.go +++ b/unexported/unexported_test.go @@ -9,6 +9,9 @@ import ( func Test(t *testing.T) { testdata := analysistest.TestData() - analysistest.Run(t, testdata, unexported.Analyzer, "a") - analysistest.Run(t, testdata, unexported.Analyzer, "b") + analysistest.Run(t, testdata, unexported.Analyzer, + "fun", + "method", + "ignoredirective", + "typeparams") }