]> Cypherpunks repositories - gostls13.git/commitdiff
go/doc: classify function returning slice of T as constructor
authorThomas Wanielista <tomwans@gmail.com>
Thu, 10 Aug 2017 22:39:18 +0000 (18:39 -0400)
committerRobert Griesemer <gri@golang.org>
Tue, 22 Aug 2017 08:09:42 +0000 (08:09 +0000)
Previously, go/doc would only consider functions that return types of
T or any number of pointers to T: *T, **T, etc. This change expands
the definition of a constructor to also include functions that return
slices of a type (or pointer to that type) in its first return.

With this change, the following return types classify a function
as a constructor of type T:

T
*T
**T (and so on)
[]T
[]*T
[]**T (and so on)

Fixes #18063.

Change-Id: I9a1a689933e13c6b8eb80b74ceec85bd4cab236d
Reviewed-on: https://go-review.googlesource.com/54971
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/doc/reader.go
src/go/doc/testdata/issue18063.0.golden [new file with mode: 0644]
src/go/doc/testdata/issue18063.1.golden [new file with mode: 0644]
src/go/doc/testdata/issue18063.2.golden [new file with mode: 0644]
src/go/doc/testdata/issue18063.go [new file with mode: 0644]

index 8e823538689be2fb783d89c4b0898fd86939b002..17635f05615b42eaa3eb6b1d80db9611806e68fe 100644 (file)
@@ -391,7 +391,13 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
                        // exactly one (named or anonymous) result associated
                        // with the first type in result signature (there may
                        // be more than one result)
-                       if n, imp := baseTypeName(res.Type); !imp && r.isVisible(n) {
+                       factoryType := res.Type
+                       if t, ok := factoryType.(*ast.ArrayType); ok && t.Len == nil {
+                               // We consider functions that return slices of type T (or
+                               // pointers to T) as factory functions of T.
+                               factoryType = t.Elt
+                       }
+                       if n, imp := baseTypeName(factoryType); !imp && r.isVisible(n) {
                                if typ := r.lookupType(n); typ != nil {
                                        // associate function with typ
                                        typ.funcs.set(fun)
diff --git a/src/go/doc/testdata/issue18063.0.golden b/src/go/doc/testdata/issue18063.0.golden
new file mode 100644 (file)
index 0000000..0afbc16
--- /dev/null
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+       testdata/issue18063
+
+FILENAMES
+       testdata/issue18063.go
+
+FUNCTIONS
+       // NewArray is not a factory function because arrays of type T are ...
+       func NewArray() [1]T
+
+       // NewPointerArray is not a factory function because arrays of ...
+       func NewPointerArray() [1]*T
+
+       // NewPointerSliceOfSlice is not a factory function because slices ...
+       func NewPointerSliceOfSlice() [][]*T
+
+       // NewSlice3 is not a factory function because 3 nested slices of ...
+       func NewSlice3() [][][]T
+
+       // NewSliceOfSlice is not a factory function because slices of a ...
+       func NewSliceOfSlice() [][]T
+
+
+TYPES
+       // 
+       type T struct{}
+
+       // 
+       func New() T
+
+       // 
+       func NewPointer() *T
+
+       // 
+       func NewPointerOfPointer() **T
+
+       // 
+       func NewPointerSlice() []*T
+
+       // 
+       func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.1.golden b/src/go/doc/testdata/issue18063.1.golden
new file mode 100644 (file)
index 0000000..0afbc16
--- /dev/null
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+       testdata/issue18063
+
+FILENAMES
+       testdata/issue18063.go
+
+FUNCTIONS
+       // NewArray is not a factory function because arrays of type T are ...
+       func NewArray() [1]T
+
+       // NewPointerArray is not a factory function because arrays of ...
+       func NewPointerArray() [1]*T
+
+       // NewPointerSliceOfSlice is not a factory function because slices ...
+       func NewPointerSliceOfSlice() [][]*T
+
+       // NewSlice3 is not a factory function because 3 nested slices of ...
+       func NewSlice3() [][][]T
+
+       // NewSliceOfSlice is not a factory function because slices of a ...
+       func NewSliceOfSlice() [][]T
+
+
+TYPES
+       // 
+       type T struct{}
+
+       // 
+       func New() T
+
+       // 
+       func NewPointer() *T
+
+       // 
+       func NewPointerOfPointer() **T
+
+       // 
+       func NewPointerSlice() []*T
+
+       // 
+       func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.2.golden b/src/go/doc/testdata/issue18063.2.golden
new file mode 100644 (file)
index 0000000..0afbc16
--- /dev/null
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+       testdata/issue18063
+
+FILENAMES
+       testdata/issue18063.go
+
+FUNCTIONS
+       // NewArray is not a factory function because arrays of type T are ...
+       func NewArray() [1]T
+
+       // NewPointerArray is not a factory function because arrays of ...
+       func NewPointerArray() [1]*T
+
+       // NewPointerSliceOfSlice is not a factory function because slices ...
+       func NewPointerSliceOfSlice() [][]*T
+
+       // NewSlice3 is not a factory function because 3 nested slices of ...
+       func NewSlice3() [][][]T
+
+       // NewSliceOfSlice is not a factory function because slices of a ...
+       func NewSliceOfSlice() [][]T
+
+
+TYPES
+       // 
+       type T struct{}
+
+       // 
+       func New() T
+
+       // 
+       func NewPointer() *T
+
+       // 
+       func NewPointerOfPointer() **T
+
+       // 
+       func NewPointerSlice() []*T
+
+       // 
+       func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.go b/src/go/doc/testdata/issue18063.go
new file mode 100644 (file)
index 0000000..1193af5
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2017 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 issue18063
+
+type T struct{}
+
+func New() T                   { return T{} }
+func NewPointer() *T           { return &T{} }
+func NewPointerSlice() []*T    { return []*T{&T{}} }
+func NewSlice() []T            { return []T{T{}} }
+func NewPointerOfPointer() **T { x := &T{}; return &x }
+
+// NewArray is not a factory function because arrays of type T are not
+// factory functions of type T.
+func NewArray() [1]T { return [1]T{T{}} }
+
+// NewPointerArray is not a factory function because arrays of type *T are not
+// factory functions of type T.
+func NewPointerArray() [1]*T { return [1]*T{&T{}} }
+
+// NewSliceOfSlice is not a factory function because slices of a slice of
+// type *T are not factory functions of type T.
+func NewSliceOfSlice() [][]T { return []T{[]T{}} }
+
+// NewPointerSliceOfSlice is not a factory function because slices of a
+// slice of type *T are not factory functions of type T.
+func NewPointerSliceOfSlice() [][]*T { return []*T{[]*T{}} }
+
+// NewSlice3 is not a factory function because 3 nested slices of type T
+// are not factory functions of type T.
+func NewSlice3() [][][]T { return []T{[]T{[]T{}}} }