Skip to content

Commit

Permalink
Merge pull request #256 from visualfc/checksigs
Browse files Browse the repository at this point in the history
func CheckSignatures
  • Loading branch information
xushiwei authored Aug 4, 2023
2 parents afd779e + 45f56b1 commit 050fa79
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 3 deletions.
40 changes: 40 additions & 0 deletions builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,46 @@ func TestCheckSignature(t *testing.T) {
}
}

func TestCheckSignatures(t *testing.T) {
denoteRecv(&ast.SelectorExpr{Sel: ident("x")})
if CheckSignatures(nil, 0, 0) != nil {
t.Fatal("TestCheckSignatures failed: CheckSignatures(nil) != nil")
}
sig := types.NewSignature(nil, nil, nil, false)
if v := CheckSignatures(sig, 0, 0); len(v) != 1 || v[0] != sig {
t.Fatal("TestCheckSignatures failed: CheckSignatures(sig)[0] != sig")
}
pkg := types.NewPackage("", "foo")
arg := types.NewParam(token.NoPos, pkg, "", sig)
sig2 := types.NewSignature(nil, types.NewTuple(arg, arg), nil, false)
o := types.NewFunc(token.NoPos, pkg, "bar", sig2)
if CheckSignatures(&templateRecvMethodType{fn: o}, 0, 0) == nil {
t.Fatal("TestCheckSignatures failed: CheckSignatures == nil")
}
sig3 := types.NewSignature(nil, types.NewTuple(arg, arg, arg), nil, false)
o2 := types.NewFunc(token.NoPos, pkg, "bar", sig3)
of := NewOverloadFunc(token.NoPos, pkg, "bar", o, o2)
if v := CheckSignatures(of.Type(), 0, 0); len(v) != 2 {
t.Fatal("TestCheckSignatures failed: OverloadFunc CheckSignatures ==", len(v))
}

if HasAutoProperty(of.Type()) {
t.Fatal("func bar has autoprop?")
}

o3 := types.NewFunc(token.NoPos, pkg, "bar2", sig)
of2 := NewOverloadFunc(token.NoPos, pkg, "bar3", o3)
if !HasAutoProperty(of2.Type()) {
t.Fatal("func bar3 has autoprop?")
}

typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "t", nil), types.Typ[types.Int], nil)
om := NewOverloadMethod(typ, token.NoPos, pkg, "bar", o, o2)
if CheckSignatures(om.Type(), 0, 1) != nil {
t.Fatal("TestCheckSignatures failed: OverloadMethod CheckSignatures != nil")
}
}

func TestCheckSigParam(t *testing.T) {
if checkSigParam(types.NewPointer(types.Typ[types.Int]), -1) {
t.Fatal("TestCheckSigParam failed: checkSigParam *int should return false")
Expand Down
42 changes: 39 additions & 3 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,12 @@ func CheckSignature(typ types.Type, idx, nin int) *types.Signature {
switch t := typ.(type) {
case *types.Signature:
if funcs, ok := CheckOverloadMethod(t); ok {
return checkOverloadFuncs(funcs, idx, nin)
return checkOverloadFunc(funcs, idx, nin)
} else {
return t
}
case *overloadFuncType:
return checkOverloadFuncs(t.funcs, idx, nin)
return checkOverloadFunc(t.funcs, idx, nin)
case *templateRecvMethodType:
if sig, ok := t.fn.Type().(*types.Signature); ok {
params := sig.Params()
Expand All @@ -337,7 +337,7 @@ func CheckSignature(typ types.Type, idx, nin int) *types.Signature {
return nil
}

func checkOverloadFuncs(funcs []types.Object, idx, nin int) *types.Signature {
func checkOverloadFunc(funcs []types.Object, idx, nin int) *types.Signature {
for _, v := range funcs {
if sig, ok := v.Type().(*types.Signature); ok {
params := sig.Params()
Expand All @@ -349,6 +349,42 @@ func checkOverloadFuncs(funcs []types.Object, idx, nin int) *types.Signature {
return nil
}

func CheckSignatures(typ types.Type, idx, nin int) []*types.Signature {
switch t := typ.(type) {
case *types.Signature:
if funcs, ok := CheckOverloadMethod(t); ok {
return checkOverloadFuncs(funcs, idx, nin)
} else {
return []*types.Signature{t}
}
case *overloadFuncType:
return checkOverloadFuncs(t.funcs, idx, nin)
case *templateRecvMethodType:
if sig, ok := t.fn.Type().(*types.Signature); ok {
params := sig.Params()
n := params.Len()
mparams := make([]*types.Var, n-1)
for i := range mparams {
mparams[i] = params.At(i + 1)
}
return []*types.Signature{types.NewSignature(nil, types.NewTuple(mparams...), sig.Results(), sig.Variadic())}
}
}
return nil
}

func checkOverloadFuncs(funcs []types.Object, idx, nin int) (sigs []*types.Signature) {
for _, v := range funcs {
if sig, ok := v.Type().(*types.Signature); ok {
params := sig.Params()
if idx < params.Len() && checkSigParam(params.At(idx).Type(), nin) {
sigs = append(sigs, sig)
}
}
}
return
}

func checkSigParam(typ types.Type, nin int) bool {
switch nin {
case -1: // input is CompositeLit
Expand Down

0 comments on commit 050fa79

Please sign in to comment.