mirror of https://github.com/golang/go.git
go/types, types2: factor out typechecker-specific code from recording.go
With this CL, the go/types and types2 recording.go files are mostly identical except for the use of different syntax trees. Preparation for generating go/types/recording.go from types2 sources. Change-Id: Iea85f8554ee04f1e1f7da63f8019725ac8f6caf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/602117 Reviewed-by: Tim King <taking@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
c5de950766
commit
1b6bb779ef
|
|
@ -514,3 +514,80 @@ func (check *Checker) cleanup() {
|
|||
}
|
||||
check.cleaners = nil
|
||||
}
|
||||
|
||||
// types2-specific support for recording type information in the syntax tree.
|
||||
func (check *Checker) recordTypeAndValueInSyntax(x syntax.Expr, mode operandMode, typ Type, val constant.Value) {
|
||||
if check.StoreTypesInSyntax {
|
||||
tv := TypeAndValue{mode, typ, val}
|
||||
stv := syntax.TypeAndValue{Type: typ, Value: val}
|
||||
if tv.IsVoid() {
|
||||
stv.SetIsVoid()
|
||||
}
|
||||
if tv.IsType() {
|
||||
stv.SetIsType()
|
||||
}
|
||||
if tv.IsBuiltin() {
|
||||
stv.SetIsBuiltin()
|
||||
}
|
||||
if tv.IsValue() {
|
||||
stv.SetIsValue()
|
||||
}
|
||||
if tv.IsNil() {
|
||||
stv.SetIsNil()
|
||||
}
|
||||
if tv.Addressable() {
|
||||
stv.SetAddressable()
|
||||
}
|
||||
if tv.Assignable() {
|
||||
stv.SetAssignable()
|
||||
}
|
||||
if tv.HasOk() {
|
||||
stv.SetHasOk()
|
||||
}
|
||||
x.SetTypeInfo(stv)
|
||||
}
|
||||
}
|
||||
|
||||
// types2-specific support for recording type information in the syntax tree.
|
||||
func (check *Checker) recordCommaOkTypesInSyntax(x syntax.Expr, t0, t1 Type) {
|
||||
if check.StoreTypesInSyntax {
|
||||
// Note: this loop is duplicated because the type of tv is different.
|
||||
// Above it is types2.TypeAndValue, here it is syntax.TypeAndValue.
|
||||
for {
|
||||
tv := x.GetTypeInfo()
|
||||
assert(tv.Type != nil) // should have been recorded already
|
||||
pos := x.Pos()
|
||||
tv.Type = NewTuple(
|
||||
NewVar(pos, check.pkg, "", t0),
|
||||
NewVar(pos, check.pkg, "", t1),
|
||||
)
|
||||
x.SetTypeInfo(tv)
|
||||
p, _ := x.(*syntax.ParenExpr)
|
||||
if p == nil {
|
||||
break
|
||||
}
|
||||
x = p.X
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// instantiatedIdent determines the identifier of the type instantiated in expr.
|
||||
// Helper function for recordInstance in recording.go.
|
||||
func instantiatedIdent(expr syntax.Expr) *syntax.Name {
|
||||
var selOrIdent syntax.Expr
|
||||
switch e := expr.(type) {
|
||||
case *syntax.IndexExpr:
|
||||
selOrIdent = e.X
|
||||
case *syntax.SelectorExpr, *syntax.Name:
|
||||
selOrIdent = e
|
||||
}
|
||||
switch x := selOrIdent.(type) {
|
||||
case *syntax.Name:
|
||||
return x
|
||||
case *syntax.SelectorExpr:
|
||||
return x.Sel
|
||||
}
|
||||
|
||||
// extra debugging of go.dev/issue/63933
|
||||
panic(sprintf(nil, true, "instantiated ident not found; please report: %s", expr))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,35 +68,7 @@ func (check *Checker) recordTypeAndValue(x syntax.Expr, mode operandMode, typ Ty
|
|||
if m := check.Types; m != nil {
|
||||
m[x] = TypeAndValue{mode, typ, val}
|
||||
}
|
||||
if check.StoreTypesInSyntax {
|
||||
tv := TypeAndValue{mode, typ, val}
|
||||
stv := syntax.TypeAndValue{Type: typ, Value: val}
|
||||
if tv.IsVoid() {
|
||||
stv.SetIsVoid()
|
||||
}
|
||||
if tv.IsType() {
|
||||
stv.SetIsType()
|
||||
}
|
||||
if tv.IsBuiltin() {
|
||||
stv.SetIsBuiltin()
|
||||
}
|
||||
if tv.IsValue() {
|
||||
stv.SetIsValue()
|
||||
}
|
||||
if tv.IsNil() {
|
||||
stv.SetIsNil()
|
||||
}
|
||||
if tv.Addressable() {
|
||||
stv.SetAddressable()
|
||||
}
|
||||
if tv.Assignable() {
|
||||
stv.SetAssignable()
|
||||
}
|
||||
if tv.HasOk() {
|
||||
stv.SetHasOk()
|
||||
}
|
||||
x.SetTypeInfo(stv)
|
||||
}
|
||||
check.recordTypeAndValueInSyntax(x, mode, typ, val)
|
||||
}
|
||||
|
||||
func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
|
||||
|
|
@ -145,25 +117,7 @@ func (check *Checker) recordCommaOkTypes(x syntax.Expr, a []*operand) {
|
|||
x = p.X
|
||||
}
|
||||
}
|
||||
if check.StoreTypesInSyntax {
|
||||
// Note: this loop is duplicated because the type of tv is different.
|
||||
// Above it is types2.TypeAndValue, here it is syntax.TypeAndValue.
|
||||
for {
|
||||
tv := x.GetTypeInfo()
|
||||
assert(tv.Type != nil) // should have been recorded already
|
||||
pos := x.Pos()
|
||||
tv.Type = NewTuple(
|
||||
NewVar(pos, check.pkg, "", t0),
|
||||
NewVar(pos, check.pkg, "", t1),
|
||||
)
|
||||
x.SetTypeInfo(tv)
|
||||
p, _ := x.(*syntax.ParenExpr)
|
||||
if p == nil {
|
||||
break
|
||||
}
|
||||
x = p.X
|
||||
}
|
||||
}
|
||||
check.recordCommaOkTypesInSyntax(x, t0, t1)
|
||||
}
|
||||
|
||||
// recordInstance records instantiation information into check.Info, if the
|
||||
|
|
@ -181,23 +135,6 @@ func (check *Checker) recordInstance(expr syntax.Expr, targs []Type, typ Type) {
|
|||
}
|
||||
}
|
||||
|
||||
func instantiatedIdent(expr syntax.Expr) *syntax.Name {
|
||||
var selOrIdent syntax.Expr
|
||||
switch e := expr.(type) {
|
||||
case *syntax.IndexExpr:
|
||||
selOrIdent = e.X
|
||||
case *syntax.SelectorExpr, *syntax.Name:
|
||||
selOrIdent = e
|
||||
}
|
||||
switch x := selOrIdent.(type) {
|
||||
case *syntax.Name:
|
||||
return x
|
||||
case *syntax.SelectorExpr:
|
||||
return x.Sel
|
||||
}
|
||||
panic("instantiated ident not found")
|
||||
}
|
||||
|
||||
func (check *Checker) recordDef(id *syntax.Name, obj Object) {
|
||||
assert(id != nil)
|
||||
if m := check.Defs; m != nil {
|
||||
|
|
|
|||
|
|
@ -535,3 +535,38 @@ func (check *Checker) cleanup() {
|
|||
}
|
||||
check.cleaners = nil
|
||||
}
|
||||
|
||||
// go/types doesn't support recording of types directly in the AST.
|
||||
// dummy function to match types2 code.
|
||||
func (check *Checker) recordTypeAndValueInSyntax(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// go/types doesn't support recording of types directly in the AST.
|
||||
// dummy function to match types2 code.
|
||||
func (check *Checker) recordCommaOkTypesInSyntax(x ast.Expr, t0, t1 Type) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// instantiatedIdent determines the identifier of the type instantiated in expr.
|
||||
// Helper function for recordInstance in recording.go.
|
||||
func instantiatedIdent(expr ast.Expr) *ast.Ident {
|
||||
var selOrIdent ast.Expr
|
||||
switch e := expr.(type) {
|
||||
case *ast.IndexExpr:
|
||||
selOrIdent = e.X
|
||||
case *ast.IndexListExpr: // only exists in go/ast, not syntax
|
||||
selOrIdent = e.X
|
||||
case *ast.SelectorExpr, *ast.Ident:
|
||||
selOrIdent = e
|
||||
}
|
||||
switch x := selOrIdent.(type) {
|
||||
case *ast.Ident:
|
||||
return x
|
||||
case *ast.SelectorExpr:
|
||||
return x.Sel
|
||||
}
|
||||
|
||||
// extra debugging of go.dev/issue/63933
|
||||
panic(sprintf(nil, nil, true, "instantiated ident not found; please report: %s", expr))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ package types
|
|||
import (
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (check *Checker) record(x *operand) {
|
||||
|
|
@ -42,7 +40,7 @@ func (check *Checker) record(x *operand) {
|
|||
}
|
||||
|
||||
func (check *Checker) recordUntyped() {
|
||||
if !debug && check.Types == nil {
|
||||
if !debug && !check.recordTypes() {
|
||||
return // nothing to do
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +68,7 @@ func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type,
|
|||
if m := check.Types; m != nil {
|
||||
m[x] = TypeAndValue{mode, typ, val}
|
||||
}
|
||||
check.recordTypeAndValueInSyntax(x, mode, typ, val)
|
||||
}
|
||||
|
||||
func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
|
||||
|
|
@ -118,6 +117,7 @@ func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
|
|||
x = p.X
|
||||
}
|
||||
}
|
||||
check.recordCommaOkTypesInSyntax(x, t0, t1)
|
||||
}
|
||||
|
||||
// recordInstance records instantiation information into check.Info, if the
|
||||
|
|
@ -135,30 +135,6 @@ func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) {
|
|||
}
|
||||
}
|
||||
|
||||
func instantiatedIdent(expr ast.Expr) *ast.Ident {
|
||||
var selOrIdent ast.Expr
|
||||
switch e := expr.(type) {
|
||||
case *ast.IndexExpr:
|
||||
selOrIdent = e.X
|
||||
case *ast.IndexListExpr:
|
||||
selOrIdent = e.X
|
||||
case *ast.SelectorExpr, *ast.Ident:
|
||||
selOrIdent = e
|
||||
}
|
||||
switch x := selOrIdent.(type) {
|
||||
case *ast.Ident:
|
||||
return x
|
||||
case *ast.SelectorExpr:
|
||||
return x.Sel
|
||||
}
|
||||
|
||||
// extra debugging of #63933
|
||||
var buf strings.Builder
|
||||
buf.WriteString("instantiated ident not found; please report: ")
|
||||
ast.Fprint(&buf, token.NewFileSet(), expr, ast.NotNilFilter)
|
||||
panic(buf.String())
|
||||
}
|
||||
|
||||
func (check *Checker) recordDef(id *ast.Ident, obj Object) {
|
||||
assert(id != nil)
|
||||
if m := check.Defs; m != nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue