本文整理汇总了Golang中go/types.LookupFieldOrMethod函数的典型用法代码示例。如果您正苦于以下问题:Golang LookupFieldOrMethod函数的具体用法?Golang LookupFieldOrMethod怎么用?Golang LookupFieldOrMethod使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了LookupFieldOrMethod函数的16个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的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 *renamer) checkSelections(from types.Object) {
for pkg, info := range r.packages {
if id := someUse(info, from); id != nil {
if !r.checkExport(id, pkg, from) {
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(), r.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(from, delta, syntax, obj)
return
}
} else if sel.Obj().Name() == r.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(from, -delta, syntax, sel.Obj())
return
}
}
}
}
}
开发者ID:ChloeTigre,项目名称:golang-tools,代码行数:62,代码来源:check.go
示例2: Ident
// Ident looks up a definition by its import path and identifier names.
//
// buildCtx can be used to control GOPATH, GOOS, GOARCH, build tags,
// and such. If buildCtx is nil, go/build.Default is used.
func Ident(lookup string, buildCtx *build.Context) (*token.Position, error) {
if buildCtx == nil {
buildCtx = &build.Default
}
importPath, lookup := lookup, ""
if idx := strings.IndexByte(importPath, '#'); idx >= 0 {
importPath, lookup = importPath[:idx], importPath[idx+1:]
}
idents := strings.Split(lookup, ".")
fset := token.NewFileSet()
imp := newImporter(buildCtx, fset)
pkg, err := imp.Import(importPath)
if err != nil {
return nil, fmt.Errorf("cannot import path: %q: %v", importPath, err)
}
obj := pkg.Scope().Lookup(idents[0])
if obj == nil {
return nil, fmt.Errorf("identifier not found: %q", idents[0])
}
for _, name := range idents[1:] {
obj, _, _ = types.LookupFieldOrMethod(obj.Type(), true, pkg, name)
if obj == nil {
return nil, fmt.Errorf("field or method not found: %q", name)
}
}
p := fset.Position(obj.Pos())
return &p, nil
}
开发者ID:tv42,项目名称:where,代码行数:37,代码来源:where.go
示例3: checkExample
func checkExample(fn *ast.FuncDecl, pkg *Package, report reporter) {
fnName := fn.Name.Name
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 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
}
if fnName == "Example" {
// Nothing more to do.
return
}
var (
exName = strings.TrimPrefix(fnName, "Example")
elems = strings.SplitN(exName, "_", 3)
ident = elems[0]
obj = lookup(ident, extendedScope(pkg))
)
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 len(elems) < 2 {
// Nothing more to do.
return
}
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
}
mmbr := elems[1]
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])
}
}
开发者ID:ybluesky,项目名称:go,代码行数:58,代码来源:tests.go
示例4:
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
}
开发者ID:ChloeTigre,项目名称:golang-tools,代码行数:9,代码来源:external.go
示例5: 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)
}
开发者ID:syreclabs,项目名称:go-tools,代码行数:12,代码来源:match18.go
示例6: accessibleFields
// accessibleFields returns the set of accessible
// field selections on a value of type recv.
func accessibleFields(recv types.Type, from *types.Package) []describeField {
wantField := func(f *types.Var) bool {
if !isAccessibleFrom(f, from) {
return false
}
// Check that the field is not shadowed.
obj, _, _ := types.LookupFieldOrMethod(recv, true, f.Pkg(), f.Name())
return obj == f
}
var fields []describeField
var visit func(t types.Type, stack []*types.Named)
visit = func(t types.Type, stack []*types.Named) {
tStruct, ok := deref(t).Underlying().(*types.Struct)
if !ok {
return
}
fieldloop:
for i := 0; i < tStruct.NumFields(); i++ {
f := tStruct.Field(i)
// Handle recursion through anonymous fields.
if f.Anonymous() {
tf := f.Type()
if ptr, ok := tf.(*types.Pointer); ok {
tf = ptr.Elem()
}
if named, ok := tf.(*types.Named); ok { // (be defensive)
// If we've already visited this named type
// on this path, break the cycle.
for _, x := range stack {
if x == named {
continue fieldloop
}
}
visit(f.Type(), append(stack, named))
}
}
// Save accessible fields.
if wantField(f) {
fields = append(fields, describeField{
implicits: append([]*types.Named(nil), stack...),
field: f,
})
}
}
}
visit(recv, nil)
return fields
}
开发者ID:guycook,项目名称:tools,代码行数:54,代码来源:describe.go
示例7: TestIssue13898
func TestIssue13898(t *testing.T) {
skipSpecialPlatforms(t)
// This package only handles gc export data.
if runtime.Compiler != "gc" {
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
return
}
// import go/internal/gcimporter which imports go/types partially
imports := make(map[string]*types.Package)
_, err := Import(imports, "go/internal/gcimporter", ".")
if err != nil {
t.Fatal(err)
}
// look for go/types package
var goTypesPkg *types.Package
for path, pkg := range imports {
if path == "go/types" {
goTypesPkg = pkg
break
}
}
if goTypesPkg == nil {
t.Fatal("go/types not found")
}
// look for go/types.Object type
obj := goTypesPkg.Scope().Lookup("Object")
if obj == nil {
t.Fatal("go/types.Object not found")
}
typ, ok := obj.Type().(*types.Named)
if !ok {
t.Fatalf("go/types.Object type is %v; wanted named type", typ)
}
// lookup go/types.Object.Pkg method
m, index, indirect := types.LookupFieldOrMethod(typ, false, nil, "Pkg")
if m == nil {
t.Fatalf("go/types.Object.Pkg not found (index = %v, indirect = %v)", index, indirect)
}
// the method must belong to go/types
if m.Pkg().Path() != "go/types" {
t.Fatalf("found %v; want go/types", m.Pkg())
}
}
开发者ID:syreclabs,项目名称:go-tools,代码行数:49,代码来源:gcimporter_test.go
示例8: buildTypes
func (p *Package) buildTypes() map[string]*Type {
if p.Types != nil {
return p.Types
}
p.Types = map[string]*Type{}
for _, docT := range p.DocPkg.Types {
name := docT.Name
if typesT, ok := p.TypesPkg.Scope().Lookup(name).(*types.TypeName); ok {
funcs := make(map[string]*Func, len(docT.Funcs))
for _, f := range docT.Funcs {
funcs[f.Name] = &Func{
Package: p,
Doc: f,
Types: p.TypesPkg.Scope().Lookup(f.Name).(*types.Func),
}
}
methods := make(map[string]*Func, len(docT.Methods))
for _, m := range docT.Methods {
// Must be found and be *types.Func
obj, _, _ := types.LookupFieldOrMethod(typesT.Type(), true, p.TypesPkg, m.Name)
methods[m.Name] = &Func{
Package: p,
Doc: m,
Types: obj.(*types.Func),
}
}
p.Types[name] = &Type{
Package: p,
Doc: docT,
Types: typesT,
Funcs: funcs,
Methods: methods,
}
}
}
return p.Types
}
开发者ID:motemen,项目名称:gompatible,代码行数:42,代码来源:package.go
示例9: implements
func implements(t types.Type, interfac *types.Interface, pkg *types.Package) bool {
if interfac == nil || t == nil || interfac.Empty() {
return false
}
if types.Implements(t, interfac) {
return true
}
//For some reason, interfaces that comes
//already built in (not from sources) are
//not working with types.Implements method
for i := 0; i < interfac.NumMethods(); i++ {
m := interfac.Method(i)
obj, _, _ := types.LookupFieldOrMethod(t, true, pkg, m.Name())
if obj == nil {
util.Debug("method %s not found in type %v", m.Name(), t)
return false
}
}
return true
}
开发者ID:rakyll,项目名称:GCSolutions,代码行数:20,代码来源:gounexport.go
示例10: 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 == "" {
// If it is an embedded field, return the type of the field.
if v, ok := obj.(*types.Var); ok && v.Anonymous() {
switch t := v.Type().(type) {
case *types.Pointer:
return []types.Object{t.Elem().(*types.Named).Obj()}, nil
case *types.Named:
return []types.Object{t.Obj()}, nil
}
}
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",
//.........这里部分代码省略.........
开发者ID:ChloeTigre,项目名称:golang-tools,代码行数:101,代码来源:spec.go
示例11: buildQueryStrings
//buildQueryStrings build names for matching
//if onlyExport it's true only query Exported identifier else only Unexported
func buildQueryStrings(queries chan *queryIdent, pkg *types.Package, info *types.Info, onlyExport bool) {
defer close(queries)
var typesDefs []types.Object
typesByField := make(map[types.Object]types.Object)
interfaceByMethod := make(map[types.Object]types.Object)
//get definition of types first
for ident, obj := range info.Defs {
if obj == nil {
continue
}
if ident.IsExported() != onlyExport {
//querying unexport, so we need save typesDefs for finding fields func etc..
if !onlyExport {
typesDefs = append(typesDefs, obj)
}
continue
}
switch obj.(type) {
case *types.TypeName:
var typeOfObj string
switch t := obj.Type().Underlying().(type) {
case *types.Struct:
for i := 0; i < t.NumFields(); i++ {
field := t.Field(i)
typesByField[field] = obj
}
typeOfObj = "@struct"
case *types.Interface:
for i := 0; i < t.NumMethods(); i++ {
method := t.Method(i)
interfaceByMethod[method] = obj
}
for i := 0; i < t.NumExplicitMethods(); i++ {
method := t.ExplicitMethod(i)
interfaceByMethod[method] = obj
}
typeOfObj = "@interface"
default:
typeOfObj = "@type"
}
query := pkg.Name() + "." + nameExported(obj.Name()) + typeOfObj
queries <- &queryIdent{query, ident}
typesDefs = append(typesDefs, obj)
}
}
//get rest of definitions
for ident, obj := range info.Defs {
if obj == nil {
continue
}
if ident.IsExported() != onlyExport {
continue
}
if sobj, ok := typesByField[obj]; ok {
queries <- &queryIdent{joinQuery(pkg, sobj, obj, "@attr"), ident}
} else if sobj, ok := interfaceByMethod[obj]; ok {
queries <- &queryIdent{joinQuery(pkg, sobj, obj, "@method"), ident}
} else {
switch t := obj.(type) {
case *types.Const:
queries <- &queryIdent{joinQuery(pkg, nil, obj, "@const"), ident}
case *types.Var:
if !t.IsField() {
queries <- &queryIdent{joinQuery(pkg, nil, obj, "@var"), ident}
}
case *types.Func:
foundLikeMethod := false
for _, tobj := range typesDefs {
tfield, _, _ := types.LookupFieldOrMethod(tobj.Type(), true, pkg, obj.Name())
if tfield == nil {
continue
}
if tfield.Pos() == obj.Pos() {
queries <- &queryIdent{joinQuery(pkg, tobj, tfield, "@method"), ident}
foundLikeMethod = true
}
}
if !foundLikeMethod {
queries <- &queryIdent{joinQuery(pkg, nil, obj, "@func"), ident}
}
default:
}
}
}
}
开发者ID:rakyll,项目名称:GCSolutions,代码行数:97,代码来源:main.go
示例12: 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
}
开发者ID:Harvey-OS,项目名称:go,代码行数:10,代码来源:types.go
示例13: 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)
}
开发者ID:sha1sum,项目名称:check,代码行数:66,代码来源:structcheck.go
示例14: 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 *renamer) checkMethod(from *types.Func) {
// e.g. error.Error
if from.Pkg() == nil {
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(), r.to)
if prev != nil {
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), r.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(), r.to)
if t == nil {
continue
}
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), r.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
}
//.........这里部分代码省略.........
开发者ID:ChloeTigre,项目名称:golang-tools,代码行数:101,代码来源:check.go
示例15: checkStructField
// checkStructField checks that the field renaming will not cause
// conflicts at its declaration, or ambiguity or changes to any selection.
func (r *renamer) checkStructField(from *types.Var) {
// 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, r.to)
if len(indices) == 1 {
r.errorf(from.Pos(), "renaming this field %q to %q",
from.Name(), r.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() == r.to {
r.errorf(from.Pos(), "renaming this field %q to %q",
from.Name(), r.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(named.Obj())
} else if named, ok := deref(from.Type()).(*types.Named); ok {
r.check(named.Obj())
}
}
// Check integrity of existing (field and method) selections.
r.checkSelections(from)
}
开发者ID:ChloeTigre,项目名称:golang-tools,代码行数:74,代码来源:check.go
示例16: 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 !strings.HasSuffix(f.name, "_test.go") {
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
}
开发者ID:danny8002,项目名称:go,代码行数:98,代码来源:example.go
注:本文中的go/types.LookupFieldOrMethod函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论