]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: move exported predicates into separate file
authorRobert Griesemer <gri@golang.org>
Tue, 14 Nov 2023 00:46:47 +0000 (16:46 -0800)
committerGopher Robot <gobot@golang.org>
Thu, 16 Nov 2023 20:54:25 +0000 (20:54 +0000)
This allows those functions to be generated for go/types.
Also, change the generator's renameIdent mechanism so that
it can rename multiple identifiers in one pass through the
AST instead of requiring multiple passes.

No type-checker functionality changes.

Change-Id: Ic78d899c6004b6a0692a95902fdc13f8ffb47824
Reviewed-on: https://go-review.googlesource.com/c/go/+/542757
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/api.go
src/cmd/compile/internal/types2/api_predicates.go [new file with mode: 0644]
src/go/types/api.go
src/go/types/api_predicates.go [new file with mode: 0644]
src/go/types/generate_test.go

index ca42c394336e94df7a61044a7af1e0da927d179c..66281744280680a346d15ef6e9f90337b5c95840 100644 (file)
@@ -460,80 +460,3 @@ func (conf *Config) Check(path string, files []*syntax.File, info *Info) (*Packa
        pkg := NewPackage(path, "")
        return pkg, NewChecker(conf, pkg, info).Files(files)
 }
-
-// AssertableTo reports whether a value of type V can be asserted to have type T.
-//
-// The behavior of AssertableTo is unspecified in three cases:
-//   - if T is Typ[Invalid]
-//   - if V is a generalized interface; i.e., an interface that may only be used
-//     as a type constraint in Go code
-//   - if T is an uninstantiated generic type
-func AssertableTo(V *Interface, T Type) bool {
-       // Checker.newAssertableTo suppresses errors for invalid types, so we need special
-       // handling here.
-       if !isValid(T.Underlying()) {
-               return false
-       }
-       return (*Checker)(nil).newAssertableTo(nopos, V, T, nil)
-}
-
-// AssignableTo reports whether a value of type V is assignable to a variable
-// of type T.
-//
-// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func AssignableTo(V, T Type) bool {
-       x := operand{mode: value, typ: V}
-       ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
-       return ok
-}
-
-// ConvertibleTo reports whether a value of type V is convertible to a value of
-// type T.
-//
-// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func ConvertibleTo(V, T Type) bool {
-       x := operand{mode: value, typ: V}
-       return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
-}
-
-// Implements reports whether type V implements interface T.
-//
-// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Implements(V Type, T *Interface) bool {
-       if T.Empty() {
-               // All types (even Typ[Invalid]) implement the empty interface.
-               return true
-       }
-       // Checker.implements suppresses errors for invalid types, so we need special
-       // handling here.
-       if !isValid(V.Underlying()) {
-               return false
-       }
-       return (*Checker)(nil).implements(nopos, V, T, false, nil)
-}
-
-// Satisfies reports whether type V satisfies the constraint T.
-//
-// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Satisfies(V Type, T *Interface) bool {
-       return (*Checker)(nil).implements(nopos, V, T, true, nil)
-}
-
-// Identical reports whether x and y are identical types.
-// Receivers of Signature types are ignored.
-func Identical(x, y Type) bool {
-       var c comparer
-       return c.identical(x, y, nil)
-}
-
-// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
-// Receivers of Signature types are ignored.
-func IdenticalIgnoreTags(x, y Type) bool {
-       var c comparer
-       c.ignoreTags = true
-       return c.identical(x, y, nil)
-}
diff --git a/src/cmd/compile/internal/types2/api_predicates.go b/src/cmd/compile/internal/types2/api_predicates.go
new file mode 100644 (file)
index 0000000..480f711
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright 2023 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 exported type predicates.
+
+package types2
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+//
+// The behavior of AssertableTo is unspecified in three cases:
+//   - if T is Typ[Invalid]
+//   - if V is a generalized interface; i.e., an interface that may only be used
+//     as a type constraint in Go code
+//   - if T is an uninstantiated generic type
+func AssertableTo(V *Interface, T Type) bool {
+       // Checker.newAssertableTo suppresses errors for invalid types, so we need special
+       // handling here.
+       if !isValid(T.Underlying()) {
+               return false
+       }
+       return (*Checker)(nil).newAssertableTo(nopos, V, T, nil)
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable
+// of type T.
+//
+// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func AssignableTo(V, T Type) bool {
+       x := operand{mode: value, typ: V}
+       ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
+       return ok
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of
+// type T.
+//
+// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func ConvertibleTo(V, T Type) bool {
+       x := operand{mode: value, typ: V}
+       return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+//
+// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Implements(V Type, T *Interface) bool {
+       if T.Empty() {
+               // All types (even Typ[Invalid]) implement the empty interface.
+               return true
+       }
+       // Checker.implements suppresses errors for invalid types, so we need special
+       // handling here.
+       if !isValid(V.Underlying()) {
+               return false
+       }
+       return (*Checker)(nil).implements(nopos, V, T, false, nil)
+}
+
+// Satisfies reports whether type V satisfies the constraint T.
+//
+// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Satisfies(V Type, T *Interface) bool {
+       return (*Checker)(nil).implements(nopos, V, T, true, nil)
+}
+
+// Identical reports whether x and y are identical types.
+// Receivers of [Signature] types are ignored.
+func Identical(x, y Type) bool {
+       var c comparer
+       return c.identical(x, y, nil)
+}
+
+// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
+// Receivers of [Signature] types are ignored.
+func IdenticalIgnoreTags(x, y Type) bool {
+       var c comparer
+       c.ignoreTags = true
+       return c.identical(x, y, nil)
+}
index 6635253fdfdd37f07a5f97293be36bad2b282bd8..f729e33dece79f71c9676839d6cc75a4a7be6ee4 100644 (file)
@@ -448,80 +448,3 @@ func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, i
        pkg := NewPackage(path, "")
        return pkg, NewChecker(conf, fset, pkg, info).Files(files)
 }
