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
}