diff --git a/chore/llgen/llgen.go b/chore/llgen/llgen.go index fe57b993..91fc0688 100644 --- a/chore/llgen/llgen.go +++ b/chore/llgen/llgen.go @@ -36,5 +36,5 @@ func main() { outFile := dir + "out.ll" llgen.Init() - llgen.Do(inFile, outFile) + llgen.Do(llgen.PkgPath(dir), inFile, outFile) } diff --git a/go.mod b/go.mod index 03475463..d9a37864 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,9 @@ require ( github.com/goplus/gogen v1.15.2 github.com/goplus/gop v1.2.6 github.com/goplus/llvm v0.7.1-0.20240420180312-6230a4ea7a47 + github.com/goplus/mod v0.13.10 github.com/qiniu/x v1.13.10 golang.org/x/tools v0.19.0 ) -require ( - github.com/goplus/mod v0.13.10 // indirect - golang.org/x/mod v0.17.0 // indirect -) +require golang.org/x/mod v0.17.0 // indirect diff --git a/go.sum b/go.sum index 4543999d..ec78ea4a 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,6 @@ github.com/goplus/gogen v1.15.2 h1:Q6XaSx/Zi5tWnjfAziYsQI6Jv6MgODRpFtOYqNkiiqM= github.com/goplus/gogen v1.15.2/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk= github.com/goplus/gop v1.2.6 h1:kog3c5Js+8EopqmI4+CwueXsqibnBwYVt5q5N7juRVY= github.com/goplus/gop v1.2.6/go.mod h1:uREWbR1MrFaviZ4Mbx4ZCcAYDoqzO0iv1Qo6Np0Xx4E= -github.com/goplus/llvm v0.7.1-0.20240418160956-6233231cbcc9 h1:E/NBN5tDh6COcJmygdBb9RAJhE4uIHfT51VBlP3tglU= -github.com/goplus/llvm v0.7.1-0.20240418160956-6233231cbcc9/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4= github.com/goplus/llvm v0.7.1-0.20240420180312-6230a4ea7a47 h1:B3nWTLOQh4+Yqt6NryE/cVQdo/+NLiT8AtD4YaeKScg= github.com/goplus/llvm v0.7.1-0.20240420180312-6230a4ea7a47/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4= github.com/goplus/mod v0.13.10 h1:5Om6KOvo31daN7N30kWU1vC5zhsJPM+uPbcEN/FnlzE= diff --git a/internal/llgen/llgen.go b/internal/llgen/llgen.go index 23c59be4..f33a007b 100644 --- a/internal/llgen/llgen.go +++ b/internal/llgen/llgen.go @@ -25,6 +25,7 @@ import ( "github.com/goplus/gogen/packages" "github.com/goplus/llgo/cl" + "github.com/goplus/llgo/internal/mod" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa/ssautil" @@ -37,20 +38,29 @@ func Init() { cl.SetDebug(cl.DbgFlagAll) } -func Do(inFile, outFile string) { - ret := Gen(inFile, nil) +func PkgPath(dir string) string { + _, pkgPath, err := mod.Load(dir) + check(err) + return pkgPath +} + +func Do(pkgPath, inFile, outFile string) { + ret := Gen(pkgPath, inFile, nil) err := os.WriteFile(outFile, []byte(ret), 0644) check(err) } -func Gen(inFile string, src any) string { +func Gen(pkgPath, inFile string, src any) string { fset := token.NewFileSet() f, err := parser.ParseFile(fset, inFile, src, parser.ParseComments) check(err) files := []*ast.File{f} name := f.Name.Name - pkg := types.NewPackage(name, name) + if pkgPath == "" { + pkgPath = name + } + pkg := types.NewPackage(pkgPath, name) imp := packages.NewImporter(fset) ssaPkg, _, err := ssautil.BuildPackage( &types.Config{Importer: imp}, fset, pkg, files, ssa.SanityCheckFunctions) diff --git a/internal/mod/mod.go b/internal/mod/mod.go new file mode 100644 index 00000000..ccb51114 --- /dev/null +++ b/internal/mod/mod.go @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mod + +import ( + "path" + "path/filepath" + + "github.com/goplus/mod" + "github.com/goplus/mod/gopmod" +) + +// Module represents a Go module. +type Module = gopmod.Module + +// Load loads a Go module from a directory. +func Load(dir string) (ret *Module, pkgPath string, err error) { + if dir, err = filepath.Abs(dir); err != nil { + return + } + _, gomod, err := mod.FindGoMod(dir) + if err != nil { + return + } + if ret, err = gopmod.LoadFrom(gomod, ""); err != nil { + return + } + relPath, err := filepath.Rel(ret.Root(), dir) + if err != nil { + return + } + pkgPath = path.Join(ret.Path(), filepath.ToSlash(relPath)) + return +}