]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: separate formatting from error handling functions
authorRobert Griesemer <gri@golang.org>
Fri, 23 Feb 2024 22:40:37 +0000 (14:40 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 28 Feb 2024 00:06:10 +0000 (00:06 +0000)
This change moves formatting-specific functionality into a new file
format.go and rearranges the code in the errors.go files to be in
the same order for go/types and types2, making them more similar.

No functionality change. This is a pure code reordering.

Change-Id: Ibd818792397be146ad510a6c7308c85d3bb65956
Reviewed-on: https://go-review.googlesource.com/c/go/+/566555
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
src/cmd/compile/internal/types2/errors.go
src/cmd/compile/internal/types2/format.go [new file with mode: 0644]
src/go/types/errors.go
src/go/types/format.go [new file with mode: 0644]

index f65c1b53771f713fe14cf53aa5bde9e70da187a2..ea4a69b3003a0d220f1d5b98835dbadb22edd07c 100644 (file)
@@ -2,17 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements various error reporters.
+// This file implements error reporting.
 
 package types2
 
 import (
-       "bytes"
        "cmd/compile/internal/syntax"
        "fmt"
        . "internal/types/errors"
        "runtime"
-       "strconv"
        "strings"
 )
 
@@ -52,6 +50,16 @@ func (check *Checker) newError(code Code) *error_ {
        return &error_{check: check, code: code}
 }
 
+// addf adds formatted error information to err.
+// It may be called multiple times to provide additional information.
+// The position of the first call to addf determines the position of the reported Error.
+// Subsequent calls to addf provide additional information in the form of additional lines
+// in the error message (types2) or continuation errors identified by a tab-indented error
+// message (go/types).
+func (err *error_) addf(at poser, format string, args ...interface{}) {
+       err.desc = append(err.desc, errorDesc{atPos(at), err.check.sprintf(format, args...)})
+}
+
 func (err *error_) empty() bool {
        return err.desc == nil
 }
@@ -83,139 +91,6 @@ func (err *error_) msg() string {
        return buf.String()
 }
 
-// addf adds formatted error information to err.
-// It may be called multiple times to provide additional information.
-// The position of the first call to addf determines the position of the reported Error.
-// Subsequent calls to addf provide additional information in the form of additional lines
-// in the error message (types2) or continuation errors identified by a tab-indented error
-// message (go/types).
-func (err *error_) addf(at poser, format string, args ...interface{}) {
-       err.desc = append(err.desc, errorDesc{atPos(at), err.check.sprintf(format, args...)})
-}
-
-func sprintf(qf Qualifier, tpSubscripts bool, format string, args ...any) string {
-       for i, arg := range args {
-               switch a := arg.(type) {
-               case nil:
-                       arg = "<nil>"
-               case operand:
-                       panic("got operand instead of *operand")
-               case *operand:
-                       arg = operandString(a, qf)
-               case syntax.Pos:
-                       arg = a.String()
-               case syntax.Expr:
-                       arg = ExprString(a)
-               case []syntax.Expr:
-                       var buf strings.Builder
-                       buf.WriteByte('[')
-                       for i, x := range a {
-                               if i > 0 {
-                                       buf.WriteString(", ")
-                               }
-                               buf.WriteString(ExprString(x))
-                       }
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               case Object:
-                       arg = ObjectString(a, qf)
-               case Type:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       w.typ(a)
-                       arg = buf.String()
-               case []Type:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       buf.WriteByte('[')
-                       for i, x := range a {
-                               if i > 0 {
-                                       buf.WriteString(", ")
-                               }
-                               w.typ(x)
-                       }
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               case []*TypeParam:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       buf.WriteByte('[')
-                       for i, x := range a {
-                               if i > 0 {
-                                       buf.WriteString(", ")
-                               }
-                               w.typ(x)
-                       }
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               }
-               args[i] = arg
-       }
-       return fmt.Sprintf(format, args...)
-}
-
-func (check *Checker) qualifier(pkg *Package) string {
-       // Qualify the package unless it's the package being type-checked.
-       if pkg != check.pkg {
-               if check.pkgPathMap == nil {
-                       check.pkgPathMap = make(map[string]map[string]bool)
-                       check.seenPkgMap = make(map[*Package]bool)
-                       check.markImports(check.pkg)
-               }
-               // If the same package name was used by multiple packages, display the full path.
-               if len(check.pkgPathMap[pkg.name]) > 1 {
-                       return strconv.Quote(pkg.path)
-               }
-               return pkg.name
-       }
-       return ""
-}
-
-// markImports recursively walks pkg and its imports, to record unique import
-// paths in pkgPathMap.
-func (check *Checker) markImports(pkg *Package) {
-       if check.seenPkgMap[pkg] {
-               return
-       }
-       check.seenPkgMap[pkg] = true
-
-       forName, ok := check.pkgPathMap[pkg.name]
-       if !ok {
-               forName = make(map[string]bool)
-               check.pkgPathMap[pkg.name] = forName
-       }
-       forName[pkg.path] = true
-
-       for _, imp := range pkg.imports {
-               check.markImports(imp)
-       }
-}
-
-// check may be nil.
-func (check *Checker) sprintf(format string, args ...any) string {
-       var qf Qualifier
-       if check != nil {
-               qf = check.qualifier
-       }
-       return sprintf(qf, false, format, args...)
-}
-
-func (check *Checker) trace(pos syntax.Pos, format string, args ...any) {
-       fmt.Printf("%s:\t%s%s\n",
-               pos,
-               strings.Repeat(".  ", check.indent),
-               sprintf(check.qualifier, true, format, args...),
-       )
-}
-
-// dump is only needed for debugging
-func (check *Checker) dump(format string, args ...any) {
-       fmt.Println(sprintf(check.qualifier, true, format, args...))
-}
-
 // report reports the error err, setting check.firstError if necessary.
 func (err *error_) report() {
        if err.empty() {
@@ -323,6 +198,7 @@ const (
        invalidOp  = "invalid operation: "
 )
 
+// The poser interface is used to extract the position of type-checker errors.
 type poser interface {
        Pos() syntax.Pos
 }
@@ -365,18 +241,3 @@ func atPos(at poser) syntax.Pos {
        }
        return at.Pos()
 }
-
-// stripAnnotations removes internal (type) annotations from s.
-func stripAnnotations(s string) string {
-       var buf strings.Builder
-       for _, r := range s {
-               // strip #'s and subscript digits
-               if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-                       buf.WriteRune(r)
-               }
-       }
-       if buf.Len() < len(s) {
-               return buf.String()
-       }
-       return s
-}
diff --git a/src/cmd/compile/internal/types2/format.go b/src/cmd/compile/internal/types2/format.go
new file mode 100644 (file)
index 0000000..442d219
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright 2024 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.
+
+// This file implements (error and trace) message formatting support.
+
+package types2
+
+import (
+       "bytes"
+       "cmd/compile/internal/syntax"
+       "fmt"
+       "strconv"
+       "strings"
+)
+
+func sprintf(qf Qualifier, tpSubscripts bool, format string, args ...any) string {
+       for i, arg := range args {
+               switch a := arg.(type) {
+               case nil:
+                       arg = "<nil>"
+               case operand:
+                       panic("got operand instead of *operand")
+               case *operand:
+                       arg = operandString(a, qf)
+               case syntax.Pos:
+                       arg = a.String()
+               case syntax.Expr:
+                       arg = ExprString(a)
+               case []syntax.Expr:
+                       var buf strings.Builder
+                       buf.WriteByte('[')
+                       for i, x := range a {
+                               if i > 0 {
+                                       buf.WriteString(", ")
+                               }
+                               buf.WriteString(ExprString(x))
+                       }
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               case Object:
+                       arg = ObjectString(a, qf)
+               case Type:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       w.typ(a)
+                       arg = buf.String()
+               case []Type:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       buf.WriteByte('[')
+                       for i, x := range a {
+                               if i > 0 {
+                                       buf.WriteString(", ")
+                               }
+                               w.typ(x)
+                       }
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               case []*TypeParam:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       buf.WriteByte('[')
+                       for i, x := range a {
+                               if i > 0 {
+                                       buf.WriteString(", ")
+                               }
+                               w.typ(x)
+                       }
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               }
+               args[i] = arg
+       }
+       return fmt.Sprintf(format, args...)
+}
+
+// check may be nil.
+func (check *Checker) sprintf(format string, args ...any) string {
+       var qf Qualifier
+       if check != nil {
+               qf = check.qualifier
+       }
+       return sprintf(qf, false, format, args...)
+}
+
+func (check *Checker) trace(pos syntax.Pos, format string, args ...any) {
+       fmt.Printf("%s:\t%s%s\n",
+               pos,
+               strings.Repeat(".  ", check.indent),
+               sprintf(check.qualifier, true, format, args...),
+       )
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...any) {
+       fmt.Println(sprintf(check.qualifier, true, format, args...))
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+       // Qualify the package unless it's the package being type-checked.
+       if pkg != check.pkg {
+               if check.pkgPathMap == nil {
+                       check.pkgPathMap = make(map[string]map[string]bool)
+                       check.seenPkgMap = make(map[*Package]bool)
+                       check.markImports(check.pkg)
+               }
+               // If the same package name was used by multiple packages, display the full path.
+               if len(check.pkgPathMap[pkg.name]) > 1 {
+                       return strconv.Quote(pkg.path)
+               }
+               return pkg.name
+       }
+       return ""
+}
+
+// markImports recursively walks pkg and its imports, to record unique import
+// paths in pkgPathMap.
+func (check *Checker) markImports(pkg *Package) {
+       if check.seenPkgMap[pkg] {
+               return
+       }
+       check.seenPkgMap[pkg] = true
+
+       forName, ok := check.pkgPathMap[pkg.name]
+       if !ok {
+               forName = make(map[string]bool)
+               check.pkgPathMap[pkg.name] = forName
+       }
+       forName[pkg.path] = true
+
+       for _, imp := range pkg.imports {
+               check.markImports(imp)
+       }
+}
+
+// stripAnnotations removes internal (type) annotations from s.
+func stripAnnotations(s string) string {
+       var buf strings.Builder
+       for _, r := range s {
+               // strip #'s and subscript digits
+               if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
+                       buf.WriteRune(r)
+               }
+       }
+       if buf.Len() < len(s) {
+               return buf.String()
+       }
+       return s
+}
index 1abceb5ccf3899e303fe96346ee1822c3a366ea1..878a81cd1a73c62e4afcb7313c650cff9186f43f 100644 (file)
@@ -2,18 +2,16 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements various error reporters.
+// This file implements error reporting.
 
 package types
 
 import (
-       "bytes"
        "fmt"
        "go/ast"
        "go/token"
        . "internal/types/errors"
        "runtime"
-       "strconv"
        "strings"
 )
 
