@@ -584,31 +584,7 @@ func (t *translator) translateExpr(pe *ast.Expr) {
584
584
case * ast.ParenExpr :
585
585
t .translateExpr (& e .X )
586
586
case * ast.SelectorExpr :
587
- t .translateExpr (& e .X )
588
-
589
- // Handle references to instantiated embedded fields.
590
- // We have to rewrite the name to the name used in
591
- // the translated struct definition.
592
- obj := t .importer .info .ObjectOf (e .Sel )
593
- if obj == nil {
594
- break
595
- }
596
- f , ok := obj .(* types.Var )
597
- if ! ok || ! f .Embedded () {
598
- break
599
- }
600
- named , ok := f .Type ().(* types.Named )
601
- if ! ok || len (named .TArgs ()) == 0 {
602
- break
603
- }
604
- if obj .Name () != named .Obj ().Name () {
605
- break
606
- }
607
- _ , id := t .lookupInstantiatedType (named )
608
- * pe = & ast.SelectorExpr {
609
- X : e .X ,
610
- Sel : id ,
611
- }
587
+ t .translateSelectorExpr (pe )
612
588
case * ast.IndexExpr :
613
589
t .translateExpr (& e .X )
614
590
t .translateExpr (& e .Index )
@@ -661,6 +637,63 @@ func (t *translator) translateExpr(pe *ast.Expr) {
661
637
}
662
638
}
663
639
640
+ // translateSelectorExpr translates a selector expression
641
+ // from Go with contracts to Go 1.
642
+ func (t * translator ) translateSelectorExpr (pe * ast.Expr ) {
643
+ e := (* pe ).(* ast.SelectorExpr )
644
+
645
+ t .translateExpr (& e .X )
646
+
647
+ obj := t .importer .info .ObjectOf (e .Sel )
648
+ if obj == nil {
649
+ return
650
+ }
651
+
652
+ // Handle references to promoted fields and methods,
653
+ // if they go through an embedded instantiated field.
654
+ // We have to add a reference to the field we inserted.
655
+ if xType := t .lookupType (e .X ); xType != nil {
656
+ if ptr := xType .Pointer (); ptr != nil {
657
+ xType = ptr .Elem ()
658
+ }
659
+ fobj , indexes , _ := types .LookupFieldOrMethod (xType , true , obj .Pkg (), obj .Name ())
660
+ if fobj != nil && len (indexes ) > 1 {
661
+ for _ , index := range indexes [:len (indexes )- 1 ] {
662
+ xf := xType .Struct ().Field (index )
663
+ if xf .Name () == types .TypeString (xf .Type (), types .RelativeTo (xf .Pkg ())) {
664
+ continue
665
+ }
666
+ e .X = & ast.SelectorExpr {
667
+ X : e .X ,
668
+ Sel : ast .NewIdent (xf .Name ()),
669
+ }
670
+ xType = xf .Type ()
671
+ if ptr := xType .Pointer (); ptr != nil {
672
+ xType = ptr .Elem ()
673
+ }
674
+ }
675
+ }
676
+ }
677
+
678
+ // Handle references to instantiated embedded fields.
679
+ // We have to rewrite the name to the name used in
680
+ // the translated struct definition.
681
+ if f , ok := obj .(* types.Var ); ok && f .Embedded () {
682
+ named , ok := f .Type ().(* types.Named )
683
+ if ! ok || len (named .TArgs ()) == 0 {
684
+ return
685
+ }
686
+ if obj .Name () != named .Obj ().Name () {
687
+ return
688
+ }
689
+ _ , id := t .lookupInstantiatedType (named )
690
+ * pe = & ast.SelectorExpr {
691
+ X : e .X ,
692
+ Sel : id ,
693
+ }
694
+ }
695
+ }
696
+
664
697
// TODO(iant) refactor code and get rid of this?
665
698
func splitFieldList (fl * ast.FieldList ) (methods * ast.FieldList , types []ast.Expr ) {
666
699
if fl == nil {
0 commit comments