diff --git a/ast.go b/ast.go index b0bd140b..4c95a49c 100644 --- a/ast.go +++ b/ast.go @@ -83,6 +83,8 @@ func toType(typ types.Type) ast.Expr { switch t := typ.(type) { case *types.Basic: // bool, int, etc return toBasicType(t) + case *types.Interface: + return toInterface(t) case *types.Slice: return toSliceType(t) case *types.Array: @@ -108,6 +110,21 @@ func toArrayType(t *types.Array) ast.Expr { return &ast.ArrayType{Len: len, Elt: toType(t.Elem())} } +func toInterface(t *types.Interface) ast.Expr { + var flds []*ast.Field + for i, n := 0, t.NumExplicitMethods(); i < n; i++ { + fn := t.ExplicitMethod(i) + name := ident(fn.Name()) + typ := toFuncType(fn.Type().(*types.Signature)) + fld := &ast.Field{Names: []*ast.Ident{name}, Type: typ} + flds = append(flds, fld) + } + for i, n := 0, t.NumEmbeddeds(); i < n; i++ { + panic("TODO: interface embedded") + } + return &ast.InterfaceType{Methods: &ast.FieldList{List: flds}} +} + // ----------------------------------------------------------------------------- // expression diff --git a/package_test.go b/package_test.go index 094549cb..4f8f193e 100644 --- a/package_test.go +++ b/package_test.go @@ -20,7 +20,7 @@ func domTest(t *testing.T, pkg *gox.Package, expected string) { } result := b.String() if result != expected { - t.Fatalf("\nResult:\n%s\nExpected:%s\n", result, expected) + t.Fatalf("\nResult:\n%s\nExpected:\n%s\n", result, expected) } } @@ -62,6 +62,39 @@ func main() { `) } +func TestEmptyInterface(t *testing.T) { + pkg := gox.NewPackage("", "main", nil) + v := pkg.NewParam("v", types.NewSlice(types.NewInterfaceType(nil, nil))) + pkg.NewFunc(nil, "foo", gox.NewTuple(v), nil, true).BodyStart(pkg).End() + pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).End() + domTest(t, pkg, `package main + +func foo(v ...interface { +}) { +} +func main() { +} +`) +} + +func TestInterfaceMethods(t *testing.T) { + pkg := gox.NewPackage("", "main", nil) + bar := types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignature(nil, nil, nil, false)) + methods := []*types.Func{bar} + v := pkg.NewParam("v", types.NewSlice(types.NewInterfaceType(methods, nil))) + pkg.NewFunc(nil, "foo", gox.NewTuple(v), nil, true).BodyStart(pkg).End() + pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).End() + domTest(t, pkg, `package main + +func foo(v ...interface { + Bar() +}) { +} +func main() { +} +`) +} + func TestGoTypesPkg(t *testing.T) { const src = `package foo