-
-// AssertableTo reports whether a value of type V can be asserted to have type T.
-//
-// The behavior of AssertableTo is unspecified in three cases:
-//   - if T is Typ[Invalid]
-//   - if V is a generalized interface; i.e., an interface that may only be used
-//     as a type constraint in Go code
-//   - if T is an uninstantiated generic type
-func AssertableTo(V *Interface, T Type) bool {
-       // Checker.newAssertableTo suppresses errors for invalid types, so we need special
-       // handling here.
-       if !isValid(T.Underlying()) {
-               return false
-       }
-       return (*Checker)(nil).newAssertableTo(nopos, V, T, nil)
-}
-
-// AssignableTo reports whether a value of type V is assignable to a variable
-// of type T.
-//
-// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func AssignableTo(V, T Type) bool {
-       x := operand{mode: value, typ: V}
-       ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
-       return ok
-}
-
-// ConvertibleTo reports whether a value of type V is convertible to a value of
-// type T.
-//
-// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func ConvertibleTo(V, T Type) bool {
-       x := operand{mode: value, typ: V}
-       return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
-}
-
-// Implements reports whether type V implements interface T.
-//
-// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Implements(V Type, T *Interface) bool {
-       if T.Empty() {
-               // All types (even Typ[Invalid]) implement the empty interface.
-               return true
-       }
-       // Checker.implements suppresses errors for invalid types, so we need special
-       // handling here.
-       if !isValid(V.Underlying()) {
-               return false
-       }
-       return (*Checker)(nil).implements(0, V, T, false, nil)
-}
-
-// Satisfies reports whether type V satisfies the constraint T.
-//
-// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Satisfies(V Type, T *Interface) bool {
-       return (*Checker)(nil).implements(0, V, T, true, nil)
-}
-
-// Identical reports whether x and y are identical types.
-// Receivers of [Signature] types are ignored.
-func Identical(x, y Type) bool {
-       var c comparer
-       return c.identical(x, y, nil)
-}
-
-// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
-// Receivers of [Signature] types are ignored.
-func IdenticalIgnoreTags(x, y Type) bool {
-       var c comparer
-       c.ignoreTags = true
-       return c.identical(x, y, nil)
-}
diff --git a/src/go/types/api_predicates.go b/src/go/types/api_predicates.go
new file mode 100644 (file)
index 0000000..d712afe
--- /dev/null
@@ -0,0 +1,86 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2023 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 exported type predicates.
+
+package types
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+//
+// The behavior of AssertableTo is unspecified in three cases:
+//   - if T is Typ[Invalid]
+//   - if V is a generalized interface; i.e., an interface that may only be used
+//     as a type constraint in Go code
+//   - if T is an uninstantiated generic type
+func AssertableTo(V *Interface, T Type) bool {
+       // Checker.newAssertableTo suppresses errors for invalid types, so we need special
+       // handling here.
+       if !isValid(T.Underlying()) {
+               return false
+       }
+       return (*Checker)(nil).newAssertableTo(nopos, V, T, nil)
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable
+// of type T.
+//
+// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func AssignableTo(V, T Type) bool {
+       x := operand{mode: value, typ: V}
+       ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
+       return ok
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of
+// type T.
+//
+// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func ConvertibleTo(V, T Type) bool {
+       x := operand{mode: value, typ: V}
+       return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+//
+// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Implements(V Type, T *Interface) bool {
+       if T.Empty() {
+               // All types (even Typ[Invalid]) implement the empty interface.
+               return true
+       }
+       // Checker.implements suppresses errors for invalid types, so we need special
+       // handling here.
+       if !isValid(V.Underlying()) {
+               return false
+       }
+       return (*Checker)(nil).implements(nopos, V, T, false, nil)
+}
+
+// Satisfies reports whether type V satisfies the constraint T.
+//
+// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Satisfies(V Type, T *Interface) bool {
+       return (*Checker)(nil).implements(nopos, V, T, true, nil)
+}
+
+// Identical reports whether x and y are identical types.
+// Receivers of [Signature] types are ignored.
+func Identical(x, y Type) bool {
+       var c comparer
+       return c.identical(x, y, nil)
+}
+
+// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
+// Receivers of [Signature] types are ignored.
+func IdenticalIgnoreTags(x, y Type) bool {
+       var c comparer
+       c.ignoreTags = true
+       return c.identical(x, y, nil)
+}
index e74a1e6f2566462a08d6114379aa894404a93869..59c0a97965c98428ac2d674f816e3c1e3f01444d 100644 (file)
@@ -95,16 +95,17 @@ func generate(t *testing.T, filename string, write bool) {
 type action func(in *ast.File)
 
 var filemap = map[string]action{
-       "alias.go":        nil,
-       "array.go":        nil,
-       "basic.go":        nil,
-       "chan.go":         nil,
-       "const.go":        func(f *ast.File) { fixTokenPos(f) },
-       "context.go":      nil,
-       "context_test.go": nil,
-       "gccgosizes.go":   nil,
-       "gcsizes.go":      func(f *ast.File) { renameIdent(f, "IsSyncAtomicAlign64", "_IsSyncAtomicAlign64") },
-       "hilbert_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) },
+       "alias.go":          nil,
+       "array.go":          nil,
+       "api_predicates.go": nil,
+       "basic.go":          nil,
+       "chan.go":           nil,
+       "const.go":          func(f *ast.File) { fixTokenPos(f) },
+       "context.go":        nil,
+       "context_test.go":   nil,
+       "gccgosizes.go":     nil,
+       "gcsizes.go":        func(f *ast.File) { renameIdents(f, "IsSyncAtomicAlign64->_IsSyncAtomicAlign64") },
+       "hilbert_test.go":   func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) },
        "infer.go": func(f *ast.File) {
                fixTokenPos(f)
                fixInferSig(f)
@@ -116,7 +117,7 @@ var filemap = map[string]action{
        "main_test.go":        nil,
        "map.go":              nil,
        "named.go":            func(f *ast.File) { fixTokenPos(f); fixTraceSel(f) },
-       "object.go":           func(f *ast.File) { fixTokenPos(f); renameIdent(f, "NewTypeNameLazy", "_NewTypeNameLazy") },
+       "object.go":           func(f *ast.File) { fixTokenPos(f); renameIdents(f, "NewTypeNameLazy->_NewTypeNameLazy") },
        "object_test.go":      func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) },
        "objset.go":           nil,
        "package.go":          nil,
