]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: support indexing into *int* maps
authorEmmanuel Odeke <emm.odeke@gmail.com>
Mon, 22 May 2017 21:17:38 +0000 (15:17 -0600)
committerIan Lance Taylor <iant@golang.org>
Sat, 12 Aug 2017 00:21:16 +0000 (00:21 +0000)
Ensure that we can index maps whose key types are:
* int
* uint
* int32
* uint32
* int64
* uint64
* uintptr

Fixes #20439

Change-Id: I8fa96b14073c8af72786482ff4ffc3508064ea86
Reviewed-on: https://go-review.googlesource.com/43850
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/text/template/exec_test.go
src/text/template/funcs.go

index 9f7e637c190a4814e668ead626900a28f69c76ea..d0cda6bd625da787d8dd41fb204ff79ae392fbce 100644 (file)
@@ -44,6 +44,12 @@ type T struct {
        MSIEmpty map[string]int
        MXI      map[interface{}]int
        MII      map[int]int
+       MI32S    map[int32]string
+       MI64S    map[int64]string
+       MUI32S   map[uint32]string
+       MUI64S   map[uint64]string
+       MI8S     map[int8]string
+       MUI8S    map[uint8]string
        SMSI     []map[string]int
        // Empty interfaces; used to see if we can dig inside one.
        Empty0 interface{} // nil
@@ -124,6 +130,12 @@ var tVal = &T{
        MSIone: map[string]int{"one": 1},
        MXI:    map[interface{}]int{"one": 1},
        MII:    map[int]int{1: 1},
+       MI32S:  map[int32]string{1: "one", 2: "two"},
+       MI64S:  map[int64]string{2: "i642", 3: "i643"},
+       MUI32S: map[uint32]string{2: "u322", 3: "u323"},
+       MUI64S: map[uint64]string{2: "ui642", 3: "ui643"},
+       MI8S:   map[int8]string{2: "i82", 3: "i83"},
+       MUI8S:  map[uint8]string{2: "u82", 3: "u83"},
        SMSI: []map[string]int{
                {"one": 1, "two": 2},
                {"eleven": 11, "twelve": 12},
@@ -448,6 +460,11 @@ var execTests = []execTest{
        {"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
        {"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
        {"nil[1]", "{{index nil 1}}", "", tVal, false},
+       {"map MI64S", "{{index .MI64S 2}}", "i642", tVal, true},
+       {"map MI32S", "{{index .MI32S 2}}", "two", tVal, true},
+       {"map MUI64S", "{{index .MUI64S 3}}", "ui643", tVal, true},
+       {"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true},
+       {"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true},
 
        // Len.
        {"slice", "{{len .SI}}", "3", tVal, true},
index 910743103747a53bd903523a3abfe9f58d41f41b..abddfa1141b1f60edb633b799caddf51dd9e6784 100644 (file)
@@ -139,10 +139,24 @@ func prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error
                }
                value = reflect.Zero(argType)
        }
-       if !value.Type().AssignableTo(argType) {
-               return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
+       if value.Type().AssignableTo(argType) {
+               return value, nil
        }
-       return value, nil
+       if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {
+               value = value.Convert(argType)
+               return value, nil
+       }
+       return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
+}
+
+func intLike(typ reflect.Kind) bool {
+       switch typ {
+       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+               return true
+       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+               return true
+       }
+       return false
 }
 
 // Indexing.