Skip to content

Instantly share code, notes, and snippets.

@Dentrax
Created April 27, 2020 09:29
Show Gist options
  • Save Dentrax/3801b3b1dd7ddc2e8fb08a0a15791257 to your computer and use it in GitHub Desktop.
Save Dentrax/3801b3b1dd7ddc2e8fb08a0a15791257 to your computer and use it in GitHub Desktop.
Go | Simple Linter
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"os"
"strings"
"time"
)
func main() {
var fileset = token.NewFileSet()
file, err := parser.ParseFile(fileset, "AST.go", nil, parser.ParseComments)
if err != nil {
panic(err)
}
if hasTimeImport(file) {
if isAnyNowUnixCall(file) {
fmt.Println("Linter FAIL: `Unix()` call detected!")
os.Exit(1)
}
}
fmt.Printf("Hello World! Time is: %d\n", time.Now().Unix())
}
func hasTimeImport(file *ast.File) bool {
have := false
f := func(node ast.Node) bool {
is, ok := node.(*ast.ImportSpec)
if !ok {
return true
}
if is.Path == nil {
return true
}
if is.Path.Value == "\"time\"" {
have = true
return false
}
return true
}
ast.Inspect(file, f)
return have
}
func isAnyNowUnixCall(file *ast.File) bool {
used := false
f := func(node ast.Node) bool {
se, ok := node.(*ast.SelectorExpr)
if !ok {
return true
}
if ce, ok := se.X.(*ast.CallExpr); !ok {
if ce == nil || ce.Fun == nil {
return false
}
if se2, ok := ce.Fun.(*ast.SelectorExpr); !ok {
if i, ok := se2.X.(*ast.Ident); !ok {
if i.Name == "time" {
return true
}
}
if se2.Sel.Name == "Now" {
return true
}
}
if se.Sel.Name == "Unix" {
return true
}
}
value, _ := getNodeValue(node)
if strings.Contains(value, "time.Now().Unix") {
used = true
return false
}
return true
}
ast.Inspect(file, f)
return used
}
func getNodeValue(node ast.Node) (string, error) {
buffer := new(bytes.Buffer)
if err := format.Node(buffer, token.NewFileSet(), node); err != nil {
return "", err
}
return buffer.String(), nil
}
func printNode(node ast.Node) {
value, _ := getNodeValue(node)
fmt.Printf("Node: \"%s\"\n\n", value)
ast.Fprint(os.Stdout, nil, node, nil)
fmt.Println("===============")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment