From 0cc35d2ab074eedfa50a42bc8c956a509ea4f464 Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Fri, 28 Oct 2022 12:58:12 -0500 Subject: [PATCH 1/3] refactor: Create shorten package --- Makefile | 8 +- generate/graph.go | 22 +- graph_generated.go | 542 ----------------- main.go | 8 +- annotation.go => shorten/annotation.go | 46 +- .../annotation_test.go | 20 +- graph.go => shorten/graph.go | 34 +- shorten/graph_generated.go | 543 ++++++++++++++++++ graph_test.go => shorten/graph_test.go | 4 +- shortener.go => shorten/shortener.go | 44 +- .../shortener_test.go | 8 +- tags.go => shorten/tags.go | 10 +- tags_test.go => shorten/tags_test.go | 14 +- 13 files changed, 653 insertions(+), 650 deletions(-) delete mode 100644 graph_generated.go rename annotation.go => shorten/annotation.go (56%) rename annotation_test.go => shorten/annotation_test.go (51%) rename graph.go => shorten/graph.go (73%) create mode 100644 shorten/graph_generated.go rename graph_test.go => shorten/graph_test.go (96%) rename shortener.go => shorten/shortener.go (94%) rename shortener_test.go => shorten/shortener_test.go (95%) rename tags.go => shorten/tags.go (95%) rename tags_test.go => shorten/tags_test.go (58%) diff --git a/Makefile b/Makefile index c92f4fa..41b7997 100644 --- a/Makefile +++ b/Makefile @@ -13,16 +13,16 @@ build: .PHONY: test test: vet - go test -count=1 -cover -coverprofile=coverage.out . + go test -count=1 -cover -coverprofile=coverage.out ./... go tool cover -func=coverage.out .PHONY: vet vet: - go vet . + go vet ./... .PHONY: regenerate regenerate: - REGENERATE_TEST_OUTPUTS=true go test . + REGENERATE_TEST_OUTPUTS=true go test ./... .PHONY: graph graph: @@ -34,4 +34,4 @@ vendor: .PHONY: format format: - goimports -w ./*go + goimports -w ./*go ./pkg/**/*go diff --git a/generate/graph.go b/generate/graph.go index 2a4d61a..8314660 100644 --- a/generate/graph.go +++ b/generate/graph.go @@ -15,7 +15,7 @@ const ( // graph node. The latter can then be used to generate a dot file for debugging // purposes. func genNodeToGraphNode() error { - f := jen.NewFile("main") + f := jen.NewFile("shorten") f.HeaderComment("Generated by generate/main.go. DO NOT EDIT.") // Sort the keys in the dst map so that output is in stable order @@ -27,16 +27,16 @@ func genNodeToGraphNode() error { sort.Strings(dataKeys) - f.Func().Id("NodeToGraphNode").Params( + f.Func().Id("nodeToGraphNode").Params( jen.Id("node").Qual(dstPath, "Node"), - ).Op("*").Id("GraphNode").BlockFunc( + ).Op("*").Id("graphNode").BlockFunc( func(g *jen.Group) { - g.Id("gNode").Op(":=").Op("&").Id("GraphNode").Values( + g.Id("gNode").Op(":=").Op("&").Id("graphNode").Values( jen.Id("Node").Op(":").Id("node"), - jen.Id("Edges").Op(":").Index().Op("*").Id("GraphEdge").Values(), + jen.Id("Edges").Op(":").Index().Op("*").Id("graphEdge").Values(), ) - g.Var().Id("child").Op("*").Id("GraphNode") + g.Var().Id("child").Op("*").Id("graphNode") g.Switch(jen.Id("n").Op(":=").Id("node").Assert(jen.Id("type"))).BlockFunc( func(g *jen.Group) { @@ -51,13 +51,13 @@ func genNodeToGraphNode() error { switch p := part.(type) { case data.Node: g.If(p.Field.Get("n").Op("!=").Nil()).Block( - jen.Id("child").Op("=").Id("NodeToGraphNode"). + jen.Id("child").Op("=").Id("nodeToGraphNode"). Call( p.Field.Get("n"), ), jen.Id("gNode").Dot("Edges").Op("=").Append( jen.Id("gNode").Dot("Edges"), - jen.Op("&").Id("GraphEdge").Values( + jen.Op("&").Id("graphEdge").Values( jen.Id("Dest").Op(":").Id("child"), jen.Id("Relationship").Op(":").Lit(p.Name), ), @@ -69,13 +69,13 @@ func genNodeToGraphNode() error { jen.List(jen.Id("_"), jen.Id("obj")). Op(":=").Range().Add(p.Field.Get("n")), ).Block( - jen.Id("child").Op("=").Id("NodeToGraphNode"). + jen.Id("child").Op("=").Id("nodeToGraphNode"). Call( jen.Id("obj"), ), jen.Id("gNode").Dot("Edges").Op("=").Append( jen.Id("gNode").Dot("Edges"), - jen.Op("&").Id("GraphEdge").Values( + jen.Op("&").Id("graphEdge").Values( jen.Id("Dest").Op(":").Id("child"), jen.Id("Relationship").Op(":").Lit(p.Name), ), @@ -103,7 +103,7 @@ func genNodeToGraphNode() error { }, ) - f.Save("../graph_generated.go") + f.Save("../shorten/graph_generated.go") return nil } diff --git a/graph_generated.go b/graph_generated.go deleted file mode 100644 index 007f22d..0000000 --- a/graph_generated.go +++ /dev/null @@ -1,542 +0,0 @@ -// Generated by generate/main.go. DO NOT EDIT. - -package main - -import ( - dst "github.com/dave/dst" - "log" -) - -func NodeToGraphNode(node dst.Node) *GraphNode { - gNode := &GraphNode{Node: node, Edges: []*GraphEdge{}} - var child *GraphNode - switch n := node.(type) { - case *dst.ArrayType: - gNode.Type = "ArrayType" - if n.Len != nil { - child = NodeToGraphNode(n.Len) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Len"}) - } - if n.Elt != nil { - child = NodeToGraphNode(n.Elt) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Elt"}) - } - case *dst.AssignStmt: - gNode.Type = "AssignStmt" - if n.Lhs != nil { - for _, obj := range n.Lhs { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Lhs"}) - } - } - if n.Rhs != nil { - for _, obj := range n.Rhs { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Rhs"}) - } - } - case *dst.BadDecl: - gNode.Type = "BadDecl" - case *dst.BadExpr: - gNode.Type = "BadExpr" - case *dst.BadStmt: - gNode.Type = "BadStmt" - case *dst.BasicLit: - gNode.Type = "BasicLit" - gNode.Value = n.Value - case *dst.BinaryExpr: - gNode.Type = "BinaryExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Y != nil { - child = NodeToGraphNode(n.Y) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Y"}) - } - case *dst.BlockStmt: - gNode.Type = "BlockStmt" - if n.List != nil { - for _, obj := range n.List { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "List"}) - } - } - case *dst.BranchStmt: - gNode.Type = "BranchStmt" - if n.Label != nil { - child = NodeToGraphNode(n.Label) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Label"}) - } - case *dst.CallExpr: - gNode.Type = "CallExpr" - if n.Fun != nil { - child = NodeToGraphNode(n.Fun) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Fun"}) - } - if n.Args != nil { - for _, obj := range n.Args { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Args"}) - } - } - case *dst.CaseClause: - gNode.Type = "CaseClause" - if n.List != nil { - for _, obj := range n.List { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "List"}) - } - } - if n.Body != nil { - for _, obj := range n.Body { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - } - case *dst.ChanType: - gNode.Type = "ChanType" - if n.Value != nil { - child = NodeToGraphNode(n.Value) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Value"}) - } - case *dst.CommClause: - gNode.Type = "CommClause" - if n.Comm != nil { - child = NodeToGraphNode(n.Comm) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Comm"}) - } - if n.Body != nil { - for _, obj := range n.Body { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - } - case *dst.CompositeLit: - gNode.Type = "CompositeLit" - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - if n.Elts != nil { - for _, obj := range n.Elts { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Elts"}) - } - } - case *dst.DeclStmt: - gNode.Type = "DeclStmt" - if n.Decl != nil { - child = NodeToGraphNode(n.Decl) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Decl"}) - } - case *dst.DeferStmt: - gNode.Type = "DeferStmt" - if n.Call != nil { - child = NodeToGraphNode(n.Call) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Call"}) - } - case *dst.Ellipsis: - gNode.Type = "Ellipsis" - if n.Elt != nil { - child = NodeToGraphNode(n.Elt) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Elt"}) - } - case *dst.EmptyStmt: - gNode.Type = "EmptyStmt" - case *dst.ExprStmt: - gNode.Type = "ExprStmt" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - case *dst.Field: - gNode.Type = "Field" - if n.Names != nil { - for _, obj := range n.Names { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Names"}) - } - } - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - if n.Tag != nil { - child = NodeToGraphNode(n.Tag) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Tag"}) - } - case *dst.FieldList: - gNode.Type = "FieldList" - if n.List != nil { - for _, obj := range n.List { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "List"}) - } - } - case *dst.File: - gNode.Type = "File" - if n.Name != nil { - child = NodeToGraphNode(n.Name) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Name"}) - } - if n.Decls != nil { - for _, obj := range n.Decls { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Decls"}) - } - } - if n.Imports != nil { - for _, obj := range n.Imports { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Imports"}) - } - } - case *dst.ForStmt: - gNode.Type = "ForStmt" - if n.Init != nil { - child = NodeToGraphNode(n.Init) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Init"}) - } - if n.Cond != nil { - child = NodeToGraphNode(n.Cond) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Cond"}) - } - if n.Post != nil { - child = NodeToGraphNode(n.Post) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Post"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.FuncDecl: - gNode.Type = "FuncDecl" - if n.Recv != nil { - child = NodeToGraphNode(n.Recv) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Recv"}) - } - if n.Name != nil { - child = NodeToGraphNode(n.Name) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Name"}) - } - if n.Type.TypeParams != nil { - child = NodeToGraphNode(n.Type.TypeParams) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "TypeParams"}) - } - if n.Type.Params != nil { - child = NodeToGraphNode(n.Type.Params) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Params"}) - } - if n.Type.Results != nil { - child = NodeToGraphNode(n.Type.Results) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Results"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.FuncLit: - gNode.Type = "FuncLit" - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.FuncType: - gNode.Type = "FuncType" - if n.TypeParams != nil { - child = NodeToGraphNode(n.TypeParams) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "TypeParams"}) - } - if n.Params != nil { - child = NodeToGraphNode(n.Params) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Params"}) - } - if n.Results != nil { - child = NodeToGraphNode(n.Results) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Results"}) - } - case *dst.GenDecl: - gNode.Type = "GenDecl" - if n.Specs != nil { - for _, obj := range n.Specs { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Specs"}) - } - } - case *dst.GoStmt: - gNode.Type = "GoStmt" - if n.Call != nil { - child = NodeToGraphNode(n.Call) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Call"}) - } - case *dst.Ident: - gNode.Type = "Ident" - gNode.Value = n.Name - case *dst.IfStmt: - gNode.Type = "IfStmt" - if n.Init != nil { - child = NodeToGraphNode(n.Init) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Init"}) - } - if n.Cond != nil { - child = NodeToGraphNode(n.Cond) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Cond"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - if n.Else != nil { - child = NodeToGraphNode(n.Else) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Else"}) - } - case *dst.ImportSpec: - gNode.Type = "ImportSpec" - if n.Name != nil { - child = NodeToGraphNode(n.Name) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Name"}) - } - if n.Path != nil { - child = NodeToGraphNode(n.Path) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Path"}) - } - case *dst.IncDecStmt: - gNode.Type = "IncDecStmt" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - case *dst.IndexExpr: - gNode.Type = "IndexExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Index != nil { - child = NodeToGraphNode(n.Index) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Index"}) - } - case *dst.IndexListExpr: - gNode.Type = "IndexListExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Indices != nil { - for _, obj := range n.Indices { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Indices"}) - } - } - case *dst.InterfaceType: - gNode.Type = "InterfaceType" - if n.Methods != nil { - child = NodeToGraphNode(n.Methods) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Methods"}) - } - case *dst.KeyValueExpr: - gNode.Type = "KeyValueExpr" - if n.Key != nil { - child = NodeToGraphNode(n.Key) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Key"}) - } - if n.Value != nil { - child = NodeToGraphNode(n.Value) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Value"}) - } - case *dst.LabeledStmt: - gNode.Type = "LabeledStmt" - if n.Label != nil { - child = NodeToGraphNode(n.Label) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Label"}) - } - if n.Stmt != nil { - child = NodeToGraphNode(n.Stmt) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Stmt"}) - } - case *dst.MapType: - gNode.Type = "MapType" - if n.Key != nil { - child = NodeToGraphNode(n.Key) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Key"}) - } - if n.Value != nil { - child = NodeToGraphNode(n.Value) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Value"}) - } - case *dst.Package: - gNode.Type = "Package" - case *dst.ParenExpr: - gNode.Type = "ParenExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - case *dst.RangeStmt: - gNode.Type = "RangeStmt" - if n.Key != nil { - child = NodeToGraphNode(n.Key) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Key"}) - } - if n.Value != nil { - child = NodeToGraphNode(n.Value) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Value"}) - } - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.ReturnStmt: - gNode.Type = "ReturnStmt" - if n.Results != nil { - for _, obj := range n.Results { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Results"}) - } - } - case *dst.SelectStmt: - gNode.Type = "SelectStmt" - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.SelectorExpr: - gNode.Type = "SelectorExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Sel != nil { - child = NodeToGraphNode(n.Sel) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Sel"}) - } - case *dst.SendStmt: - gNode.Type = "SendStmt" - if n.Chan != nil { - child = NodeToGraphNode(n.Chan) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Chan"}) - } - if n.Value != nil { - child = NodeToGraphNode(n.Value) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Value"}) - } - case *dst.SliceExpr: - gNode.Type = "SliceExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Low != nil { - child = NodeToGraphNode(n.Low) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Low"}) - } - if n.High != nil { - child = NodeToGraphNode(n.High) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "High"}) - } - if n.Max != nil { - child = NodeToGraphNode(n.Max) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Max"}) - } - case *dst.StarExpr: - gNode.Type = "StarExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - case *dst.StructType: - gNode.Type = "StructType" - if n.Fields != nil { - child = NodeToGraphNode(n.Fields) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Fields"}) - } - case *dst.SwitchStmt: - gNode.Type = "SwitchStmt" - if n.Init != nil { - child = NodeToGraphNode(n.Init) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Init"}) - } - if n.Tag != nil { - child = NodeToGraphNode(n.Tag) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Tag"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.TypeAssertExpr: - gNode.Type = "TypeAssertExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - case *dst.TypeSpec: - gNode.Type = "TypeSpec" - if n.Name != nil { - child = NodeToGraphNode(n.Name) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Name"}) - } - if n.TypeParams != nil { - child = NodeToGraphNode(n.TypeParams) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "TypeParams"}) - } - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - case *dst.TypeSwitchStmt: - gNode.Type = "TypeSwitchStmt" - if n.Init != nil { - child = NodeToGraphNode(n.Init) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Init"}) - } - if n.Assign != nil { - child = NodeToGraphNode(n.Assign) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Assign"}) - } - if n.Body != nil { - child = NodeToGraphNode(n.Body) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Body"}) - } - case *dst.UnaryExpr: - gNode.Type = "UnaryExpr" - if n.X != nil { - child = NodeToGraphNode(n.X) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "X"}) - } - case *dst.ValueSpec: - gNode.Type = "ValueSpec" - if n.Names != nil { - for _, obj := range n.Names { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Names"}) - } - } - if n.Type != nil { - child = NodeToGraphNode(n.Type) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Type"}) - } - if n.Values != nil { - for _, obj := range n.Values { - child = NodeToGraphNode(obj) - gNode.Edges = append(gNode.Edges, &GraphEdge{Dest: child, Relationship: "Values"}) - } - } - default: - log.Println("Unrecognized type") - } - return gNode -} diff --git a/main.go b/main.go index a20446c..f7e93f8 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,8 @@ import ( "runtime/pprof" "strings" + "github.com/segmentio/golines/shorten" + log "github.com/sirupsen/logrus" prefixed "github.com/x-cray/logrus-prefixed-formatter" kingpin "gopkg.in/alecthomas/kingpin.v2" @@ -113,7 +115,7 @@ func main() { } func run() error { - config := ShortenerConfig{ + config := shorten.Config{ MaxLen: *maxLen, TabLen: *tabLen, KeepAnnotations: *keepAnnotations, @@ -124,7 +126,7 @@ func run() error { BaseFormatterCmd: *baseFormatterCmd, ChainSplitDots: *chainSplitDots, } - shortener := NewShortener(config) + shortener := shorten.New(config) if len(*paths) == 0 { // Read input from stdin @@ -203,7 +205,7 @@ func run() error { // processFile uses the provided Shortener instance to shorten the lines // in a file. It returns the original contents (useful for debugging), the // shortened version, and an error. -func processFile(shortener *Shortener, path string) ([]byte, []byte, error) { +func processFile(shortener *shorten.Shortener, path string) ([]byte, []byte, error) { _, fileName := filepath.Split(path) if *ignoreGenerated && strings.HasPrefix(fileName, "generated_") { return nil, nil, nil diff --git a/annotation.go b/shorten/annotation.go similarity index 56% rename from annotation.go rename to shorten/annotation.go index 0790a30..99e54cc 100644 --- a/annotation.go +++ b/shorten/annotation.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "fmt" @@ -10,8 +10,8 @@ import ( const annotationPrefix = "// __golines:shorten:" -// CreateAnnotation generates the text of a comment that will annotate long lines. -func CreateAnnotation(length int) string { +// createAnnotation generates the text of a comment that will annotate long lines. +func createAnnotation(length int) string { return fmt.Sprintf( "%s%d", annotationPrefix, @@ -19,34 +19,34 @@ func CreateAnnotation(length int) string { ) } -// IsAnnotation determines whether the given line is an annotation created with CreateAnnotation. -func IsAnnotation(line string) bool { +// isAnnotation determines whether the given line is an annotation created with createAnnotation. +func isAnnotation(line string) bool { return strings.HasPrefix( strings.Trim(line, " \t"), annotationPrefix, ) } -// HasAnnotation determines whether the given AST node has a line length annotation on it. -func HasAnnotation(node dst.Node) bool { +// hasAnnotation determines whether the given AST node has a line length annotation on it. +func hasAnnotation(node dst.Node) bool { startDecorations := node.Decorations().Start.All() return len(startDecorations) > 0 && - IsAnnotation(startDecorations[len(startDecorations)-1]) + isAnnotation(startDecorations[len(startDecorations)-1]) } -// HasTailAnnotation determines whether the given AST node has a line length annotation at its +// hasTailAnnotation determines whether the given AST node has a line length annotation at its // end. This is needed to catch long function declarations with inline interface definitions. -func HasTailAnnotation(node dst.Node) bool { +func hasTailAnnotation(node dst.Node) bool { endDecorations := node.Decorations().End.All() return len(endDecorations) > 0 && - IsAnnotation(endDecorations[len(endDecorations)-1]) + isAnnotation(endDecorations[len(endDecorations)-1]) } -// HasAnnotationRecursive determines whether the given node or one of its children has a +// hasAnnotationRecursive determines whether the given node or one of its children has a // golines annotation on it. It's currently implemented for function declarations, fields, // call expressions, and selector expressions only. -func HasAnnotationRecursive(node dst.Node) bool { - if HasAnnotation(node) { +func hasAnnotationRecursive(node dst.Node) bool { + if hasAnnotation(node) { return true } @@ -54,28 +54,28 @@ func HasAnnotationRecursive(node dst.Node) bool { case *dst.FuncDecl: if n.Type != nil && n.Type.Params != nil { for _, item := range n.Type.Params.List { - if HasAnnotationRecursive(item) { + if hasAnnotationRecursive(item) { return true } } } case *dst.Field: - return HasTailAnnotation(n) || HasAnnotationRecursive(n.Type) + return hasTailAnnotation(n) || hasAnnotationRecursive(n.Type) case *dst.SelectorExpr: - return HasAnnotation(n.Sel) || HasAnnotation(n.X) + return hasAnnotation(n.Sel) || hasAnnotation(n.X) case *dst.CallExpr: - if HasAnnotationRecursive(n.Fun) { + if hasAnnotationRecursive(n.Fun) { return true } for _, arg := range n.Args { - if HasAnnotation(arg) { + if hasAnnotation(arg) { return true } } case *dst.InterfaceType: for _, field := range n.Methods.List { - if HasAnnotationRecursive(field) { + if hasAnnotationRecursive(field) { return true } } @@ -84,10 +84,10 @@ func HasAnnotationRecursive(node dst.Node) bool { return false } -// ParseAnnotation returns the line length encoded in a golines annotation. If none is found, +// parseAnnotation returns the line length encoded in a golines annotation. If none is found, // it returns -1. -func ParseAnnotation(line string) int { - if IsAnnotation(line) { +func parseAnnotation(line string) int { + if isAnnotation(line) { components := strings.SplitN(line, ":", 3) val, err := strconv.Atoi(components[2]) if err != nil { diff --git a/annotation_test.go b/shorten/annotation_test.go similarity index 51% rename from annotation_test.go rename to shorten/annotation_test.go index 330a65d..32b8511 100644 --- a/annotation_test.go +++ b/shorten/annotation_test.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "testing" @@ -8,12 +8,12 @@ import ( ) func TestAnnotationStrings(t *testing.T) { - assert.Equal(t, "// __golines:shorten:5", CreateAnnotation(5)) - assert.Equal(t, 5, ParseAnnotation("// __golines:shorten:5")) - assert.Equal(t, -1, ParseAnnotation("// __golines:shorten:not_a_number")) - assert.Equal(t, -1, ParseAnnotation("// not an annotation")) - assert.True(t, IsAnnotation("// __golines:shorten:5")) - assert.False(t, IsAnnotation("// not an annotation")) + assert.Equal(t, "// __golines:shorten:5", createAnnotation(5)) + assert.Equal(t, 5, parseAnnotation("// __golines:shorten:5")) + assert.Equal(t, -1, parseAnnotation("// __golines:shorten:not_a_number")) + assert.Equal(t, -1, parseAnnotation("// not an annotation")) + assert.True(t, isAnnotation("// __golines:shorten:5")) + assert.False(t, isAnnotation("// not an annotation")) } func TestHasAnnotation(t *testing.T) { @@ -23,12 +23,12 @@ func TestHasAnnotation(t *testing.T) { NodeDecs: dst.NodeDecs{ Start: []string{ "// not an annotation", - CreateAnnotation(55), + createAnnotation(55), }, }, }, } - assert.True(t, HasAnnotation(node1)) + assert.True(t, hasAnnotation(node1)) node2 := &dst.Ident{ Name: "x", @@ -40,5 +40,5 @@ func TestHasAnnotation(t *testing.T) { }, }, } - assert.False(t, HasAnnotation(node2)) + assert.False(t, hasAnnotation(node2)) } diff --git a/graph.go b/shorten/graph.go similarity index 73% rename from graph.go rename to shorten/graph.go index 0e06cbe..a262526 100644 --- a/graph.go +++ b/shorten/graph.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "fmt" @@ -9,33 +9,33 @@ import ( "github.com/dave/dst" ) -// GraphNode is a representation of a node in the AST graph. -type GraphNode struct { +// graphNode is a representation of a node in the AST graph. +type graphNode struct { Type string Value string Node dst.Node - Edges []*GraphEdge + Edges []*graphEdge // Used for keeping track of node position during rendering level int seq int } -func (n *GraphNode) id() string { +func (n *graphNode) id() string { return fmt.Sprintf("%s_%d_%d", n.Type, n.level, n.seq) } -// GraphEdge is a representation of an edge in the AST graph. -type GraphEdge struct { - Dest *GraphNode +// graphEdge is a representation of an edge in the AST graph. +type graphEdge struct { + Dest *graphNode Relationship string } -// CreateDot creates a dot representation of the graph associated with a dst node. -func CreateDot(node dst.Node, out io.Writer) error { - root := NodeToGraphNode(node) +// createDot creates a dot representation of the graph associated with a dst node. +func createDot(node dst.Node, out io.Writer) error { + root := nodeToGraphNode(node) - dotGraph, err := WalkGraph(root) + dotGraph, err := walkGraph(root) if err != nil { return err } @@ -44,11 +44,11 @@ func CreateDot(node dst.Node, out io.Writer) error { return err } -// WalkGraph walks the graph starting at the argument root and returns +// walkGraph walks the graph starting at the argument root and returns // a graphviz (dot) representation. -func WalkGraph(root *GraphNode) (string, error) { - toProcess := []*GraphNode{root} - processed := []*GraphNode{} +func walkGraph(root *graphNode) (string, error) { + toProcess := []*graphNode{root} + processed := []*graphNode{} outLines := []string{"digraph {"} var currLevel int @@ -84,7 +84,7 @@ func WalkGraph(root *GraphNode) (string, error) { var nodeLabel string var nodeFormat string - if HasAnnotation(node.Node) { + if hasAnnotation(node.Node) { nodeFormat = ",penwidth=3.0" } diff --git a/shorten/graph_generated.go b/shorten/graph_generated.go new file mode 100644 index 0000000..f6a33d6 --- /dev/null +++ b/shorten/graph_generated.go @@ -0,0 +1,543 @@ +// Generated by generate/main.go. DO NOT EDIT. + +package shorten + +import ( + "log" + + dst "github.com/dave/dst" +) + +func nodeToGraphNode(node dst.Node) *graphNode { + gNode := &graphNode{Node: node, Edges: []*graphEdge{}} + var child *graphNode + switch n := node.(type) { + case *dst.ArrayType: + gNode.Type = "ArrayType" + if n.Len != nil { + child = nodeToGraphNode(n.Len) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Len"}) + } + if n.Elt != nil { + child = nodeToGraphNode(n.Elt) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Elt"}) + } + case *dst.AssignStmt: + gNode.Type = "AssignStmt" + if n.Lhs != nil { + for _, obj := range n.Lhs { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Lhs"}) + } + } + if n.Rhs != nil { + for _, obj := range n.Rhs { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Rhs"}) + } + } + case *dst.BadDecl: + gNode.Type = "BadDecl" + case *dst.BadExpr: + gNode.Type = "BadExpr" + case *dst.BadStmt: + gNode.Type = "BadStmt" + case *dst.BasicLit: + gNode.Type = "BasicLit" + gNode.Value = n.Value + case *dst.BinaryExpr: + gNode.Type = "BinaryExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Y != nil { + child = nodeToGraphNode(n.Y) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Y"}) + } + case *dst.BlockStmt: + gNode.Type = "BlockStmt" + if n.List != nil { + for _, obj := range n.List { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "List"}) + } + } + case *dst.BranchStmt: + gNode.Type = "BranchStmt" + if n.Label != nil { + child = nodeToGraphNode(n.Label) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Label"}) + } + case *dst.CallExpr: + gNode.Type = "CallExpr" + if n.Fun != nil { + child = nodeToGraphNode(n.Fun) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Fun"}) + } + if n.Args != nil { + for _, obj := range n.Args { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Args"}) + } + } + case *dst.CaseClause: + gNode.Type = "CaseClause" + if n.List != nil { + for _, obj := range n.List { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "List"}) + } + } + if n.Body != nil { + for _, obj := range n.Body { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + } + case *dst.ChanType: + gNode.Type = "ChanType" + if n.Value != nil { + child = nodeToGraphNode(n.Value) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Value"}) + } + case *dst.CommClause: + gNode.Type = "CommClause" + if n.Comm != nil { + child = nodeToGraphNode(n.Comm) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Comm"}) + } + if n.Body != nil { + for _, obj := range n.Body { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + } + case *dst.CompositeLit: + gNode.Type = "CompositeLit" + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + if n.Elts != nil { + for _, obj := range n.Elts { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Elts"}) + } + } + case *dst.DeclStmt: + gNode.Type = "DeclStmt" + if n.Decl != nil { + child = nodeToGraphNode(n.Decl) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Decl"}) + } + case *dst.DeferStmt: + gNode.Type = "DeferStmt" + if n.Call != nil { + child = nodeToGraphNode(n.Call) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Call"}) + } + case *dst.Ellipsis: + gNode.Type = "Ellipsis" + if n.Elt != nil { + child = nodeToGraphNode(n.Elt) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Elt"}) + } + case *dst.EmptyStmt: + gNode.Type = "EmptyStmt" + case *dst.ExprStmt: + gNode.Type = "ExprStmt" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + case *dst.Field: + gNode.Type = "Field" + if n.Names != nil { + for _, obj := range n.Names { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Names"}) + } + } + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + if n.Tag != nil { + child = nodeToGraphNode(n.Tag) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Tag"}) + } + case *dst.FieldList: + gNode.Type = "FieldList" + if n.List != nil { + for _, obj := range n.List { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "List"}) + } + } + case *dst.File: + gNode.Type = "File" + if n.Name != nil { + child = nodeToGraphNode(n.Name) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Name"}) + } + if n.Decls != nil { + for _, obj := range n.Decls { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Decls"}) + } + } + if n.Imports != nil { + for _, obj := range n.Imports { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Imports"}) + } + } + case *dst.ForStmt: + gNode.Type = "ForStmt" + if n.Init != nil { + child = nodeToGraphNode(n.Init) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Init"}) + } + if n.Cond != nil { + child = nodeToGraphNode(n.Cond) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Cond"}) + } + if n.Post != nil { + child = nodeToGraphNode(n.Post) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Post"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.FuncDecl: + gNode.Type = "FuncDecl" + if n.Recv != nil { + child = nodeToGraphNode(n.Recv) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Recv"}) + } + if n.Name != nil { + child = nodeToGraphNode(n.Name) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Name"}) + } + if n.Type.TypeParams != nil { + child = nodeToGraphNode(n.Type.TypeParams) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "TypeParams"}) + } + if n.Type.Params != nil { + child = nodeToGraphNode(n.Type.Params) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Params"}) + } + if n.Type.Results != nil { + child = nodeToGraphNode(n.Type.Results) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Results"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.FuncLit: + gNode.Type = "FuncLit" + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.FuncType: + gNode.Type = "FuncType" + if n.TypeParams != nil { + child = nodeToGraphNode(n.TypeParams) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "TypeParams"}) + } + if n.Params != nil { + child = nodeToGraphNode(n.Params) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Params"}) + } + if n.Results != nil { + child = nodeToGraphNode(n.Results) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Results"}) + } + case *dst.GenDecl: + gNode.Type = "GenDecl" + if n.Specs != nil { + for _, obj := range n.Specs { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Specs"}) + } + } + case *dst.GoStmt: + gNode.Type = "GoStmt" + if n.Call != nil { + child = nodeToGraphNode(n.Call) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Call"}) + } + case *dst.Ident: + gNode.Type = "Ident" + gNode.Value = n.Name + case *dst.IfStmt: + gNode.Type = "IfStmt" + if n.Init != nil { + child = nodeToGraphNode(n.Init) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Init"}) + } + if n.Cond != nil { + child = nodeToGraphNode(n.Cond) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Cond"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + if n.Else != nil { + child = nodeToGraphNode(n.Else) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Else"}) + } + case *dst.ImportSpec: + gNode.Type = "ImportSpec" + if n.Name != nil { + child = nodeToGraphNode(n.Name) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Name"}) + } + if n.Path != nil { + child = nodeToGraphNode(n.Path) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Path"}) + } + case *dst.IncDecStmt: + gNode.Type = "IncDecStmt" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + case *dst.IndexExpr: + gNode.Type = "IndexExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Index != nil { + child = nodeToGraphNode(n.Index) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Index"}) + } + case *dst.IndexListExpr: + gNode.Type = "IndexListExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Indices != nil { + for _, obj := range n.Indices { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Indices"}) + } + } + case *dst.InterfaceType: + gNode.Type = "InterfaceType" + if n.Methods != nil { + child = nodeToGraphNode(n.Methods) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Methods"}) + } + case *dst.KeyValueExpr: + gNode.Type = "KeyValueExpr" + if n.Key != nil { + child = nodeToGraphNode(n.Key) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Key"}) + } + if n.Value != nil { + child = nodeToGraphNode(n.Value) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Value"}) + } + case *dst.LabeledStmt: + gNode.Type = "LabeledStmt" + if n.Label != nil { + child = nodeToGraphNode(n.Label) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Label"}) + } + if n.Stmt != nil { + child = nodeToGraphNode(n.Stmt) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Stmt"}) + } + case *dst.MapType: + gNode.Type = "MapType" + if n.Key != nil { + child = nodeToGraphNode(n.Key) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Key"}) + } + if n.Value != nil { + child = nodeToGraphNode(n.Value) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Value"}) + } + case *dst.Package: + gNode.Type = "Package" + case *dst.ParenExpr: + gNode.Type = "ParenExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + case *dst.RangeStmt: + gNode.Type = "RangeStmt" + if n.Key != nil { + child = nodeToGraphNode(n.Key) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Key"}) + } + if n.Value != nil { + child = nodeToGraphNode(n.Value) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Value"}) + } + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.ReturnStmt: + gNode.Type = "ReturnStmt" + if n.Results != nil { + for _, obj := range n.Results { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Results"}) + } + } + case *dst.SelectStmt: + gNode.Type = "SelectStmt" + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.SelectorExpr: + gNode.Type = "SelectorExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Sel != nil { + child = nodeToGraphNode(n.Sel) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Sel"}) + } + case *dst.SendStmt: + gNode.Type = "SendStmt" + if n.Chan != nil { + child = nodeToGraphNode(n.Chan) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Chan"}) + } + if n.Value != nil { + child = nodeToGraphNode(n.Value) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Value"}) + } + case *dst.SliceExpr: + gNode.Type = "SliceExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Low != nil { + child = nodeToGraphNode(n.Low) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Low"}) + } + if n.High != nil { + child = nodeToGraphNode(n.High) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "High"}) + } + if n.Max != nil { + child = nodeToGraphNode(n.Max) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Max"}) + } + case *dst.StarExpr: + gNode.Type = "StarExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + case *dst.StructType: + gNode.Type = "StructType" + if n.Fields != nil { + child = nodeToGraphNode(n.Fields) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Fields"}) + } + case *dst.SwitchStmt: + gNode.Type = "SwitchStmt" + if n.Init != nil { + child = nodeToGraphNode(n.Init) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Init"}) + } + if n.Tag != nil { + child = nodeToGraphNode(n.Tag) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Tag"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.TypeAssertExpr: + gNode.Type = "TypeAssertExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + case *dst.TypeSpec: + gNode.Type = "TypeSpec" + if n.Name != nil { + child = nodeToGraphNode(n.Name) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Name"}) + } + if n.TypeParams != nil { + child = nodeToGraphNode(n.TypeParams) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "TypeParams"}) + } + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + case *dst.TypeSwitchStmt: + gNode.Type = "TypeSwitchStmt" + if n.Init != nil { + child = nodeToGraphNode(n.Init) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Init"}) + } + if n.Assign != nil { + child = nodeToGraphNode(n.Assign) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Assign"}) + } + if n.Body != nil { + child = nodeToGraphNode(n.Body) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Body"}) + } + case *dst.UnaryExpr: + gNode.Type = "UnaryExpr" + if n.X != nil { + child = nodeToGraphNode(n.X) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "X"}) + } + case *dst.ValueSpec: + gNode.Type = "ValueSpec" + if n.Names != nil { + for _, obj := range n.Names { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Names"}) + } + } + if n.Type != nil { + child = nodeToGraphNode(n.Type) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Type"}) + } + if n.Values != nil { + for _, obj := range n.Values { + child = nodeToGraphNode(obj) + gNode.Edges = append(gNode.Edges, &graphEdge{Dest: child, Relationship: "Values"}) + } + } + default: + log.Println("Unrecognized type") + } + return gNode +} diff --git a/graph_test.go b/shorten/graph_test.go similarity index 96% rename from graph_test.go rename to shorten/graph_test.go index 0deaa44..ece7532 100644 --- a/graph_test.go +++ b/shorten/graph_test.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "bytes" @@ -44,7 +44,7 @@ func TestCreateDot(t *testing.T) { assert.Nil(t, err) out := &bytes.Buffer{} - err = CreateDot(node, out) + err = createDot(node, out) assert.Nil(t, err) assert.Equal(t, strings.TrimSpace(expDot), string(out.Bytes())) diff --git a/shortener.go b/shorten/shortener.go similarity index 94% rename from shortener.go rename to shorten/shortener.go index 144d78f..eb2b255 100644 --- a/shortener.go +++ b/shorten/shortener.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "bufio" @@ -32,8 +32,8 @@ var ( // prevent loops that prevent termination. const maxRounds = 20 -// ShortenerConfig stores the configuration options exposed by a Shortener instance. -type ShortenerConfig struct { +// Config stores the configuration options exposed by a Shortener instance. +type Config struct { MaxLen int // Max target width for each line TabLen int // Width of a tab character KeepAnnotations bool // Whether to keep annotations in final result (for debugging only) @@ -51,7 +51,7 @@ type ShortenerConfig struct { // Shortener shortens a single go file according to a small set of user style // preferences. type Shortener struct { - config ShortenerConfig + config Config // Some extra params around the base formatter generated from the BaseFormatterCmd // argument in the config. @@ -59,8 +59,8 @@ type Shortener struct { baseFormatterArgs []string } -// NewShortener creates a new shortener instance from the provided config. -func NewShortener(config ShortenerConfig) *Shortener { +// New creates a new shortener instance from the provided config. +func New(config Config) *Shortener { var formatterComponents []string if config.BaseFormatterCmd == "" { @@ -115,7 +115,7 @@ func (s *Shortener) Shorten(contents []byte) ([]byte, error) { if round == 0 { if !s.config.ReformatTags { stop = true - } else if !HasMultiKeyTags(lines) { + } else if !hasMultiKeyTags(lines) { stop = true } } else { @@ -144,7 +144,7 @@ func (s *Shortener) Shorten(contents []byte) ([]byte, error) { defer dotFile.Close() log.Debugf("Writing dot file output to %s", s.config.DotFile) - err = CreateDot(result, dotFile) + err = createDot(result, dotFile) if err != nil { return nil, err } @@ -238,19 +238,19 @@ func (s *Shortener) annotateLongLines(lines []string) ([]string, int) { annotatedLines = annotatedLines[:len(annotatedLines)-1] } else if length < prevLen { // Replace annotation with new length - annotatedLines[len(annotatedLines)-1] = CreateAnnotation(length) + annotatedLines[len(annotatedLines)-1] = createAnnotation(length) linesToShorten++ } } else if !s.isComment(line) && length > s.config.MaxLen { annotatedLines = append( annotatedLines, - CreateAnnotation(length), + createAnnotation(length), ) linesToShorten++ } annotatedLines = append(annotatedLines, line) - prevLen = ParseAnnotation(line) + prevLen = parseAnnotation(line) } return annotatedLines, linesToShorten @@ -263,7 +263,7 @@ func (s *Shortener) removeAnnotations(contents []byte) []byte { lines := strings.Split(string(contents), "\n") for _, line := range lines { - if !IsAnnotation(line) { + if !isAnnotation(line) { cleanedLines = append(cleanedLines, line) } } @@ -279,7 +279,7 @@ func (s *Shortener) shortenCommentsFunc(contents []byte) []byte { prefix := "" lines := strings.Split(string(contents), "\n") for _, line := range lines { - if s.isComment(line) && !IsAnnotation(line) && + if s.isComment(line) && !isAnnotation(line) && !s.isGoDirective(line) && s.lineLen(line) > s.config.MaxLen { start := strings.Index(line, "//") @@ -380,7 +380,7 @@ func (s *Shortener) formatNode(node dst.Node) { func (s *Shortener) formatDecl(decl dst.Decl) { switch d := decl.(type) { case *dst.FuncDecl: - if HasAnnotationRecursive(decl) { + if hasAnnotationRecursive(decl) { if d.Type != nil && d.Type.Params != nil { s.formatFieldList(d.Type.Params) } @@ -388,7 +388,7 @@ func (s *Shortener) formatDecl(decl dst.Decl) { s.formatStmt(d.Body) case *dst.GenDecl: for _, spec := range d.Specs { - s.formatSpec(spec, HasAnnotation(decl)) + s.formatSpec(spec, hasAnnotation(decl)) } default: log.Debugf( @@ -420,7 +420,7 @@ func (s *Shortener) formatStmt(stmt dst.Stmt) { return } - shouldShorten := HasAnnotation(stmt) + shouldShorten := hasAnnotation(stmt) switch st := stmt.(type) { case *dst.AssignStmt: @@ -482,7 +482,7 @@ func (s *Shortener) formatStmt(stmt dst.Stmt) { // formatExpr formats an AST expression node. These include uniary and binary expressions, function // literals, and key/value pair statements, among others. func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { - shouldShorten := force || HasAnnotation(expr) + shouldShorten := force || hasAnnotation(expr) switch e := expr.(type) { case *dst.BinaryExpr: @@ -501,7 +501,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { if ok && s.config.ChainSplitDots && - (shouldShorten || HasAnnotationRecursive(e)) && + (shouldShorten || hasAnnotationRecursive(e)) && (isChain || s.chainLength(e) > 1) { e.Decorations().After = dst.NewLine @@ -511,7 +511,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { s.formatExpr(e.Fun, shouldShorten, true) } else { - shortenChildArgs := shouldShorten || HasAnnotationRecursive(e) + shortenChildArgs := shouldShorten || hasAnnotationRecursive(e) for a, arg := range e.Args { if shortenChildArgs { @@ -547,7 +547,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { } case *dst.InterfaceType: for _, method := range e.Methods.List { - if HasAnnotation(method) { + if hasAnnotation(method) { s.formatExpr(method.Type, true, isChain) } } @@ -557,7 +557,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { s.formatExpr(e.X, shouldShorten, isChain) case *dst.StructType: if s.config.ReformatTags { - FormatStructTags(e.Fields) + formatStructTags(e.Fields) } case *dst.UnaryExpr: s.formatExpr(e.X, shouldShorten, isChain) @@ -573,7 +573,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { // formatSpec formats an AST spec node. These include type specifications, among other things. func (s *Shortener) formatSpec(spec dst.Spec, force bool) { - shouldShorten := HasAnnotation(spec) || force + shouldShorten := hasAnnotation(spec) || force switch sp := spec.(type) { case *dst.ValueSpec: for _, expr := range sp.Values { diff --git a/shortener_test.go b/shorten/shortener_test.go similarity index 95% rename from shortener_test.go rename to shorten/shortener_test.go index 0f36545..d91ae10 100644 --- a/shortener_test.go +++ b/shorten/shortener_test.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "io/ioutil" @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" ) -const fixturesDir = "_fixtures" +const fixturesDir = "../_fixtures" // TestShortener verifies the core shortening functionality on the files in the _fixtures // directory. To update the expected outputs, run tests with the REGENERATE_TEST_OUTPUTS @@ -42,8 +42,8 @@ func TestShortener(t *testing.T) { } defer os.RemoveAll(dotDir) - shortener := NewShortener( - ShortenerConfig{ + shortener := New( + Config{ MaxLen: 100, TabLen: 4, KeepAnnotations: false, diff --git a/tags.go b/shorten/tags.go similarity index 95% rename from tags.go rename to shorten/tags.go index 933e995..f7a22e8 100644 --- a/tags.go +++ b/shorten/tags.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "fmt" @@ -12,9 +12,9 @@ import ( var structTagRegexp = regexp.MustCompile("`([ ]*[a-zA-Z0-9_-]+:\".*\"[ ]*){2,}`") -// HasMultiKeyTags returns whether the given lines have a multikey struct line. +// hasMultiKeyTags returns whether the given lines have a multikey struct line. // It's used as an optimization step to avoid unnnecessary shortening rounds. -func HasMultiKeyTags(lines []string) bool { +func hasMultiKeyTags(lines []string) bool { for _, line := range lines { if structTagRegexp.MatchString(line) { return true @@ -24,12 +24,12 @@ func HasMultiKeyTags(lines []string) bool { return false } -// FormatStructTags formats struct tags so that the keys within each block of fields are aligned. +// formatStructTags formats struct tags so that the keys within each block of fields are aligned. // It's not technically a shortening (and it usually makes these tags longer), so it's being // kept separate from the core shortening logic for now. // // See the struct_tags fixture for examples. -func FormatStructTags(fieldList *dst.FieldList) { +func formatStructTags(fieldList *dst.FieldList) { if fieldList == nil || len(fieldList.List) == 0 { return } diff --git a/tags_test.go b/shorten/tags_test.go similarity index 58% rename from tags_test.go rename to shorten/tags_test.go index 9e673f0..ff2ea9c 100644 --- a/tags_test.go +++ b/shorten/tags_test.go @@ -1,4 +1,4 @@ -package main +package shorten import ( "testing" @@ -7,13 +7,13 @@ import ( ) func TestHasMultiKeyTags(t *testing.T) { - assert.False(t, HasMultiKeyTags([]string{"xxxxx"})) - assert.False(t, HasMultiKeyTags([]string{"key `xxxxx yyyy zzzz key:`"})) - assert.False(t, HasMultiKeyTags([]string{"key `tagKey:\"tag value\"`"})) - assert.False(t, HasMultiKeyTags([]string{"key ` tagKey:\"tag value\" `"})) + assert.False(t, hasMultiKeyTags([]string{"xxxxx"})) + assert.False(t, hasMultiKeyTags([]string{"key `xxxxx yyyy zzzz key:`"})) + assert.False(t, hasMultiKeyTags([]string{"key `tagKey:\"tag value\"`"})) + assert.False(t, hasMultiKeyTags([]string{"key ` tagKey:\"tag value\" `"})) assert.True( t, - HasMultiKeyTags( + hasMultiKeyTags( []string{ "xxxx", "key `tagKey1:\"tag value1\" tagKey2:\"tag value2\" `", @@ -22,7 +22,7 @@ func TestHasMultiKeyTags(t *testing.T) { ) assert.True( t, - HasMultiKeyTags( + hasMultiKeyTags( []string{ "key ` tagKey1:\"tag value1\" tagKey2:\"tag value2\" tagKey3:\"tag value3\" `", "zzzz", From 52ca1014961498d13375edf9d8381b988d62dd72 Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Fri, 28 Oct 2022 13:11:21 -0500 Subject: [PATCH 2/3] feat(shortener): Add default config --- shorten/shortener.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shorten/shortener.go b/shorten/shortener.go index eb2b255..95c3bd3 100644 --- a/shorten/shortener.go +++ b/shorten/shortener.go @@ -48,6 +48,16 @@ type Config struct { BaseFormatterCmd string } +func DefaultConfig() Config { + return Config{ + MaxLen: 100, + TabLen: 4, + ReformatTags: true, + IgnoreGenerated: true, + ChainSplitDots: true, + } +} + // Shortener shortens a single go file according to a small set of user style // preferences. type Shortener struct { From ec6f2dc5912d4f3b9f9ea2f9c74b508debfcf3cc Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Fri, 28 Oct 2022 13:11:59 -0500 Subject: [PATCH 3/3] feat(new): Make config an optional parameter --- shorten/shortener.go | 9 ++++++++- shorten/shortener_test.go | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/shorten/shortener.go b/shorten/shortener.go index 95c3bd3..91043f5 100644 --- a/shorten/shortener.go +++ b/shorten/shortener.go @@ -70,7 +70,14 @@ type Shortener struct { } // New creates a new shortener instance from the provided config. -func New(config Config) *Shortener { +func New(configs ...Config) *Shortener { + var config Config + if len(configs) == 0 { + config = DefaultConfig() + } else { + config = configs[0] + } + var formatterComponents []string if config.BaseFormatterCmd == "" { diff --git a/shorten/shortener_test.go b/shorten/shortener_test.go index d91ae10..59db4d9 100644 --- a/shorten/shortener_test.go +++ b/shorten/shortener_test.go @@ -94,3 +94,8 @@ func TestShortener(t *testing.T) { assert.Equal(t, string(expectedContents), string(shortenedContents)) } } + +func TestShortener_NewDefaultConfig(t *testing.T) { + shortener := New() + assert.Equal(t, DefaultConfig(), shortener.config) +}