github.phpd.cn/thought-machine/please@v12.2.0+incompatible/src/parse/asp/util.go (about) 1 package asp 2 3 import "strings" 4 5 // FindTarget returns the top-level call in a BUILD file that corresponds to a target 6 // of the given name (or nil if one does not exist). 7 func FindTarget(statements []*Statement, name string) *Statement { 8 for _, statement := range statements { 9 if ident := statement.Ident; ident != nil && ident.Action != nil && ident.Action.Call != nil { 10 for _, arg := range ident.Action.Call.Arguments { 11 if arg.Name == "name" { 12 if arg.Value.Val != nil && arg.Value.Val.String != "" && strings.Trim(arg.Value.Val.String, `"`) == name { 13 return statement 14 } 15 } 16 } 17 } 18 } 19 return nil 20 } 21 22 // NextStatement finds the statement that follows the given one. 23 // This is often useful to find the extent of a statement in source code. 24 // It will return nil if there is not one following it. 25 func NextStatement(statements []*Statement, statement *Statement) *Statement { 26 for i, s := range statements { 27 if s == statement && i < len(statements)-1 { 28 return statements[i+1] 29 } 30 } 31 return nil 32 } 33 34 // GetExtents returns the "extents" of a statement, i.e. the lines that it covers in source. 35 // The caller must pass a value for the maximum extent of the file; we can't detect it here 36 // because the AST only contains positions for the beginning of the statements. 37 func GetExtents(statements []*Statement, statement *Statement, max int) (int, int) { 38 next := NextStatement(statements, statement) 39 if next == nil { 40 // Assume it reaches to the end of the file 41 return statement.Pos.Line, max 42 } 43 return statement.Pos.Line, next.Pos.Line - 1 44 } 45 46 // FindArgument finds an argument of any one of the given names, or nil if there isn't one. 47 // The statement must be a function call (e.g. as returned by FindTarget). 48 func FindArgument(statement *Statement, args ...string) *CallArgument { 49 for i, a := range statement.Ident.Action.Call.Arguments { 50 for _, arg := range args { 51 if a.Name == arg { 52 return &statement.Ident.Action.Call.Arguments[i] 53 } 54 } 55 } 56 return nil 57 }