mirror of
https://github.com/golang/go
synced 2024-11-14 15:10:54 -07:00
[dev.typeparams] go/types: import some support functions from dev.go2go
Import dev.go2go changes for exprstring.go, sizes.go, and scope.go. These files have been reviewed, but are unmodified. Change-Id: I9df9f8967bab73ce535a539b049346a872877572 Reviewed-on: https://go-review.googlesource.com/c/go/+/278593 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
a4d4c10340
commit
ceb77db24f
@ -8,6 +8,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
|
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
default:
|
default:
|
||||||
buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr
|
buf.WriteString(fmt.Sprintf("(ast: %T)", x)) // nil, ast.BadExpr, ast.KeyValueExpr
|
||||||
|
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
buf.WriteString(x.Name)
|
buf.WriteString(x.Name)
|
||||||
@ -97,17 +98,16 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
|
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
WriteExpr(buf, x.Fun)
|
WriteExpr(buf, x.Fun)
|
||||||
buf.WriteByte('(')
|
var l, r byte = '(', ')'
|
||||||
for i, arg := range x.Args {
|
if x.Brackets {
|
||||||
if i > 0 {
|
l, r = '[', ']'
|
||||||
buf.WriteString(", ")
|
|
||||||
}
|
|
||||||
WriteExpr(buf, arg)
|
|
||||||
}
|
}
|
||||||
|
buf.WriteByte(l)
|
||||||
|
writeExprList(buf, x.Args)
|
||||||
if x.Ellipsis.IsValid() {
|
if x.Ellipsis.IsValid() {
|
||||||
buf.WriteString("...")
|
buf.WriteString("...")
|
||||||
}
|
}
|
||||||
buf.WriteByte(')')
|
buf.WriteByte(r)
|
||||||
|
|
||||||
case *ast.StarExpr:
|
case *ast.StarExpr:
|
||||||
buf.WriteByte('*')
|
buf.WriteByte('*')
|
||||||
@ -134,7 +134,7 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
|
|
||||||
case *ast.StructType:
|
case *ast.StructType:
|
||||||
buf.WriteString("struct{")
|
buf.WriteString("struct{")
|
||||||
writeFieldList(buf, x.Fields, "; ", false)
|
writeFieldList(buf, x.Fields.List, "; ", false)
|
||||||
buf.WriteByte('}')
|
buf.WriteByte('}')
|
||||||
|
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
@ -142,8 +142,29 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
writeSigExpr(buf, x)
|
writeSigExpr(buf, x)
|
||||||
|
|
||||||
case *ast.InterfaceType:
|
case *ast.InterfaceType:
|
||||||
|
// separate type list types from method list
|
||||||
|
// TODO(gri) we can get rid of this extra code if writeExprList does the separation
|
||||||
|
var types []ast.Expr
|
||||||
|
var methods []*ast.Field
|
||||||
|
for _, f := range x.Methods.List {
|
||||||
|
if len(f.Names) > 1 && f.Names[0].Name == "type" {
|
||||||
|
// type list type
|
||||||
|
types = append(types, f.Type)
|
||||||
|
} else {
|
||||||
|
// method or embedded interface
|
||||||
|
methods = append(methods, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buf.WriteString("interface{")
|
buf.WriteString("interface{")
|
||||||
writeFieldList(buf, x.Methods, "; ", true)
|
writeFieldList(buf, methods, "; ", true)
|
||||||
|
if len(types) > 0 {
|
||||||
|
if len(methods) > 0 {
|
||||||
|
buf.WriteString("; ")
|
||||||
|
}
|
||||||
|
buf.WriteString("type ")
|
||||||
|
writeExprList(buf, types)
|
||||||
|
}
|
||||||
buf.WriteByte('}')
|
buf.WriteByte('}')
|
||||||
|
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
@ -169,7 +190,7 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
|
|||||||
|
|
||||||
func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
|
func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
|
||||||
buf.WriteByte('(')
|
buf.WriteByte('(')
|
||||||
writeFieldList(buf, sig.Params, ", ", false)
|
writeFieldList(buf, sig.Params.List, ", ", false)
|
||||||
buf.WriteByte(')')
|
buf.WriteByte(')')
|
||||||
|
|
||||||
res := sig.Results
|
res := sig.Results
|
||||||
@ -188,23 +209,18 @@ func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
|
|||||||
|
|
||||||
// multiple or named result(s)
|
// multiple or named result(s)
|
||||||
buf.WriteByte('(')
|
buf.WriteByte('(')
|
||||||
writeFieldList(buf, res, ", ", false)
|
writeFieldList(buf, res.List, ", ", false)
|
||||||
buf.WriteByte(')')
|
buf.WriteByte(')')
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) {
|
func writeFieldList(buf *bytes.Buffer, list []*ast.Field, sep string, iface bool) {
|
||||||
for i, f := range fields.List {
|
for i, f := range list {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buf.WriteString(sep)
|
buf.WriteString(sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
// field list names
|
// field list names
|
||||||
for i, name := range f.Names {
|
writeIdentList(buf, f.Names)
|
||||||
if i > 0 {
|
|
||||||
buf.WriteString(", ")
|
|
||||||
}
|
|
||||||
buf.WriteString(name.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// types of interface methods consist of signatures only
|
// types of interface methods consist of signatures only
|
||||||
if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
|
if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
|
||||||
@ -222,3 +238,21 @@ func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface
|
|||||||
// ignore tag
|
// ignore tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeIdentList(buf *bytes.Buffer, list []*ast.Ident) {
|
||||||
|
for i, x := range list {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
buf.WriteString(x.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeExprList(buf *bytes.Buffer, list []ast.Expr) {
|
||||||
|
for i, x := range list {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
WriteExpr(buf, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -108,6 +108,40 @@ func (s *Scope) Insert(obj Object) Object {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Squash merges s with its parent scope p by adding all
|
||||||
|
// objects of s to p, adding all children of s to the
|
||||||
|
// children of p, and removing s from p's children.
|
||||||
|
// The function f is called for each object obj in s which
|
||||||
|
// has an object alt in p. s should be discarded after
|
||||||
|
// having been squashed.
|
||||||
|
func (s *Scope) Squash(err func(obj, alt Object)) {
|
||||||
|
p := s.parent
|
||||||
|
assert(p != nil)
|
||||||
|
for _, obj := range s.elems {
|
||||||
|
obj.setParent(nil)
|
||||||
|
if alt := p.Insert(obj); alt != nil {
|
||||||
|
err(obj, alt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j := -1 // index of s in p.children
|
||||||
|
for i, ch := range p.children {
|
||||||
|
if ch == s {
|
||||||
|
j = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(j >= 0)
|
||||||
|
k := len(p.children) - 1
|
||||||
|
p.children[j] = p.children[k]
|
||||||
|
p.children = p.children[:k]
|
||||||
|
|
||||||
|
p.children = append(p.children, s.children...)
|
||||||
|
|
||||||
|
s.children = nil
|
||||||
|
s.elems = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Pos and End describe the scope's source code extent [pos, end).
|
// Pos and End describe the scope's source code extent [pos, end).
|
||||||
// The results are guaranteed to be valid only if the type-checked
|
// The results are guaranteed to be valid only if the type-checked
|
||||||
// AST has complete position information. The extent is undefined
|
// AST has complete position information. The extent is undefined
|
||||||
|
@ -48,7 +48,7 @@ type StdSizes struct {
|
|||||||
func (s *StdSizes) Alignof(T Type) int64 {
|
func (s *StdSizes) Alignof(T Type) int64 {
|
||||||
// For arrays and structs, alignment is defined in terms
|
// For arrays and structs, alignment is defined in terms
|
||||||
// of alignment of the elements and fields, respectively.
|
// of alignment of the elements and fields, respectively.
|
||||||
switch t := T.Underlying().(type) {
|
switch t := optype(T).(type) {
|
||||||
case *Array:
|
case *Array:
|
||||||
// spec: "For a variable x of array type: unsafe.Alignof(x)
|
// spec: "For a variable x of array type: unsafe.Alignof(x)
|
||||||
// is the same as unsafe.Alignof(x[0]), but at least 1."
|
// is the same as unsafe.Alignof(x[0]), but at least 1."
|
||||||
@ -118,7 +118,7 @@ var basicSizes = [...]byte{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StdSizes) Sizeof(T Type) int64 {
|
func (s *StdSizes) Sizeof(T Type) int64 {
|
||||||
switch t := T.Underlying().(type) {
|
switch t := optype(T).(type) {
|
||||||
case *Basic:
|
case *Basic:
|
||||||
assert(isTyped(T))
|
assert(isTyped(T))
|
||||||
k := t.kind
|
k := t.kind
|
||||||
@ -148,6 +148,8 @@ func (s *StdSizes) Sizeof(T Type) int64 {
|
|||||||
}
|
}
|
||||||
offsets := s.Offsetsof(t.fields)
|
offsets := s.Offsetsof(t.fields)
|
||||||
return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
|
return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
|
||||||
|
case *Sum:
|
||||||
|
panic("Sizeof unimplemented for type sum")
|
||||||
case *Interface:
|
case *Interface:
|
||||||
return s.WordSize * 2
|
return s.WordSize * 2
|
||||||
}
|
}
|
||||||
@ -239,7 +241,7 @@ func (conf *Config) offsetsof(T *Struct) []int64 {
|
|||||||
func (conf *Config) offsetof(typ Type, index []int) int64 {
|
func (conf *Config) offsetof(typ Type, index []int) int64 {
|
||||||
var o int64
|
var o int64
|
||||||
for _, i := range index {
|
for _, i := range index {
|
||||||
s := typ.Underlying().(*Struct)
|
s := asStruct(typ)
|
||||||
o += conf.offsetsof(s)[i]
|
o += conf.offsetsof(s)[i]
|
||||||
typ = s.fields[i].typ
|
typ = s.fields[i].typ
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user