]> Cypherpunks repositories - gostls13.git/commitdiff
go/printer: remove exported StdFormat flag
authorDmitri Shuralyov <dmitshur@golang.org>
Wed, 1 Jul 2020 16:49:43 +0000 (12:49 -0400)
committerDmitri Shuralyov <dmitshur@golang.org>
Fri, 17 Jul 2020 02:15:01 +0000 (02:15 +0000)
The StdFormat flag was added as part of CL 231461, where the primary aim
was to fix the bug #37476. It's expected that the existing printer modes
only adjust spacing but do not change any of the code text itself. A new
printing flag served as a way for cmd/gofmt and go/format to delegate
a part of formatting work to the printer—where it's more more convenient
and efficient to perform—while maintaining current low-level printing
behavior of go/printer unmodified.

We already have cmd/gofmt and the go/format API that implement standard
formatting of Go source code, so there isn't a need to expose StdFormat
flag to the world, as it can only cause confusion.

Consider that to format source in canonical gofmt style completely it
may require tasks A, B, C to be done. In one version of Go, the printer
may do both A and B, while cmd/gofmt and go/format will do the remaining
task C. In another version, the printer may take on doing just A, while
cmd/gofmt and go/format will perform B and C. This makes it hard to add
a gofmt-like mode to the printer without compromising on above fluidity.

This change prefers to shift back some complexity to the implementation
of the standard library, allowing us to avoid creating the new exported
printing flag just for the internal needs of gofmt and go/format today.

We may still want to re-think the API and consider if something better
should be added, but unfortunately there isn't time for Go 1.15. We are
not adding new APIs now, so we can defer this decision until Go 1.16 or
later, when there is more time.

For #37476.
For #37453.
For #39489.
For #37419.

Change-Id: I0bb07156dca852b043487099dcf05c5350b29e20
Reviewed-on: https://go-review.googlesource.com/c/go/+/240683
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
api/go1.15.txt
doc/go1.15.html
src/cmd/gofmt/gofmt.go
src/go/format/format.go
src/go/format/format_test.go
src/go/printer/nodes.go
src/go/printer/performance_test.go
src/go/printer/printer.go
src/go/printer/printer_test.go
src/go/printer/testdata/go2numbers.norm [moved from src/go/printer/testdata/go2numbers.stdfmt with 100% similarity]

index b51837cf3806c58ac76172b374300383493fdba7..dd90506eba46b6190af200ee410f822f5f3aa170 100644 (file)
@@ -112,8 +112,6 @@ pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
 pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_GUI ideal-int
 pkg debug/pe, const IMAGE_SUBSYSTEM_XBOX = 14
 pkg debug/pe, const IMAGE_SUBSYSTEM_XBOX ideal-int
-pkg go/printer, const StdFormat = 16
-pkg go/printer, const StdFormat Mode
 pkg math/big, method (*Int) FillBytes([]uint8) []uint8
 pkg net, method (*Resolver) LookupIP(context.Context, string, string) ([]IP, error)
 pkg net/url, method (*URL) EscapedFragment() string
index e4a2491e7044bcba91e79b958f2b4d61a63a710e..448a507f6abae90732d8e35bb0c6f0b873eb6f9f 100644 (file)
@@ -658,15 +658,18 @@ Do not send CLs removing the interior tags from such phrases.
   </dd>
 </dl><!-- fmt -->
 
-<dl id="go/printer"><dt><a href="/pkg/go/printer/">go/printer</a></dt>
+<dl id="go/format"><dt><a href="/pkg/go/format/">go/format</a></dt>
   <dd>
-    <p><!-- CL 231461 -->
-      The new <a href="/pkg/go/printer/#Mode"><code>Mode</code></a>
-      value <a href="/pkg/go/printer/#StdFormat"><code>StdFormat</code></a>
-      directs the printer to apply standard formatting changes while
-      printing the output.
+    <p><!-- golang.org/issue/37476, CL 231461, CL 240683 -->
+      The <a href="/pkg/go/format/#Source"><code>Source</code></a> and
+      <a href="/pkg/go/format/#Node"><code>Node</code></a> functions
+      now canonicalize number literal prefixes and exponents as part
+      of formatting Go source code. This matches the behavior of the
+      <a href="/pkg/cmd/gofmt/"><code>gofmt</code></a> command as it
+      was implemented <a href="/doc/go1.13#gofmt">since Go 1.13</a>.
+    </p>
   </dd>
-</dl><!-- go/printer -->
+</dl><!-- go/format -->
 
 <dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
   <dd>
