本文整理匯總了Golang中golang.org/x/tools/go/types.LookupFieldOrMethod函數的典型用法代碼示例。如果您正苦於以下問題:Golang LookupFieldOrMethod函數的具體用法?Golang LookupFieldOrMethod怎麽用?Golang LookupFieldOrMethod使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了LookupFieldOrMethod函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: checkSelections
// checkSelection checks that all uses and selections that resolve to
// the specified object would continue to do so after the renaming.
func (r *Unexporter) checkSelections(objsToUpdate map[types.Object]string, from types.Object, to string) {
for pkg, info := range r.packages {
if id := someUse(info, from); id != nil {
if !r.checkExport(id, pkg, from, to) {
return
}
}
for syntax, sel := range info.Selections {
// There may be extant selections of only the old
// name or only the new name, so we must check both.
// (If neither, the renaming is sound.)
//
// In both cases, we wish to compare the lengths
// of the implicit field path (Selection.Index)
// to see if the renaming would change it.
//
// If a selection that resolves to 'from', when renamed,
// would yield a path of the same or shorter length,
// this indicates ambiguity or a changed referent,
// analogous to same- or sub-block lexical conflict.
//
// If a selection using the name 'to' would
// yield a path of the same or shorter length,
// this indicates ambiguity or shadowing,
// analogous to same- or super-block lexical conflict.
// TODO(adonovan): fix: derive from Types[syntax.X].Mode
// TODO(adonovan): test with pointer, value, addressable value.
isAddressable := true
if sel.Obj() == from {
if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), to); obj != nil {
// Renaming this existing selection of
// 'from' may block access to an existing
// type member named 'to'.
delta := len(indices) - len(sel.Index())
if delta > 0 {
continue // no ambiguity
}
r.selectionConflict(objsToUpdate, from, to, delta, syntax, obj)
return
}
} else if sel.Obj().Name() == to {
if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), from.Name()); obj == from {
// Renaming 'from' may cause this existing
// selection of the name 'to' to change
// its meaning.
delta := len(indices) - len(sel.Index())
if delta > 0 {
continue // no ambiguity
}
r.selectionConflict(objsToUpdate, from, to, -delta, syntax, sel.Obj())
return
}
}
}
}
}
示例2: isInterfaceMethod
func (u *Unexporter) isInterfaceMethod(e Export) map[string][]*types.Package {
if _, ok := e.obj.(*types.Func); !ok {
return nil
}
f := e.obj.(*types.Func)
r := f.Type().(*types.Signature).Recv()
if r == nil {
return nil
}
if u.f == nil {
calculateConstraints(u)
}
interfaces := make(map[string][]*types.Package)
for constraint := range u.f {
if constraint.RHS == r.Type() && types.IsInterface(constraint.LHS) {
sure, _, _ := types.LookupFieldOrMethod(constraint.LHS, true, f.Pkg(), f.Name())
if sure != nil {
interfaces[constraint.LHS.String()] = append(interfaces[constraint.LHS.String()], f.Pkg())
}
}
}
return interfaces
}
示例3: buildStructFields
func (g *Grapher) buildStructFields(pkgInfo *loader.PackageInfo) {
for _, obj := range pkgInfo.Defs {
if tn, ok := obj.(*types.TypeName); ok {
typ := tn.Type().Underlying()
if st, ok := typ.(*types.Struct); ok {
for i := 0; i < st.NumFields(); i++ {
sf := st.Field(i)
g.structFields[sf] = &structField{sf, tn.Type()}
}
}
}
}
for selExpr, sel := range pkgInfo.Selections {
switch sel.Kind() {
case types.FieldVal:
rt := derefType(sel.Recv())
var pkg *types.Package
switch rt := rt.(type) {
case *types.Named:
pkg = rt.Obj().Pkg()
case *types.Struct:
pkg = sel.Obj().Pkg()
default:
panic("unhandled field recv type " + rt.String())
}
sfobj, _, _ := types.LookupFieldOrMethod(derefType(sel.Recv()), false, pkg, selExpr.Sel.Name)
// Record that this field is in this struct so we can construct the
// right def path to the field.
sf, _ := sfobj.(*types.Var)
g.structFields[sf] = &structField{sf, rt}
}
}
}
示例4: main
func main() {
flag.Parse()
exitStatus := 0
importPaths := gotool.ImportPaths(flag.Args())
if len(importPaths) == 0 {
importPaths = []string{"."}
}
for _, pkgPath := range importPaths {
visitor := &visitor{
info: types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
},
m: make(map[types.Type]map[string]int),
skip: make(map[types.Type]struct{}),
}
fset, astFiles := check.ASTFilesForPackage(pkgPath, *loadTestFiles)
imp := importer.New()
// Preliminary cgo support.
imp.Config = importer.Config{UseGcFallback: true}
config := types.Config{Import: imp.Import}
var err error
visitor.pkg, err = config.Check(pkgPath, fset, astFiles, &visitor.info)
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", pkgPath, err)
continue
}
for _, f := range astFiles {
ast.Walk(visitor, f)
}
for t := range visitor.m {
if _, skip := visitor.skip[t]; skip {
continue
}
for fieldName, v := range visitor.m[t] {
if !*reportExported && ast.IsExported(fieldName) {
continue
}
if v == 0 {
field, _, _ := types.LookupFieldOrMethod(t, false, visitor.pkg, fieldName)
if fieldName == "XMLName" {
if named, ok := field.Type().(*types.Named); ok && named.Obj().Pkg().Path() == "encoding/xml" {
continue
}
}
pos := fset.Position(field.Pos())
fmt.Printf("%s: %s:%d:%d: %s.%s\n",
pkgPath, pos.Filename, pos.Line, pos.Column,
types.TypeString(t, nil), fieldName,
)
exitStatus = 1
}
}
}
}
os.Exit(exitStatus)
}
示例5:
func ext۰sync۰Pool۰Get(fr *frame, args []value) value {
Pool := fr.i.prog.ImportedPackage("sync").Type("Pool").Object()
_, newIndex, _ := types.LookupFieldOrMethod(Pool.Type(), false, Pool.Pkg(), "New")
if New := (*args[0].(*value)).(structure)[newIndex[0]]; New != nil {
return call(fr.i, fr, 0, New, nil)
}
return nil
}
示例6: matchSelectorExpr
func (tr *Transformer) matchSelectorExpr(x, y *ast.SelectorExpr) bool {
if xobj, ok := tr.wildcardObj(x.X); ok {
field := x.Sel.Name
yt := tr.info.TypeOf(y.X)
o, _, _ := types.LookupFieldOrMethod(yt, true, tr.currentPkg, field)
if o != nil {
tr.env[xobj.Name()] = y.X // record binding
return true
}
}
return tr.matchExpr(x.X, y.X)
}
示例7: checkSelections
// checkSelection checks that all uses and selections that resolve to
// the specified object would continue to do so after the renaming.
func (e *Export) checkSelections(from types.Object, to string) {
info := e.u.pkgInfo
if id := someUse(info, from); id != nil {
e.Conflicting = true
return
}
for _, sel := range info.Selections {
if sel.Obj() == from {
if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), true, from.Pkg(), to); obj != nil {
// Renaming this existing selection of
// 'from' may block access to an existing
// type member named 'to'.
delta := len(indices) - len(sel.Index())
if delta > 0 {
continue // no ambiguity
}
e.Conflicting = true
return
}
} else if sel.Obj().Name() == to {
if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), true, from.Pkg(), from.Name()); obj == from {
// Renaming 'from' may cause this existing
// selection of the name 'to' to change
// its meaning.
delta := len(indices) - len(sel.Index())
if delta > 0 {
continue // no ambiguity
}
e.Conflicting = true
return
}
}
}
}
示例8: checkStructField
// checkStructField checks that the field renaming will not cause
// conflicts at its declaration, or ambiguity or changes to any selection.
func (e *Export) checkStructField(from *types.Var, to string) {
// Check that the struct declaration is free of field conflicts,
// and field/method conflicts.
t := getEnclosingStruct(from)
if t != t.Underlying() {
// This struct is also a named type.
// We must check for direct (non-promoted) field/field
// and method/field conflicts.
_, indices, _ := types.LookupFieldOrMethod(t, true, e.u.pkgInfo.Pkg, to)
if len(indices) == 1 {
e.Conflicting = true
return
}
} else {
// This struct is not a named type.
// We need only check for direct (non-promoted) field/field conflicts.
T := t.Underlying().(*types.Struct)
for i := 0; i < T.NumFields(); i++ {
if prev := T.Field(i); prev.Name() == to {
e.Conflicting = true
return
}
}
}
// Renaming an anonymous field requires renaming the type too. e.g.
// print(s.T) // if we rename T to U,
// type T int // this and
// var s struct {T} // this must change too.
if from.Anonymous() {
if named, ok := from.Type().(*types.Named); ok {
e.check(named.Obj(), to)
} else if named, ok := deref(from.Type()).(*types.Named); ok {
e.check(named.Obj(), to)
}
}
// Check integrity of existing (field and method) selections.
e.checkSelections(from, to)
}
示例9: checkMethod
// checkMethod performs safety checks for renaming a method.
// There are three hazards:
// - declaration conflicts
// - selection ambiguity/changes
// - entailed renamings of assignable concrete/interface types.
// We reject renamings initiated at concrete methods if it would
// change the assignability relation. For renamings of abstract
// methods, we rename all methods transitively coupled to it via
// assignability.
func (r *Unexporter) checkMethod(objsToUpdate map[types.Object]string, from *types.Func, to string) {
// e.g. error.Error
if from.Pkg() == nil {
r.warn(from, r.errorf(from.Pos(), "you cannot rename built-in method %s", from))
return
}
// ASSIGNABILITY: We reject renamings of concrete methods that
// would break a 'satisfy' constraint; but renamings of abstract
// methods are allowed to proceed, and we rename affected
// concrete and abstract methods as necessary. It is the
// initial method that determines the policy.
// Check for conflict at point of declaration.
// Check to ensure preservation of assignability requirements.
R := recv(from).Type()
if isInterface(R) {
// Abstract method
// declaration
prev, _, _ := types.LookupFieldOrMethod(R, false, from.Pkg(), to)
if prev != nil {
r.warn(from,
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), to),
r.errorf(prev.Pos(), "\twould conflict with this method"))
return
}
// Check all interfaces that embed this one for
// declaration conflicts too.
for _, info := range r.packages {
// Start with named interface types (better errors)
for _, obj := range info.Defs {
if obj, ok := obj.(*types.TypeName); ok && isInterface(obj.Type()) {
f, _, _ := types.LookupFieldOrMethod(
obj.Type(), false, from.Pkg(), from.Name())
if f == nil {
continue
}
t, _, _ := types.LookupFieldOrMethod(
obj.Type(), false, from.Pkg(), to)
if t == nil {
continue
}
r.warn(from,
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), to),
r.errorf(t.Pos(), "\twould conflict with this method"),
r.errorf(obj.Pos(), "\tin named interface type %q", obj.Name()))
}
}
// Now look at all literal interface types (includes named ones again).
for e, tv := range info.Types {
if e, ok := e.(*ast.InterfaceType); ok {
_ = e
_ = tv.Type.(*types.Interface)
// TODO(adonovan): implement same check as above.
}
}
}
// assignability
//
// Find the set of concrete or abstract methods directly
// coupled to abstract method 'from' by some
// satisfy.Constraint, and rename them too.
for key := range r.satisfy() {
// key = (lhs, rhs) where lhs is always an interface.
lsel := r.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name())
if lsel == nil {
continue
}
rmethods := r.msets.MethodSet(key.RHS)
rsel := rmethods.Lookup(from.Pkg(), from.Name())
if rsel == nil {
continue
}
// If both sides have a method of this name,
// and one of them is m, the other must be coupled.
var coupled *types.Func
switch from {
case lsel.Obj():
coupled = rsel.Obj().(*types.Func)
case rsel.Obj():
coupled = lsel.Obj().(*types.Func)
default:
continue
//.........這裏部分代碼省略.........
示例10: checkStructField
// checkStructField checks that the field renaming will not cause
// conflicts at its declaration, or ambiguity or changes to any selection.
func (r *Unexporter) checkStructField(objsToUpdate map[types.Object]string, from *types.Var, to string) {
// Check that the struct declaration is free of field conflicts,
// and field/method conflicts.
// go/types offers no easy way to get from a field (or interface
// method) to its declaring struct (or interface), so we must
// ascend the AST.
info, path, _ := r.iprog.PathEnclosingInterval(from.Pos(), from.Pos())
// path matches this pattern:
// [Ident SelectorExpr? StarExpr? Field FieldList StructType ParenExpr* ... File]
// Ascend to FieldList.
var i int
for {
if _, ok := path[i].(*ast.FieldList); ok {
break
}
i++
}
i++
tStruct := path[i].(*ast.StructType)
i++
// Ascend past parens (unlikely).
for {
_, ok := path[i].(*ast.ParenExpr)
if !ok {
break
}
i++
}
if spec, ok := path[i].(*ast.TypeSpec); ok {
// This struct is also a named type.
// We must check for direct (non-promoted) field/field
// and method/field conflicts.
named := info.Defs[spec.Name].Type()
prev, indices, _ := types.LookupFieldOrMethod(named, true, info.Pkg, to)
if len(indices) == 1 {
r.warn(from,
r.errorf(from.Pos(), "renaming this field %q to %q",
from.Name(), to),
r.errorf(prev.Pos(), "\twould conflict with this %s",
objectKind(prev)))
return // skip checkSelections to avoid redundant errors
}
} else {
// This struct is not a named type.
// We need only check for direct (non-promoted) field/field conflicts.
t := info.Types[tStruct].Type.Underlying().(*types.Struct)
for i := 0; i < t.NumFields(); i++ {
if prev := t.Field(i); prev.Name() == to {
r.warn(from,
r.errorf(from.Pos(), "renaming this field %q to %q",
from.Name(), to),
r.errorf(prev.Pos(), "\twould conflict with this field"))
return // skip checkSelections to avoid redundant errors
}
}
}
// Renaming an anonymous field requires renaming the type too. e.g.
// print(s.T) // if we rename T to U,
// type T int // this and
// var s struct {T} // this must change too.
if from.Anonymous() {
if named, ok := from.Type().(*types.Named); ok {
r.check(objsToUpdate, named.Obj(), to)
} else if named, ok := deref(from.Type()).(*types.Named); ok {
r.check(objsToUpdate, named.Obj(), to)
}
}
// Check integrity of existing (field and method) selections.
r.checkSelections(objsToUpdate, from, to)
}
示例11: findObjects
// On success, findObjects returns the list of objects named
// spec.fromName matching the spec. On success, the result has exactly
// one element unless spec.searchFor!="", in which case it has at least one
// element.
//
func findObjects(info *loader.PackageInfo, spec *spec) ([]types.Object, error) {
if spec.pkgMember == "" {
if spec.searchFor == "" {
panic(spec)
}
objects := searchDefs(&info.Info, spec.searchFor)
if objects == nil {
return nil, fmt.Errorf("no object %q declared in package %q",
spec.searchFor, info.Pkg.Path())
}
return objects, nil
}
pkgMember := info.Pkg.Scope().Lookup(spec.pkgMember)
if pkgMember == nil {
return nil, fmt.Errorf("package %q has no member %q",
info.Pkg.Path(), spec.pkgMember)
}
var searchFunc *types.Func
if spec.typeMember == "" {
// package member
if spec.searchFor == "" {
return []types.Object{pkgMember}, nil
}
// Search within pkgMember, which must be a function.
searchFunc, _ = pkgMember.(*types.Func)
if searchFunc == nil {
return nil, fmt.Errorf("cannot search for %q within %s %q",
spec.searchFor, objectKind(pkgMember), pkgMember)
}
} else {
// field/method of type
// e.g. (encoding/json.Decoder).Decode
// or ::x within it.
tName, _ := pkgMember.(*types.TypeName)
if tName == nil {
return nil, fmt.Errorf("%s.%s is a %s, not a type",
info.Pkg.Path(), pkgMember.Name(), objectKind(pkgMember))
}
// search within named type.
obj, _, _ := types.LookupFieldOrMethod(tName.Type(), true, info.Pkg, spec.typeMember)
if obj == nil {
return nil, fmt.Errorf("cannot find field or method %q of %s %s.%s",
spec.typeMember, typeKind(tName.Type()), info.Pkg.Path(), tName.Name())
}
if spec.searchFor == "" {
return []types.Object{obj}, nil
}
searchFunc, _ = obj.(*types.Func)
if searchFunc == nil {
return nil, fmt.Errorf("cannot search for local name %q within %s (%s.%s).%s; need a function",
spec.searchFor, objectKind(obj), info.Pkg.Path(), tName.Name(),
obj.Name())
}
if isInterface(tName.Type()) {
return nil, fmt.Errorf("cannot search for local name %q within abstract method (%s.%s).%s",
spec.searchFor, info.Pkg.Path(), tName.Name(), searchFunc.Name())
}
}
// -- search within function or method --
decl := funcDecl(info, searchFunc)
if decl == nil {
return nil, fmt.Errorf("cannot find syntax for %s", searchFunc) // can't happen?
}
var objects []types.Object
for _, obj := range searchDefs(&info.Info, spec.searchFor) {
// We use positions, not scopes, to determine whether
// the obj is within searchFunc. This is clumsy, but the
// alternative, using the types.Scope tree, doesn't
// account for non-lexical objects like fields and
// interface methods.
if decl.Pos() <= obj.Pos() && obj.Pos() < decl.End() && obj != searchFunc {
objects = append(objects, obj)
}
}
if objects == nil {
return nil, fmt.Errorf("no local definition of %q within %s",
spec.searchFor, searchFunc)
}
return objects, nil
}
示例12: checkMethod
func (e *Export) checkMethod(from *types.Func, to string) {
// e.g. error.Error
if from.Pkg() == nil {
e.Conflicting = true
return
}
// ASSIGNABILITY: We reject renamings of concrete methods that
// would break a 'satisfy' constraint; but renamings of abstract
// methods are allowed to proceed, and we rename affected
// concrete and abstract methods as necessary. It is the
// initial method that determines the policy.
// Check for conflict at point of declaration.
// Check to ensure preservation of assignability requirements.
R := recv(from).Type()
if isInterface(R) {
// Abstract method
// declaration
prev, _, _ := types.LookupFieldOrMethod(R, false, from.Pkg(), to)
if prev != nil {
e.Conflicting = true
return
}
// Check all interfaces that embed this one for
// declaration conflicts too.
for _, info := range e.u.prog.AllPackages {
// Start with named interface types (better errors)
for _, obj := range info.Defs {
if obj, ok := obj.(*types.TypeName); ok && isInterface(obj.Type()) {
f, _, _ := types.LookupFieldOrMethod(
obj.Type(), false, from.Pkg(), from.Name())
if f == nil {
continue
}
t, _, _ := types.LookupFieldOrMethod(obj.Type(), false, from.Pkg(), to)
if t == nil {
continue
}
e.Conflicting = true
return
}
}
}
// assignability
//
// Find the set of concrete or abstract methods directly
// coupled to abstract method 'from' by some
// satisfy.Constraint, and rename them too.
for key := range e.u.satisfy() {
// key = (lhs, rhs) where lhs is always an interface.
lsel := e.u.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name())
if lsel == nil {
continue
}
rmethods := e.u.msets.MethodSet(key.RHS)
rsel := rmethods.Lookup(from.Pkg(), from.Name())
if rsel == nil {
continue
}
// If both sides have a method of this name,
// and one of them is m, the other must be coupled.
var coupled *types.Func
switch from {
case lsel.Obj():
coupled = rsel.Obj().(*types.Func)
case rsel.Obj():
coupled = lsel.Obj().(*types.Func)
default:
continue
}
// We must treat concrete-to-interface
// constraints like an implicit selection C.f of
// each interface method I.f, and check that the
// renaming leaves the selection unchanged and
// unambiguous.
//
// Fun fact: the implicit selection of C.f
// type I interface{f()}
// type C struct{I}
// func (C) g()
// var _ I = C{} // here
// yields abstract method I.f. This can make error
// messages less than obvious.
//
if !isInterface(key.RHS) {
// The logic below was derived from checkSelections.
rtosel := rmethods.Lookup(from.Pkg(), to)
if rtosel != nil {
delta := len(rsel.Index()) - len(rtosel.Index())
if delta < 0 {
continue // no ambiguity
}
//.........這裏部分代碼省略.........
示例13: hasMethod
// hasMethod reports whether the type contains a method with the given name.
// It is part of the workaround for Formatters and should be deleted when
// that workaround is no longer necessary.
// TODO: This could be better once issue 6259 is fixed.
func (f *File) hasMethod(typ types.Type, name string) bool {
// assume we have an addressable variable of type typ
obj, _, _ := types.LookupFieldOrMethod(typ, true, f.pkg.typesPkg, name)
_, ok := obj.(*types.Func)
return ok
}
示例14: checkExample
// checkExample walks the documentation example functions checking for common
// mistakes of misnamed functions, failure to map functions to existing
// identifiers, etc.
func checkExample(f *File, node ast.Node) {
if !f.IsTest() {
return
}
var (
pkg = f.pkg
pkgName = pkg.typesPkg.Name()
scopes = []*types.Scope{pkg.typesPkg.Scope()}
lookup = func(name string) types.Object {
for _, scope := range scopes {
if o := scope.Lookup(name); o != nil {
return o
}
}
return nil
}
)
if strings.HasSuffix(pkgName, "_test") {
// Treat 'package foo_test' as an alias for 'package foo'.
var (
basePkg = strings.TrimSuffix(pkgName, "_test")
pkg = f.pkg
)
for _, p := range pkg.typesPkg.Imports() {
if p.Name() == basePkg {
scopes = append(scopes, p.Scope())
break
}
}
}
fn, ok := node.(*ast.FuncDecl)
if !ok {
// Ignore non-functions.
return
}
var (
fnName = fn.Name.Name
report = func(format string, args ...interface{}) { f.Badf(node.Pos(), format, args...) }
)
if fn.Recv != nil || !strings.HasPrefix(fnName, "Example") {
// Ignore methods and types not named "Example".
return
}
if params := fn.Type.Params; len(params.List) != 0 {
report("%s should be niladic", fnName)
}
if results := fn.Type.Results; results != nil && len(results.List) != 0 {
report("%s should return nothing", fnName)
}
if fnName == "Example" {
// Nothing more to do.
return
}
if filesRun && !includesNonTest {
// The coherence checks between a test and the package it tests
// will report false positives if no non-test files have
// been provided.
return
}
var (
exName = strings.TrimPrefix(fnName, "Example")
elems = strings.SplitN(exName, "_", 3)
ident = elems[0]
obj = lookup(ident)
)
if ident != "" && obj == nil {
// Check ExampleFoo and ExampleBadFoo.
report("%s refers to unknown identifier: %s", fnName, ident)
// Abort since obj is absent and no subsequent checks can be performed.
return
}
if elemCnt := strings.Count(exName, "_"); elemCnt == 0 {
// Nothing more to do.
return
}
mmbr := elems[1]
if ident == "" {
// Check Example_suffix and Example_BadSuffix.
if residual := strings.TrimPrefix(exName, "_"); !isExampleSuffix(residual) {
report("%s has malformed example suffix: %s", fnName, residual)
}
return
}
if !isExampleSuffix(mmbr) {
// Check ExampleFoo_Method and ExampleFoo_BadMethod.
if obj, _, _ := types.LookupFieldOrMethod(obj.Type(), true, obj.Pkg(), mmbr); obj == nil {
report("%s refers to unknown field or method: %s.%s", fnName, ident, mmbr)
}
}
if len(elems) == 3 && !isExampleSuffix(elems[2]) {
// Check ExampleFoo_Method_suffix and ExampleFoo_Method_Badsuffix.
report("%s has malformed example suffix: %s", fnName, elems[2])
}
return
}
示例15: main
func main() {
flag.Parse()
exitStatus := 0
importPaths := gotool.ImportPaths(flag.Args())
if len(importPaths) == 0 {
importPaths = []string{"."}
}
ctx := build.Default
for _, pkgPath := range importPaths {
visitor := &visitor{
m: make(map[types.Type]map[string]int),
skip: make(map[types.Type]struct{}),
}
loadcfg := loader.Config{
Build: &ctx,
}
rest, err := loadcfg.FromArgs([]string{pkgPath}, *loadTestFiles)
if err != nil {
fmt.Fprintf(os.Stderr, "could not parse arguments: %s", err)
continue
}
if len(rest) > 0 {
fmt.Fprintf(os.Stderr, "unhandled extra arguments: %v", rest)
continue
}
program, err := loadcfg.Load()
if err != nil {
fmt.Fprintf(os.Stderr, "could not type check: %s", err)
continue
}
pkg := program.InitialPackages()[0]
visitor.prog = program
visitor.pkg = pkg
for _, f := range pkg.Files {
ast.Walk(visitor, f)
}
for t := range visitor.m {
if _, skip := visitor.skip[t]; skip {
continue
}
for fieldName, v := range visitor.m[t] {
if !*reportExported && ast.IsExported(fieldName) {
continue
}
if v == 0 {
field, _, _ := types.LookupFieldOrMethod(t, false, pkg.Pkg, fieldName)
if fieldName == "XMLName" {
if named, ok := field.Type().(*types.Named); ok && named.Obj().Pkg().Path() == "encoding/xml" {
continue
}
}
pos := program.Fset.Position(field.Pos())
fmt.Printf("%s: %s:%d:%d: %s.%s\n",
pkgPath, pos.Filename, pos.Line, pos.Column,
types.TypeString(t, nil), fieldName,
)
exitStatus = 1
}
}
}
}
os.Exit(exitStatus)
}