123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package main
- import (
- "log"
- "io/ioutil"
- "os"
- "path/filepath"
- "regexp"
- "strings"
- sitter "github.com/smacker/go-tree-sitter"
- "github.com/smacker/go-tree-sitter/ruby"
- )
- const NUM_WORKERS = 32
- func gatherFiles(root string, ch chan string) {
- defer close(ch)
- i := 0
- err := filepath.Walk(root,
- func(path string, info os.FileInfo, err error) error {
- if err != nil {
- log.Printf("Error reading directory %s: %s\n", root, err)
- return nil
- }
- i += 1
- name := info.Name()
- if strings.HasSuffix(name, ".rb") {
- ch <- path
- }
- return nil
- })
- log.Printf("Checked %d files\n", i)
- if err != nil {
- log.Fatalf("Error reading directory %s: %s\n", root, err)
- return
- }
- }
- func findTypedLine(path string, tree *sitter.Tree, buf []byte) *string {
- r := regexp.MustCompile("# typed: (ignore|false|true|strict|strong|__STDLIB_INTERNAL)")
- root := tree.RootNode()
- for i := 0; i < int(root.ChildCount()); i++ {
- n := root.Child(i)
- if n.Type() == "comment" {
- matches := r.FindStringSubmatch(n.Content(buf))
- if matches == nil {
- continue
- }
- return &matches[1]
- }
- }
- return nil
- }
- func worker(ch chan string, finished chan int) {
- parser := sitter.NewParser()
- parser.SetLanguage(ruby.GetLanguage())
- for {
- path, more := <-ch
- if !more {
- finished <- -1
- return
- }
- buf, err := ioutil.ReadFile(path)
- if err != nil {
- log.Printf("Error reading %s: %s\n", path, err)
- continue
- }
- node := parser.Parse(nil, buf)
- sigil := findTypedLine(path, node, buf)
- if sigil == nil {
- log.Printf("File %s: missing typed sigil", path)
- } else if *sigil == "false" || *sigil == "ignore" {
- log.Printf("File %s: expected at least `true`, but got `%s`", path, *sigil)
- }
- finished <- 1
- }
- }
- func main() {
- ch := make(chan string)
- go gatherFiles(".", ch)
- finished := make(chan int)
- for i := 0; i < NUM_WORKERS; i++ {
- go worker(ch, finished)
- }
- all_files := 0
- done := 0
- for done < NUM_WORKERS {
- n := <- finished
- if n == -1 {
- done += 1
- } else {
- all_files += 1
- }
- }
- log.Printf("Parsed %d files\n", all_files)
- }
|