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 9d2c85e2..b0dd4215 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,12 @@ require ( github.com/goplus/gogen v1.15.2 github.com/goplus/gop v1.2.6 github.com/goplus/llvm v0.7.1 + github.com/goplus/mod v0.13.10 github.com/qiniu/x v1.13.10 golang.org/x/tools v0.20.0 ) require ( - github.com/goplus/mod v0.13.10 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect ) 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 +}