q/src/build/Scan.go
2023-10-31 11:57:37 +01:00

69 lines
1.2 KiB
Go

package build
import (
"os"
"path/filepath"
"strings"
"sync"
"git.akyoto.dev/cli/q/src/directory"
"git.akyoto.dev/cli/q/src/log"
"git.akyoto.dev/cli/q/src/token"
)
// Scan scans the directory.
func Scan(path string) (<-chan *Function, <-chan error) {
functions := make(chan *Function, 16)
errors := make(chan error)
go func() {
scanDirectory(path, functions, errors)
close(functions)
close(errors)
}()
return functions, errors
}
// scanDirectory scans the directory without channel allocations.
func scanDirectory(path string, functions chan<- *Function, errors chan<- error) {
wg := sync.WaitGroup{}
directory.Walk(path, func(name string) {
if !strings.HasSuffix(name, ".q") {
return
}
fullPath := filepath.Join(path, name)
wg.Add(1)
go func() {
defer wg.Done()
err := scanFile(fullPath, functions)
if err != nil {
errors <- err
}
}()
})
wg.Wait()
}
// scanFile scans a single file.
func scanFile(path string, functions chan<- *Function) error {
contents, err := os.ReadFile(path)
if err != nil {
return err
}
tokens := token.Tokenize(contents)
for _, t := range tokens {
log.Info.Println(t.Kind, t.Position, strings.TrimSpace(t.String()))
}
return nil
}