Skip to content

Commit

Permalink
feat(transpile): allow extra root dirs
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <norman@samourai.coop>
  • Loading branch information
n0izn0iz committed Jun 29, 2024
1 parent 10a6f7e commit 9f57248
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 9 deletions.
10 changes: 9 additions & 1 deletion gnovm/cmd/gno/transpile.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
type transpileCfg struct {
verbose bool
rootDir string
extraDirs string
skipImports bool
gobuild bool
goBinary string
Expand Down Expand Up @@ -94,6 +95,13 @@ func (c *transpileCfg) RegisterFlags(fs *flag.FlagSet) {
"clone location of github.com/gnolang/gno (gno tries to guess it)",
)

fs.StringVar(
&c.extraDirs,
"extra-dirs",
"",
"extra directories to look for packages in",
)

fs.BoolVar(
&c.skipImports,
"skip-imports",
Expand Down Expand Up @@ -251,7 +259,7 @@ func transpileFile(srcPath string, opts *transpileOptions) error {
targetFilename, tags := transpiler.TranspiledFilenameAndTags(srcPath)

// preprocess.
transpileRes, err := transpiler.Transpile(string(source), tags, srcPath)
transpileRes, err := transpiler.Transpile(string(source), tags, srcPath, strings.Split(opts.cfg.extraDirs, ","))
if err != nil {
return fmt.Errorf("transpile: %w", err)
}
Expand Down
46 changes: 43 additions & 3 deletions gnovm/pkg/transpiler/transpiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import (
"go/parser"
goscanner "go/scanner"
"go/token"
"io/fs"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -75,7 +77,7 @@ func TranspiledFilenameAndTags(gnoFilePath string) (targetFilename, tags string)
// Transpile performs transpilation on the given source code. tags can be used
// to specify build tags; and filename helps generate useful error messages and
// discriminate between test and normal source files.
func Transpile(source, tags, filename string) (*Result, error) {
func Transpile(source, tags, filename string, extraDirs []string) (*Result, error) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, source,
// SkipObjectResolution -- unused here.
Expand All @@ -87,7 +89,8 @@ func Transpile(source, tags, filename string) (*Result, error) {

isTestFile := strings.HasSuffix(filename, "_test.gno") || strings.HasSuffix(filename, "_filetest.gno")
ctx := &transpileCtx{
rootDir: gnoenv.RootDir(),
rootDir: gnoenv.RootDir(),
extraDirs: extraDirs,
}
stdlibPrefix := filepath.Join(ctx.rootDir, "gnovm", "stdlibs")
if isTestFile {
Expand Down Expand Up @@ -142,6 +145,9 @@ type transpileCtx struct {
// If rootDir is given, we will check that the directory of the import path
// exists (using rootDir/packageDirLocation()).
rootDir string
// If extraDirs is given, we will check that the directory of the import path
// exists (using rootDir/packageDirLocation()).
extraDirs []string
// This should be set if we're working with a file from a standard library.
// This allows us to easily check if a function has a native binding, and as
// such modify its call expressions appropriately.
Expand All @@ -165,7 +171,41 @@ func (ctx *transpileCtx) transformFile(fset *token.FileSet, f *ast.File) (*ast.F
continue
}

if ctx.rootDir != "" {
foundInExtra := false
for _, extraDir := range ctx.extraDirs {
// TODO: find packages once
modFiles := []string{}
if err := filepath.Walk(extraDir, func(path string, info fs.FileInfo, err error) error {
if !strings.HasSuffix(path, "/gno.mod") {
return nil
}
modFiles = append(modFiles, path)
return nil
}); err != nil {
return nil, err
}
packageNames := []string{}
for _, modFile := range modFiles {
modData, err := os.ReadFile(modFile)
if err != nil {
continue
}
re := regexp.MustCompile(`^module (.+)`)
res := re.FindSubmatch(modData)
if len(res) != 2 {
continue
}
packageNames = append(packageNames, string(res[1]))
}

for _, pn := range packageNames {
if pn == importPath {
foundInExtra = true
}
}
}

if !foundInExtra && ctx.rootDir != "" {
dirPath := filepath.Join(ctx.rootDir, PackageDirLocation(importPath))
if _, err := os.Stat(dirPath); err != nil {
if !os.IsNotExist(err) {
Expand Down
2 changes: 1 addition & 1 deletion gnovm/pkg/transpiler/transpiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ func testfunc() {
if filename == "" {
filename = "foo.gno"
}
res, err := Transpile(source, c.tags, filename)
res, err := Transpile(source, c.tags, filename, nil)

if c.expectedError != "" {
require.EqualError(t, err, c.expectedError)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/onsi/gomega v1.27.10 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/zondax/hid v0.9.2 // indirect
Expand Down
6 changes: 2 additions & 4 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9f57248

Please sign in to comment.