@@ -32,6 +32,16 @@ type Ctx struct {
32
32
namesToTranslate map [string ]bool
33
33
info * types.Info
34
34
pkgPath string
35
+
36
+ // XXX: Initially tried using `pkg.Name` as the Gallina identifier holding
37
+ // the full package path, but that doesn't work in a `package main` with a `func main`.
38
+ // In that case, as soon as `func main` is defined inside `Module main.`,
39
+ // reference to simply `main` (which should be the go_string holding the
40
+ // package path) end up referring to the function. So, this uses `filename +
41
+ // "." + pkg.Name` to refer to the Gallina definition that holds a package's
42
+ // full path as a go_string (e.g. in `globals_test`, instead of `func_call #main ...`,
43
+ // this results in `func_call #globals_test.main ...`).
44
+ pkgIdent string
35
45
errorReporter
36
46
37
47
// XXX: this is so we can determine the expected return type when handling a
@@ -87,9 +97,12 @@ func getFfi(pkg *packages.Package) string {
87
97
88
98
// NewPkgCtx initializes a context based on a properly loaded package
89
99
func NewPkgCtx (pkg * packages.Package , filter declfilter.DeclFilter ) Ctx {
100
+ ss := strings .Split (pkg .PkgPath , "/" )
101
+ pkgIdent := ss [len (ss )- 1 ]
90
102
return Ctx {
91
103
info : pkg .TypesInfo ,
92
104
pkgPath : pkg .PkgPath ,
105
+ pkgIdent : pkgIdent + "." + pkg .Name ,
93
106
errorReporter : newErrorReporter (pkg .Fset ),
94
107
dep : newDepTracker (),
95
108
importNames : make (map [string ]struct {}),
@@ -646,26 +659,28 @@ func (ctx *Ctx) qualifiedName(obj types.Object) string {
646
659
}
647
660
648
661
func (ctx * Ctx ) getPkgAndName (obj types.Object ) (pkg string , name string ) {
662
+ if obj .Pkg () == nil {
663
+ ctx .unsupported (obj , "expected object to have package" )
664
+ }
649
665
name = obj .Name ()
650
- pkg = "pkg_name'"
651
- if obj .Pkg () == nil || ctx .pkgPath == obj .Pkg ().Path () {
652
- return
666
+ if obj .Pkg ().Path () == ctx .pkgPath {
667
+ pkg = ctx .pkgIdent
668
+ } else {
669
+ pkg = obj .Pkg ().Name ()
653
670
}
654
- pkg = obj .Pkg ().Name () + "." + pkg
655
671
return
656
672
}
657
673
658
674
func (ctx * Ctx ) selectorExprAddr (e * ast.SelectorExpr ) glang.Expr {
659
675
selection := ctx .info .Selections [e ]
660
676
if selection == nil {
661
- pkg , ok := getIdent (e .X )
677
+ pkgName , ok := getIdent (e .X )
662
678
if ! ok {
663
679
ctx .unsupported (e , "expected package selector with idtent, got %T" , e .X )
664
680
}
665
681
if _ , ok := ctx .info .ObjectOf (e .Sel ).(* types.Var ); ok {
666
- ctx .dep .addDep ("pkg_name'" )
667
682
return glang .NewCallExpr (glang .GallinaIdent ("globals.get" ),
668
- glang.StringVal {Value : glang .GallinaIdent (pkg + ".pkg_name'" )},
683
+ glang.StringVal {Value : glang .GallinaIdent (pkgName )},
669
684
glang.StringVal {Value : glang.StringLiteral {Value : e .Sel .Name }},
670
685
)
671
686
} else {
@@ -858,7 +873,7 @@ func (ctx *Ctx) selectorExpr(e *ast.SelectorExpr) glang.Expr {
858
873
ctx .info .TypeOf (e ),
859
874
glang .NewCallExpr (
860
875
glang .GallinaIdent ("func_call" ),
861
- glang.StringVal {Value : glang .GallinaIdent (f .Pkg ().Name () + ".pkg_name'" )},
876
+ glang.StringVal {Value : glang .GallinaIdent (f .Pkg ().Name ())},
862
877
glang.StringVal {Value : glang.StringLiteral {Value : e .Sel .Name }},
863
878
),
864
879
)
@@ -1307,12 +1322,13 @@ func (ctx *Ctx) unaryExpr(e *ast.UnaryExpr, isSpecial bool) glang.Expr {
1307
1322
}
1308
1323
1309
1324
func (ctx * Ctx ) function (s * ast.Ident ) glang.Expr {
1310
- ctx .dep .addDep ("pkg_name'" )
1311
-
1312
1325
typeArgs := ctx .info .Instances [s ].TypeArgs
1313
1326
if typeArgs .Len () == 0 {
1327
+ if ctx .info .ObjectOf (s ).Pkg ().Path () != ctx .pkgPath {
1328
+ ctx .nope (s , "expected function ident to refer to local function" )
1329
+ }
1314
1330
return glang .NewCallExpr (glang .GallinaIdent ("func_call" ),
1315
- glang.StringVal {Value : glang .GallinaIdent ("pkg_name'" )},
1331
+ glang.StringVal {Value : glang .GallinaIdent (ctx . pkgIdent )},
1316
1332
glang.StringVal {Value : glang.StringLiteral {Value : s .Name }},
1317
1333
)
1318
1334
}
@@ -1904,9 +1920,14 @@ func (ctx *Ctx) exprAddr(e ast.Expr) glang.Expr {
1904
1920
obj := ctx .info .ObjectOf (e )
1905
1921
if _ , ok := obj .(* types.Var ); ok {
1906
1922
if obj .Pkg ().Scope () == obj .Parent () {
1907
- ctx .dep .addDep ("pkg_name'" )
1923
+ pkgIdent := ""
1924
+ if obj .Pkg ().Path () == ctx .pkgPath {
1925
+ pkgIdent = ctx .pkgIdent
1926
+ } else {
1927
+ pkgIdent = obj .Pkg ().Name ()
1928
+ }
1908
1929
return glang .NewCallExpr (glang .GallinaIdent ("globals.get" ),
1909
- glang.StringVal {Value : glang .GallinaIdent ("pkg_name'" )},
1930
+ glang.StringVal {Value : glang .GallinaIdent (pkgIdent )},
1910
1931
glang.StringVal {Value : glang.StringLiteral {Value : e .Name }},
1911
1932
)
1912
1933
} else {
@@ -2827,12 +2848,6 @@ func (ctx *Ctx) decl(d ast.Decl) []glang.Decl {
2827
2848
2828
2849
func (ctx * Ctx ) initFunctions () []glang.Decl {
2829
2850
var decls = []glang.Decl {}
2830
- nameDecl := glang.ConstDecl {
2831
- Name : "pkg_name'" ,
2832
- Val : glang .GallinaString (ctx .pkgPath ),
2833
- Type : glang .GallinaIdent ("go_string" ),
2834
- }
2835
- decls = append (decls , nameDecl )
2836
2851
2837
2852
ctx .dep .setCurrentName ("initialize'" )
2838
2853
initFunc := glang.FuncDecl {Name : "initialize'" }
@@ -2882,6 +2897,33 @@ func (ctx *Ctx) initFunctions() []glang.Decl {
2882
2897
}
2883
2898
decls = append (decls , msetsDecl )
2884
2899
2900
+ var imports glang.ListExpr
2901
+ for _ , impName := range ctx .importNamesOrdered {
2902
+ imports = append (imports , glang .GallinaIdent (fmt .Sprintf ("%s" , impName )))
2903
+ }
2904
+ infoRecord := glang.RecordLiteral {
2905
+ Fields : []glang.RecordField {
2906
+ {Name : "pkg_vars" ,
2907
+ Value : glang .GallinaIdent ("vars'" )},
2908
+ {Name : "pkg_functions" ,
2909
+ Value : glang .GallinaIdent ("functions'" )},
2910
+ {Name : "pkg_msets" ,
2911
+ Value : glang .GallinaIdent ("msets'" )},
2912
+ {Name : "pkg_imported_pkgs" ,
2913
+ Value : imports },
2914
+ },
2915
+ }
2916
+
2917
+ infoInstanceDecl := glang.InstanceDecl {
2918
+ Type : glang .NewCallExpr (glang .GallinaIdent ("PkgInfo" ),
2919
+ glang .GallinaIdent (ctx .pkgIdent ),
2920
+ ),
2921
+ Global : true ,
2922
+ Body : infoRecord ,
2923
+ Name : "info'" , // no name required
2924
+ }
2925
+ decls = append (decls , infoInstanceDecl )
2926
+
2885
2927
var e glang.Expr
2886
2928
2887
2929
// add all init() function bodies
@@ -2919,7 +2961,7 @@ InitLoop:
2919
2961
e = glang .NewDoSeq (
2920
2962
glang.StoreStmt {
2921
2963
Dst : glang .NewCallExpr (glang .GallinaIdent ("globals.get" ),
2922
- glang.StringVal {Value : glang .GallinaIdent ("pkg_name'" )},
2964
+ glang.StringVal {Value : glang .GallinaIdent (ctx . pkgIdent )},
2923
2965
glang.StringVal {Value : glang.StringLiteral {Value : init .Lhs [i - 1 ].Name ()}},
2924
2966
),
2925
2967
X : glang .IdentExpr (fmt .Sprintf ("$r%d" , i - 1 )),
@@ -2988,10 +3030,7 @@ InitLoop:
2988
3030
2989
3031
e = glang .NewCallExpr (glang .GallinaIdent ("exception_do" ), e )
2990
3032
e = glang .NewCallExpr (glang .GallinaIdent ("globals.package_init" ),
2991
- glang .GallinaIdent ("pkg_name'" ),
2992
- glang .GallinaIdent ("vars'" ),
2993
- glang .GallinaIdent ("functions'" ),
2994
- glang .GallinaIdent ("msets'" ),
3033
+ glang .GallinaIdent (ctx .pkgIdent ),
2995
3034
glang.FuncLit {Args : nil , Body : e },
2996
3035
)
2997
3036
0 commit comments