Add structured coroutines and explicit error handling
This commit is contained in:
parent
de1262b4cf
commit
fe62e81152
31 changed files with 1701 additions and 325 deletions
|
|
@ -70,7 +70,7 @@ fun main() {
|
|||
for _, want := range []string{
|
||||
`"strings"`,
|
||||
`rand "math/rand"`,
|
||||
`upper := gotlinAutoThrow(strings.ToUpper("go"))`,
|
||||
`upper := strings.ToUpper("go")`,
|
||||
`fmt.Println(rand.Intn(3))`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
@ -294,7 +294,7 @@ fun main() {
|
|||
`func (self *Greeter) greet() {`,
|
||||
`fmt.Println("hello, " + self.name)`,
|
||||
`fmt.Println(self.name)`,
|
||||
`greeter := gotlinAutoThrow(NewGreeter("world"))`,
|
||||
`greeter := NewGreeter("world")`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
t.Fatalf("generated Go missing %q:\n%s", want, code)
|
||||
|
|
@ -388,7 +388,7 @@ fun main() {
|
|||
`type EpicControllerImpl struct {`,
|
||||
`func NewEpicControllerImpl() *EpicControllerImpl`,
|
||||
`func (self *EpicControllerImpl) hello(w http.ResponseWriter, r *http.Request) {`,
|
||||
`var epicController EpicController = gotlinAutoThrow(NewEpicControllerImpl())`,
|
||||
`var epicController EpicController = NewEpicControllerImpl()`,
|
||||
`http.HandleFunc("/", epicController.hello)`,
|
||||
`http.ListenAndServe(":8080", http.DefaultServeMux)`,
|
||||
} {
|
||||
|
|
@ -546,7 +546,7 @@ fun main() {
|
|||
`type gotlinResult struct {`,
|
||||
`func gotlinRunCatching(fn func()) (result gotlinResult) {`,
|
||||
`panic("boom")`,
|
||||
`result := gotlinAutoThrow(gotlinRunCatching(func() {`,
|
||||
`result := gotlinRunCatching(func() {`,
|
||||
`if recovered := recover(); recovered != nil {`,
|
||||
`e := recovered`,
|
||||
} {
|
||||
|
|
@ -556,7 +556,7 @@ fun main() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGenerateGoAutoThrowForGoErrorResults(t *testing.T) {
|
||||
func TestGenerateGoExplicitErrorsForGoErrorResults(t *testing.T) {
|
||||
src := `
|
||||
package demo
|
||||
|
||||
|
|
@ -569,6 +569,7 @@ fun main() {
|
|||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
prog, err := Parse(src)
|
||||
|
|
@ -583,9 +584,8 @@ fun main() {
|
|||
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`func gotlinAutoThrow[T any](value T, rest ...any) T {`,
|
||||
`db := gotlinAutoThrow(sql.Open("postgres", "postgres://localhost/postgres?sslmode=disable"))`,
|
||||
`err := gotlinAutoThrow(db.Ping())`,
|
||||
`db := sql.Open("postgres", "postgres://localhost/postgres?sslmode=disable")`,
|
||||
`err := db.Ping()`,
|
||||
`if err != nil {`,
|
||||
`panic(err)`,
|
||||
} {
|
||||
|
|
@ -595,7 +595,32 @@ fun main() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGenerateGoAutoThrowForErrorExprStmt(t *testing.T) {
|
||||
func TestGenerateGoMigrationInteropHelpers(t *testing.T) {
|
||||
prog, err := Parse(`package demo
|
||||
data class Versioned(var version: Long)
|
||||
fun names(values: Map<String, Int>): List<String> { return keys(values) }
|
||||
fun buffer(): ByteSlice { return ByteSlice(32) }
|
||||
fun optionalError(): Error? { return null }`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
out, err := GenerateGo(prog)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, want := range []string{
|
||||
"Version int64",
|
||||
"for key := range values",
|
||||
"return make([]byte, 32)",
|
||||
"func optionalError() error",
|
||||
} {
|
||||
if !strings.Contains(string(out), want) {
|
||||
t.Fatalf("generated Go missing %q:\n%s", want, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateGoExplicitErrorsForErrorExprStmt(t *testing.T) {
|
||||
src := `
|
||||
package demo
|
||||
|
||||
|
|
@ -619,7 +644,7 @@ fun main() {
|
|||
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`db := gotlinAutoThrow(sql.Open("postgres", "postgres://localhost/postgres?sslmode=disable"))`,
|
||||
`db := sql.Open("postgres", "postgres://localhost/postgres?sslmode=disable")`,
|
||||
`db.Ping()`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
@ -654,7 +679,7 @@ fun main() {
|
|||
for _, want := range []string{
|
||||
`type User struct {`,
|
||||
`func NewUser(Name string) *User`,
|
||||
`user := gotlinAutoThrow(NewUser("alice"))`,
|
||||
`user := NewUser("alice")`,
|
||||
`fmt.Println(user.Name)`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
@ -723,8 +748,8 @@ fun main() {
|
|||
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`var names []string = gotlinAutoThrow([]string{"alice", "bob"})`,
|
||||
`var ages map[string]int = gotlinAutoThrow(map[string]int{"alice": 30, "bob": 25})`,
|
||||
`var names []string = []string{"alice", "bob"}`,
|
||||
`var ages map[string]int = map[string]int{"alice": 30, "bob": 25}`,
|
||||
`fmt.Println(names)`,
|
||||
`fmt.Println(ages)`,
|
||||
} {
|
||||
|
|
@ -758,8 +783,8 @@ fun main() {
|
|||
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`test := gotlinAutoThrow([]int{})`,
|
||||
`labels := gotlinAutoThrow(map[string]int{})`,
|
||||
`test := []int{}`,
|
||||
`labels := map[string]int{}`,
|
||||
`fmt.Println(test)`,
|
||||
`fmt.Println(labels)`,
|
||||
} {
|
||||
|
|
@ -791,7 +816,7 @@ fun main() {
|
|||
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`_ = gotlinAutoThrow([]int{1, 7})`,
|
||||
`_ = []int{1, 7}`,
|
||||
`fmt.Println("ok")`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
@ -814,7 +839,7 @@ fun runWorker(name: String) {
|
|||
}
|
||||
|
||||
fun main() {
|
||||
go runWorker("alice")
|
||||
runBlocking { launch { runWorker("alice") } }
|
||||
}
|
||||
`
|
||||
|
||||
|
|
@ -832,9 +857,9 @@ fun main() {
|
|||
for _, want := range []string{
|
||||
`func runWorker(name string)`,
|
||||
`fmt.Println(name)`,
|
||||
`go func() {`,
|
||||
`gotlinScope.Launch`,
|
||||
`runWorker("alice")`,
|
||||
`println("async panic:", recovered)`,
|
||||
`gotlinRunBlocking`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
t.Fatalf("generated Go missing %q:\n%s", want, code)
|
||||
|
|
@ -854,16 +879,9 @@ worker Counter {
|
|||
}
|
||||
`
|
||||
|
||||
prog, err := Parse(src)
|
||||
if err != nil {
|
||||
t.Fatalf("parse failed: %v", err)
|
||||
}
|
||||
_, err = GenerateGo(prog)
|
||||
_, err := Parse(src)
|
||||
if err == nil {
|
||||
t.Fatal("expected worker self-call generation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "worker self-calls are forbidden") {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
t.Fatal("expected removed worker syntax error")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1054,25 +1072,9 @@ worker Counter {
|
|||
}
|
||||
}
|
||||
`
|
||||
prog, err := Parse(src)
|
||||
if err != nil {
|
||||
t.Fatalf("parse failed: %v", err)
|
||||
}
|
||||
out, err := GenerateGo(prog)
|
||||
if err != nil {
|
||||
t.Fatalf("go generation failed: %v", err)
|
||||
}
|
||||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`panicCh := make(chan any, 1)`,
|
||||
`if recovered := recover(); recovered != nil {`,
|
||||
`panicCh <- recovered`,
|
||||
`case recovered := <-panicCh:`,
|
||||
`panic(recovered)`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
t.Fatalf("generated Go missing %q:\n%s", want, code)
|
||||
}
|
||||
_, err := Parse(src)
|
||||
if err == nil {
|
||||
t.Fatal("expected removed worker syntax error")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1089,7 +1091,7 @@ fun main() {
|
|||
if err == nil {
|
||||
t.Fatal("expected parse error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "'go' expects a function call expression") {
|
||||
if !strings.Contains(err.Error(), "bare go is removed") {
|
||||
t.Fatalf("unexpected parse error: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1104,9 +1106,11 @@ fun writer(ch: Channel<Int>) {
|
|||
|
||||
fun main() {
|
||||
val ch = Channel<Int>()
|
||||
go writer(ch)
|
||||
select {
|
||||
ch -> println(it)
|
||||
runBlocking {
|
||||
launch { writer(ch) }
|
||||
select {
|
||||
ch -> println(it)
|
||||
}
|
||||
}
|
||||
val v = ch.read()
|
||||
println(v)
|
||||
|
|
@ -1127,13 +1131,13 @@ fun main() {
|
|||
for _, want := range []string{
|
||||
`func writer(ch chan int)`,
|
||||
`ch <- 7`,
|
||||
`ch := gotlinAutoThrow(make(chan int))`,
|
||||
`go func() {`,
|
||||
`ch := make(chan int)`,
|
||||
`gotlinScope.Launch`,
|
||||
`writer(ch)`,
|
||||
`select {`,
|
||||
`case it := <-ch:`,
|
||||
`fmt.Println(it)`,
|
||||
`v := gotlinAutoThrow(<-ch)`,
|
||||
`v := <-ch`,
|
||||
`fmt.Println(v)`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
@ -1326,7 +1330,7 @@ fun main() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGenerateGoAutoThrowForBunStyleCalls(t *testing.T) {
|
||||
func TestGenerateGoExplicitErrorsForBunStyleCalls(t *testing.T) {
|
||||
src := `
|
||||
package demo
|
||||
|
||||
|
|
@ -1356,7 +1360,7 @@ class Repo(val db: *bun.DB) {
|
|||
code := string(out)
|
||||
for _, want := range []string{
|
||||
`self.db.NewSelect().ColumnExpr("1").Scan(ctx)`,
|
||||
`total := gotlinAutoThrow(self.db.NewSelect().ColumnExpr("1").Count(ctx))`,
|
||||
`total := self.db.NewSelect().ColumnExpr("1").Count(ctx)`,
|
||||
`fmt.Println(total)`,
|
||||
} {
|
||||
if !strings.Contains(code, want) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue