this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cmd/cue: support type parameters in get go

Go type parameters are represented as their basic types in most cases, but
there are some more complicated areas which are not handled yet. These
cases are documented clearly as TODOs and may be good candidates for
improvement work in future. For now, this should unblock importing some
packages.

Fixes #2217

Change-Id: I5b4660ed3b8c6a11a1f135fe68ed55e966e371b1
Signed-off-by: Thomas Way <thomas@6f.io>
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1171015
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

authored by

Thomas Way and committed by
Daniel Martí
3b4e03d5 286dfcb8

+169 -7
+78 -5
cmd/cue/cmd/get_go.go
··· 1023 1023 } 1024 1024 1025 1025 func (e *extractor) makeType(expr types.Type) (result cueast.Expr) { 1026 - if x, ok := expr.(*types.Named); ok { 1026 + switch x := expr.(type) { 1027 + case *types.Named: 1027 1028 obj := x.Obj() 1028 1029 if obj.Pkg() == nil { 1029 1030 return e.ident("_", false) ··· 1076 1077 result = cueast.NewSel(p, "#"+obj.Name()) 1077 1078 e.usedPkg(pkg.Path()) 1078 1079 } 1079 - return 1080 - } 1080 + 1081 + // TODO(uhthomas): Fields with type parameters should not be 1082 + // top. 1083 + // 1084 + // For example: 1085 + // 1086 + // type A[T any] struct { 1087 + // SomeField T 1088 + // } 1089 + // 1090 + // type B A[string] 1091 + // 1092 + // Should become: 1093 + // 1094 + // #A: SomeField: _ 1095 + // 1096 + // #B: #A & { 1097 + // _#T: string 1098 + // SomeField: _#T 1099 + // } 1100 + // 1101 + // Or maybe: 1102 + // 1103 + // #A: { 1104 + // #T: _ 1105 + // SomeField: #T 1106 + // } 1107 + // 1108 + // #B: #A & { 1109 + // #T: string 1110 + // } 1111 + // 1112 + // The values of x.TypeParams() and x.TypeArgs() may be helpful. 1113 + 1114 + // params := x.TypeParams() 1115 + // args := x.TypeArgs() 1116 + // if params.Len() > 0 { 1117 + // var fields []any 1118 + // for i := 0; i < params.Len(); i++ { 1119 + // name := params.At(i).Obj().Name() 1120 + // fields = append(fields, e.ident(name, true), e.makeType(args.At(i))) 1121 + // } 1122 + // return cueast.NewBinExpr(cuetoken.AND, result, cueast.NewStruct(fields...)) 1123 + // } 1081 1124 1082 - switch x := expr.(type) { 1125 + return result 1083 1126 case *types.Pointer: 1084 1127 return &cueast.BinaryExpr{ 1085 1128 X: cueast.NewNull(), ··· 1148 1191 return e.ident(x.String(), false) 1149 1192 } 1150 1193 1194 + case *types.Union: 1195 + var exprs []cueast.Expr 1196 + for i := 0; i < x.Len(); i++ { 1197 + exprs = append(exprs, e.makeType(x.Term(i).Type())) 1198 + } 1199 + return cueast.NewBinExpr(cuetoken.OR, exprs...) 1200 + 1151 1201 case *types.Interface: 1152 - return e.ident("_", false) 1202 + // TODO(uhthomas): Should interfaces with methods (IsMethodSet) 1203 + // be set to top? 1204 + if !x.IsComparable() { 1205 + return e.ident("_", false) 1206 + } 1207 + 1208 + // TODO(uhthomas): Simplify expressions. 1209 + // 1210 + // For example: 1211 + // 1212 + // int | (int | string) 1213 + // 1214 + // Should really become: 1215 + // 1216 + // int | string 1217 + // 1218 + var exprs []cueast.Expr 1219 + for i := 0; i < x.NumEmbeddeds(); i++ { 1220 + exprs = append(exprs, e.makeType(x.EmbeddedType(i))) 1221 + } 1222 + return cueast.NewBinExpr(cuetoken.OR, exprs...) 1223 + 1224 + case *types.TypeParam: 1225 + return e.makeType(x.Constraint()) 1153 1226 1154 1227 default: 1155 1228 // record error
+91 -2
cmd/cue/cmd/testdata/script/get_go_types.txtar
··· 13 13 cmp ./pkg1/alias_go_gen.cue ./pkg1/alias_go_gen.cue.golden 14 14 cmp ./pkg2/pkg2_go_gen.cue ./pkg2/pkg2_go_gen.cue.golden 15 15 cmp ./pkg4/pkg4_go_gen.cue ./pkg4/pkg4_go_gen.cue.golden 16 + cmp ./pkg_generics/pkg_generics_go_gen.cue ./pkg_generics/pkg_generics_go_gen.cue.golden 16 17 17 18 # Verify dependencies did not change 18 19 cmp go.mod go.mod.golden ··· 20 21 -- go.mod -- 21 22 module mod.test 22 23 23 - go 1.14 24 + go 1.21 24 25 -- go.mod.golden -- 25 26 module mod.test 26 27 27 - go 1.14 28 + go 1.21 28 29 -- cue.mod -- 29 30 module: "mod.test" 30 31 -- pkg1/alias.go -- ··· 433 434 #A: { 434 435 UnsafePointer: uint64 @go(,unsafe.Pointer) 435 436 } 437 + -- pkg_generics/pkg_generics.go -- 438 + package pkg_generics 439 + 440 + type SomeUnionInterface interface { 441 + string | int | byte 442 + } 443 + 444 + type SomeStructAny[T any] struct { 445 + SomeField T 446 + } 447 + 448 + type SomeStructString[T string] struct { 449 + SomeField T 450 + } 451 + 452 + type SomeStructSomeInterface[T SomeUnionInterface] struct { 453 + SomeField T 454 + } 455 + 456 + type SomeStructMultipleTypeParameters[T string, Z ~int] struct { 457 + SomeField T 458 + SomeOtherField Z 459 + } 460 + 461 + type SomeStructComparable[T comparable] struct { 462 + SomeField T 463 + } 464 + 465 + type SomeInterfaceWithMethod interface { 466 + int 467 + 468 + Do() string 469 + } 470 + 471 + type SomeAlias = string 472 + 473 + type StructWithAlias[T SomeAlias] struct { 474 + SomeField T 475 + } 476 + 477 + type SomeType int 478 + 479 + type StructWithType[T SomeType] struct { 480 + SomeField T 481 + } 482 + -- pkg_generics/pkg_generics_go_gen.cue.golden -- 483 + // Code generated by cue get go. DO NOT EDIT. 484 + 485 + //cue:generate cue get go mod.test/pkg_generics 486 + 487 + package pkg_generics 488 + 489 + #SomeUnionInterface: string | int | uint8 490 + 491 + #SomeStructAny: { 492 + SomeField: _ @go(,T) 493 + } 494 + 495 + #SomeStructString: { 496 + SomeField: string @go(,T) 497 + } 498 + 499 + #SomeStructSomeInterface: { 500 + SomeField: #SomeUnionInterface @go(,T) 501 + } 502 + 503 + #SomeStructMultipleTypeParameters: { 504 + SomeField: string @go(,T) 505 + SomeOtherField: int @go(,Z) 506 + } 507 + 508 + #SomeStructComparable: { 509 + SomeField: _ @go(,T) 510 + } 511 + 512 + #SomeInterfaceWithMethod: int 513 + 514 + #SomeAlias: string 515 + 516 + #StructWithAlias: { 517 + SomeField: string @go(,T) 518 + } 519 + 520 + #SomeType: int 521 + 522 + #StructWithType: { 523 + SomeField: #SomeType @go(,T) 524 + }