some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / cfg / builder.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/cfg/builder.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/cfg/builder.go
deleted file mode 100644 (file)
index 7f95a29..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cfg
-
-// This file implements the CFG construction pass.
-
-import (
-       "fmt"
-       "go/ast"
-       "go/token"
-)
-
-type builder struct {
-       cfg       *CFG
-       mayReturn func(*ast.CallExpr) bool
-       current   *Block
-       lblocks   map[*ast.Object]*lblock // labeled blocks
-       targets   *targets                // linked stack of branch targets
-}
-
-func (b *builder) stmt(_s ast.Stmt) {
-       // The label of the current statement.  If non-nil, its _goto
-       // target is always set; its _break and _continue are set only
-       // within the body of switch/typeswitch/select/for/range.
-       // It is effectively an additional default-nil parameter of stmt().
-       var label *lblock
-start:
-       switch s := _s.(type) {
-       case *ast.BadStmt,
-               *ast.SendStmt,
-               *ast.IncDecStmt,
-               *ast.GoStmt,
-               *ast.DeferStmt,
-               *ast.EmptyStmt,
-               *ast.AssignStmt:
-               // No effect on control flow.
-               b.add(s)
-
-       case *ast.ExprStmt:
-               b.add(s)
-               if call, ok := s.X.(*ast.CallExpr); ok && !b.mayReturn(call) {
-                       // Calls to panic, os.Exit, etc, never return.
-                       b.current = b.newBlock("unreachable.call")
-               }
-
-       case *ast.DeclStmt:
-               // Treat each var ValueSpec as a separate statement.
-               d := s.Decl.(*ast.GenDecl)
-               if d.Tok == token.VAR {
-                       for _, spec := range d.Specs {
-                               if spec, ok := spec.(*ast.ValueSpec); ok {
-                                       b.add(spec)
-                               }
-                       }
-               }
-
-       case *ast.LabeledStmt:
-               label = b.labeledBlock(s.Label)
-               b.jump(label._goto)
-               b.current = label._goto
-               _s = s.Stmt
-               goto start // effectively: tailcall stmt(g, s.Stmt, label)
-
-       case *ast.ReturnStmt:
-               b.add(s)
-               b.current = b.newBlock("unreachable.return")
-
-       case *ast.BranchStmt:
-               b.branchStmt(s)
-
-       case *ast.BlockStmt:
-               b.stmtList(s.List)
-
-       case *ast.IfStmt:
-               if s.Init != nil {
-                       b.stmt(s.Init)
-               }
-               then := b.newBlock("if.then")
-               done := b.newBlock("if.done")
-               _else := done
-               if s.Else != nil {
-                       _else = b.newBlock("if.else")
-               }
-               b.add(s.Cond)
-               b.ifelse(then, _else)
-               b.current = then
-               b.stmt(s.Body)
-               b.jump(done)
-
-               if s.Else != nil {
-                       b.current = _else
-                       b.stmt(s.Else)
-                       b.jump(done)
-               }
-
-               b.current = done
-
-       case *ast.SwitchStmt:
-               b.switchStmt(s, label)
-
-       case *ast.TypeSwitchStmt:
-               b.typeSwitchStmt(s, label)
-
-       case *ast.SelectStmt:
-               b.selectStmt(s, label)
-
-       case *ast.ForStmt:
-               b.forStmt(s, label)
-
-       case *ast.RangeStmt:
-               b.rangeStmt(s, label)
-
-       default:
-               panic(fmt.Sprintf("unexpected statement kind: %T", s))
-       }
-}
-
-func (b *builder) stmtList(list []ast.Stmt) {
-       for _, s := range list {
-               b.stmt(s)
-       }
-}
-
-func (b *builder) branchStmt(s *ast.BranchStmt) {
-       var block *Block
-       switch s.Tok {
-       case token.BREAK:
-               if s.Label != nil {
-                       if lb := b.labeledBlock(s.Label); lb != nil {
-                               block = lb._break
-                       }
-               } else {
-                       for t := b.targets; t != nil && block == nil; t = t.tail {
-                               block = t._break
-                       }
-               }
-
-       case token.CONTINUE:
-               if s.Label != nil {
-                       if lb := b.labeledBlock(s.Label); lb != nil {
-                               block = lb._continue
-                       }
-               } else {
-                       for t := b.targets; t != nil && block == nil; t = t.tail {
-                               block = t._continue
-                       }
-               }
-
-       case token.FALLTHROUGH:
-               for t := b.targets; t != nil && block == nil; t = t.tail {
-                       block = t._fallthrough
-               }
-
-       case token.GOTO:
-               if s.Label != nil {
-                       block = b.labeledBlock(s.Label)._goto
-               }
-       }
-       if block == nil {
-               block = b.newBlock("undefined.branch")
-       }
-       b.jump(block)
-       b.current = b.newBlock("unreachable.branch")
-}
-
-func (b *builder) switchStmt(s *ast.SwitchStmt, label *lblock) {
-       if s.Init != nil {
-               b.stmt(s.Init)
-       }
-       if s.Tag != nil {
-               b.add(s.Tag)
-       }
-       done := b.newBlock("switch.done")
-       if label != nil {
-               label._break = done
-       }
-       // We pull the default case (if present) down to the end.
-       // But each fallthrough label must point to the next
-       // body block in source order, so we preallocate a
-       // body block (fallthru) for the next case.
-       // Unfortunately this makes for a confusing block order.
-       var defaultBody *[]ast.Stmt
-       var defaultFallthrough *Block
-       var fallthru, defaultBlock *Block
-       ncases := len(s.Body.List)
-       for i, clause := range s.Body.List {
-               body := fallthru
-               if body == nil {
-                       body = b.newBlock("switch.body") // first case only
-               }
-
-               // Preallocate body block for the next case.
-               fallthru = done
-               if i+1 < ncases {
-                       fallthru = b.newBlock("switch.body")
-               }
-
-               cc := clause.(*ast.CaseClause)
-               if cc.List == nil {
-                       // Default case.
-                       defaultBody = &cc.Body
-                       defaultFallthrough = fallthru
-                       defaultBlock = body
-                       continue
-               }
-
-               var nextCond *Block
-               for _, cond := range cc.List {
-                       nextCond = b.newBlock("switch.next")
-                       b.add(cond) // one half of the tag==cond condition
-                       b.ifelse(body, nextCond)
-                       b.current = nextCond
-               }
-               b.current = body
-               b.targets = &targets{
-                       tail:         b.targets,
-                       _break:       done,
-                       _fallthrough: fallthru,
-               }
-               b.stmtList(cc.Body)
-               b.targets = b.targets.tail
-               b.jump(done)
-               b.current = nextCond
-       }
-       if defaultBlock != nil {
-               b.jump(defaultBlock)
-               b.current = defaultBlock
-               b.targets = &targets{
-                       tail:         b.targets,
-                       _break:       done,
-                       _fallthrough: defaultFallthrough,
-               }
-               b.stmtList(*defaultBody)
-               b.targets = b.targets.tail
-       }
-       b.jump(done)
-       b.current = done
-}
-
-func (b *builder) typeSwitchStmt(s *ast.TypeSwitchStmt, label *lblock) {
-       if s.Init != nil {
-               b.stmt(s.Init)
-       }
-       if s.Assign != nil {
-               b.add(s.Assign)
-       }
-
-       done := b.newBlock("typeswitch.done")
-       if label != nil {
-               label._break = done
-       }
-       var default_ *ast.CaseClause
-       for _, clause := range s.Body.List {
-               cc := clause.(*ast.CaseClause)
-               if cc.List == nil {
-                       default_ = cc
-                       continue
-               }
-               body := b.newBlock("typeswitch.body")
-               var next *Block
-               for _, casetype := range cc.List {
-                       next = b.newBlock("typeswitch.next")
-                       // casetype is a type, so don't call b.add(casetype).
-                       // This block logically contains a type assertion,
-                       // x.(casetype), but it's unclear how to represent x.
-                       _ = casetype
-                       b.ifelse(body, next)
-                       b.current = next
-               }
-               b.current = body
-               b.typeCaseBody(cc, done)
-               b.current = next
-       }
-       if default_ != nil {
-               b.typeCaseBody(default_, done)
-       } else {
-               b.jump(done)
-       }
-       b.current = done
-}
-
-func (b *builder) typeCaseBody(cc *ast.CaseClause, done *Block) {
-       b.targets = &targets{
-               tail:   b.targets,
-               _break: done,
-       }
-       b.stmtList(cc.Body)
-       b.targets = b.targets.tail
-       b.jump(done)
-}
-
-func (b *builder) selectStmt(s *ast.SelectStmt, label *lblock) {
-       // First evaluate channel expressions.
-       // TODO(adonovan): fix: evaluate only channel exprs here.
-       for _, clause := range s.Body.List {
-               if comm := clause.(*ast.CommClause).Comm; comm != nil {
-                       b.stmt(comm)
-               }
-       }
-
-       done := b.newBlock("select.done")
-       if label != nil {
-               label._break = done
-       }
-
-       var defaultBody *[]ast.Stmt
-       for _, cc := range s.Body.List {
-               clause := cc.(*ast.CommClause)
-               if clause.Comm == nil {
-                       defaultBody = &clause.Body
-                       continue
-               }
-               body := b.newBlock("select.body")
-               next := b.newBlock("select.next")
-               b.ifelse(body, next)
-               b.current = body
-               b.targets = &targets{
-                       tail:   b.targets,
-                       _break: done,
-               }
-               switch comm := clause.Comm.(type) {
-               case *ast.ExprStmt: // <-ch
-                       // nop
-               case *ast.AssignStmt: // x := <-states[state].Chan
-                       b.add(comm.Lhs[0])
-               }
-               b.stmtList(clause.Body)
-               b.targets = b.targets.tail
-               b.jump(done)
-               b.current = next
-       }
-       if defaultBody != nil {
-               b.targets = &targets{
-                       tail:   b.targets,
-                       _break: done,
-               }
-               b.stmtList(*defaultBody)
-               b.targets = b.targets.tail
-               b.jump(done)
-       }
-       b.current = done
-}
-
-func (b *builder) forStmt(s *ast.ForStmt, label *lblock) {
-       //      ...init...
-       //      jump loop
-       // loop:
-       //      if cond goto body else done
-       // body:
-       //      ...body...
-       //      jump post
-       // post:                                 (target of continue)
-       //      ...post...
-       //      jump loop
-       // done:                                 (target of break)
-       if s.Init != nil {
-               b.stmt(s.Init)
-       }
-       body := b.newBlock("for.body")
-       done := b.newBlock("for.done") // target of 'break'
-       loop := body                   // target of back-edge
-       if s.Cond != nil {
-               loop = b.newBlock("for.loop")
-       }
-       cont := loop // target of 'continue'
-       if s.Post != nil {
-               cont = b.newBlock("for.post")
-       }
-       if label != nil {
-               label._break = done
-               label._continue = cont
-       }
-       b.jump(loop)
-       b.current = loop
-       if loop != body {
-               b.add(s.Cond)
-               b.ifelse(body, done)
-               b.current = body
-       }
-       b.targets = &targets{
-               tail:      b.targets,
-               _break:    done,
-               _continue: cont,
-       }
-       b.stmt(s.Body)
-       b.targets = b.targets.tail
-       b.jump(cont)
-
-       if s.Post != nil {
-               b.current = cont
-               b.stmt(s.Post)
-               b.jump(loop) // back-edge
-       }
-       b.current = done
-}
-
-func (b *builder) rangeStmt(s *ast.RangeStmt, label *lblock) {
-       b.add(s.X)
-
-       if s.Key != nil {
-               b.add(s.Key)
-       }
-       if s.Value != nil {
-               b.add(s.Value)
-       }
-
-       //      ...
-       // loop:                                   (target of continue)
-       //      if ... goto body else done
-       // body:
-       //      ...
-       //      jump loop
-       // done:                                   (target of break)
-
-       loop := b.newBlock("range.loop")
-       b.jump(loop)
-       b.current = loop
-
-       body := b.newBlock("range.body")
-       done := b.newBlock("range.done")
-       b.ifelse(body, done)
-       b.current = body
-
-       if label != nil {
-               label._break = done
-               label._continue = loop
-       }
-       b.targets = &targets{
-               tail:      b.targets,
-               _break:    done,
-               _continue: loop,
-       }
-       b.stmt(s.Body)
-       b.targets = b.targets.tail
-       b.jump(loop) // back-edge
-       b.current = done
-}
-
-// -------- helpers --------
-
-// Destinations associated with unlabeled for/switch/select stmts.
-// We push/pop one of these as we enter/leave each construct and for
-// each BranchStmt we scan for the innermost target of the right type.
-//
-type targets struct {
-       tail         *targets // rest of stack
-       _break       *Block
-       _continue    *Block
-       _fallthrough *Block
-}
-
-// Destinations associated with a labeled block.
-// We populate these as labels are encountered in forward gotos or
-// labeled statements.
-//
-type lblock struct {
-       _goto     *Block
-       _break    *Block
-       _continue *Block
-}
-
-// labeledBlock returns the branch target associated with the
-// specified label, creating it if needed.
-//
-func (b *builder) labeledBlock(label *ast.Ident) *lblock {
-       lb := b.lblocks[label.Obj]
-       if lb == nil {
-               lb = &lblock{_goto: b.newBlock(label.Name)}
-               if b.lblocks == nil {
-                       b.lblocks = make(map[*ast.Object]*lblock)
-               }
-               b.lblocks[label.Obj] = lb
-       }
-       return lb
-}
-
-// newBlock appends a new unconnected basic block to b.cfg's block
-// slice and returns it.
-// It does not automatically become the current block.
-// comment is an optional string for more readable debugging output.
-func (b *builder) newBlock(comment string) *Block {
-       g := b.cfg
-       block := &Block{
-               Index:   int32(len(g.Blocks)),
-               comment: comment,
-       }
-       block.Succs = block.succs2[:0]
-       g.Blocks = append(g.Blocks, block)
-       return block
-}
-
-func (b *builder) add(n ast.Node) {
-       b.current.Nodes = append(b.current.Nodes, n)
-}
-
-// jump adds an edge from the current block to the target block,
-// and sets b.current to nil.
-func (b *builder) jump(target *Block) {
-       b.current.Succs = append(b.current.Succs, target)
-       b.current = nil
-}
-
-// ifelse emits edges from the current block to the t and f blocks,
-// and sets b.current to nil.
-func (b *builder) ifelse(t, f *Block) {
-       b.current.Succs = append(b.current.Succs, t, f)
-       b.current = nil
-}