Skip to content

Commit

Permalink
make API
Browse files Browse the repository at this point in the history
  • Loading branch information
golangcidev committed May 6, 2018
1 parent 86da7ad commit cfe4005
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 93 deletions.
66 changes: 20 additions & 46 deletions cmd/structcheck/structcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,22 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package main
package structcheck

import (
"flag"
"fmt"
"go/ast"
"go/build"
"go/token"
"go/types"
"os"
"strings"

"github.com/kisielk/gotool"
"golang.org/x/tools/go/loader"
)

var (
assignmentsOnly = flag.Bool("a", false, "Count assignments only")
loadTestFiles = flag.Bool("t", false, "Load test files too")
reportExported = flag.Bool("e", false, "Report exported fields")
buildTags = flag.String("tags", "", "Build tags")
assignmentsOnly = flag.Bool("structcheck.a", false, "Count assignments only")
loadTestFiles = flag.Bool("structcheck.t", false, "Load test files too")
buildTags = flag.String("structcheck.tags", "", "Build tags")
)

type visitor struct {
Expand Down Expand Up @@ -144,36 +140,14 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
return v
}

func main() {
flag.Parse()
exitStatus := 0
importPaths := gotool.ImportPaths(flag.Args())
if len(importPaths) == 0 {
importPaths = []string{"."}
}
ctx := build.Default
if *buildTags != "" {
ctx.BuildTags = strings.Split(*buildTags, ",")
}
loadcfg := loader.Config{
Build: &ctx,
}
rest, err := loadcfg.FromArgs(importPaths, *loadTestFiles)
if err != nil {
fmt.Fprintf(os.Stderr, "could not parse arguments: %s", err)
os.Exit(1)
}
if len(rest) > 0 {
fmt.Fprintf(os.Stderr, "unhandled extra arguments: %v", rest)
os.Exit(1)
}

program, err := loadcfg.Load()
if err != nil {
fmt.Fprintf(os.Stderr, "could not type check: %s", err)
os.Exit(1)
}
type Issue struct {
Pos token.Position
Type string
FieldName string
}

func Run(program *loader.Program, reportExported bool) []Issue {
var issues []Issue
for _, pkg := range program.InitialPackages() {
visitor := &visitor{
m: make(map[types.Type]map[string]int),
Expand All @@ -190,14 +164,13 @@ func main() {
continue
}
for fieldName, v := range visitor.m[t] {
if !*reportExported && ast.IsExported(fieldName) {
if !reportExported && ast.IsExported(fieldName) {
continue
}
if v == 0 {
field, _, _ := types.LookupFieldOrMethod(t, false, pkg.Pkg, fieldName)
if field == nil {
fmt.Printf("%s: unknown field or method: %s.%s\n", pkg.Pkg.Path(), t, fieldName)
exitStatus = 1
continue
}
if fieldName == "XMLName" {
Expand All @@ -206,14 +179,15 @@ func main() {
}
}
pos := program.Fset.Position(field.Pos())
fmt.Printf("%s: %s:%d:%d: %s.%s\n",
pkg.Pkg.Path(), pos.Filename, pos.Line, pos.Column,
types.TypeString(t, nil), fieldName,
)
exitStatus = 1
issues = append(issues, Issue{
Pos: pos,
Type: types.TypeString(t, nil),
FieldName: fieldName,
})
}
}
}
}
os.Exit(exitStatus)

return issues
}
61 changes: 14 additions & 47 deletions cmd/varcheck/varcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,21 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package main
package varcheck

import (
"flag"
"fmt"
"go/ast"
"go/build"
"go/token"
"log"
"os"
"sort"
"strings"

"go/types"

"github.com/kisielk/gotool"
"golang.org/x/tools/go/loader"
)

var (
reportExported = flag.Bool("e", false, "Report exported variables and constants")
buildTags = flag.String("tags", "", "Build tags")
buildTags = flag.String("varcheck.tags", "", "Build tags")
)

type object struct {
Expand Down Expand Up @@ -129,34 +122,13 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
return v
}

func main() {
flag.Parse()
exitStatus := 0
importPaths := gotool.ImportPaths(flag.Args())
if len(importPaths) == 0 {
importPaths = []string{"."}
}

ctx := build.Default
if *buildTags != "" {
ctx.BuildTags = strings.Fields(*buildTags)
}
loadcfg := loader.Config{
Build: &ctx,
}
rest, err := loadcfg.FromArgs(importPaths, true)
if err != nil {
log.Fatalf("could not parse arguments: %s", err)
}
if len(rest) > 0 {
log.Fatalf("unhandled extra arguments: %v", rest)
}

program, err := loadcfg.Load()
if err != nil {
log.Fatalf("could not type check: %s", err)
}
type Issue struct {
Pos token.Position
VarName string
}

func Run(program *loader.Program, reportExported bool) []Issue {
var issues []Issue
uses := make(map[object]int)
positions := make(map[object]token.Position)

Expand All @@ -177,20 +149,15 @@ func main() {
}
}

var lines []string

for obj, useCount := range uses {
if useCount == 0 && (*reportExported || !ast.IsExported(obj.name)) {
if useCount == 0 && (reportExported || !ast.IsExported(obj.name)) {
pos := positions[obj]
lines = append(lines, fmt.Sprintf("%s: %s:%d:%d: %s", obj.pkgPath, pos.Filename, pos.Line, pos.Column, obj.name))
exitStatus = 1
issues = append(issues, Issue{
Pos: pos,
VarName: obj.name,
})
}
}

sort.Strings(lines)
for _, line := range lines {
fmt.Println(line)
}

os.Exit(exitStatus)
return issues
}

0 comments on commit cfe4005

Please sign in to comment.