本文整理汇总了Golang中go/ast.BlockStmt.End方法的典型用法代码示例。如果您正苦于以下问题:Golang BlockStmt.End方法的具体用法?Golang BlockStmt.End怎么用?Golang BlockStmt.End使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类go/ast.BlockStmt
的用法示例。
在下文中一共展示了BlockStmt.End方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: labels
// labels checks correct label use in body.
func (check *Checker) labels(body *ast.BlockStmt) {
// set of all labels in this body
all := NewScope(nil, body.Pos(), body.End(), "label")
fwdJumps := check.blockBranches(all, nil, nil, body.List)
// If there are any forward jumps left, no label was found for
// the corresponding goto statements. Either those labels were
// never defined, or they are inside blocks and not reachable
// for the respective gotos.
for _, jmp := range fwdJumps {
var msg string
name := jmp.Label.Name
if alt := all.Lookup(name); alt != nil {
msg = "goto %s jumps into block"
alt.(*Label).used = true // avoid another error
} else {
msg = "label %s not declared"
}
check.errorf(jmp.Label.Pos(), msg, name)
}
// spec: "It is illegal to define a label that is never used."
for _, obj := range all.elems {
if lbl := obj.(*Label); !lbl.used {
check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
}
}
}
示例2: lastComment
// lastComment returns the last comment inside the provided block.
func lastComment(b *ast.BlockStmt, c []*ast.CommentGroup) (i int, last *ast.CommentGroup) {
pos, end := b.Pos(), b.End()
for j, cg := range c {
if cg.Pos() < pos {
continue
}
if cg.End() > end {
break
}
i, last = j, cg
}
return
}
示例3: New
// New returns a new control-flow graph for the specified function body,
// which must be non-nil.
//
// The CFG builder calls mayReturn to determine whether a given function
// call may return. For example, calls to panic, os.Exit, and log.Fatal
// do not return, so the builder can remove infeasible graph edges
// following such calls. The builder calls mayReturn only for a
// CallExpr beneath an ExprStmt.
func New(body *ast.BlockStmt, mayReturn func(*ast.CallExpr) bool) *CFG {
b := builder{
mayReturn: mayReturn,
cfg: new(CFG),
}
b.current = b.newBlock("entry")
b.stmt(body)
// Does control fall off the end of the function's body?
// Make implicit return explicit.
if b.current != nil && !b.current.unreachable {
b.add(&ast.ReturnStmt{
Return: body.End() - 1,
})
}
return b.cfg
}
示例4: funcBody
func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) {
if trace {
if name == "" {
name = "<function literal>"
}
fmt.Printf("--- %s: %s {\n", name, sig)
defer fmt.Println("--- <end>")
}
// set function scope extent
sig.scope.pos = body.Pos()
sig.scope.end = body.End()
// save/restore current context and setup function context
// (and use 0 indentation at function start)
defer func(ctxt context, indent int) {
check.context = ctxt
check.indent = indent
}(check.context, check.indent)
check.context = context{
decl: decl,
scope: sig.scope,
sig: sig,
}
check.indent = 0
check.stmtList(0, body.List)
if check.hasLabel {
check.labels(body)
}
if sig.results.Len() > 0 && !check.isTerminating(body, "") {
check.error(body.Rbrace, "missing return")
}
// spec: "Implementation restriction: A compiler may make it illegal to
// declare a variable inside a function body if the variable is never used."
// (One could check each scope after use, but that distributes this check
// over several places because CloseScope is not always called explicitly.)
check.usage(sig.scope)
}
示例5: playExample
//.........这里部分代码省略.........
} else if topDecls[id.Obj] {
usesTopDecl = true
}
}
return true
}
ast.Inspect(body, inspectFunc)
if usesTopDecl {
// We don't support examples that are not self-contained (yet).
return nil
}
// Remove predeclared identifiers from unresolved list.
for n := range unresolved {
if predeclaredTypes[n] || predeclaredConstants[n] || predeclaredFuncs[n] {
delete(unresolved, n)
}
}
// Use unresolved identifiers to determine the imports used by this
// example. The heuristic assumes package names match base import
// paths for imports w/o renames (should be good enough most of the time).
namedImports := make(map[string]string) // [name]path
var blankImports []ast.Spec // _ imports
for _, s := range file.Imports {
p, err := strconv.Unquote(s.Path.Value)
if err != nil {
continue
}
n := path.Base(p)
if s.Name != nil {
n = s.Name.Name
switch n {
case "_":
blankImports = append(blankImports, s)
continue
case ".":
// We can't resolve dot imports (yet).
return nil
}
}
if unresolved[n] {
namedImports[n] = p
delete(unresolved, n)
}
}
// If there are other unresolved identifiers, give up because this
// synthesized file is not going to build.
if len(unresolved) > 0 {
return nil
}
// Include documentation belonging to blank imports.
var comments []*ast.CommentGroup
for _, s := range blankImports {
if c := s.(*ast.ImportSpec).Doc; c != nil {
comments = append(comments, c)
}
}
// Include comments that are inside the function body.
for _, c := range file.Comments {
if body.Pos() <= c.Pos() && c.End() <= body.End() {
comments = append(comments, c)
}
}
// Strip "Output:" commment and adjust body end position.
body, comments = stripOutputComment(body, comments)
// Synthesize import declaration.
importDecl := &ast.GenDecl{
Tok: token.IMPORT,
Lparen: 1, // Need non-zero Lparen and Rparen so that printer
Rparen: 1, // treats this as a factored import.
}
for n, p := range namedImports {
s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p)}}
if path.Base(p) != n {
s.Name = ast.NewIdent(n)
}
importDecl.Specs = append(importDecl.Specs, s)
}
importDecl.Specs = append(importDecl.Specs, blankImports...)
// Synthesize main function.
funcDecl := &ast.FuncDecl{
Name: ast.NewIdent("main"),
Type: &ast.FuncType{},
Body: body,
}
// Synthesize file.
return &ast.File{
Name: ast.NewIdent("main"),
Decls: []ast.Decl{importDecl, funcDecl},
Comments: comments,
}
}
示例6: playExample
// playExample synthesizes a new *ast.File based on the provided
// file with the provided function body as the body of main.
func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
if !strings.HasSuffix(file.Name.Name, "_test") {
// We don't support examples that are part of the
// greater package (yet).
return nil
}
// Find unresolved identifiers
unresolved := make(map[string]bool)
ast.Inspect(body, func(n ast.Node) bool {
// For an expression like fmt.Println, only add "fmt" to the
// set of unresolved names.
if e, ok := n.(*ast.SelectorExpr); ok {
if id, ok := e.X.(*ast.Ident); ok && id.Obj == nil {
unresolved[id.Name] = true
}
return false
}
if id, ok := n.(*ast.Ident); ok && id.Obj == nil {
unresolved[id.Name] = true
}
return true
})
// Remove predeclared identifiers from unresolved list.
for n := range unresolved {
if predeclaredTypes[n] || predeclaredConstants[n] || predeclaredFuncs[n] {
delete(unresolved, n)
}
}
// Use unresolved identifiers to determine the imports used by this
// example. The heuristic assumes package names match base import
// paths. (Should be good enough most of the time.)
imports := make(map[string]string) // [name]path
for _, s := range file.Imports {
p, err := strconv.Unquote(s.Path.Value)
if err != nil {
continue
}
n := path.Base(p)
if s.Name != nil {
if s.Name.Name == "." {
// We can't resolve dot imports (yet).
return nil
}
n = s.Name.Name
}
if unresolved[n] {
imports[n] = p
delete(unresolved, n)
}
}
// If there are other unresolved identifiers, give up because this
// synthesized file is not going to build.
if len(unresolved) > 0 {
return nil
}
// Filter out comments that are outside the function body.
var comments []*ast.CommentGroup
for _, c := range file.Comments {
if c.Pos() < body.Pos() || c.Pos() >= body.End() {
continue
}
comments = append(comments, c)
}
// Strip "Output:" commment and adjust body end position.
body, comments = stripOutputComment(body, comments)
// Synthesize import declaration.
importDecl := &ast.GenDecl{
Tok: token.IMPORT,
Lparen: 1, // Need non-zero Lparen and Rparen so that printer
Rparen: 1, // treats this as a factored import.
}
for n, p := range imports {
s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p)}}
if path.Base(p) != n {
s.Name = ast.NewIdent(n)
}
importDecl.Specs = append(importDecl.Specs, s)
}
// Synthesize main function.
funcDecl := &ast.FuncDecl{
Name: ast.NewIdent("main"),
Type: &ast.FuncType{},
Body: body,
}
// Synthesize file.
return &ast.File{
Name: ast.NewIdent("main"),
Decls: []ast.Decl{importDecl, funcDecl},
Comments: comments,
//.........这里部分代码省略.........
示例7: buildFunction
// buildFunction takes a function Value, a list of parameters, and a body,
// and generates code for the function.
func (c *compiler) buildFunction(f *LLVMValue, context, params, results *types.Tuple, body *ast.BlockStmt) {
if currblock := c.builder.GetInsertBlock(); !currblock.IsNil() {
defer c.builder.SetInsertPointAtEnd(currblock)
}
llvm_fn := llvm.ConstExtractValue(f.LLVMValue(), []uint32{0})
entry := llvm.AddBasicBlock(llvm_fn, "entry")
c.builder.SetInsertPointAtEnd(entry)
// For closures, context is the captured context values.
var paramoffset int
if context != nil {
paramoffset++
// Store the existing values. We're going to temporarily
// replace the values with offsets into the context param.
oldvalues := make([]*LLVMValue, context.Len())
for i := range oldvalues {
v := context.At(i)
oldvalues[i] = c.objectdata[v].Value
}
defer func() {
for i := range oldvalues {
v := context.At(i)
c.objectdata[v].Value = oldvalues[i]
}
}()
// The context parameter is a pointer to a struct
// whose elements are pointers to captured values.
arg0 := llvm_fn.Param(0)
for i := range oldvalues {
v := context.At(i)
argptr := c.builder.CreateStructGEP(arg0, i, "")
argptr = c.builder.CreateLoad(argptr, "")
ptrtyp := oldvalues[i].pointer.Type()
newvalue := c.NewValue(argptr, ptrtyp)
c.objectdata[v].Value = newvalue.makePointee()
}
}
// Bind receiver, arguments and return values to their
// identifiers/objects. We'll store each parameter on the stack so
// they're addressable.
nparams := int(params.Len())
for i := 0; i < nparams; i++ {
v := params.At(i)
name := v.Name()
if !isBlank(name) {
value := llvm_fn.Param(i + paramoffset)
c.newArgStackVar(i+1, f, v, value, name)
}
}
funcstate := &function{LLVMValue: f, results: results}
c.functions.push(funcstate)
hasdefer := hasDefer(funcstate, body)
// Allocate space on the stack for named results.
for i := 0; i < results.Len(); i++ {
v := results.At(i)
name := v.Name()
allocstack := !isBlank(name)
if !allocstack && hasdefer {
c.objectdata[v] = &ObjectData{}
allocstack = true
}
if allocstack {
typ := v.Type()
llvmtyp := c.types.ToLLVM(typ)
c.newStackVar(f, v, llvm.ConstNull(llvmtyp), name)
}
}
// Create the function body.
if hasdefer {
c.makeDeferBlock(funcstate, body)
}
c.VisitBlockStmt(body, false)
c.functions.pop()
c.setDebugLine(body.End())
// If the last instruction in the function is not a terminator, then
// we either have unreachable code or a missing optional return statement
// (the latter case is allowable only for functions without results).
//
// Use GetInsertBlock rather than LastBasicBlock, since the
// last basic block might actually be a "defer" block.
last := c.builder.GetInsertBlock()
if in := last.LastInstruction(); in.IsNil() || in.IsATerminatorInst().IsNil() {
c.builder.SetInsertPointAtEnd(last)
if results.Len() == 0 {
if funcstate.deferblock.IsNil() {
c.builder.CreateRetVoid()
} else {
c.builder.CreateBr(funcstate.deferblock)
}
} else {
//.........这里部分代码省略.........