...
1
15
16 package rule
17
18 import (
19 "sort"
20 "strings"
21
22 bzl "github.com/bazelbuild/buildtools/build"
23 )
24
25
26
27
28 func sortExprLabels(e bzl.Expr, _ []bzl.Expr) {
29 list, ok := e.(*bzl.ListExpr)
30 if !ok || len(list.List) == 0 {
31 return
32 }
33
34 keys := make([]stringSortKey, len(list.List))
35 for i, elem := range list.List {
36 s, ok := elem.(*bzl.StringExpr)
37 if !ok {
38 return
39 }
40 keys[i] = makeSortKey(i, s)
41 }
42
43 before := keys[0].x.Comment().Before
44 keys[0].x.Comment().Before = nil
45 sort.Sort(byStringExpr(keys))
46 keys[0].x.Comment().Before = append(before, keys[0].x.Comment().Before...)
47 for i, k := range keys {
48 list.List[i] = k.x
49 }
50 }
51
52
53
54
55
56
57
58
59
60
61 type stringSortKey struct {
62 phase int
63 split []string
64 value string
65 original int
66 x bzl.Expr
67 }
68
69 func makeSortKey(index int, x *bzl.StringExpr) stringSortKey {
70 key := stringSortKey{
71 value: x.Value,
72 original: index,
73 x: x,
74 }
75
76 switch {
77 case strings.HasPrefix(x.Value, ":"):
78 key.phase = 1
79 case strings.HasPrefix(x.Value, "//"):
80 key.phase = 2
81 case strings.HasPrefix(x.Value, "@"):
82 key.phase = 3
83 }
84
85 key.split = strings.Split(strings.Replace(x.Value, ":", ".", -1), ".")
86 return key
87 }
88
89
90 type byStringExpr []stringSortKey
91
92 func (x byStringExpr) Len() int { return len(x) }
93 func (x byStringExpr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
94
95 func (x byStringExpr) Less(i, j int) bool {
96 xi := x[i]
97 xj := x[j]
98
99 if xi.phase != xj.phase {
100 return xi.phase < xj.phase
101 }
102 for k := 0; k < len(xi.split) && k < len(xj.split); k++ {
103 if xi.split[k] != xj.split[k] {
104 return xi.split[k] < xj.split[k]
105 }
106 }
107 if len(xi.split) != len(xj.split) {
108 return len(xi.split) < len(xj.split)
109 }
110 if xi.value != xj.value {
111 return xi.value < xj.value
112 }
113 return xi.original < xj.original
114 }
115
View as plain text