@@ -53,6 +51,16 @@ func (check *Checker) newError(code Code) *error_ {
        return &error_{check: check, code: code}
 }
 
+// addf adds formatted error information to err.
+// It may be called multiple times to provide additional information.
+// The position of the first call to addf determines the position of the reported Error.
+// Subsequent calls to addf provide additional information in the form of additional lines
+// in the error message (types2) or continuation errors identified by a tab-indented error
+// message (go/types).
+func (err *error_) addf(at positioner, format string, args ...interface{}) {
+       err.desc = append(err.desc, errorDesc{at, err.check.sprintf(format, args...)})
+}
+
 func (err *error_) empty() bool {
        return err.desc == nil
 }
@@ -84,138 +92,6 @@ func (err *error_) msg() string {
        return buf.String()
 }
 
-// addf adds formatted error information to err.
-// It may be called multiple times to provide additional information.
-// The position of the first call to addf determines the position of the reported Error.
-// Subsequent calls to addf provide additional information in the form of additional lines
-// in the error message (types2) or continuation errors identified by a tab-indented error
-// message (go/types).
-func (err *error_) addf(at positioner, format string, args ...interface{}) {
-       err.desc = append(err.desc, errorDesc{at, err.check.sprintf(format, args...)})
-}
-
-func (check *Checker) qualifier(pkg *Package) string {
-       // Qualify the package unless it's the package being type-checked.
-       if pkg != check.pkg {
-               if check.pkgPathMap == nil {
-                       check.pkgPathMap = make(map[string]map[string]bool)
-                       check.seenPkgMap = make(map[*Package]bool)
-                       check.markImports(check.pkg)
-               }
-               // If the same package name was used by multiple packages, display the full path.
-               if len(check.pkgPathMap[pkg.name]) > 1 {
-                       return strconv.Quote(pkg.path)
-               }
-               return pkg.name
-       }
-       return ""
-}
-
-// markImports recursively walks pkg and its imports, to record unique import
-// paths in pkgPathMap.
-func (check *Checker) markImports(pkg *Package) {
-       if check.seenPkgMap[pkg] {
-               return
-       }
-       check.seenPkgMap[pkg] = true
-
-       forName, ok := check.pkgPathMap[pkg.name]
-       if !ok {
-               forName = make(map[string]bool)
-               check.pkgPathMap[pkg.name] = forName
-       }
-       forName[pkg.path] = true
-
-       for _, imp := range pkg.imports {
-               check.markImports(imp)
-       }
-}
-
-// check may be nil.
-func (check *Checker) sprintf(format string, args ...any) string {
-       var fset *token.FileSet
-       var qf Qualifier
-       if check != nil {
-               fset = check.fset
-               qf = check.qualifier
-       }
-       return sprintf(fset, qf, false, format, args...)
-}
-
-func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
-       for i, arg := range args {
-               switch a := arg.(type) {
-               case nil:
-                       arg = "<nil>"
-               case operand:
-                       panic("got operand instead of *operand")
-               case *operand:
-                       arg = operandString(a, qf)
-               case token.Pos:
-                       if fset != nil {
-                               arg = fset.Position(a).String()
-                       }
-               case ast.Expr:
-                       arg = ExprString(a)
-               case []ast.Expr:
-                       var buf bytes.Buffer
-                       buf.WriteByte('[')
-                       writeExprList(&buf, a)
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               case Object:
-                       arg = ObjectString(a, qf)
-               case Type:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       w.typ(a)
-                       arg = buf.String()
-               case []Type:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       buf.WriteByte('[')
-                       for i, x := range a {
-                               if i > 0 {
-                                       buf.WriteString(", ")
-                               }
-                               w.typ(x)
-                       }
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               case []*TypeParam:
-                       var buf bytes.Buffer
-                       w := newTypeWriter(&buf, qf)
-                       w.tpSubscripts = tpSubscripts
-                       buf.WriteByte('[')
-                       for i, x := range a {
-                               if i > 0 {
-                                       buf.WriteString(", ")
-                               }
-                               w.typ(x)
-                       }
-                       buf.WriteByte(']')
-                       arg = buf.String()
-               }
-               args[i] = arg
-       }
-       return fmt.Sprintf(format, args...)
-}
-
-func (check *Checker) trace(pos token.Pos, format string, args ...any) {
-       fmt.Printf("%s:\t%s%s\n",
-               check.fset.Position(pos),
-               strings.Repeat(".  ", check.indent),
-               sprintf(check.fset, check.qualifier, true, format, args...),
-       )
-}
-
-// dump is only needed for debugging
-func (check *Checker) dump(format string, args ...any) {
-       fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...))
-}
-
 // report reports the error err, setting check.firstError if necessary.
 func (err *error_) report() {
        if err.empty() {
@@ -337,8 +213,7 @@ const (
        invalidOp  = "invalid operation: "
 )
 
-// The positioner interface is used to extract the position of type-checker
-// errors.
+// The positioner interface is used to extract the position of type-checker errors.
 type positioner interface {
        Pos() token.Pos
 }
@@ -369,6 +244,13 @@ func (check *Checker) versionErrorf(at positioner, v goVersion, format string, a
        err.report()
 }
 
+// atPos wraps a token.Pos to implement the positioner interface.
+type atPos token.Pos
+
+func (s atPos) Pos() token.Pos {
+       return token.Pos(s)
+}
+
 // posSpan holds a position range along with a highlighted position within that
 // range. This is used for positioning errors, with pos by convention being the
 // first position in the source where the error is known to exist, and start
@@ -393,13 +275,6 @@ func inNode(node ast.Node, pos token.Pos) posSpan {
        return posSpan{start, pos, end}
 }
 
-// atPos wraps a token.Pos to implement the positioner interface.
-type atPos token.Pos
-
-func (s atPos) Pos() token.Pos {
-       return token.Pos(s)
-}
-
 // spanOf extracts an error span from the given positioner. By default this is
 // the trivial span starting and ending at pos, but this span is expanded when
 // the argument naturally corresponds to a span of source code.
@@ -423,18 +298,3 @@ func spanOf(at positioner) posSpan {
                return posSpan{pos, pos, pos}
        }
 }
-
-// stripAnnotations removes internal (type) annotations from s.
-func stripAnnotations(s string) string {
-       var buf strings.Builder
-       for _, r := range s {
-               // strip #'s and subscript digits
-               if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-                       buf.WriteRune(r)
-               }
-       }
-       if buf.Len() < len(s) {
-               return buf.String()
-       }
-       return s
-}
diff --git a/src/go/types/format.go b/src/go/types/format.go
new file mode 100644 (file)
index 0000000..09e599c
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright 2024 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.
+
+// This file implements (error and trace) message formatting support.
+
+package types
+
+import (
+       "bytes"
+       "fmt"
+       "go/ast"
+       "go/token"
+       "strconv"
+       "strings"
+)
+
+func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
+       for i, arg := range args {
+               switch a := arg.(type) {
+               case nil:
+                       arg = "<nil>"
+               case operand:
+                       panic("got operand instead of *operand")
+               case *operand:
+                       arg = operandString(a, qf)
+               case token.Pos:
+                       if fset != nil {
+                               arg = fset.Position(a).String()
+                       }
+               case ast.Expr:
+                       arg = ExprString(a)
+               case []ast.Expr:
+                       var buf bytes.Buffer
+                       buf.WriteByte('[')
+                       writeExprList(&buf, a)
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               case Object:
+                       arg = ObjectString(a, qf)
+               case Type:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       w.typ(a)
+                       arg = buf.String()
+               case []Type:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       buf.WriteByte('[')
+                       for i, x := range a {
+                               if i > 0 {
+                                       buf.WriteString(", ")
+                               }
+                               w.typ(x)
+                       }
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               case []*TypeParam:
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       buf.WriteByte('[')
+                       for i, x := range a {
+                               if i > 0 {
+                                       buf.WriteString(", ")
+                               }
+                               w.typ(x)
+                       }
+                       buf.WriteByte(']')
+                       arg = buf.String()
+               }
+               args[i] = arg
+       }
+       return fmt.Sprintf(format, args...)
+}
+
+// check may be nil.
+func (check *Checker) sprintf(format string, args ...any) string {
+       var fset *token.FileSet
+       var qf Qualifier
+       if check != nil {
+               fset = check.fset
+               qf = check.qualifier
+       }
+       return sprintf(fset, qf, false, format, args...)
+}
+
+func (check *Checker) trace(pos token.Pos, format string, args ...any) {
+       fmt.Printf("%s:\t%s%s\n",
+               check.fset.Position(pos),
+               strings.Repeat(".  ", check.indent),
+               sprintf(check.fset, check.qualifier, true, format, args...),
+       )
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...any) {
+       fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...))
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+       // Qualify the package unless it's the package being type-checked.
+       if pkg != check.pkg {
+               if check.pkgPathMap == nil {
+                       check.pkgPathMap = make(map[string]map[string]bool)
+                       check.seenPkgMap = make(map[*Package]bool)
+                       check.markImports(check.pkg)
+               }
+               // If the same package name was used by multiple packages, display the full path.
+               if len(check.pkgPathMap[pkg.name]) > 1 {
+                       return strconv.Quote(pkg.path)
+               }
+               return pkg.name
+       }
+       return ""
+}
+
+// markImports recursively walks pkg and its imports, to record unique import
+// paths in pkgPathMap.
+func (check *Checker) markImports(pkg *Package) {
+       if check.seenPkgMap[pkg] {
+               return
+       }
+       check.seenPkgMap[pkg] = true
+
+       forName, ok := check.pkgPathMap[pkg.name]
+       if !ok {
+               forName = make(map[string]bool)
+               check.pkgPathMap[pkg.name] = forName
+       }
+       forName[pkg.path] = true
+
+       for _, imp := range pkg.imports {
+               check.markImports(imp)
+       }
+}
+
+// stripAnnotations removes internal (type) annotations from s.
+func stripAnnotations(s string) string {
+       var buf strings.Builder
+       for _, r := range s {
+               // strip #'s and subscript digits
+               if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
+                       buf.WriteRune(r)
+               }
+       }
+       if buf.Len() < len(s) {
+               return buf.String()
+       }
+       return s
+}