@@ -124,11 +125,10 @@ var filemap = map[string]action{
        "predicates.go":       nil,
        "scope.go": func(f *ast.File) {
                fixTokenPos(f)
-               renameIdent(f, "Squash", "squash")
-               renameIdent(f, "InsertLazy", "_InsertLazy")
+               renameIdents(f, "Squash->squash", "InsertLazy->_InsertLazy")
        },
        "selection.go":     nil,
-       "sizes.go":         func(f *ast.File) { renameIdent(f, "IsSyncAtomicAlign64", "_IsSyncAtomicAlign64") },
+       "sizes.go":         func(f *ast.File) { renameIdents(f, "IsSyncAtomicAlign64->_IsSyncAtomicAlign64") },
        "slice.go":         nil,
        "subst.go":         func(f *ast.File) { fixTokenPos(f); fixTraceSel(f) },
        "termlist.go":      nil,
@@ -148,14 +148,24 @@ var filemap = map[string]action{
 // TODO(gri) We should be able to make these rewriters more configurable/composable.
 //           For now this is a good starting point.
 
-// renameIdent renames an identifier.
-// Note: This doesn't change the use of the identifier in comments.
-func renameIdent(f *ast.File, from, to string) {
+// renameIdent renames identifiers: each renames entry is of the form from->to.
+// Note: This doesn't change the use of the identifiers in comments.
+func renameIdents(f *ast.File, renames ...string) {
+       var list [][]string
+       for _, r := range renames {
+               s := strings.Split(r, "->")
+               if len(s) != 2 {
+                       panic("invalid rename entry: " + r)
+               }
+               list = append(list, s)
+       }
        ast.Inspect(f, func(n ast.Node) bool {
                switch n := n.(type) {
                case *ast.Ident:
-                       if n.Name == from {
-                               n.Name = to
+                       for _, r := range list {
+                               if n.Name == r[0] {
+                                       n.Name = r[1]
+                               }
                        }
                        return false
                }