package import_resolve import ( "fmt" "path/filepath" "github.com/marzeq/quokka/parser" "github.com/marzeq/quokka/shared" "github.com/marzeq/quokka/tokeniser" ) func ProcessImports(root *parser.RootNode, loaded map[string]*parser.RootNode, recStack map[string]bool) (*parser.RootNode, error) { fmt.Print() filePath := root.Loc.FilePath if recStack[filePath] { return nil, shared.NewError(root.Loc, "import cycle detected for file '%s'", filePath) } if merged, ok := loaded[filePath]; ok { return merged, nil } recStack[filePath] = true merged := &parser.RootNode{ Loc: root.Loc, Body: []parser.Node{}, } for _, n := range root.Body { switch node := n.(type) { case *parser.ImportNode: for _, module := range(node.Modules) { resolvedPath := filepath.Join(filepath.Dir(filePath), module) t, err := tokeniser.NewTokeniserFromFile(resolvedPath) if err != nil { switch err.(type) { case shared.Error: return nil, err default: return nil, shared.NewError(node.Loc, "import failed: %v", err) } } toks, err := t.Tokenise() if err != nil { return nil, err } p := parser.NewParser(toks) ast, err := p.Parse() if err != nil { return nil, err } importedMerged, err := ProcessImports(ast, loaded, recStack) if err != nil { return nil, err } merged.Body = append(merged.Body, importedMerged.Body...) } } } for _, node := range root.Body { switch node.(type) { case *parser.ImportNode: continue default: merged.Body = append(merged.Body, node) } } loaded[filePath] = merged delete(recStack, filePath) return merged, nil }