當前位置: 首頁>>代碼示例>>Golang>>正文


Golang types.LookupFieldOrMethod函數代碼示例

本文整理匯總了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
                }
            }
        }
    }
}
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:62,代碼來源:check.go

示例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
}
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:26,代碼來源:unexporter.go

示例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}
        }
    }
}
開發者ID:ildarisaev,項目名稱:srclib-go,代碼行數:35,代碼來源:struct_field.go

示例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)
}
開發者ID:aganno2,項目名稱:check,代碼行數:59,代碼來源:structcheck.go

示例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
}
開發者ID:binaryedge,項目名稱:40fy-client,代碼行數:9,代碼來源:external.go

示例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)
}
開發者ID:CyCoreSystems,項目名稱:coreos-kubernetes,代碼行數:12,代碼來源:match14.go

示例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
            }
        }
    }
}
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:38,代碼來源:check.go

示例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)
}
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:42,代碼來源:check.go

示例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
//.........這裏部分代碼省略.........
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:101,代碼來源:check.go

示例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)
}
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:76,代碼來源:check.go

示例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
}
開發者ID:Christeefym,項目名稱:lantern,代碼行數:95,代碼來源:spec.go

示例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
                    }
//.........這裏部分代碼省略.........
開發者ID:rakyll,項目名稱:GCSolutions,代碼行數:101,代碼來源:check.go

示例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
}
開發者ID:Lane391,項目名稱:golangdemo,代碼行數:10,代碼來源:types.go

示例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
}
開發者ID:wshert1688,項目名稱:tools,代碼行數:98,代碼來源:example.go

示例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)
}
開發者ID:alaska,項目名稱:check,代碼行數:66,代碼來源:structcheck.go


注:本文中的golang.org/x/tools/go/types.LookupFieldOrMethod函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。