@@ -16,10 +16,10 @@ limitations under the License.
1616package rule
1717
1818import (
19- "fmt"
2019 "log"
2120 "reflect"
2221 "sort"
22+ "strconv"
2323
2424 bzl "github.com/bazelbuild/buildtools/build"
2525)
@@ -228,27 +228,53 @@ func ExprFromValue(val interface{}) bzl.Expr {
228228 return be .BzlExpr ()
229229 }
230230
231- rv := reflect .ValueOf (val )
232- switch rv .Kind () {
233- case reflect .Bool :
234- tok := "False"
235- if rv .Bool () {
236- tok = "True"
231+ // Fast paths for common types to avoid reflection overhead.
232+ switch v := val .(type ) {
233+ // primitives
234+ case string :
235+ return & bzl.StringExpr {Value : v }
236+ case bool :
237+ if v {
238+ return & bzl.LiteralExpr {Token : "True" }
237239 }
238- return & bzl.LiteralExpr {Token : tok }
239-
240- case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,
241- reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 :
242- return & bzl.LiteralExpr {Token : fmt .Sprintf ("%d" , val )}
243-
244- case reflect .Float32 , reflect .Float64 :
245- return & bzl.LiteralExpr {Token : fmt .Sprintf ("%f" , val )}
246-
247- case reflect .String :
248- return & bzl.StringExpr {Value : val .(string )}
240+ return & bzl.LiteralExpr {Token : "False" }
241+ case int :
242+ return intLiteralExpr (int64 (v ))
243+ case int8 :
244+ return intLiteralExpr (int64 (v ))
245+ case int16 :
246+ return intLiteralExpr (int64 (v ))
247+ case int32 :
248+ return intLiteralExpr (int64 (v ))
249+ case int64 :
250+ return intLiteralExpr (v )
251+ case uint :
252+ return uintLiteralExpr (uint64 (v ))
253+ case uint8 :
254+ return uintLiteralExpr (uint64 (v ))
255+ case uint16 :
256+ return uintLiteralExpr (uint64 (v ))
257+ case uint32 :
258+ return uintLiteralExpr (uint64 (v ))
259+ case uint64 :
260+ return uintLiteralExpr (v )
261+ case float32 :
262+ return floatLiteralExpr (float64 (v ))
263+ case float64 :
264+ return floatLiteralExpr (v )
265+
266+ // common types of slices
267+ case []string :
268+ return stringSliceToExpr (v )
269+ case []interface {}:
270+ return interfaceSliceToExpr (v )
271+ }
249272
273+ // Fallback to reflection for less common types
274+ rv := reflect .ValueOf (val )
275+ switch rv .Kind () {
250276 case reflect .Slice , reflect .Array :
251- var list []bzl.Expr
277+ list := make ( []bzl.Expr , 0 , rv . Len ())
252278 for i := 0 ; i < rv .Len (); i ++ {
253279 elem := ExprFromValue (rv .Index (i ).Interface ())
254280 list = append (list , elem )
@@ -274,6 +300,34 @@ func ExprFromValue(val interface{}) bzl.Expr {
274300 return nil
275301}
276302
303+ func intLiteralExpr (v int64 ) bzl.Expr {
304+ return & bzl.LiteralExpr {Token : strconv .FormatInt (v , 10 )}
305+ }
306+
307+ func uintLiteralExpr (v uint64 ) bzl.Expr {
308+ return & bzl.LiteralExpr {Token : strconv .FormatUint (v , 10 )}
309+ }
310+
311+ func floatLiteralExpr (v float64 ) bzl.Expr {
312+ return & bzl.LiteralExpr {Token : strconv .FormatFloat (v , 'g' , - 1 , 64 )}
313+ }
314+
315+ func stringSliceToExpr (strs []string ) * bzl.ListExpr {
316+ list := make ([]bzl.Expr , len (strs ))
317+ for i , s := range strs {
318+ list [i ] = & bzl.StringExpr {Value : s }
319+ }
320+ return & bzl.ListExpr {List : list }
321+ }
322+
323+ func interfaceSliceToExpr (vals []interface {}) * bzl.ListExpr {
324+ list := make ([]bzl.Expr , len (vals ))
325+ for i , v := range vals {
326+ list [i ] = ExprFromValue (v )
327+ }
328+ return & bzl.ListExpr {List : list }
329+ }
330+
277331func mapKeyString (k reflect.Value ) string {
278332 switch s := k .Interface ().(type ) {
279333 case string :
0 commit comments