本文整理汇总了Golang中go/ast.SwitchStmt类的典型用法代码示例。如果您正苦于以下问题:Golang SwitchStmt类的具体用法?Golang SwitchStmt怎么用?Golang SwitchStmt使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SwitchStmt类的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: wrapSwitch
func (v *visitor) wrapSwitch(_switch *ast.SwitchStmt, identList []*ast.Ident) (block *ast.BlockStmt) {
block = astPrintf(`
{
godebug.Line(ctx, %s, %s)
%s
scope := %s.EnteringNewChildScope()
_ = scope // placeholder
_ = scope // placeholder
}`, v.scopeVar, pos2lineString(_switch.Pos()), _switch.Init, v.scopeVar)[0].(*ast.BlockStmt)
block.List[3] = newDeclareCall(idents.scope, identList)
_switch.Init = nil
block.List[4] = _switch
return block
}
示例2: Visit
func (s *Sonar) Visit(n ast.Node) ast.Visitor {
// TODO: detect "x&mask==0", emit sonar(x, x&^mask)
switch nn := n.(type) {
case *ast.BinaryExpr:
break
case *ast.GenDecl:
if nn.Tok != token.VAR {
return nil // constants and types are not interesting
}
return s
case *ast.SelectorExpr:
return nil
case *ast.SwitchStmt:
if nn.Tag == nil || nn.Body == nil {
return s // recurse
}
// Replace:
// switch a := foo(); bar(a) {
// case x: ...
// case y: ...
// }
// with:
// switch {
// default:
// a := foo()
// __tmp := bar(a)
// switch {
// case __tmp == x: ...
// case __tmp == y: ...
// }
// }
// The == comparisons will be instrumented later when we recurse.
sw := new(ast.SwitchStmt)
*sw = *nn
var stmts []ast.Stmt
if sw.Init != nil {
stmts = append(stmts, sw.Init)
sw.Init = nil
}
const tmpvar = "__go_fuzz_tmp"
tmp := &ast.Ident{Name: tmpvar}
typ := s.info.Types[sw.Tag]
s.info.Types[tmp] = typ
stmts = append(stmts, &ast.AssignStmt{Lhs: []ast.Expr{tmp}, Tok: token.DEFINE, Rhs: []ast.Expr{sw.Tag}})
stmts = append(stmts, &ast.AssignStmt{Lhs: []ast.Expr{&ast.Ident{Name: "_"}}, Tok: token.ASSIGN, Rhs: []ast.Expr{tmp}})
sw.Tag = nil
stmts = append(stmts, sw)
for _, cas1 := range sw.Body.List {
cas := cas1.(*ast.CaseClause)
for i, expr := range cas.List {
tmp := &ast.Ident{Name: tmpvar, NamePos: expr.Pos()}
s.info.Types[tmp] = typ
cas.List[i] = &ast.BinaryExpr{X: tmp, Op: token.EQL, Y: expr}
}
}
nn.Tag = nil
nn.Init = nil
nn.Body = &ast.BlockStmt{List: []ast.Stmt{&ast.CaseClause{Body: stmts}}}
return s // recurse
case *ast.ForStmt:
// For condition is usually uninteresting, but produces lots of samples.
// So we skip it if it looks boring.
if nn.Init != nil {
ast.Walk(s, nn.Init)
}
if nn.Post != nil {
ast.Walk(s, nn.Post)
}
ast.Walk(s, nn.Body)
if nn.Cond != nil {
// Look for the following pattern:
// for foo := ...; foo ? ...; ... { ... }
boring := false
if nn.Init != nil {
if init, ok1 := nn.Init.(*ast.AssignStmt); ok1 && init.Tok == token.DEFINE && len(init.Lhs) == 1 {
if id, ok2 := init.Lhs[0].(*ast.Ident); ok2 {
if bex, ok3 := nn.Cond.(*ast.BinaryExpr); ok3 {
if x, ok4 := bex.X.(*ast.Ident); ok4 && x.Name == id.Name {
boring = true
}
if x, ok4 := bex.Y.(*ast.Ident); ok4 && x.Name == id.Name {
boring = true
}
}
}
}
}
if !boring {
ast.Walk(s, nn.Cond)
}
}
return nil
default:
return s // recurse
}
//.........这里部分代码省略.........
示例3: compileSwitchStmt
func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
// Create implicit scope around switch
bc := a.enterChild()
defer bc.exit()
// Compile init statement, if any
if s.Init != nil {
bc.compileStmt(s.Init)
}
// Compile condition, if any, and extract its effects
var cond *expr
condbc := bc.enterChild()
if s.Tag != nil {
e := condbc.compileExpr(condbc.block, false, s.Tag)
if e != nil {
var effect func(*Thread)
effect, cond = e.extractEffect(condbc.block, "switch")
a.push(effect)
}
}
// Count cases
ncases := 0
hasDefault := false
for _, c := range s.Body.List {
clause, ok := c.(*ast.CaseClause)
if !ok {
a.diagAt(clause.Pos(), "switch statement must contain case clauses")
continue
}
if clause.List == nil {
if hasDefault {
a.diagAt(clause.Pos(), "switch statement contains more than one default case")
}
hasDefault = true
} else {
ncases += len(clause.List)
}
}
// Compile case expressions
cases := make([]func(*Thread) bool, ncases)
i := 0
for _, c := range s.Body.List {
clause, ok := c.(*ast.CaseClause)
if !ok {
continue
}
for _, v := range clause.List {
e := condbc.compileExpr(condbc.block, false, v)
switch {
case e == nil:
// Error reported by compileExpr
case cond == nil && !e.t.isBoolean():
a.diagAt(v.Pos(), "'case' condition must be boolean")
case cond == nil:
cases[i] = e.asBool()
case cond != nil:
// Create comparison
// TOOD(austin) This produces bad error messages
compare := e.compileBinaryExpr(token.EQL, cond, e)
if compare != nil {
cases[i] = compare.asBool()
}
}
i++
}
}
// Emit condition
casePCs := make([]*uint, ncases+1)
endPC := badPC
a.flow.put(false, false, casePCs)
a.push(func(t *Thread) {
for i, c := range cases {
if c(t) {
t.pc = *casePCs[i]
return
}
}
t.pc = *casePCs[ncases]
})
condbc.exit()
// Compile cases
i = 0
for _, c := range s.Body.List {
clause, ok := c.(*ast.CaseClause)
if !ok {
continue
}
// Save jump PC's
pc := a.nextPC()
if clause.List != nil {
for _ = range clause.List {
casePCs[i] = &pc
i++
//.........这里部分代码省略.........
示例4: Visit
func (s *Sonar) Visit(n ast.Node) ast.Visitor {
// TODO: detect "x&mask==0", emit sonar(x, x&^mask)
switch nn := n.(type) {
case *ast.BinaryExpr:
break
case *ast.GenDecl:
if nn.Tok != token.VAR {
return nil // constants and types are not interesting
}
return s
case *ast.FuncDecl:
if s.pkg == "math" && (nn.Name.Name == "Y0" || nn.Name.Name == "Y1" || nn.Name.Name == "Yn" ||
nn.Name.Name == "J0" || nn.Name.Name == "J1" || nn.Name.Name == "Jn" ||
nn.Name.Name == "Pow") {
// Can't handle code there:
// math/j0.go:93: constant 680564733841876926926749214863536422912 overflows int
return nil
}
return s // recurse
case *ast.SwitchStmt:
if nn.Tag == nil || nn.Body == nil {
return s // recurse
}
// Replace:
// switch a := foo(); bar(a) {
// case x: ...
// case y: ...
// }
// with:
// switch {
// default:
// a := foo()
// __tmp := bar(a)
// switch {
// case __tmp == x: ...
// case __tmp == y: ...
// }
// }
// The == comparisons will be instrumented later when we recurse.
sw := new(ast.SwitchStmt)
*sw = *nn
var stmts []ast.Stmt
if sw.Init != nil {
stmts = append(stmts, sw.Init)
sw.Init = nil
}
stmts = append(stmts, &ast.AssignStmt{Lhs: []ast.Expr{&ast.Ident{Name: "__go_fuzz_tmp"}}, Tok: token.DEFINE, Rhs: []ast.Expr{sw.Tag}})
sw.Tag = nil
stmts = append(stmts, sw)
for _, cas1 := range sw.Body.List {
cas := cas1.(*ast.CaseClause)
for i, expr := range cas.List {
cas.List[i] = &ast.BinaryExpr{X: &ast.Ident{Name: "__go_fuzz_tmp", NamePos: expr.Pos()}, Op: token.EQL, Y: expr}
}
}
nn.Tag = nil
nn.Init = nil
nn.Body = &ast.BlockStmt{List: []ast.Stmt{&ast.CaseClause{Body: stmts}}}
return s // recurse
case *ast.ForStmt:
// For condition is usually uninteresting, but produces lots of samples.
// So we skip it if it looks boring.
if nn.Init != nil {
ast.Walk(s, nn.Init)
}
if nn.Post != nil {
ast.Walk(s, nn.Post)
}
ast.Walk(s, nn.Body)
if nn.Cond != nil {
// Look for the following pattern:
// for foo := ...; foo ? ...; ... { ... }
boring := false
if nn.Init != nil {
if init, ok1 := nn.Init.(*ast.AssignStmt); ok1 && init.Tok == token.DEFINE && len(init.Lhs) == 1 {
if id, ok2 := init.Lhs[0].(*ast.Ident); ok2 {
if bex, ok3 := nn.Cond.(*ast.BinaryExpr); ok3 {
if x, ok4 := bex.X.(*ast.Ident); ok4 && x.Name == id.Name {
boring = true
}
if x, ok4 := bex.Y.(*ast.Ident); ok4 && x.Name == id.Name {
boring = true
}
}
}
}
}
if !boring {
ast.Walk(s, nn.Cond)
}
}
return nil
default:
return s // recurse
}
//.........这里部分代码省略.........