本文整理汇总了Golang中golang.org/x/tools/go/types.Var.Pos方法的典型用法代码示例。如果您正苦于以下问题:Golang Var.Pos方法的具体用法?Golang Var.Pos怎么用?Golang Var.Pos使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类golang.org/x/tools/go/types.Var
的用法示例。
在下文中一共展示了Var.Pos方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: getDeclareStructOrInterface
func getDeclareStructOrInterface(prog *loader.Program, v *types.Var) string {
// From x/tools/refactor/rename/check.go(checkStructField)#L288
// 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.
_, path, _ := prog.PathEnclosingInterval(v.Pos(), v.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++
_ = path[i].(*ast.StructType)
i++
for {
if _, ok := path[i].(*ast.ParenExpr); !ok {
break
}
i++
}
if spec, ok := path[i].(*ast.TypeSpec); ok {
return spec.Name.String()
}
return ""
}
示例2: VarValue
// VarValue returns the SSA Value that corresponds to a specific
// identifier denoting the source-level named variable obj.
//
// VarValue returns nil if a local variable was not found, perhaps
// because its package was not built, the debug information was not
// requested during SSA construction, or the value was optimized away.
//
// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval),
// and that ident must resolve to obj.
//
// pkg is the package enclosing the reference. (A reference to a var
// always occurs within a function, so we need to know where to find it.)
//
// If the identifier is a field selector and its base expression is
// non-addressable, then VarValue returns the value of that field.
// For example:
// func f() struct {x int}
// f().x // VarValue(x) returns a *Field instruction of type int
//
// All other identifiers denote addressable locations (variables).
// For them, VarValue may return either the variable's address or its
// value, even when the expression is evaluated only for its value; the
// situation is reported by isAddr, the second component of the result.
//
// If !isAddr, the returned value is the one associated with the
// specific identifier. For example,
// var x int // VarValue(x) returns Const 0 here
// x = 1 // VarValue(x) returns Const 1 here
//
// It is not specified whether the value or the address is returned in
// any particular case, as it may depend upon optimizations performed
// during SSA code generation, such as registerization, constant
// folding, avoidance of materialization of subexpressions, etc.
//
func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) {
// All references to a var are local to some function, possibly init.
fn := EnclosingFunction(pkg, ref)
if fn == nil {
return // e.g. def of struct field; SSA not built?
}
id := ref[0].(*ast.Ident)
// Defining ident of a parameter?
if id.Pos() == obj.Pos() {
for _, param := range fn.Params {
if param.Object() == obj {
return param, false
}
}
}
// Other ident?
for _, b := range fn.Blocks {
for _, instr := range b.Instrs {
if dr, ok := instr.(*DebugRef); ok {
if dr.Pos() == id.Pos() {
return dr.X, dr.IsAddr
}
}
}
}
// Defining ident of package-level var?
if v := prog.packageLevelValue(obj); v != nil {
return v.(*Global), true
}
return // e.g. debug info not requested, or var optimized away
}
示例3: 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)
}