X-Git-Url: https://git.josue.xyz/?a=blobdiff_plain;f=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201028153306-37f0764111ff%2Fcmd%2Fcover%2Ffunc.go;fp=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201028153306-37f0764111ff%2Fcmd%2Fcover%2Ffunc.go;h=41d9fceca587be2e4477fe1cae57fb4856081fe4;hb=4d07c77cf4d78cab8639e13ddc3c22495e585b0b;hp=0000000000000000000000000000000000000000;hpb=b3950616b54221c40a7dab9099bda675007e5b6e;p=dotfiles%2F.git diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/cmd/cover/func.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/cmd/cover/func.go new file mode 100644 index 00000000..41d9fcec --- /dev/null +++ b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/cmd/cover/func.go @@ -0,0 +1,166 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements the visitor that computes the (line, column)-(line-column) range for each function. + +package main + +import ( + "bufio" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "os" + "path/filepath" + "text/tabwriter" + + "golang.org/x/tools/cover" +) + +// funcOutput takes two file names as arguments, a coverage profile to read as input and an output +// file to write ("" means to write to standard output). The function reads the profile and produces +// as output the coverage data broken down by function, like this: +// +// fmt/format.go:30: init 100.0% +// fmt/format.go:57: clearflags 100.0% +// ... +// fmt/scan.go:1046: doScan 100.0% +// fmt/scan.go:1075: advance 96.2% +// fmt/scan.go:1119: doScanf 96.8% +// total: (statements) 91.9% + +func funcOutput(profile, outputFile string) error { + profiles, err := cover.ParseProfiles(profile) + if err != nil { + return err + } + + var out *bufio.Writer + if outputFile == "" { + out = bufio.NewWriter(os.Stdout) + } else { + fd, err := os.Create(outputFile) + if err != nil { + return err + } + defer fd.Close() + out = bufio.NewWriter(fd) + } + defer out.Flush() + + tabber := tabwriter.NewWriter(out, 1, 8, 1, '\t', 0) + defer tabber.Flush() + + var total, covered int64 + for _, profile := range profiles { + fn := profile.FileName + file, err := findFile(fn) + if err != nil { + return err + } + funcs, err := findFuncs(file) + if err != nil { + return err + } + // Now match up functions and profile blocks. + for _, f := range funcs { + c, t := f.coverage(profile) + fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n", fn, f.startLine, f.name, 100.0*float64(c)/float64(t)) + total += t + covered += c + } + } + fmt.Fprintf(tabber, "total:\t(statements)\t%.1f%%\n", 100.0*float64(covered)/float64(total)) + + return nil +} + +// findFuncs parses the file and returns a slice of FuncExtent descriptors. +func findFuncs(name string) ([]*FuncExtent, error) { + fset := token.NewFileSet() + parsedFile, err := parser.ParseFile(fset, name, nil, 0) + if err != nil { + return nil, err + } + visitor := &FuncVisitor{ + fset: fset, + name: name, + astFile: parsedFile, + } + ast.Walk(visitor, visitor.astFile) + return visitor.funcs, nil +} + +// FuncExtent describes a function's extent in the source by file and position. +type FuncExtent struct { + name string + startLine int + startCol int + endLine int + endCol int +} + +// FuncVisitor implements the visitor that builds the function position list for a file. +type FuncVisitor struct { + fset *token.FileSet + name string // Name of file. + astFile *ast.File + funcs []*FuncExtent +} + +// Visit implements the ast.Visitor interface. +func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor { + switch n := node.(type) { + case *ast.FuncDecl: + start := v.fset.Position(n.Pos()) + end := v.fset.Position(n.End()) + fe := &FuncExtent{ + name: n.Name.Name, + startLine: start.Line, + startCol: start.Column, + endLine: end.Line, + endCol: end.Column, + } + v.funcs = append(v.funcs, fe) + } + return v +} + +// coverage returns the fraction of the statements in the function that were covered, as a numerator and denominator. +func (f *FuncExtent) coverage(profile *cover.Profile) (num, den int64) { + // We could avoid making this n^2 overall by doing a single scan and annotating the functions, + // but the sizes of the data structures is never very large and the scan is almost instantaneous. + var covered, total int64 + // The blocks are sorted, so we can stop counting as soon as we reach the end of the relevant block. + for _, b := range profile.Blocks { + if b.StartLine > f.endLine || (b.StartLine == f.endLine && b.StartCol >= f.endCol) { + // Past the end of the function. + break + } + if b.EndLine < f.startLine || (b.EndLine == f.startLine && b.EndCol <= f.startCol) { + // Before the beginning of the function + continue + } + total += int64(b.NumStmt) + if b.Count > 0 { + covered += int64(b.NumStmt) + } + } + if total == 0 { + total = 1 // Avoid zero denominator. + } + return covered, total +} + +// findFile finds the location of the named file in GOROOT, GOPATH etc. +func findFile(file string) (string, error) { + dir, file := filepath.Split(file) + pkg, err := build.Import(dir, ".", build.FindOnly) + if err != nil { + return "", fmt.Errorf("can't find %q: %v", file, err) + } + return filepath.Join(pkg.Dir, file), nil +}