Browse Source

basic finding of typed sigils

Getty Ritter 2 years ago
commit
780095fc64
3 changed files with 117 additions and 0 deletions
  1. 104 0
      cmd/blarto/main.go
  2. 5 0
      go.mod
  3. 8 0
      go.sum

+ 104 - 0
cmd/blarto/main.go

@@ -0,0 +1,104 @@
+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)
+}

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module github.com/aisamanra/blarto
+
+go 1.16
+
+require github.com/smacker/go-tree-sitter v0.0.0-20211116060328-db7fde9b5e82 // indirect

+ 8 - 0
go.sum

@@ -0,0 +1,8 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/smacker/go-tree-sitter v0.0.0-20211116060328-db7fde9b5e82 h1:e17/Q2AF05ZITfj9y/dqOU+ceEXOeYzKGGuIXNsDlxM=
+github.com/smacker/go-tree-sitter v0.0.0-20211116060328-db7fde9b5e82/go.mod h1:EiUuVMUfLQj8Sul+S8aKWJwQy7FRYnJCO2EWzf8F5hk=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=