| 398 | } |
| 399 | |
| 400 | func CompareTypes(a, b Type) int { |
| 401 | aID, bID := a.ID(), b.ID() |
| 402 | if aID == bID { |
| 403 | if a, ok := a.(*TypeNamed); ok { |
| 404 | if b, ok := b.(*TypeNamed); ok { |
| 405 | // Named types sharing an underlying type are |
| 406 | // ordered by name. |
| 407 | return strings.Compare(a.Name, b.Name) |
| 408 | } |
| 409 | // Named type a is ordered after its underlying type b. |
| 410 | return 1 |
| 411 | } |
| 412 | if _, ok := b.(*TypeNamed); ok { |
| 413 | // Named type b is ordered after its underlying type a. |
| 414 | return -1 |
| 415 | } |
| 416 | // a == b |
| 417 | return 0 |
| 418 | } |
| 419 | if cmp := cmp.Compare(a.Kind(), b.Kind()); cmp != 0 { |
| 420 | return cmp |
| 421 | } |
| 422 | a, b = TypeUnder(a), TypeUnder(b) |
| 423 | switch a.Kind() { |
| 424 | case PrimitiveKind: |
| 425 | return cmp.Compare(aID, bID) |
| 426 | case RecordKind: |
| 427 | ra, rb := TypeRecordOf(a), TypeRecordOf(b) |
| 428 | // First compare number of fields. |
| 429 | if cmp := cmp.Compare(len(ra.Fields), len(rb.Fields)); cmp != 0 { |
| 430 | return cmp |
| 431 | } |
| 432 | // Second compare field names. |
| 433 | for i := range ra.Fields { |
| 434 | if cmp := strings.Compare(ra.Fields[i].Name, rb.Fields[i].Name); cmp != 0 { |
| 435 | return cmp |
| 436 | } |
| 437 | } |
| 438 | // Lastly compare field types. |
| 439 | for i := range ra.Fields { |
| 440 | if cmp := CompareTypes(ra.Fields[i].Type, rb.Fields[i].Type); cmp != 0 { |
| 441 | return cmp |
| 442 | } |
| 443 | } |
| 444 | return 0 |
| 445 | case ArrayKind, SetKind: |
| 446 | a, b = InnerType(a), InnerType(b) |
| 447 | return CompareTypes(a, b) |
| 448 | case MapKind: |
| 449 | ma, mb := a.(*TypeMap), b.(*TypeMap) |
| 450 | if cmp := CompareTypes(ma.KeyType, mb.KeyType); cmp != 0 { |
| 451 | return cmp |
| 452 | } |
| 453 | return CompareTypes(ma.ValType, mb.ValType) |
| 454 | case UnionKind: |
| 455 | ua, ub := a.(*TypeUnion), b.(*TypeUnion) |
| 456 | if cmp := cmp.Compare(len(ua.Types), len(ub.Types)); cmp != 0 { |
| 457 | return cmp |