forked from cloudspannerecosystem/memefish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
91 lines (81 loc) · 2.07 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package ast
import (
"github.com/cloudspannerecosystem/memefish/token"
"strings"
)
// Helper functions for SQL()
// sqlOpt outputs:
//
// when node != nil: left + node.SQL() + right
// else : empty string
//
// This function corresponds to sqlOpt in ast.go
func sqlOpt[T interface {
Node
comparable
}](left string, node T, right string) string {
var zero T
if node == zero {
return ""
}
return left + node.SQL() + right
}
// strOpt outputs:
//
// when pred == true: s
// else : empty string
//
// This function corresponds to {{if pred}}s{{end}} in ast.go
func strOpt(pred bool, s string) string {
if pred {
return s
}
return ""
}
// sqlJoin outputs joined string of SQL() of all elems by sep.
// This function corresponds to sqlJoin in ast.go
func sqlJoin[T Node](elems []T, sep string) string {
var b strings.Builder
for i, r := range elems {
if i > 0 {
b.WriteString(sep)
}
b.WriteString(r.SQL())
}
return b.String()
}
// Helper functions for Pos(), End()
// lastElem returns last element of slice s.
// This function corresponds to NodeSliceVar[$] in ast.go.
func lastElem[T any](s []T) T {
return s[len(s)-1]
}
// firstValidEnd returns the first valid Pos() in argument.
// "valid" means the node is not nil and Pos().Invalid() is not true.
// This function corresponds to "(n0 ?? n1 ?? ...).End()"
func firstValidEnd(ns ...Node) token.Pos {
for _, n := range ns {
if n != nil && !n.End().Invalid() {
return n.End()
}
}
return token.InvalidPos
}
// firstPos returns the Pos() of the first node.
// If argument is an empty slice, this function returns token.InvalidPos.
// This function corresponds to NodeSliceVar[0].pos in ast.go.
func firstPos[T Node](s []T) token.Pos {
if len(s) == 0 {
return token.InvalidPos
}
return s[0].Pos()
}
// lastEnd returns the End() of the last node.
// If argument is an empty slice, this function returns token.InvalidPos.
// This function corresponds to NodeSliceVar[$].end in ast.go.
func lastEnd[T Node](s []T) token.Pos {
if len(s) == 0 {
return token.InvalidPos
}
return lastElem(s).End()
}