Skip to content

Commit 501bfab

Browse files
committed
cache builtin numeric types
1 parent cb06eb3 commit 501bfab

2 files changed

Lines changed: 49 additions & 51 deletions

File tree

checker/checker.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ func (v *Checker) binaryNode(node *ast.BinaryNode) Nature {
403403
}
404404

405405
case "%":
406-
if l.IsInteger() && r.IsInteger() {
406+
if l.IsInteger && r.IsInteger {
407407
return v.config.NtCache.FromType(intType)
408408
}
409409
if l.MaybeCompatible(&v.config.NtCache, r, IntegerCheck) {
@@ -478,7 +478,7 @@ func (v *Checker) binaryNode(node *ast.BinaryNode) Nature {
478478
}
479479

480480
case "..":
481-
if l.IsInteger() && r.IsInteger() || l.MaybeCompatible(&v.config.NtCache, r, IntegerCheck) {
481+
if l.IsInteger && r.IsInteger || l.MaybeCompatible(&v.config.NtCache, r, IntegerCheck) {
482482
return ArrayFromType(&v.config.NtCache, intType)
483483
}
484484

@@ -562,7 +562,7 @@ func (v *Checker) memberNode(node *ast.MemberNode) Nature {
562562
return base.Elem(&v.config.NtCache)
563563

564564
case reflect.Array, reflect.Slice:
565-
if !prop.IsInteger() && !prop.IsUnknown(&v.config.NtCache) {
565+
if !prop.IsInteger && !prop.IsUnknown(&v.config.NtCache) {
566566
return v.error(node.Property, "array elements can only be selected using an integer (got %s)", prop.String())
567567
}
568568
return base.Elem(&v.config.NtCache)
@@ -607,14 +607,14 @@ func (v *Checker) sliceNode(node *ast.SliceNode) Nature {
607607

608608
if node.From != nil {
609609
from := v.visit(node.From)
610-
if !from.IsInteger() && !from.IsUnknown(&v.config.NtCache) {
610+
if !from.IsInteger && !from.IsUnknown(&v.config.NtCache) {
611611
return v.error(node.From, "non-integer slice index %v", from.String())
612612
}
613613
}
614614

615615
if node.To != nil {
616616
to := v.visit(node.To)
617-
if !to.IsInteger() && !to.IsUnknown(&v.config.NtCache) {
617+
if !to.IsInteger && !to.IsUnknown(&v.config.NtCache) {
618618
return v.error(node.To, "non-integer slice index %v", to.String())
619619
}
620620
}
@@ -959,7 +959,7 @@ func (v *Checker) checkBuiltinGet(node *ast.BuiltinNode) Nature {
959959

960960
switch base.Kind {
961961
case reflect.Slice, reflect.Array:
962-
if !prop.IsInteger() && !prop.IsUnknown(&v.config.NtCache) {
962+
if !prop.IsInteger && !prop.IsUnknown(&v.config.NtCache) {
963963
return v.error(node.Arguments[1], "non-integer slice index %s", prop.String())
964964
}
965965
return base.Elem(&v.config.NtCache)
@@ -1107,12 +1107,12 @@ func (v *Checker) checkArguments(
11071107
in = fn.In(&v.config.NtCache, i+fnInOffset)
11081108
}
11091109

1110-
if in.IsFloat() && argNature.IsInteger() {
1110+
if in.IsFloat && argNature.IsInteger {
11111111
traverseAndReplaceIntegerNodesWithFloatNodes(&arguments[i], in)
11121112
continue
11131113
}
11141114

1115-
if in.IsInteger() && argNature.IsInteger() && argNature.Kind != in.Kind {
1115+
if in.IsInteger && argNature.IsInteger && argNature.Kind != in.Kind {
11161116
traverseAndReplaceIntegerNodesWithIntegerNodes(&arguments[i], in)
11171117
continue
11181118
}

checker/nature/nature.go

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,24 @@ var (
1515
arrayType = reflect.TypeOf([]any{})
1616
timeType = reflect.TypeOf(time.Time{})
1717
durationType = reflect.TypeOf(time.Duration(0))
18+
19+
builtinInt = map[reflect.Type]struct{}{
20+
reflect.TypeOf(int(0)): {},
21+
reflect.TypeOf(int8(0)): {},
22+
reflect.TypeOf(int16(0)): {},
23+
reflect.TypeOf(int32(0)): {},
24+
reflect.TypeOf(int64(0)): {},
25+
reflect.TypeOf(uintptr(0)): {},
26+
reflect.TypeOf(uint(0)): {},
27+
reflect.TypeOf(uint8(0)): {},
28+
reflect.TypeOf(uint16(0)): {},
29+
reflect.TypeOf(uint32(0)): {},
30+
reflect.TypeOf(uint64(0)): {},
31+
}
32+
builtinFloat = map[reflect.Type]struct{}{
33+
reflect.TypeOf(float32(0)): {},
34+
reflect.TypeOf(float64(0)): {},
35+
}
1836
)
1937

2038
type NatureCheck int
@@ -45,13 +63,14 @@ type Nature struct {
4563
// - Array-like types: then Ref is the Elem nature of array type (usually Type is []any, but ArrayOf can be any nature).
4664
Ref *Nature
4765

48-
Nil bool // If value is nil.
49-
Strict bool // If map is types.StrictMap.
50-
Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
66+
Nil bool // If value is nil.
67+
Strict bool // If map is types.StrictMap.
68+
Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
69+
IsInteger bool // If it's a builtin integer or unsigned integer type.
70+
IsFloat bool // If it's a builtin float type.
5171
}
5272

5373
type TypeData struct {
54-
pkgPath string
5574
methodset *methodset // optional to avoid the map in *Cache
5675

5776
*structData
@@ -66,7 +85,6 @@ type TypeData struct {
6685
inElem, outZero *Nature
6786
numIn, numOut int
6887

69-
pkgPathSet bool
7088
isVariadic bool
7189
isVariadicSet bool
7290
numInSet bool
@@ -100,7 +118,8 @@ func (c *Cache) FromType(t reflect.Type) Nature {
100118
if t == nil {
101119
return Nature{}
102120
}
103-
var opt *TypeData
121+
var td *TypeData
122+
var isInteger, isFloat bool
104123
k := t.Kind()
105124
switch k {
106125
case reflect.Struct:
@@ -111,9 +130,20 @@ func (c *Cache) FromType(t reflect.Type) Nature {
111130
}
112131
fallthrough
113132
case reflect.Func:
114-
opt = new(TypeData)
133+
td = new(TypeData)
134+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
135+
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
136+
_, isInteger = builtinInt[t]
137+
case reflect.Float32, reflect.Float64:
138+
_, isFloat = builtinFloat[t]
139+
}
140+
return Nature{
141+
Type: t,
142+
Kind: k,
143+
TypeData: td,
144+
IsInteger: isInteger,
145+
IsFloat: isFloat,
115146
}
116-
return Nature{Type: t, Kind: k, TypeData: opt}
117147
}
118148

119149
func (c *Cache) getStruct(t reflect.Type) Nature {
@@ -355,21 +385,6 @@ func (n *Nature) FieldByName(c *Cache, name string) (Nature, bool) {
355385
return Nature{}, false
356386
}
357387

358-
func (n *Nature) PkgPath() string {
359-
if n.Type == nil {
360-
return ""
361-
}
362-
if n.TypeData != nil && n.TypeData.pkgPathSet {
363-
return n.TypeData.pkgPath
364-
}
365-
p := n.Type.PkgPath()
366-
if n.TypeData != nil {
367-
n.TypeData.pkgPathSet = true
368-
n.TypeData.pkgPath = p
369-
}
370-
return p
371-
}
372-
373388
func (n *Nature) IsFastMap() bool {
374389
return n.Type != nil &&
375390
n.Type.Kind() == reflect.Map &&
@@ -451,31 +466,14 @@ func (n *Nature) All(c *Cache) map[string]Nature {
451466
}
452467

453468
func (n *Nature) IsNumber() bool {
454-
return n.IsInteger() || n.IsFloat()
455-
}
456-
457-
func (n *Nature) IsInteger() bool {
458-
switch n.Kind {
459-
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
460-
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
461-
return n.PkgPath() == ""
462-
}
463-
return false
464-
}
465-
466-
func (n *Nature) IsFloat() bool {
467-
switch n.Kind {
468-
case reflect.Float32, reflect.Float64:
469-
return n.PkgPath() == ""
470-
}
471-
return false
469+
return n.IsInteger || n.IsFloat
472470
}
473471

474472
func (n *Nature) PromoteNumericNature(c *Cache, rhs Nature) Nature {
475473
if n.IsUnknown(c) || rhs.IsUnknown(c) {
476474
return Nature{}
477475
}
478-
if n.IsFloat() || rhs.IsFloat() {
476+
if n.IsFloat || rhs.IsFloat {
479477
return c.FromType(floatType)
480478
}
481479
return c.FromType(intType)
@@ -526,7 +524,7 @@ func (n *Nature) IsAnyOf(cs ...NatureCheck) bool {
526524
case StringCheck:
527525
result = n.IsString()
528526
case IntegerCheck:
529-
result = n.IsInteger()
527+
result = n.IsInteger
530528
case NumberCheck:
531529
result = n.IsNumber()
532530
case MapCheck:

0 commit comments

Comments
 (0)