]> Cypherpunks repositories - gostls13.git/commitdiff
go/doc: propagate types from unexported constants
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 23 Dec 2014 20:10:36 +0000 (12:10 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 6 Jan 2015 00:24:13 +0000 (00:24 +0000)
When constants were declared using unexported constants,
the type information was lost when those constants were filtered out.
This CL propagates the type information of unexported constants
so that it is available for display.

This is a follow-up to CL 144110044, which fixed this problem
specifically for _ constants.

Updates #5397.

Change-Id: I3f0c767a4007d88169a5634ab2870deea4e6a740
Reviewed-on: https://go-review.googlesource.com/2091
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/doc/exports.go
src/go/doc/testdata/blank.0.golden
src/go/doc/testdata/blank.1.golden
src/go/doc/testdata/blank.2.golden
src/go/doc/testdata/blank.go

index 1d3b466d8c7bb6d767913f04ec8843470ab3713b..06789bc1081289b7c2bfcbeebe9cf3e7b279d8b4 100644 (file)
@@ -26,6 +26,17 @@ func filterIdentList(list []*ast.Ident, blankOk bool) []*ast.Ident {
        return list[0:j]
 }
 
+// hasExportedOrBlankName reports whether list contains any exported or blank names.
+//
+func hasExportedOrBlankName(list []*ast.Ident) bool {
+       for _, x := range list {
+               if x.IsExported() || x.Name == "_" {
+                       return true
+               }
+       }
+       return false
+}
+
 // removeErrorField removes anonymous fields named "error" from an interface.
 // This is called when "error" has been determined to be a local name,
 // not the predeclared type.
@@ -165,7 +176,47 @@ func (r *reader) filterSpec(spec ast.Spec, tok token.Token) bool {
        return false
 }
 
+// copyConstType returns a copy of typ with position pos.
+// typ must be a valid constant type.
+// In practice, only (possibly qualified) identifiers are possible.
+//
+func copyConstType(typ ast.Expr, pos token.Pos) ast.Expr {
+       switch typ := typ.(type) {
+       case *ast.Ident:
+               return &ast.Ident{Name: typ.Name, NamePos: pos}
+       case *ast.SelectorExpr:
+               if id, ok := typ.X.(*ast.Ident); ok {
+                       // presumably a qualified identifier
+                       return &ast.SelectorExpr{
+                               Sel: ast.NewIdent(typ.Sel.Name),
+                               X:   &ast.Ident{Name: id.Name, NamePos: pos},
+                       }
+               }
+       }
+       return nil // shouldn't happen, but be conservative and don't panic
+}
+
 func (r *reader) filterSpecList(list []ast.Spec, tok token.Token) []ast.Spec {
+       if tok == token.CONST {
+               // Propagate any type information that would get lost otherwise
+               // when unexported constants are filtered.
+               var prevType ast.Expr
+               for _, spec := range list {
+                       spec := spec.(*ast.ValueSpec)
+                       if spec.Type == nil && prevType != nil {
+                               // provide current spec with an explicit type
+                               spec.Type = copyConstType(prevType, spec.Pos())
+                       }
+                       if hasExportedOrBlankName(spec.Names) {
+                               // both exported and blank names are preserved
+                               // so there's no need to propagate the type
+                               prevType = nil
+                       } else {
+                               prevType = spec.Type
+                       }
+               }
+       }
+
        j := 0
        for _, s := range list {
                if r.filterSpec(s, tok) {
index dae3ab2affa0e99fc628a46d55fae2ce31eba769..5f34038426b9fd933229abf5b90ed083c065ca64 100644 (file)
@@ -4,10 +4,30 @@ PACKAGE blank
 IMPORTPATH
        testdata/blank
 
+IMPORTS
+       os
+
 FILENAMES
        testdata/blank.go
 
 CONSTANTS
+       // T constants counting from unexported constants. 
+       const (
+               C1      T
+               C2
+       
+               C3
+       
+               C4      int
+       )
+
+       // Constants with an imported type that needs to be propagated. 
+       const (
+               Default         os.FileMode     = 0644
+               Useless                         = 0312
+               WideOpen                        = 0777
+       )
+
        // Package constants. 
        const (
                _       int     = iota
@@ -28,7 +48,7 @@ TYPES
        // 
        type T int
 
-       // T constants. 
+       // T constants counting from a blank constant
        const (
                _       T       = iota
                T1
index 333d7e5b040baac8bed9c65467c0b6905f19470f..af5328fbb6904aa5eea872e14ced6baeedd3cb20 100644 (file)
@@ -4,10 +4,25 @@ PACKAGE blank
 IMPORTPATH
        testdata/blank
 
+IMPORTS
+       os
+
 FILENAMES
        testdata/blank.go
 
 CONSTANTS
+       // T constants counting from unexported constants. 
+       const (
+               tweedledee      T       = iota
+               tweedledum
+               C1
+               C2
+               alice
+               C3
+               redQueen        int     = iota
+               C4
+       )
+
        // Package constants. 
        const (
                _       int     = iota
@@ -15,6 +30,14 @@ CONSTANTS
                I2
        )
 
+       // Constants with an imported type that needs to be propagated. 
+       const (
+               zero            os.FileMode     = 0
+               Default                         = 0644
+               Useless                         = 0312
+               WideOpen                        = 0777
+       )
+
 
 VARIABLES
        // 
@@ -37,7 +60,7 @@ TYPES
        // 
        type T int
 
-       // T constants. 
+       // T constants counting from a blank constant
        const (
                _       T       = iota
                T1
index dae3ab2affa0e99fc628a46d55fae2ce31eba769..5f34038426b9fd933229abf5b90ed083c065ca64 100644 (file)
@@ -4,10 +4,30 @@ PACKAGE blank
 IMPORTPATH
        testdata/blank
 
+IMPORTS
+       os
+
 FILENAMES
        testdata/blank.go
 
 CONSTANTS
+       // T constants counting from unexported constants. 
+       const (
+               C1      T
+               C2
+       
+               C3
+       
+               C4      int
+       )
+
+       // Constants with an imported type that needs to be propagated. 
+       const (
+               Default         os.FileMode     = 0644
+               Useless                         = 0312
+               WideOpen                        = 0777
+       )
+
        // Package constants. 
        const (
                _       int     = iota
@@ -28,7 +48,7 @@ TYPES
        // 
        type T int
 
-       // T constants. 
+       // T constants counting from a blank constant
        const (
                _       T       = iota
                T1
index f812c77b777d1714029444d81e2c6d973032e3b3..83e42ed39fa9cd509b06b95408d6dbcc671b7a8f 100644 (file)
@@ -6,15 +6,37 @@
 // See issue 5397.
 package blank
 
+import "os"
+
 type T int
 
-// T constants.
+// T constants counting from a blank constant.
 const (
        _ T = iota
        T1
        T2
 )
 
+// T constants counting from unexported constants.
+const (
+       tweedledee T = iota
+       tweedledum
+       C1
+       C2
+       alice
+       C3
+       redQueen int = iota
+       C4
+)
+
+// Constants with an imported type that needs to be propagated.
+const (
+       zero     os.FileMode = 0
+       Default              = 0644
+       Useless              = 0312
+       WideOpen             = 0777
+)
+
 // Package constants.
 const (
        _ int = iota