mirror of
https://github.com/golang/go
synced 2024-11-18 17:54:57 -07:00
exp/types: process ast.Fun in checkObj; fix variadic function building
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
This commit is contained in:
parent
fda29b6a42
commit
d399b681a4
@ -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")
|
||||
|
67
src/pkg/exp/types/types_test.go
Normal file
67
src/pkg/exp/types/types_test.go
Normal file
@ -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.
|
||||
}
|
Loading…
Reference in New Issue
Block a user