mirror of https://github.com/golang/go.git
go/types: : generate operand.go from types2 source
This CL reduces the amount of code that needs to be maintained manually by about 400 LOC. Change-Id: I03f77c8067aebfdb2a1cce6827ded733ff55e1cc Reviewed-on: https://go-review.googlesource.com/c/go/+/565837 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
55bb3d1c10
commit
f278f756bd
|
|
@ -11,7 +11,6 @@ import (
|
|||
"cmd/compile/internal/syntax"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
. "internal/types/errors"
|
||||
)
|
||||
|
||||
|
|
@ -109,14 +108,20 @@ func (x *operand) Pos() syntax.Pos {
|
|||
// cgofunc <expr> ( <mode> of type <typ>)
|
||||
func operandString(x *operand, qf Qualifier) string {
|
||||
// special-case nil
|
||||
if x.mode == nilvalue {
|
||||
switch x.typ {
|
||||
case nil, Typ[Invalid]:
|
||||
return "nil (with invalid type)"
|
||||
case Typ[UntypedNil]:
|
||||
if isTypes2 {
|
||||
if x.mode == nilvalue {
|
||||
switch x.typ {
|
||||
case nil, Typ[Invalid]:
|
||||
return "nil (with invalid type)"
|
||||
case Typ[UntypedNil]:
|
||||
return "nil"
|
||||
default:
|
||||
return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
|
||||
}
|
||||
}
|
||||
} else { // go/types
|
||||
if x.mode == value && x.typ == Typ[UntypedNil] {
|
||||
return "nil"
|
||||
default:
|
||||
return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +229,7 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
|
|||
unreachable()
|
||||
}
|
||||
|
||||
val := constant.MakeFromLiteral(lit, kind2tok[k], 0)
|
||||
val := makeFromLiteral(lit, k)
|
||||
if val.Kind() == constant.Unknown {
|
||||
x.mode = invalid
|
||||
x.typ = Typ[Invalid]
|
||||
|
|
@ -236,7 +241,13 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
|
|||
}
|
||||
|
||||
// isNil reports whether x is the (untyped) nil value.
|
||||
func (x *operand) isNil() bool { return x.mode == nilvalue }
|
||||
func (x *operand) isNil() bool {
|
||||
if isTypes2 {
|
||||
return x.mode == nilvalue
|
||||
} else { // go/types
|
||||
return x.mode == value && x.typ == Typ[UntypedNil]
|
||||
}
|
||||
}
|
||||
|
||||
// assignableTo reports whether x is assignable to a variable of type T. If the
|
||||
// result is false and a non-nil cause is provided, it may be set to a more
|
||||
|
|
@ -332,7 +343,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
|
|||
return false, IncompatibleAssign
|
||||
}
|
||||
|
||||
errorf := func(format string, args ...interface{}) {
|
||||
errorf := func(format string, args ...any) {
|
||||
if check != nil && cause != nil {
|
||||
msg := check.sprintf(format, args...)
|
||||
if *cause != "" {
|
||||
|
|
@ -385,12 +396,3 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
|
|||
|
||||
return false, IncompatibleAssign
|
||||
}
|
||||
|
||||
// kind2tok translates syntax.LitKinds into token.Tokens.
|
||||
var kind2tok = [...]token.Token{
|
||||
syntax.IntLit: token.INT,
|
||||
syntax.FloatLit: token.FLOAT,
|
||||
syntax.ImagLit: token.IMAG,
|
||||
syntax.RuneLit: token.CHAR,
|
||||
syntax.StringLit: token.STRING,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@
|
|||
|
||||
package types2
|
||||
|
||||
import "cmd/compile/internal/syntax"
|
||||
import (
|
||||
"cmd/compile/internal/syntax"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
)
|
||||
|
||||
const isTypes2 = true
|
||||
|
||||
|
|
@ -40,3 +44,16 @@ func ExprString(x syntax.Node) string { return syntax.String(x) }
|
|||
|
||||
// endPos returns the position of the first character immediately after node n.
|
||||
func endPos(n syntax.Node) syntax.Pos { return syntax.EndPos(n) }
|
||||
|
||||
// makeFromLiteral returns the constant value for the given literal string and kind.
|
||||
func makeFromLiteral(lit string, kind syntax.LitKind) constant.Value {
|
||||
return constant.MakeFromLiteral(lit, kind2tok[kind], 0)
|
||||
}
|
||||
|
||||
var kind2tok = [...]token.Token{
|
||||
syntax.IntLit: token.INT,
|
||||
syntax.FloatLit: token.FLOAT,
|
||||
syntax.ImagLit: token.IMAG,
|
||||
syntax.RuneLit: token.CHAR,
|
||||
syntax.StringLit: token.STRING,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,27 +136,37 @@ var filemap = map[string]action{
|
|||
"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,
|
||||
"pointer.go": nil,
|
||||
"predicates.go": nil,
|
||||
"scope.go": func(f *ast.File) { fixTokenPos(f); renameIdents(f, "Squash->squash", "InsertLazy->_InsertLazy") },
|
||||
"selection.go": nil,
|
||||
"sizes.go": func(f *ast.File) { renameIdents(f, "IsSyncAtomicAlign64->_IsSyncAtomicAlign64") },
|
||||
"slice.go": nil,
|
||||
"subst.go": func(f *ast.File) { fixTokenPos(f); renameSelectors(f, "Trace->_Trace") },
|
||||
"termlist.go": nil,
|
||||
"termlist_test.go": nil,
|
||||
"tuple.go": nil,
|
||||
"typelists.go": nil,
|
||||
"typeparam.go": nil,
|
||||
"typeterm_test.go": nil,
|
||||
"typeterm.go": nil,
|
||||
"typestring.go": nil,
|
||||
"under.go": nil,
|
||||
"unify.go": fixSprintf,
|
||||
"universe.go": fixGlobalTypVarDecl,
|
||||
"util_test.go": fixTokenPos,
|
||||
"validtype.go": nil,
|
||||
"operand.go": func(f *ast.File) {
|
||||
insertImportPath(f, `"go/token"`)
|
||||
renameImportPath(f, `"cmd/compile/internal/syntax"->"go/ast"`)
|
||||
renameSelectorExprs(f,
|
||||
"syntax.Pos->token.Pos", "syntax.LitKind->token.Token",
|
||||
"syntax.IntLit->token.INT", "syntax.FloatLit->token.FLOAT",
|
||||
"syntax.ImagLit->token.IMAG", "syntax.RuneLit->token.CHAR",
|
||||
"syntax.StringLit->token.STRING") // must happen before renaming identifiers
|
||||
renameIdents(f, "syntax->ast")
|
||||
},
|
||||
"package.go": nil,
|
||||
"pointer.go": nil,
|
||||
"predicates.go": nil,
|
||||
"scope.go": func(f *ast.File) { fixTokenPos(f); renameIdents(f, "Squash->squash", "InsertLazy->_InsertLazy") },
|
||||
"selection.go": nil,
|
||||
"sizes.go": func(f *ast.File) { renameIdents(f, "IsSyncAtomicAlign64->_IsSyncAtomicAlign64") },
|
||||
"slice.go": nil,
|
||||
"subst.go": func(f *ast.File) { fixTokenPos(f); renameSelectors(f, "Trace->_Trace") },
|
||||
"termlist.go": nil,
|
||||
"termlist_test.go": nil,
|
||||
"tuple.go": nil,
|
||||
"typelists.go": nil,
|
||||
"typeparam.go": nil,
|
||||
"typeterm_test.go": nil,
|
||||
"typeterm.go": nil,
|
||||
"typestring.go": nil,
|
||||
"under.go": nil,
|
||||
"unify.go": fixSprintf,
|
||||
"universe.go": fixGlobalTypVarDecl,
|
||||
"util_test.go": fixTokenPos,
|
||||
"validtype.go": nil,
|
||||
}
|
||||
|
||||
// TODO(gri) We should be able to make these rewriters more configurable/composable.
|
||||
|
|
@ -259,6 +269,18 @@ func renameImportPath(f *ast.File, renames ...string) {
|
|||
})
|
||||
}
|
||||
|
||||
// insertImportPath inserts the given import path.
|
||||
// There must be at least one import declaration present already.
|
||||
func insertImportPath(f *ast.File, path string) {
|
||||
for _, d := range f.Decls {
|
||||
if g, _ := d.(*ast.GenDecl); g != nil && g.Tok == token.IMPORT {
|
||||
g.Specs = append(g.Specs, &ast.ImportSpec{Path: &ast.BasicLit{ValuePos: g.End(), Kind: token.STRING, Value: path}})
|
||||
return
|
||||
}
|
||||
}
|
||||
panic("no import declaration present")
|
||||
}
|
||||
|
||||
// fixTokenPos changes imports of "cmd/compile/internal/syntax" to "go/token",
|
||||
// uses of syntax.Pos to token.Pos, and calls to x.IsKnown() to x.IsValid().
|
||||
func fixTokenPos(f *ast.File) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
|
||||
|
||||
// Copyright 2012 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.
|
||||
|
|
@ -8,6 +10,7 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
|
|
@ -95,6 +98,9 @@ func (x *operand) Pos() token.Pos {
|
|||
// value <expr> (<untyped kind> <mode> )
|
||||
// value <expr> ( <mode> of type <typ>)
|
||||
//
|
||||
// nilvalue untyped nil
|
||||
// nilvalue nil ( of type <typ>)
|
||||
//
|
||||
// commaok <expr> (<untyped kind> <mode> )
|
||||
// commaok <expr> ( <mode> of type <typ>)
|
||||
//
|
||||
|
|
@ -105,8 +111,21 @@ func (x *operand) Pos() token.Pos {
|
|||
// cgofunc <expr> ( <mode> of type <typ>)
|
||||
func operandString(x *operand, qf Qualifier) string {
|
||||
// special-case nil
|
||||
if x.mode == value && x.typ == Typ[UntypedNil] {
|
||||
return "nil"
|
||||
if isTypes2 {
|
||||
if x.mode == nilvalue {
|
||||
switch x.typ {
|
||||
case nil, Typ[Invalid]:
|
||||
return "nil (with invalid type)"
|
||||
case Typ[UntypedNil]:
|
||||
return "nil"
|
||||
default:
|
||||
return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
|
||||
}
|
||||
}
|
||||
} else { // go/types
|
||||
if x.mode == value && x.typ == Typ[UntypedNil] {
|
||||
return "nil"
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
|
@ -196,9 +215,9 @@ func (x *operand) String() string {
|
|||
}
|
||||
|
||||
// setConst sets x to the untyped constant for literal lit.
|
||||
func (x *operand) setConst(tok token.Token, lit string) {
|
||||
func (x *operand) setConst(k token.Token, lit string) {
|
||||
var kind BasicKind
|
||||
switch tok {
|
||||
switch k {
|
||||
case token.INT:
|
||||
kind = UntypedInt
|
||||
case token.FLOAT:
|
||||
|
|
@ -213,7 +232,7 @@ func (x *operand) setConst(tok token.Token, lit string) {
|
|||
unreachable()
|
||||
}
|
||||
|
||||
val := constant.MakeFromLiteral(lit, tok, 0)
|
||||
val := makeFromLiteral(lit, k)
|
||||
if val.Kind() == constant.Unknown {
|
||||
x.mode = invalid
|
||||
x.typ = Typ[Invalid]
|
||||
|
|
@ -225,7 +244,13 @@ func (x *operand) setConst(tok token.Token, lit string) {
|
|||
}
|
||||
|
||||
// isNil reports whether x is the (untyped) nil value.
|
||||
func (x *operand) isNil() bool { return x.mode == value && x.typ == Typ[UntypedNil] }
|
||||
func (x *operand) isNil() bool {
|
||||
if isTypes2 {
|
||||
return x.mode == nilvalue
|
||||
} else { // go/types
|
||||
return x.mode == value && x.typ == Typ[UntypedNil]
|
||||
}
|
||||
}
|
||||
|
||||
// assignableTo reports whether x is assignable to a variable of type T. If the
|
||||
// result is false and a non-nil cause is provided, it may be set to a more
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package types
|
|||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
)
|
||||
|
||||
|
|
@ -37,3 +38,8 @@ func argErrPos(call *ast.CallExpr) positioner { return inNode(call, call.Rparen)
|
|||
|
||||
// endPos returns the position of the first character immediately after node n.
|
||||
func endPos(n ast.Node) token.Pos { return n.End() }
|
||||
|
||||
// makeFromLiteral returns the constant value for the given literal string and kind.
|
||||
func makeFromLiteral(lit string, kind token.Token) constant.Value {
|
||||
return constant.MakeFromLiteral(lit, kind, 0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue