• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang token.Pos类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中go/token.Pos的典型用法代码示例。如果您正苦于以下问题:Golang Pos类的具体用法?Golang Pos怎么用?Golang Pos使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



在下文中一共展示了Pos类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。

示例1: parseCallOrConversion

func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
	if p.trace {
		defer un(trace(p, "CallOrConversion"))
	}

	lparen := p.expect(token.LPAREN)
	p.exprLev++
	var list []ast.Expr
	var ellipsis token.Pos
	for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
		list = append(list, p.parseExpr())
		if p.tok == token.ELLIPSIS {
			ellipsis = p.pos
			p.next()
		}
		if p.tok != token.COMMA {
			break
		}
		p.next()
	}
	p.exprLev--
	rparen := p.expect(token.RPAREN)

	return &ast.CallExpr{fun, lparen, list, ellipsis, rparen}
}
开发者ID:IntegerCompany,项目名称:linaro-android-gcc,代码行数:25,代码来源:parser.go


示例2: initVars

// If returnPos is valid, initVars is called to type-check the assignment of
// return expressions, and returnPos is the position of the return statement.
func (check *checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
	l := len(lhs)
	get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
	if l != r {
		// invalidate lhs
		for _, obj := range lhs {
			if obj.Type == nil {
				obj.Type = Typ[Invalid]
			}
		}
		if returnPos.IsValid() {
			check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
			return
		}
		check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
		return
	}

	var x operand
	if commaOk {
		var a [2]Type
		for i := range a {
			get(&x, i)
			a[i] = check.initVar(lhs[i], &x)
		}
		check.recordCommaOkTypes(rhs[0], a)
		return
	}

	for i, lhs := range lhs {
		get(&x, i)
		check.initVar(lhs, &x)
	}
}
开发者ID:gordonklaus,项目名称:flux,代码行数:36,代码来源:assignments.go


示例3: debugCall

func debugCall(fName string, pos token.Pos, args ...string) []byte {
	vals := make(map[string]string)
	if len(args) > 0 {
		vals["args"] = strings.Join(args, ", ")
	} else {
		vals["args"] = ""
	}

	if timing {
		vals["timing"] = "true"
	}

	vals["fname"] = fName

	if pos.IsValid() {
		vals["position"] = fset.Position(pos).String()
	}

	if showReturn {
		vals["return"] = "true"
	}

	var b bytes.Buffer
	err := funcTemplate.Execute(&b, vals)
	if err != nil {
		log.Fatal(err)
	}
	return b.Bytes()
}
开发者ID:dewrich,项目名称:gotrace,代码行数:29,代码来源:trace.go


示例4: declareObj

func (check *checker) declareObj(scope, altScope *Scope, obj Object, dotImport token.Pos) {
	alt := scope.Insert(obj)
	if alt == nil && altScope != nil {
		// see if there is a conflicting declaration in altScope
		alt = altScope.Lookup(obj.Name())
	}
	if alt != nil {
		prevDecl := ""

		// for dot-imports, local declarations are declared first - swap messages
		if dotImport.IsValid() {
			if pos := alt.Pos(); pos.IsValid() {
				check.errorf(pos, fmt.Sprintf("%s redeclared in this block by dot-import at %s",
					obj.Name(), check.fset.Position(dotImport)))
				return
			}

			// get by w/o other position
			check.errorf(dotImport, fmt.Sprintf("dot-import redeclares %s", obj.Name()))
			return
		}

		if pos := alt.Pos(); pos.IsValid() {
			prevDecl = fmt.Sprintf("\n\tother declaration at %s", check.fset.Position(pos))
		}
		check.errorf(obj.Pos(), fmt.Sprintf("%s redeclared in this block%s", obj.Name(), prevDecl))
	}
}
开发者ID:pombredanne,项目名称:go.tools,代码行数:28,代码来源:resolve.go


示例5: distanceFrom

// distanceFrom returns the column difference between from and p.pos (the current
// estimated position) if both are on the same line; if they are on different lines
// (or unknown) the result is infinity.
func (p *printer) distanceFrom(from token.Pos) int {
	if from.IsValid() && p.pos.IsValid() {
		if f := p.posFor(from); f.Line == p.pos.Line {
			return p.pos.Column - f.Column
		}
	}
	return infinity
}
开发者ID:ZeusbasePython,项目名称:appscale,代码行数:11,代码来源:nodes.go


示例6: error_

func error_(pos token.Pos, msg string, args ...interface{}) {
	nerrors++
	if pos.IsValid() {
		fmt.Fprintf(os.Stderr, "%s: ", fset.Position(pos).String())
	}
	fmt.Fprintf(os.Stderr, msg, args...)
	fmt.Fprintf(os.Stderr, "\n")
}
开发者ID:tav,项目名称:go,代码行数:8,代码来源:util.go


示例7: warn

func warn(pos token.Pos, msg string, args ...interface{}) {
	if pos.IsValid() {
		msg = "%s: " + msg
		arg1 := []interface{}{fset.Position(pos).String()}
		args = append(arg1, args...)
	}
	fmt.Fprintf(os.Stderr, msg+"\n", args...)
}
开发者ID:h8liu,项目名称:golang,代码行数:8,代码来源:fix.go


示例8: LookupParent

// LookupParent follows the parent chain of scopes starting with s until
// it finds a scope where Lookup(name) returns a non-nil object, and then
// returns that scope and object. If a valid position pos is provided,
// only objects that were declared at or before pos are considered.
// If no such scope and object exists, the result is (nil, nil).
//
// Note that obj.Parent() may be different from the returned scope if the
// object was inserted into the scope and already had a parent at that
// time (see Insert, below). This can only happen for dot-imported objects
// whose scope is the scope of the package that exported them.
func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) {
	for ; s != nil; s = s.parent {
		if obj := s.elems[name]; obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) {
			return s, obj
		}
	}
	return nil, nil
}
开发者ID:Greentor,项目名称:go,代码行数:18,代码来源:scope.go


示例9: SetLocation

// SetLocation sets the current debug location.
func (d *DIBuilder) SetLocation(b llvm.Builder, pos token.Pos) {
	if !pos.IsValid() {
		return
	}
	position := d.fset.Position(pos)
	d.lb = llvm.Metadata{}
	if position.Filename != d.fnFile && position.Filename != "" {
		// This can happen rarely, e.g. in init functions.
		diFile := d.builder.CreateFile(d.remapFilePath(position.Filename), "")
		d.lb = d.builder.CreateLexicalBlockFile(d.scope(), diFile, 0)
	}
	b.SetCurrentDebugLocation(uint(position.Line), uint(position.Column), d.scope(), llvm.Metadata{})
}
开发者ID:glycerine,项目名称:llgo,代码行数:14,代码来源:debug.go


示例10: Eval

// Eval returns the type and, if constant, the value for the
// expression expr, evaluated at position pos of package pkg,
// which must have been derived from type-checking an AST with
// complete position information relative to the provided file
// set.
//
// If the expression contains function literals, their bodies
// are ignored (i.e., the bodies are not type-checked).
//
// If pkg == nil, the Universe scope is used and the provided
// position pos is ignored. If pkg != nil, and pos is invalid,
// the package scope is used. Otherwise, pos must belong to the
// package.
//
// An error is returned if pos is not within the package or
// if the node cannot be evaluated.
//
// Note: Eval should not be used instead of running Check to compute
// types and values, but in addition to Check. Eval will re-evaluate
// its argument each time, and it also does not know about the context
// in which an expression is used (e.g., an assignment). Thus, top-
// level untyped constants will return an untyped type rather then the
// respective context-specific type.
//
func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (tv TypeAndValue, err error) {
	// determine scope
	var scope *Scope
	if pkg == nil {
		scope = Universe
		pos = token.NoPos
	} else if !pos.IsValid() {
		scope = pkg.scope
	} else {
		// The package scope extent (position information) may be
		// incorrect (files spread accross a wide range of fset
		// positions) - ignore it and just consider its children
		// (file scopes).
		for _, fscope := range pkg.scope.children {
			if scope = fscope.Innermost(pos); scope != nil {
				break
			}
		}
		if scope == nil || debug {
			s := scope
			for s != nil && s != pkg.scope {
				s = s.parent
			}
			// s == nil || s == pkg.scope
			if s == nil {
				return TypeAndValue{}, fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name)
			}
		}
	}

	// parse expressions
	// BUG(gri) In case of type-checking errors below, the type checker
	//          doesn't have the correct file set for expr. The correct
	//          solution requires a ParseExpr that uses the incoming
	//          file set fset.
	node, err := parser.ParseExpr(expr)
	if err != nil {
		return TypeAndValue{}, err
	}

	// initialize checker
	check := NewChecker(nil, fset, pkg, nil)
	check.scope = scope
	check.pos = pos
	defer check.handleBailout(&err)

	// evaluate node
	var x operand
	check.rawExpr(&x, node, nil)
	return TypeAndValue{x.mode, x.typ, x.val}, err
}
开发者ID:Christeefym,项目名称:lantern,代码行数:75,代码来源:eval.go


示例11: MakePosHash

// MakePosHash keeps track of references put into the code for later extraction in a runtime debug function.
// It returns the PosHash integer to be used for exception handling that was passed in.
func MakePosHash(pos token.Pos) PosHash {
	if pos.IsValid() {
		fname := rootProgram.Fset.Position(pos).Filename
		for f := range PosHashFileList {
			if PosHashFileList[f].FileName == fname {
				LatestValidPosHash = PosHash(PosHashFileList[f].BasePosHash + rootProgram.Fset.Position(pos).Line)
				return LatestValidPosHash
			}
		}
		panic(fmt.Errorf("pogo.MakePosHash() Cant find file: %s", fname))
	} else {
		if LatestValidPosHash == NoPosHash {
			return NoPosHash
		}
		return -LatestValidPosHash // -ve value => nearby reference
	}
}
开发者ID:joao-parana,项目名称:tardisgo,代码行数:19,代码来源:errors.go


示例12: argument

// argument checks passing of argument x to the i'th parameter of the given signature.
// If ellipsis is valid, the argument is followed by ... at that position in the call.
func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos) {
	n := sig.params.Len()

	// determine parameter type
	var typ Type
	switch {
	case i < n:
		typ = sig.params.vars[i].typ
	case sig.variadic:
		typ = sig.params.vars[n-1].typ
		if debug {
			if _, ok := typ.(*Slice); !ok {
				check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
			}
		}
	default:
		check.errorf(x.pos(), "too many arguments")
		return
	}

	if ellipsis.IsValid() {
		// argument is of the form x...
		if i != n-1 {
			check.errorf(ellipsis, "can only use ... with matching parameter")
			return
		}
		switch t := x.typ.Underlying().(type) {
		case *Slice:
			// ok
		case *Tuple:
			check.errorf(ellipsis, "cannot use ... with %d-valued expression %s", t.Len(), x)
			return
		default:
			check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
			return
		}
	} else if sig.variadic && i >= n-1 {
		// use the variadic parameter slice's element type
		typ = typ.(*Slice).elem
	}

	if !check.assignment(x, typ) && x.mode != invalid {
		check.errorf(x.pos(), "cannot pass argument %s to parameter of type %s", x, typ)
	}
}
开发者ID:2722,项目名称:lantern,代码行数:47,代码来源:call.go


示例13: SetLocation

// SetLocation sets the current debug location.
func (d *DIBuilder) SetLocation(b llvm.Builder, pos token.Pos) {
	if !pos.IsValid() {
		return
	}
	position := d.fset.Position(pos)
	d.lb = llvm.Value{nil}
	if position.Filename != d.fnFile && position.Filename != "" {
		// This can happen rarely, e.g. in init functions.
		diFile := d.builder.CreateFile(d.remapFilePath(position.Filename), "")
		d.lb = d.builder.CreateLexicalBlockFile(d.scope(), diFile, 0)
	}
	b.SetCurrentDebugLocation(llvm.MDNode([]llvm.Value{
		llvm.ConstInt(llvm.Int32Type(), uint64(position.Line), false),
		llvm.ConstInt(llvm.Int32Type(), uint64(position.Column), false),
		d.scope(),
		llvm.Value{},
	}))
}
开发者ID:hinike,项目名称:llgo,代码行数:19,代码来源:debug.go


示例14: initVars

// If returnPos is valid, initVars is called to type-check the assignment of
// return expressions, and returnPos is the position of the return statement.
func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
	l := len(lhs)
	get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
	if get == nil || l != r {
		// invalidate lhs and use rhs
		for _, obj := range lhs {
			if obj.typ == nil {
				obj.typ = Typ[Invalid]
			}
		}
		if get == nil {
			return // error reported by unpack
		}
		check.useGetter(get, r)
		if returnPos.IsValid() {
			check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
			return
		}
		check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
		return
	}

	context := "assignment"
	if returnPos.IsValid() {
		context = "return statement"
	}

	var x operand
	if commaOk {
		var a [2]Type
		for i := range a {
			get(&x, i)
			a[i] = check.initVar(lhs[i], &x, context)
		}
		check.recordCommaOkTypes(rhs[0], a)
		return
	}

	for i, lhs := range lhs {
		get(&x, i)
		check.initVar(lhs, &x, context)
	}
}
开发者ID:achanda,项目名称:go,代码行数:45,代码来源:assignments.go


示例15: argument

// argument checks passing of argument x to the i'th parameter of the given signature.
// If ellipsis is valid, the argument is followed by ... at that position in the call.
func (check *Checker) argument(fun ast.Expr, sig *Signature, i int, x *operand, ellipsis token.Pos) {
	check.singleValue(x)
	if x.mode == invalid {
		return
	}

	n := sig.params.Len()

	// determine parameter type
	var typ Type
	switch {
	case i < n:
		typ = sig.params.vars[i].typ
	case sig.variadic:
		typ = sig.params.vars[n-1].typ
		if debug {
			if _, ok := typ.(*Slice); !ok {
				check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
			}
		}
	default:
		check.errorf(x.pos(), "too many arguments")
		return
	}

	if ellipsis.IsValid() {
		// argument is of the form x... and x is single-valued
		if i != n-1 {
			check.errorf(ellipsis, "can only use ... with matching parameter")
			return
		}
		if _, ok := x.typ.Underlying().(*Slice); !ok {
			check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
			return
		}
	} else if sig.variadic && i >= n-1 {
		// use the variadic parameter slice's element type
		typ = typ.(*Slice).elem
	}

	check.assignment(x, typ, check.sprintf("argument to %s", fun))
}
开发者ID:Harvey-OS,项目名称:go,代码行数:44,代码来源:call.go


示例16: newPosLink_urlFunc

func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n interface{}) string {
	// n must be an ast.Node or a *doc.Note
	return func(info *PageInfo, n interface{}) string {
		var pos, end token.Pos

		switch n := n.(type) {
		case ast.Node:
			pos = n.Pos()
			end = n.End()
		case *doc.Note:
			pos = n.Pos
			end = n.End
		default:
			panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
		}

		var relpath string
		var line int
		var low, high int // selection offset range

		if pos.IsValid() {
			p := info.FSet.Position(pos)
			relpath = p.Filename
			line = p.Line
			low = p.Offset
		}
		if end.IsValid() {
			high = info.FSet.Position(end).Offset
		}

		return srcPosLinkFunc(relpath, line, low, high)
	}
}
开发者ID:iolg,项目名称:golangdoc,代码行数:33,代码来源:godoc.go


示例17: posLink_urlFunc

// n must be an ast.Node or a *doc.Note
func posLink_urlFunc(info *PageInfo, n interface{}) string {
	var pos, end token.Pos

	switch n := n.(type) {
	case ast.Node:
		pos = n.Pos()
		end = n.End()
	case *doc.Note:
		pos = n.Pos
		end = n.End
	default:
		panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
	}

	var relpath string
	var line int
	var low, high int // selection offset range

	if pos.IsValid() {
		p := info.FSet.Position(pos)
		relpath = p.Filename
		line = p.Line
		low = p.Offset
	}
	if end.IsValid() {
		high = info.FSet.Position(end).Offset
	}

	var buf bytes.Buffer
	template.HTMLEscape(&buf, []byte(relpath))
	// selection ranges are of form "s=low:high"
	if low < high {
		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
		// if we have a selection, position the page
		// such that the selection is a bit below the top
		line -= 10
		if line < 1 {
			line = 1
		}
	}
	// line id's in html-printed source are of the
	// form "L%d" where %d stands for the line number
	if line > 0 {
		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
	}

	return buf.String()
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:49,代码来源:godoc.go


示例18: initVars

// If returnPos is valid, initVars is called to type-check the assignment of
// return expressions, and returnPos is the position of the return statement.
func (check *checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
	l := len(lhs)
	r := len(rhs)
	assert(l > 0)

	// If the lhs and rhs have corresponding expressions,
	// treat each matching pair as an individual pair.
	if l == r {
		var x operand
		for i, e := range rhs {
			check.expr(&x, e)
			check.initVar(lhs[i], &x)
		}
		return
	}

	// Otherwise, the rhs must be a single expression (possibly
	// a function call returning multiple values, or a comma-ok
	// expression).
	if r == 1 {
		// l > 1
		// Start with rhs so we have expression types
		// for declarations with implicit types.
		var x operand
		rhs := rhs[0]
		check.expr(&x, rhs)
		if x.mode == invalid {
			invalidateVars(lhs)
			return
		}

		if t, ok := x.typ.(*Tuple); ok {
			// function result
			r = t.Len()
			if l == r {
				for i, lhs := range lhs {
					x.mode = value
					x.expr = rhs
					x.typ = t.At(i).typ
					check.initVar(lhs, &x)
				}
				return
			}
		}

		if !returnPos.IsValid() && x.mode == valueok && l == 2 {
			// comma-ok expression (not permitted with return statements)
			x.mode = value
			t1 := check.initVar(lhs[0], &x)

			x.mode = value
			x.expr = rhs
			x.typ = Typ[UntypedBool]
			t2 := check.initVar(lhs[1], &x)

			if t1 != nil && t2 != nil {
				check.recordCommaOkTypes(rhs, t1, t2)
			}
			return
		}
	}

	invalidateVars(lhs)

	// lhs variables may be function result parameters (return statement);
	// use rhs position for properly located error messages
	if returnPos.IsValid() {
		check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
		return
	}
	check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:74,代码来源:assignments.go


示例19: stmt

// stmt typechecks statement s.
func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
	// statements cannot use iota in general
	// (constant declarations set it explicitly)
	assert(check.iota == nil)

	// statements must end with the same top scope as they started with
	if debug {
		defer func(scope *Scope) {
			// don't check if code is panicking
			if p := recover(); p != nil {
				panic(p)
			}
			assert(scope == check.topScope)
		}(check.topScope)
	}

	inner := ctxt &^ fallthroughOk
	switch s := s.(type) {
	case *ast.BadStmt, *ast.EmptyStmt:
		// ignore

	case *ast.DeclStmt:
		check.declStmt(s.Decl)

	case *ast.LabeledStmt:
		check.hasLabel = true
		check.stmt(ctxt, s.Stmt)

	case *ast.ExprStmt:
		// spec: "With the exception of specific built-in functions,
		// function and method calls and receive operations can appear
		// in statement context. Such statements may be parenthesized."
		var x operand
		kind := check.rawExpr(&x, s.X, nil)
		var msg string
		switch x.mode {
		default:
			if kind == statement {
				return
			}
			msg = "is not used"
		case builtin:
			msg = "must be called"
		case typexpr:
			msg = "is not an expression"
		}
		check.errorf(x.pos(), "%s %s", &x, msg)

	case *ast.SendStmt:
		var ch, x operand
		check.expr(&ch, s.Chan)
		check.expr(&x, s.Value)
		if ch.mode == invalid || x.mode == invalid {
			return
		}
		if tch, ok := ch.typ.Underlying().(*Chan); !ok || tch.dir&ast.SEND == 0 || !check.assignment(&x, tch.elt) {
			if x.mode != invalid {
				check.invalidOp(ch.pos(), "cannot send %s to channel %s", &x, &ch)
			}
		}

	case *ast.IncDecStmt:
		var op token.Token
		switch s.Tok {
		case token.INC:
			op = token.ADD
		case token.DEC:
			op = token.SUB
		default:
			check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok)
			return
		}
		var x operand
		Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
		check.binary(&x, s.X, Y, op, nil)
		if x.mode == invalid {
			return
		}
		check.assignVar(s.X, &x)

	case *ast.AssignStmt:
		switch s.Tok {
		case token.ASSIGN, token.DEFINE:
			if len(s.Lhs) == 0 {
				check.invalidAST(s.Pos(), "missing lhs in assignment")
				return
			}
			if s.Tok == token.DEFINE {
				check.shortVarDecl(s.Lhs, s.Rhs)
			} else {
				// regular assignment
				check.assignVars(s.Lhs, s.Rhs)
			}

		default:
			// assignment operations
			if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
				check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok)
				return
//.........这里部分代码省略.........
开发者ID:min4builder,项目名称:go-operators,代码行数:101,代码来源:stmt.go


示例20: getErrorInfo

func (ctxt *context) getErrorInfo(v ssa.Value, member int, enclosingPos token.Pos, seen map[ssa.Value]bool) (result *errorInfo) {
	if !enclosingPos.IsValid() {
		panicf("getErrorInfo with invalid pos; %T %s", v, v)
	}
	//	log.Printf("getErrorInfo[%d] %T %v {", member, v, v)
	//	defer func() {
	//		log.Printf("} -> %+v", result)
	//	}()

	if seen[v] {
		return &errorInfo{}
	}
	seen[v] = true
	defer delete(seen, v)
	if pos := v.Pos(); pos.IsValid() {
		enclosingPos = pos
	}
	terminate := func() []errorTermination {
		return []errorTermination{{
			val: v,
			pos: enclosingPos,
		}}
	}
	switch v := v.(type) {
	case *ssa.Call:
		if member > 0 && member != v.Type().(*types.Tuple).Len()-1 {
			log.Printf("error from non-final member of function")
			return &errorInfo{unknown: terminate()}
		}
		return &errorInfo{nested: []*ssa.Call{v}}
	case *ssa.ChangeInterface:
		return ctxt.getErrorInfo(v.X, 0, enclosingPos, seen)
	case *ssa.Extract:
		return ctxt.getErrorInfo(v.Tuple, v.Index, enclosingPos, seen)
	case *ssa.Field:
		return &errorInfo{unknown: terminate()}
	case *ssa.Index:
		return &errorInfo{unknown: terminate()}
	case *ssa.Lookup:
		return &errorInfo{unknown: terminate()}
	case *ssa.Const:
		if v.Value != nil {
			panicf("non-nil constant cannot make error, surely?")
		}
		return &errorInfo{}
	case *ssa.MakeInterface:
		// TODO look into components of v.X
		return &errorInfo{nonNil: terminate()}
	case *ssa.Next:
		return &errorInfo{unknown: terminate()}
	case *ssa.Parameter:
		return &errorInfo{unknown: terminate()}
	case *ssa.Phi:
		var info errorInfo
		for _, edge := range v.Edges {
			info.add(ctxt.getErrorInfo(edge, member, enclosingPos, seen))
		}
		return &info
	case *ssa.Select:
		return &errorInfo{unknown: terminate()}
	case *ssa.TypeAssert:
		if v.CommaOk {
			return &errorInfo{unknown: terminate()}
		}
		return ctxt.getErrorInfo(v.X, 0, enclosingPos, seen)
	case *ssa.UnOp:
		switch v.Op {
		case token.ARROW:
			return &errorInfo{unknown: terminate()}
		case token.MUL:
			if _, isGlobal := v.X.(*ssa.Global); isGlobal {
				// Assume that if we're returning a global variable, it's a
				// global non-nil error, such as os.ErrInvalid.
				return &errorInfo{nonNil: terminate()}
			}
			return &errorInfo{unknown: terminate()}
		default:
			panicf("unexpected unary operator %s at %s", v, ctxt.lprog.Fset.Position(enclosingPos))
		}
	}
	panicf("unexpected value found for error: %T; %v", v, v)
	panic("not reached")
}
开发者ID:juanman2,项目名称:dot-emacs,代码行数:83,代码来源:errorpaths.go



注:本文中的go/token.Pos类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang token.Position类代码示例发布时间:2022-05-28
下一篇:
Golang token.FileSet类代码示例发布时间:2022-05-28
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap