2018-11-07 09:11:08 +03:00

122 lines
2.5 KiB
Go

package lintutil
import (
"go/ast"
"go/token"
)
var (
nilIdent = &ast.Ident{}
nilSelectorExpr = &ast.SelectorExpr{}
nilUnaryExpr = &ast.UnaryExpr{}
nilBinaryExpr = &ast.BinaryExpr{}
nilCallExpr = &ast.CallExpr{}
nilParenExpr = &ast.ParenExpr{}
nilAssignStmt = &ast.AssignStmt{}
)
// IsNil reports whether x is nil.
// Unlike simple nil check, also detects nil AST sentinels.
func IsNil(x ast.Node) bool {
switch x := x.(type) {
case *ast.Ident:
return x == nilIdent || x == nil
case *ast.SelectorExpr:
return x == nilSelectorExpr || x == nil
case *ast.UnaryExpr:
return x == nilUnaryExpr || x == nil
case *ast.BinaryExpr:
return x == nilBinaryExpr || x == nil
case *ast.CallExpr:
return x == nilCallExpr || x == nil
case *ast.ParenExpr:
return x == nilParenExpr || x == nil
case *ast.AssignStmt:
return x == nilAssignStmt || x == nil
default:
return x == nil
}
}
// AsIdent coerces x into non-nil ident.
func AsIdent(x ast.Node) *ast.Ident {
e, ok := x.(*ast.Ident)
if !ok {
return nilIdent
}
return e
}
// AsSelectorExpr coerces x into non-nil selector expr.
func AsSelectorExpr(x ast.Node) *ast.SelectorExpr {
e, ok := x.(*ast.SelectorExpr)
if !ok {
return nilSelectorExpr
}
return e
}
// AsUnaryExpr coerces x into non-nil unary expr.
func AsUnaryExpr(x ast.Node) *ast.UnaryExpr {
e, ok := x.(*ast.UnaryExpr)
if !ok {
return nilUnaryExpr
}
return e
}
// AsUnaryExprOp is like AsUnaryExpr, but also checks for op token.
func AsUnaryExprOp(x ast.Node, op token.Token) *ast.UnaryExpr {
e, ok := x.(*ast.UnaryExpr)
if !ok || e.Op != op {
return nilUnaryExpr
}
return e
}
// AsBinaryExpr coerces x into non-nil binary expr.
func AsBinaryExpr(x ast.Node) *ast.BinaryExpr {
e, ok := x.(*ast.BinaryExpr)
if !ok {
return nilBinaryExpr
}
return e
}
// AsBinaryExprOp is like AsBinaryExpr, but also checks for op token.
func AsBinaryExprOp(x ast.Node, op token.Token) *ast.BinaryExpr {
e, ok := x.(*ast.BinaryExpr)
if !ok || e.Op != op {
return nilBinaryExpr
}
return e
}
// AsCallExpr coerces x into non-nil call expr.
func AsCallExpr(x ast.Node) *ast.CallExpr {
e, ok := x.(*ast.CallExpr)
if !ok {
return nilCallExpr
}
return e
}
// AsParenExpr coerces x into non-nil paren expr.
func AsParenExpr(x ast.Node) *ast.ParenExpr {
e, ok := x.(*ast.ParenExpr)
if !ok {
return nilParenExpr
}
return e
}
// AsAssignStmt coerces x into non-nil assign stmt.
func AsAssignStmt(x ast.Node) *ast.AssignStmt {
stmt, ok := x.(*ast.AssignStmt)
if !ok {
return nilAssignStmt
}
return stmt
}