index 679fdd7b8a5313d9da7a3825ab93db79672dfd84..8c56af7559690b300849408003665b6b0600242e 100644 (file)
@@ -40,7 +40,13 @@ var (
 // Keep these in sync with go/format/format.go.
 const (
        tabWidth    = 8
-       printerMode = printer.UseSpaces | printer.TabIndent | printer.StdFormat
+       printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers
+
+       // printerNormalizeNumbers means to canonicalize number literal prefixes
+       // and exponents while printing. See https://golang.org/doc/go1.13#gofmt.
+       //
+       // This value is defined in go/printer specifically for go/format and cmd/gofmt.
+       printerNormalizeNumbers = 1 << 30
 )
 
 var (
index 84afbb066a9c28073ccf5af0b08be143b2a02fde..a603d9630e6794bc2d62f190ae29bdf9487128c2 100644 (file)
@@ -27,7 +27,13 @@ import (
 // Keep these in sync with cmd/gofmt/gofmt.go.
 const (
        tabWidth    = 8
-       printerMode = printer.UseSpaces | printer.TabIndent | printer.StdFormat
+       printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers
+
+       // printerNormalizeNumbers means to canonicalize number literal prefixes
+       // and exponents while printing. See https://golang.org/doc/go1.13#gofmt.
+       //
+       // This value is defined in go/printer specifically for go/format and cmd/gofmt.
+       printerNormalizeNumbers = 1 << 30
 )
 
 var config = printer.Config{Mode: printerMode, Tabwidth: tabWidth}
index aee51e2da13acd76374f66e5fa6ee0f5c09a3678..58e088ede31535d5d000a33e90aad291ccd539a8 100644 (file)
@@ -58,8 +58,8 @@ func TestNode(t *testing.T) {
        diff(t, buf.Bytes(), src)
 }
 
-// Node is documented to not modify the AST. Test that it is so, even when
-// formatting changes are applied due to printer.StdFormat mode being used.
+// Node is documented to not modify the AST.
+// Test that it is so even when numbers are normalized.
 func TestNodeNoModify(t *testing.T) {
        const (
                src    = "package p\n\nconst _ = 0000000123i\n"
index 0360c4606e26dd2169a28dd1eb02fc12ad13909f..95b9e918917cd50685cb27e3ac03dc9ca89e4877 100644 (file)
@@ -791,8 +791,8 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
                }
 
        case *ast.BasicLit:
-               if p.Config.Mode&StdFormat != 0 {
-                       x = normalizeNumbers(x)
+               if p.Config.Mode&normalizeNumbers != 0 {
+                       x = normalizedNumber(x)
                }
                p.print(x)
 
@@ -974,11 +974,15 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
        }
 }
 
-// normalizeNumbers rewrites base prefixes and exponents to
-// use lower-case letters, and removes leading 0's from
-// integer imaginary literals. It leaves hexadecimal digits
-// alone.
-func normalizeNumbers(lit *ast.BasicLit) *ast.BasicLit {
+// normalizedNumber rewrites base prefixes and exponents
+// of numbers to use lower-case letters (0X123 to 0x123 and 1.2E3 to 1.2e3),
+// and removes leading 0's from integer imaginary literals (0765i to 765i).
+// It leaves hexadecimal digits alone.
+//
+// normalizedNumber doesn't modify the ast.BasicLit value lit points to.
+// If lit is not a number or a number in canonical format already,
+// lit is returned as is. Otherwise a new ast.BasicLit is created.
+func normalizedNumber(lit *ast.BasicLit) *ast.BasicLit {
        if lit.Kind != token.INT && lit.Kind != token.FLOAT && lit.Kind != token.IMAG {
                return lit // not a number - nothing to do
        }
index 3f34bfcc326db1789535ca3ed5d975516e962786..2e67154e6b4cf5556fbf90f906dee6dec195becc 100644 (file)
@@ -20,7 +20,7 @@ import (
 var testfile *ast.File
 
 func testprint(out io.Writer, file *ast.File) {
-       if err := (&Config{TabIndent | UseSpaces | StdFormat, 8, 0}).Fprint(out, fset, file); err != nil {
+       if err := (&Config{TabIndent | UseSpaces | normalizeNumbers, 8, 0}).Fprint(out, fset, file); err != nil {
                log.Fatalf("print error: %s", err)
        }
 }
index 9d0add40b6b9719c2690b2f627edccb376184918..0077afeaff7c92691485787f9762466bc73bf0df 100644 (file)
@@ -1276,7 +1276,22 @@ const (
        TabIndent                  // use tabs for indentation independent of UseSpaces
        UseSpaces                  // use spaces instead of tabs for alignment
        SourcePos                  // emit //line directives to preserve original source positions
-       StdFormat                  // apply standard formatting changes (exact byte output may change between versions of Go)
+)
+
+// The mode below is not included in printer's public API because
+// editing code text is deemed out of scope. Because this mode is
+// unexported, it's also possible to modify or remove it based on
+// the evolving needs of go/format and cmd/gofmt without breaking
+// users. See discussion in CL 240683.
+const (
+       // normalizeNumbers means to canonicalize number
+       // literal prefixes and exponents while printing.
+       //
+       // This value is known in and used by go/format and cmd/gofmt.
+       // It is currently more convenient and performant for those
+       // packages to apply number normalization during printing,
+       // rather than by modifying the AST in advance.
+       normalizeNumbers Mode = 1 << 30
 )
 
 // A Config node controls the output of Fprint.
index 1e9d47ce7350762e92171ba089952ffeae0a718e..b64bc6bfb7d9ae4112317d3aa45f67ec70a0e641 100644 (file)
@@ -33,7 +33,7 @@ type checkMode uint
 const (
        export checkMode = 1 << iota
        rawFormat
-       stdFormat
+       normNumber
        idempotent
 )
 
@@ -58,8 +58,8 @@ func format(src []byte, mode checkMode) ([]byte, error) {
        if mode&rawFormat != 0 {
                cfg.Mode |= RawFormat
        }
-       if mode&stdFormat != 0 {
-               cfg.Mode |= StdFormat
+       if mode&normNumber != 0 {
+               cfg.Mode |= normalizeNumbers
        }
 
        // print AST
@@ -205,7 +205,7 @@ var data = []entry{
        {"slow.input", "slow.golden", idempotent},
        {"complit.input", "complit.x", export},
        {"go2numbers.input", "go2numbers.golden", idempotent},
-       {"go2numbers.input", "go2numbers.stdfmt", stdFormat | idempotent},
+       {"go2numbers.input", "go2numbers.norm", normNumber | idempotent},
 }
 
 func TestFiles(t *testing.T) {