]> Cypherpunks repositories - gostls13.git/commitdiff
exp/types: process ast.Fun in checkObj; fix variadic function building
authorAndrew Wilkins <axwalk@gmail.com>
Thu, 26 Jul 2012 18:47:46 +0000 (11:47 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 26 Jul 2012 18:47:46 +0000 (11:47 -0700)
Fixed creation of Func's, taking IsVariadic from parameter list rather
than results.

Updated checkObj to process ast.Fun objects.

R=gri
CC=golang-dev
https://golang.org/cl/6402046

src/pkg/exp/types/check.go
src/pkg/exp/types/types_test.go [new file with mode: 0644]

index ae0beb4e9b0b1d59ed876106a4fa6f5ff9b87c0d..aebabd6421bd969eef56f908c678b6c3c201e162 100644 (file)
@@ -158,8 +158,8 @@ func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) {
                return &Struct{Fields: fields, Tags: tags}
 
        case *ast.FuncType:
-               params, _, _ := c.collectFields(token.FUNC, t.Params, true)
-               results, _, isVariadic := c.collectFields(token.FUNC, t.Results, true)
+               params, _, isVariadic := c.collectFields(token.FUNC, t.Params, true)
+               results, _, _ := c.collectFields(token.FUNC, t.Results, true)
                return &Func{Recv: nil, Params: params, Results: results, IsVariadic: isVariadic}
 
        case *ast.InterfaceType:
@@ -200,7 +200,21 @@ func (c *checker) checkObj(obj *ast.Object, ref bool) {
                // TODO(gri) complete this
 
        case ast.Fun:
-               // TODO(gri) complete this
+               fdecl := obj.Decl.(*ast.FuncDecl)
+               ftyp := c.makeType(fdecl.Type, ref).(*Func)
+               obj.Type = ftyp
+               if fdecl.Recv != nil {
+                       recvField := fdecl.Recv.List[0]
+                       if len(recvField.Names) > 0 {
+                               ftyp.Recv = recvField.Names[0].Obj
+                       } else {
+                               ftyp.Recv = ast.NewObj(ast.Var, "_")
+                               ftyp.Recv.Decl = recvField
+                       }
+                       c.checkObj(ftyp.Recv, ref)
+                       // TODO(axw) add method to a list in the receiver type.
+               }
+               // TODO(axw) check function body, if non-nil.
 
        default:
                panic("unreachable")
diff --git a/src/pkg/exp/types/types_test.go b/src/pkg/exp/types/types_test.go
new file mode 100644 (file)
index 0000000..feb3948
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests verifying the types associated with an AST after
+// type checking.
+
+package types
+
+import (
+       "go/ast"
+       "go/parser"
+       "testing"
+)
+
+func checkSource(t *testing.T, src string) *ast.Package {
+       const filename = "<src>"
+       file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors)
+       if err != nil {
+               t.Fatal(err)
+       }
+       files := map[string]*ast.File{filename: file}
+       pkg, err := ast.NewPackage(fset, files, GcImport, Universe)
+       if err != nil {
+               t.Fatal(err)
+       }
+       _, err = Check(fset, pkg)
+       if err != nil {
+               t.Fatal(err)
+       }
+       return pkg
+}
+
+func TestVariadicFunctions(t *testing.T) {
+       pkg := checkSource(t, `
+package p
+func f1(arg ...int)
+func f2(arg1 string, arg2 ...int)
+func f3()
+func f4(arg int)
+       `)
+       f1 := pkg.Scope.Lookup("f1")
+       f2 := pkg.Scope.Lookup("f2")
+       for _, f := range [...](*ast.Object){f1, f2} {
+               ftype := f.Type.(*Func)
+               if !ftype.IsVariadic {
+                       t.Errorf("expected %s to be variadic", f.Name)
+               }
+               param := ftype.Params[len(ftype.Params)-1]
+               if param.Type != Int {
+                       t.Errorf("expected last parameter of %s to have type int, found %T", f.Name, param.Type)
+               }
+       }
+
+       f3 := pkg.Scope.Lookup("f3")
+       f4 := pkg.Scope.Lookup("f4")
+       for _, f := range [...](*ast.Object){f3, f4} {
+               ftype := f.Type.(*Func)
+               if ftype.IsVariadic {
+                       t.Fatalf("expected %s to not be variadic", f.Name)
+               }
+       }
+       // TODO(axw) replace this function's innards with table driven tests.
+       // We should have a helper function that prints a type signature. Then
+       // we can have a table of function declarations and expected type
+       // signatures which can be easily expanded.
+}