From 2d1af6b74559d665b9a67aca5789c6d5b25e065e Mon Sep 17 00:00:00 2001 From: xushiwei <x@goplus.org> Date: Thu, 7 Nov 2024 15:31:10 +0800 Subject: [PATCH 1/3] cb.ValWithUnit --- codebuild.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/codebuild.go b/codebuild.go index 79cbe94..8ac29d2 100644 --- a/codebuild.go +++ b/codebuild.go @@ -26,6 +26,7 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/goplus/gogen/internal" xtoken "github.com/goplus/gogen/token" @@ -1382,6 +1383,44 @@ func (p *CodeBuilder) pushVal(v interface{}, src ast.Node) *CodeBuilder { return p } +// ValWithUnit func +func (p *CodeBuilder) ValWithUnit(v *ast.BasicLit, t types.Type, unit string) *CodeBuilder { + if debugInstr { + log.Println("ValWithUnit", v.Value, t, unit) + } + named, ok := t.(*types.Named) + if !ok { + panic("TODO: ValWithUnit: t isn't a named type") + } + o := named.Obj() + e := toExpr(p.pkg, v, v) + if o.Pkg().Path() == "time" && o.Name() == "Duration" { // time.Duration + u, ok := timeDurationUnits[unit] + if !ok { + panic("TODO: ValWithUnit: unknown unit of time.Duration - " + unit) + } + val := constant.BinaryOp(e.CVal, token.MUL, constant.MakeInt64(int64(u))) + e.CVal = val + e.Val = &ast.BasicLit{Kind: token.INT, Value: val.ExactString()} + e.Type = t + p.Val(e, v) + } else { + panic("TODO: notimpl") + } + return p +} + +var timeDurationUnits = map[string]time.Duration{ + "ns": time.Nanosecond, + "us": time.Microsecond, + "µs": time.Microsecond, + "ms": time.Millisecond, + "s": time.Second, + "m": time.Minute, + "h": time.Hour, + "d": 24 * time.Hour, +} + // Star func func (p *CodeBuilder) Star(src ...ast.Node) *CodeBuilder { if debugInstr { From 84b0690ea8631cb349b7a25b57e7c22610b1426c Mon Sep 17 00:00:00 2001 From: xushiwei <x@goplus.org> Date: Thu, 7 Nov 2024 15:48:02 +0800 Subject: [PATCH 2/3] TestValWithUnit --- builtin_test.go | 25 +++++++++++++++++++++++++ codebuild.go | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/builtin_test.go b/builtin_test.go index 797dbf9..5d2aa6f 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -44,6 +44,31 @@ func getConf() *Config { return &Config{Fset: fset, Importer: imp} } +func TestValWithUnit(t *testing.T) { + pkg := NewPackage("", "foo", nil) + cb := pkg.CB() + testValWithUnitPanic(t, "no unit for int", cb, types.Typ[types.Int], "m") + testValWithUnitPanic(t, "y is not unit of time.Duration", cb, namedType("time", "Duration"), "y") + testValWithUnitPanic(t, "user defined type: not impl", cb, namedType("foo", "Bar"), "m") + cb.ValWithUnit(&ast.BasicLit{Value: "1", Kind: token.INT}, namedType("time", "Duration"), "m") +} + +func namedType(pkgName, tName string) types.Type { + pkg := types.NewPackage(pkgName, "") + return types.NewNamed(types.NewTypeName(0, pkg, tName, nil), types.Typ[types.Int64], nil) +} + +func testValWithUnitPanic(t *testing.T, name string, cb *CodeBuilder, typ types.Type, unit string) { + t.Run(name, func(t *testing.T) { + defer func() { + if e := recover(); e == nil { + t.Fatal("TestErrValWithUnit: no panic?") + } + }() + cb.ValWithUnit(&ast.BasicLit{Value: "1", Kind: token.INT}, typ, unit) + }) +} + func TestSwitchStmtThen(t *testing.T) { pkg := NewPackage("", "foo", nil) cb := pkg.CB() diff --git a/codebuild.go b/codebuild.go index 8ac29d2..8d7be02 100644 --- a/codebuild.go +++ b/codebuild.go @@ -1392,9 +1392,9 @@ func (p *CodeBuilder) ValWithUnit(v *ast.BasicLit, t types.Type, unit string) *C if !ok { panic("TODO: ValWithUnit: t isn't a named type") } - o := named.Obj() e := toExpr(p.pkg, v, v) - if o.Pkg().Path() == "time" && o.Name() == "Duration" { // time.Duration + o := named.Obj() + if o.Name() == "Duration" && o.Pkg().Path() == "time" { // time.Duration u, ok := timeDurationUnits[unit] if !ok { panic("TODO: ValWithUnit: unknown unit of time.Duration - " + unit) From 1605e44d181315d6cc020730f84738d415670d07 Mon Sep 17 00:00:00 2001 From: xushiwei <x@goplus.org> Date: Thu, 7 Nov 2024 15:50:56 +0800 Subject: [PATCH 3/3] t.Helper --- builtin_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin_test.go b/builtin_test.go index 5d2aa6f..f97fb56 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -59,6 +59,7 @@ func namedType(pkgName, tName string) types.Type { } func testValWithUnitPanic(t *testing.T, name string, cb *CodeBuilder, typ types.Type, unit string) { + t.Helper() t.Run(name, func(t *testing.T) { defer func() { if e := recover(); e == nil {