Merge pull request #17737 from owen-mc/go/extractor/objecttypes-consistency-generics-2

Go: extractor/objecttypes consistency generics (second try)
This commit is contained in:
Owen Mansel-Chan 2024-10-15 15:50:45 +01:00 коммит произвёл GitHub
Родитель f9eca42ded 9381dda4a9
Коммит 5efb88ed1f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
1 изменённых файлов: 23 добавлений и 5 удалений

Просмотреть файл

@ -518,6 +518,7 @@ func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label {
// For more information on objects, see: // For more information on objects, see:
// https://github.com/golang/example/blob/master/gotypes/README.md#objects // https://github.com/golang/example/blob/master/gotypes/README.md#objects
func extractObject(tw *trap.Writer, obj types.Object, lbl trap.Label) { func extractObject(tw *trap.Writer, obj types.Object, lbl trap.Label) {
checkObjectNotSpecialized(obj)
name := obj.Name() name := obj.Name()
isBuiltin := obj.Parent() == types.Universe isBuiltin := obj.Parent() == types.Universe
var kind int var kind int
@ -1607,7 +1608,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
case *types.Struct: case *types.Struct:
kind = dbscheme.StructType.Index() kind = dbscheme.StructType.Index()
for i := 0; i < tp.NumFields(); i++ { for i := 0; i < tp.NumFields(); i++ {
field := tp.Field(i) field := tp.Field(i).Origin()
// ensure the field is associated with a label - note that // ensure the field is associated with a label - note that
// struct fields do not have a parent scope, so they are not // struct fields do not have a parent scope, so they are not
@ -1637,7 +1638,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
// Note that methods coming from embedded interfaces can be // Note that methods coming from embedded interfaces can be
// accessed through `Method(i)`, so there is no need to // accessed through `Method(i)`, so there is no need to
// deal with them separately. // deal with them separately.
meth := tp.Method(i) meth := tp.Method(i).Origin()
// Note that methods do not have a parent scope, so they are // Note that methods do not have a parent scope, so they are
// not dealt with by `extractScopes` // not dealt with by `extractScopes`
@ -1707,7 +1708,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
// ensure all methods have labels - note that methods do not have a // ensure all methods have labels - note that methods do not have a
// parent scope, so they are not dealt with by `extractScopes` // parent scope, so they are not dealt with by `extractScopes`
for i := 0; i < origintp.NumMethods(); i++ { for i := 0; i < origintp.NumMethods(); i++ {
meth := origintp.Method(i) meth := origintp.Method(i).Origin()
extractMethod(tw, meth) extractMethod(tw, meth)
} }
@ -1715,7 +1716,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
// associate all methods of underlying interface with this type // associate all methods of underlying interface with this type
if underlyingInterface, ok := underlying.(*types.Interface); ok { if underlyingInterface, ok := underlying.(*types.Interface); ok {
for i := 0; i < underlyingInterface.NumMethods(); i++ { for i := 0; i < underlyingInterface.NumMethods(); i++ {
methlbl := extractMethod(tw, underlyingInterface.Method(i)) methlbl := extractMethod(tw, underlyingInterface.Method(i).Origin())
dbscheme.MethodHostsTable.Emit(tw, methlbl, lbl) dbscheme.MethodHostsTable.Emit(tw, methlbl, lbl)
} }
} }
@ -1787,7 +1788,7 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
case *types.Interface: case *types.Interface:
var b strings.Builder var b strings.Builder
for i := 0; i < tp.NumMethods(); i++ { for i := 0; i < tp.NumMethods(); i++ {
meth := tp.Method(i) meth := tp.Method(i).Origin()
methLbl := extractType(tw, meth.Type()) methLbl := extractType(tw, meth.Type())
if i > 0 { if i > 0 {
b.WriteString(",") b.WriteString(",")
@ -2143,3 +2144,20 @@ func skipExtractingValueForLeftOperand(tw *trap.Writer, be *ast.BinaryExpr) bool
} }
return true return true
} }
// checkObjectNotSpecialized exits the program if `obj` is specialized. Note
// that specialization is only possible for function objects and variable
// objects.
func checkObjectNotSpecialized(obj types.Object) {
if funcObj, ok := obj.(*types.Func); ok && funcObj != funcObj.Origin() {
log.Fatalf("Encountered unexpected specialization %s of generic function object %s", funcObj.FullName(), funcObj.Origin().FullName())
}
if varObj, ok := obj.(*types.Var); ok && varObj != varObj.Origin() {
log.Fatalf("Encountered unexpected specialization %s of generic variable object %s", varObj.String(), varObj.Origin().String())
}
if typeNameObj, ok := obj.(*types.TypeName); ok {
if namedType, ok := typeNameObj.Type().(*types.Named); ok && namedType != namedType.Origin() {
log.Fatalf("Encountered type object for specialization %s of named type %s", namedType.String(), namedType.Origin().String())
}
}
}