forked from golang/gddo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vet.go
81 lines (74 loc) · 2.54 KB
/
vet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// 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 or at
// https://developers.google.com/open-source/licenses/bsd.
package doc
import (
"fmt"
"go/ast"
"go/token"
"strconv"
"strings"
"github.com/golang/gddo/gosrc"
)
// This list of deprecated exports is used to find code that has not been
// updated for Go 1.
var deprecatedExports = map[string][]string{
`"bytes"`: {"Add"},
`"crypto/aes"`: {"Cipher"},
`"crypto/hmac"`: {"NewSHA1", "NewSHA256"},
`"crypto/rand"`: {"Seed"},
`"encoding/json"`: {"MarshalForHTML"},
`"encoding/xml"`: {"Marshaler", "NewParser", "Parser"},
`"html"`: {"NewTokenizer", "Parse"},
`"image"`: {"Color", "NRGBAColor", "RGBAColor"},
`"io"`: {"Copyn"},
`"log"`: {"Exitf"},
`"math"`: {"Fabs", "Fmax", "Fmod"},
`"os"`: {"Envs", "Error", "Getenverror", "NewError", "Time", "UnixSignal", "Wait"},
`"reflect"`: {"MapValue", "Typeof"},
`"runtime"`: {"UpdateMemStats"},
`"strconv"`: {"Atob", "Atof32", "Atof64", "AtofN", "Atoi64", "Atoui", "Atoui64", "Btoui64", "Ftoa64", "Itoa64", "Uitoa", "Uitoa64"},
`"time"`: {"LocalTime", "Nanoseconds", "NanosecondsToLocalTime", "Seconds", "SecondsToLocalTime", "SecondsToUTC"},
`"unicode/utf8"`: {"NewString"},
}
type vetVisitor struct {
errors map[string]token.Pos
}
func (v *vetVisitor) Visit(n ast.Node) ast.Visitor {
if sel, ok := n.(*ast.SelectorExpr); ok {
if x, _ := sel.X.(*ast.Ident); x != nil {
if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
for _, name := range deprecatedExports[spec.Path.Value] {
if name == sel.Sel.Name {
v.errors[fmt.Sprintf("%s.%s not found", spec.Path.Value, sel.Sel.Name)] = n.Pos()
return nil
}
}
}
}
}
}
return v
}
func (b *builder) vetPackage(pkg *Package, apkg *ast.Package) {
errors := make(map[string]token.Pos)
for _, file := range apkg.Files {
for _, is := range file.Imports {
importPath, _ := strconv.Unquote(is.Path.Value)
if !gosrc.IsValidPath(importPath) &&
!strings.HasPrefix(importPath, "exp/") &&
!strings.HasPrefix(importPath, "appengine") {
errors[fmt.Sprintf("Unrecognized import path %q", importPath)] = is.Pos()
}
}
v := vetVisitor{errors: errors}
ast.Walk(&v, file)
}
for message, pos := range errors {
pkg.Errors = append(pkg.Errors,
fmt.Sprintf("%s (%s)", message, b.fset.Position(pos)))
}
}