Skip to content

Commit 9c096db

Browse files
committed
Add support for interface methods
1 parent c5c8394 commit 9c096db

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

checker/checker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ func (v *visitor) SliceNode(node *ast.SliceNode) reflect.Type {
319319

320320
func (v *visitor) FunctionNode(node *ast.FunctionNode) reflect.Type {
321321
if f, ok := v.types[node.Name]; ok {
322-
if fn, ok := funcType(f.Type); ok {
322+
if fn, ok := isFuncType(f.Type); ok {
323323
if isInterface(fn) {
324324
return interfaceType
325325
}
@@ -378,7 +378,7 @@ func (v *visitor) FunctionNode(node *ast.FunctionNode) reflect.Type {
378378
func (v *visitor) MethodNode(node *ast.MethodNode) reflect.Type {
379379
t := v.visit(node.Node)
380380
if f, method, ok := methodType(t, node.Method); ok {
381-
if fn, ok := funcType(f); ok {
381+
if fn, ok := isFuncType(f); ok {
382382
if isInterface(fn) {
383383
return interfaceType
384384
}

checker/checker_test.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ func TestVisitor_MethodNode(t *testing.T) {
5454
+ Var.Any(true)
5555
+ Var.Get()
5656
+ Var.Sub(3)
57-
+ (Duration.String() == "" ? 1 : 0)`
57+
+ (Duration.String() == "" ? 1 : 0)
58+
+ Interface.Method(0)
59+
+ Tickets[0].Method(0)`
5860

5961
tree, err := parser.Parse(input)
6062
assert.NoError(t, err)
@@ -102,11 +104,12 @@ func TestCheck_AsBool(t *testing.T) {
102104

103105
type mockEnv struct {
104106
*mockEmbed
105-
Add func(int64) int64
106-
Any interface{}
107-
Var *mockVar
108-
Tickets []mockTicket
109-
Duration time.Duration
107+
Add func(int64) int64
108+
Any interface{}
109+
Var *mockVar
110+
Tickets []mockTicket
111+
Duration time.Duration
112+
Interface mockInterface
110113
}
111114

112115
func (f *mockEnv) Set(v int64, any interface{}) int64 {
@@ -132,11 +135,19 @@ func (*mockVar) Set(v int64, f float64) int64 {
132135
return 0
133136
}
134137

138+
type mockInterface interface {
139+
Method(int) int
140+
}
141+
135142
type mockTicket struct {
136143
Price int
137144
Origin string
138145
}
139146

147+
func (t mockTicket) Method(int) int {
148+
return 0
149+
}
150+
140151
// Other tests.
141152

142153
func TestCheck(t *testing.T) {

checker/types.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,13 @@ func methodType(t reflect.Type, name string) (reflect.Type, bool, bool) {
235235
if t != nil {
236236
// First, check methods defined on type itself,
237237
// independent of which type it is.
238-
for i := 0; i < t.NumMethod(); i++ {
239-
m := t.Method(i)
240-
if m.Name == name {
238+
if m, ok := t.MethodByName(name); ok {
239+
if t.Kind() == reflect.Interface {
240+
// In case of interface type method will not have a receiver,
241+
// and to prevent checker decreasing numbers of in arguments
242+
// return method type as not method (second argument is false).
243+
return m.Type, false, true
244+
} else {
241245
return m.Type, true, true
242246
}
243247
}
@@ -292,7 +296,7 @@ func indexType(ntype reflect.Type) (reflect.Type, bool) {
292296
return nil, false
293297
}
294298

295-
func funcType(ntype reflect.Type) (reflect.Type, bool) {
299+
func isFuncType(ntype reflect.Type) (reflect.Type, bool) {
296300
ntype = dereference(ntype)
297301
if ntype == nil {
298302
return nil, false
@@ -308,10 +312,6 @@ func funcType(ntype reflect.Type) (reflect.Type, bool) {
308312
return nil, false
309313
}
310314

311-
func integerTypeWeight(t reflect.Type) uint {
312-
return uint(t.Kind())
313-
}
314-
315315
func isIntegerOrArithmeticOperation(node ast.Node) bool {
316316
switch n := node.(type) {
317317
case *ast.IntegerNode:

0 commit comments

Comments
 (0)