Skip to content

Instantly share code, notes, and snippets.

@inancgumus
Last active December 2, 2017 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inancgumus/aa43822e9e83e696bf7c0021a9579194 to your computer and use it in GitHub Desktop.
Save inancgumus/aa43822e9e83e696bf7c0021a9579194 to your computer and use it in GitHub Desktop.
Interface scanner for Go
/*
non-refactored, hacky tool to extract interfaces.
adopted from https://github.com/campoy/justforfunc/tree/master/24-ast
*/
package main
import (
"fmt"
"go/scanner"
"go/token"
"io/ioutil"
"log"
"os"
"sort"
"unicode"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "usage:\n\t%s [files]\n", os.Args[0])
os.Exit(1)
}
counts := make(map[string]int)
fs := token.NewFileSet()
for _, arg := range os.Args[1:] {
b, err := ioutil.ReadFile(arg)
if err != nil {
log.Fatal(err)
}
f := fs.AddFile(arg, fs.Base(), len(b))
var s scanner.Scanner
s.Init(f, b, nil, scanner.ScanComments)
pkg := ""
for {
_, tok, lit := s.Scan()
if tok == token.EOF {
break
}
if tok == token.PACKAGE {
_, tok, lit = s.Scan()
pkg = lit
}
if tok == token.TYPE {
_, tok, lit = s.Scan()
if lit == "" || !unicode.IsUpper(rune(lit[0])) {
break
}
name := lit
if tok == token.IDENT {
_, tok, lit = s.Scan()
if tok == token.INTERFACE {
counts[fmt.Sprintf("%s.%s", pkg, name)]++
}
}
}
}
}
type pair struct {
s string
n int
}
pairs := make([]pair, 0, len(counts))
for s, n := range counts {
pairs = append(pairs, pair{s, n})
}
sort.Slice(pairs, func(i, j int) bool { return pairs[i].s < pairs[j].s })
for i := 0; i < len(pairs); i++ {
fmt.Printf("%3d >> %s\n", pairs[i].n, pairs[i].s)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment