Skip to content

Commit

Permalink
Merge pull request #352 from visualfc/overload_named
Browse files Browse the repository at this point in the history
hide TyOverloadNamed to sig
  • Loading branch information
xushiwei authored Jan 26, 2024
2 parents ce41652 + 0c71194 commit e3792aa
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 7 deletions.
7 changes: 4 additions & 3 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -697,9 +697,10 @@ retry:
case *TyInstruction:
return t.instr.Call(pkg, args, flags, fn.Src)
case *TypeType: // type convert
return matchTypeCast(pkg, t.Type(), fn, args, flags)
case *TyOverloadNamed:
return matchOverloadNamedTypeCast(pkg, t.Obj, fn.Src, args, flags)
if on, ok := CheckOverloadNamed(t.typ); ok {
return matchOverloadNamedTypeCast(pkg, on.Obj, fn.Src, args, flags)
}
return matchTypeCast(pkg, t.typ, fn, args, flags)
case *types.Named:
fnType = pkg.cb.getUnderlying(t)
goto retry
Expand Down
2 changes: 1 addition & 1 deletion func_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const (
)

// sigFuncEx return func type ($overloadArgs ...interface{$overloadMethod()})
func sigFuncEx(pkg *types.Package, recv *types.Var, t TyFuncEx) *types.Signature {
func sigFuncEx(pkg *types.Package, recv *types.Var, t types.Type) *types.Signature {
sig := types.NewSignatureType(types.NewVar(token.NoPos, nil, "", t), nil, nil, nil, nil, false)
typ := types.NewInterfaceType([]*types.Func{
types.NewFunc(token.NoPos, nil, overloadMethod, sig),
Expand Down
25 changes: 24 additions & 1 deletion type_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,34 @@ func (p *TyOverloadNamed) String() string {

func NewOverloadNamed(pos token.Pos, pkg *types.Package, name string, typs ...*types.Named) *types.TypeName {
t := &TyOverloadNamed{Types: typs}
o := types.NewTypeName(pos, pkg, name, t)
sig := sigFuncEx(pkg, nil, t)
o := types.NewTypeName(pos, pkg, name, sig)
t.Obj = o
return o
}

// CheckOverloadNamed returns if specified type is a TyOverloadNamed or not.
func CheckOverloadNamed(typ types.Type) (*TyOverloadNamed, bool) {
switch sig := typ.(type) {
case *TyOverloadNamed:
return sig, true
case *types.Signature:
if sig.Params().Len() == 1 {
if param := sig.Params().At(0); param.Name() == overloadArgs {
if typ, ok := param.Type().(*types.Interface); ok && typ.NumMethods() == 1 {
if sig, ok := typ.Method(0).Type().(*types.Signature); ok {
if recv := sig.Recv(); recv != nil {
t, ok := recv.Type().(*TyOverloadNamed)
return t, ok
}
}
}
}
}
}
return nil, false
}

type TyInstruction struct {
instr Instruction
}
Expand Down
2 changes: 1 addition & 1 deletion typeparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func (p *Package) Instantiate(orig types.Type, targs []types.Type, src ...ast.No
p.cb.ensureLoaded(targ)
}
ctxt := p.cb.ctxt
if on, ok := orig.(*TyOverloadNamed); ok {
if on, ok := CheckOverloadNamed(orig); ok {
var first error
for _, t := range on.Types {
ret, err := types.Instantiate(ctxt, t, targs, true)
Expand Down
2 changes: 1 addition & 1 deletion typeparams_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func Gopx_Var_Cast__1[T map[string]any]() *Var__1[T] {
scope := pkgRef.Types.Scope()
log.Println("==> Lookup", scope.Lookup("Var__0"))
objVar := pkgRef.Ref("Var")
on, ok := objVar.Type().(*gox.TyOverloadNamed)
on, ok := gox.CheckOverloadNamed(objVar.Type())
if !ok {
t.Fatal("TestOverloadNamed: not TyOverloadNamed?")
}
Expand Down

0 comments on commit e3792aa

Please sign in to comment.