Skip to content

Commit

Permalink
Merge pull request #75 from chai2010/master
Browse files Browse the repository at this point in the history
优化泛型方法的链式调用
  • Loading branch information
chai2010 authored Jan 3, 2025
2 parents 0ba41e6 + 73b3152 commit 4440cb5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
33 changes: 33 additions & 0 deletions api/api_ex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,39 @@ func ExampleRunCode_args() {
// 1 : bb
}

func ExampleRunCode_genericChainCalls() {
const code = `
type A: struct { }
#wa:generic AddStr
func A.Add(i: int) => *A {
println(i)
return this
}
func A.AddStr(s: string) => *A {
println(s)
return this
}
func main() {
a: A
a.Add("abc").Add("def")
}
`

output, err := api.RunCode(api.DefaultConfig(), "hello.wa", code, "__main__.main")
if err != nil {
log.Fatal(err)
}

fmt.Print(string(output))

// Output:
// abc
// def
}

func ExampleRunCode_wz() {
const code = `
#wa:syntax=wz
Expand Down
30 changes: 30 additions & 0 deletions internal/types/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,36 @@ func (check *Checker) resolveExprOrTypeOrGenericCall(x *operand, e *ast.CallExpr
}
}
}
} else {
// eCall.X 是普通的 Expr 类型
// 作为普通的 Expr, 解析其类型(已经check过没有错误)
var thisType Type = nil
{
var xOperand operand
check.rawExpr(&xOperand, eCall.X, nil)
if xOperand.mode == value {
// 返回值必须可取地址, 才可能链式调用方法
if t, ok := xOperand.typ.(*Pointer); ok {
thisType = t.Elem()
}
}
}

// 返回值必须是指针类型, 才能链式调用
if thisType != nil {
if t, _ := thisType.(*Named); t != nil {
obj, _, _ := lookupFieldOrMethod(t, true, check.pkg, eCall.Sel.Name)
if fnObj, ok := obj.(*Func); ok && len(fnObj.generic) != 0 {
for _, genericFnObj := range fnObj.generic {
if err := check.tryGenericCall(x, genericFnObj, e); err == nil {
eCall.Sel.Name = genericFnObj.name
check.exprOrType(x, e.Fun)
return
}
}
}
}
}
}
}

Expand Down

0 comments on commit 4440cb5

Please sign in to comment.