mirror of
https://github.com/golang/go
synced 2024-11-26 01:57:56 -07:00
[dev.regabi] cmd/compile: simplify function/interface/struct typechecking
After the previous CL, the only callers to NewFuncType, tointerface, or NewStructType are the functions for type-checking the type literal ASTs. So just inline the code there. While here, refactor the Field type-checking logic a little bit, to reduce some duplication. Passes toolstash -cmp. Change-Id: Ie12d14b87ef8b6e528ac9dccd609604bd09b98ec Reviewed-on: https://go-review.googlesource.com/c/go/+/279956 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
addade2cce
commit
31267f82e1
@ -281,72 +281,6 @@ func CheckFuncStack() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn a parsed function declaration into a type
|
|
||||||
func NewFuncType(nrecv *ir.Field, nparams, nresults []*ir.Field) *types.Type {
|
|
||||||
funarg := func(n *ir.Field) *types.Field {
|
|
||||||
lno := base.Pos
|
|
||||||
base.Pos = n.Pos
|
|
||||||
|
|
||||||
if n.Ntype != nil {
|
|
||||||
n.Type = typecheckNtype(n.Ntype).Type()
|
|
||||||
n.Ntype = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
|
||||||
f.SetIsDDD(n.IsDDD)
|
|
||||||
if n.Decl != nil {
|
|
||||||
n.Decl.SetType(f.Type)
|
|
||||||
f.Nname = n.Decl
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Pos = lno
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
funargs := func(nn []*ir.Field) []*types.Field {
|
|
||||||
res := make([]*types.Field, len(nn))
|
|
||||||
for i, n := range nn {
|
|
||||||
res[i] = funarg(n)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
var recv *types.Field
|
|
||||||
if nrecv != nil {
|
|
||||||
recv = funarg(nrecv)
|
|
||||||
}
|
|
||||||
|
|
||||||
t := types.NewSignature(types.LocalPkg, recv, funargs(nparams), funargs(nresults))
|
|
||||||
checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert a parsed id/type list into
|
|
||||||
// a type for struct/interface/arglist
|
|
||||||
func NewStructType(l []*ir.Field) *types.Type {
|
|
||||||
lno := base.Pos
|
|
||||||
|
|
||||||
fields := make([]*types.Field, len(l))
|
|
||||||
for i, n := range l {
|
|
||||||
base.Pos = n.Pos
|
|
||||||
|
|
||||||
if n.Ntype != nil {
|
|
||||||
n.Type = typecheckNtype(n.Ntype).Type()
|
|
||||||
n.Ntype = nil
|
|
||||||
}
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
|
||||||
if n.Embedded {
|
|
||||||
checkembeddedtype(n.Type)
|
|
||||||
f.Embedded = 1
|
|
||||||
}
|
|
||||||
f.Note = n.Note
|
|
||||||
fields[i] = f
|
|
||||||
}
|
|
||||||
checkdupfields("field", fields)
|
|
||||||
|
|
||||||
base.Pos = lno
|
|
||||||
return types.NewStruct(types.LocalPkg, fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a method, declared as a function.
|
// Add a method, declared as a function.
|
||||||
// - msym is the method symbol
|
// - msym is the method symbol
|
||||||
// - t is function type (with receiver)
|
// - t is function type (with receiver)
|
||||||
@ -604,27 +538,6 @@ func initname(s string) bool {
|
|||||||
return s == "init"
|
return s == "init"
|
||||||
}
|
}
|
||||||
|
|
||||||
func tointerface(nmethods []*ir.Field) *types.Type {
|
|
||||||
if len(nmethods) == 0 {
|
|
||||||
return types.Types[types.TINTER]
|
|
||||||
}
|
|
||||||
|
|
||||||
lno := base.Pos
|
|
||||||
|
|
||||||
methods := make([]*types.Field, len(nmethods))
|
|
||||||
for i, n := range nmethods {
|
|
||||||
base.Pos = n.Pos
|
|
||||||
if n.Ntype != nil {
|
|
||||||
n.Type = typecheckNtype(n.Ntype).Type()
|
|
||||||
n.Ntype = nil
|
|
||||||
}
|
|
||||||
methods[i] = types.NewField(n.Pos, n.Sym, n.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Pos = lno
|
|
||||||
return types.NewInterface(types.LocalPkg, methods)
|
|
||||||
}
|
|
||||||
|
|
||||||
var vargen int
|
var vargen int
|
||||||
|
|
||||||
func Temp(t *types.Type) *ir.Name {
|
func Temp(t *types.Type) *ir.Name {
|
||||||
|
@ -73,13 +73,42 @@ func tcChanType(n *ir.ChanType) ir.Node {
|
|||||||
|
|
||||||
// tcFuncType typechecks an OTFUNC node.
|
// tcFuncType typechecks an OTFUNC node.
|
||||||
func tcFuncType(n *ir.FuncType) ir.Node {
|
func tcFuncType(n *ir.FuncType) ir.Node {
|
||||||
n.SetOTYPE(NewFuncType(n.Recv, n.Params, n.Results))
|
misc := func(f *types.Field, nf *ir.Field) {
|
||||||
|
f.SetIsDDD(nf.IsDDD)
|
||||||
|
if nf.Decl != nil {
|
||||||
|
nf.Decl.SetType(f.Type)
|
||||||
|
f.Nname = nf.Decl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lno := base.Pos
|
||||||
|
|
||||||
|
var recv *types.Field
|
||||||
|
if n.Recv != nil {
|
||||||
|
recv = tcField(n.Recv, misc)
|
||||||
|
}
|
||||||
|
|
||||||
|
t := types.NewSignature(types.LocalPkg, recv, tcFields(n.Params, misc), tcFields(n.Results, misc))
|
||||||
|
checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
|
||||||
|
|
||||||
|
base.Pos = lno
|
||||||
|
|
||||||
|
n.SetOTYPE(t)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// tcInterfaceType typechecks an OTINTER node.
|
// tcInterfaceType typechecks an OTINTER node.
|
||||||
func tcInterfaceType(n *ir.InterfaceType) ir.Node {
|
func tcInterfaceType(n *ir.InterfaceType) ir.Node {
|
||||||
n.SetOTYPE(tointerface(n.Methods))
|
if len(n.Methods) == 0 {
|
||||||
|
n.SetOTYPE(types.Types[types.TINTER])
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
lno := base.Pos
|
||||||
|
methods := tcFields(n.Methods, nil)
|
||||||
|
base.Pos = lno
|
||||||
|
|
||||||
|
n.SetOTYPE(types.NewInterface(types.LocalPkg, methods))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +146,43 @@ func tcSliceType(n *ir.SliceType) ir.Node {
|
|||||||
|
|
||||||
// tcStructType typechecks an OTSTRUCT node.
|
// tcStructType typechecks an OTSTRUCT node.
|
||||||
func tcStructType(n *ir.StructType) ir.Node {
|
func tcStructType(n *ir.StructType) ir.Node {
|
||||||
n.SetOTYPE(NewStructType(n.Fields))
|
lno := base.Pos
|
||||||
|
|
||||||
|
fields := tcFields(n.Fields, func(f *types.Field, nf *ir.Field) {
|
||||||
|
if nf.Embedded {
|
||||||
|
checkembeddedtype(f.Type)
|
||||||
|
f.Embedded = 1
|
||||||
|
}
|
||||||
|
f.Note = nf.Note
|
||||||
|
})
|
||||||
|
checkdupfields("field", fields)
|
||||||
|
|
||||||
|
base.Pos = lno
|
||||||
|
n.SetOTYPE(types.NewStruct(types.LocalPkg, fields))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tcField typechecks a generic Field.
|
||||||
|
// misc can be provided to handle specialized typechecking.
|
||||||
|
func tcField(n *ir.Field, misc func(*types.Field, *ir.Field)) *types.Field {
|
||||||
|
base.Pos = n.Pos
|
||||||
|
if n.Ntype != nil {
|
||||||
|
n.Type = typecheckNtype(n.Ntype).Type()
|
||||||
|
n.Ntype = nil
|
||||||
|
}
|
||||||
|
f := types.NewField(n.Pos, n.Sym, n.Type)
|
||||||
|
if misc != nil {
|
||||||
|
misc(f, n)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// tcFields typechecks a slice of generic Fields.
|
||||||
|
// misc can be provided to handle specialized typechecking.
|
||||||
|
func tcFields(l []*ir.Field, misc func(*types.Field, *ir.Field)) []*types.Field {
|
||||||
|
fields := make([]*types.Field, len(l))
|
||||||
|
for i, n := range l {
|
||||||
|
fields[i] = tcField(n, misc)
|
||||||
|
}
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user