From f8e03d3647811f7d4244cbb68369f9e3401e53b9 Mon Sep 17 00:00:00 2001 From: xhd2015 Date: Fri, 31 May 2024 13:13:50 +0800 Subject: [PATCH] bypass type resolution with const operations --- cmd/xgo/runtime_gen/core/version.go | 4 +-- cmd/xgo/version.go | 4 +-- patch/syntax/vars.go | 31 ++++++++++++++++--- runtime/core/version.go | 4 +-- runtime/test/debug/debug_test.go | 17 ++++++++-- .../test/patch_const/patch_const_op_test.go | 20 ++++++++++++ 6 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 runtime/test/patch_const/patch_const_op_test.go diff --git a/cmd/xgo/runtime_gen/core/version.go b/cmd/xgo/runtime_gen/core/version.go index 46d3739a..e2c0cdfc 100755 --- a/cmd/xgo/runtime_gen/core/version.go +++ b/cmd/xgo/runtime_gen/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.38" -const REVISION = "d939407b345d1697a3a32cf48c5b659d017c4cff+1" -const NUMBER = 248 +const REVISION = "808e011ba0498b1aaff762095543c880301dc26b+1" +const NUMBER = 249 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/cmd/xgo/version.go b/cmd/xgo/version.go index eef8b97d..ab61b634 100644 --- a/cmd/xgo/version.go +++ b/cmd/xgo/version.go @@ -3,8 +3,8 @@ package main import "fmt" const VERSION = "1.0.38" -const REVISION = "d939407b345d1697a3a32cf48c5b659d017c4cff+1" -const NUMBER = 248 +const REVISION = "808e011ba0498b1aaff762095543c880301dc26b+1" +const NUMBER = 249 func getRevision() string { revSuffix := "" diff --git a/patch/syntax/vars.go b/patch/syntax/vars.go index 66ac2b05..b4fe83f3 100644 --- a/patch/syntax/vars.go +++ b/patch/syntax/vars.go @@ -837,12 +837,35 @@ func getConstDeclValueType(expr syntax.Expr) string { if isBoolOp(expr.Op) { return "bool" } - if expr.X != nil { - return getConstDeclValueType(expr.X) + xIsNil := expr.X == nil + yIsNil := expr.Y == nil + if xIsNil && yIsNil { + return "" + } + // see https://github.com/xhd2015/xgo/issues/172 + // var x = 5*y, y's type is not known + var xType string + if !xIsNil { + xType = getConstDeclValueType(expr.X) + } + var yType string + if !yIsNil { + yType = getConstDeclValueType(expr.Y) + } + // either is nil + if xIsNil != yIsNil { + if xType != "" { + return xType + } + return yType } - if expr.Y != nil { - return getConstDeclValueType(expr.Y) + // 5*5 -> int + // 5*X -> unknown + if xType == yType { + return xType } + return "" + // TODO: handle SelectorExpr and iota case *syntax.ParenExpr: return getConstDeclValueType(expr.X) } diff --git a/runtime/core/version.go b/runtime/core/version.go index 46d3739a..e2c0cdfc 100644 --- a/runtime/core/version.go +++ b/runtime/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.38" -const REVISION = "d939407b345d1697a3a32cf48c5b659d017c4cff+1" -const NUMBER = 248 +const REVISION = "808e011ba0498b1aaff762095543c880301dc26b+1" +const NUMBER = 249 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/runtime/test/debug/debug_test.go b/runtime/test/debug/debug_test.go index 56541598..f1812114 100644 --- a/runtime/test/debug/debug_test.go +++ b/runtime/test/debug/debug_test.go @@ -5,8 +5,21 @@ package debug -import "testing" +import ( + "testing" + "time" + + "github.com/xhd2015/xgo/runtime/mock" +) + +const A = 20 * time.Second func TestHello(t *testing.T) { - t.Logf("hello world!") + mock.PatchByName("github.com/xhd2015/xgo/runtime/test/debug", "A", func() time.Duration { + return 10 * time.Second + }) + a := A + if a != 20*time.Second { + t.Fatalf("expect patch A failed because current xgo does not resolve operation type, actual: a=%v, want: %v", a, 20*time.Second) + } } diff --git a/runtime/test/patch_const/patch_const_op_test.go b/runtime/test/patch_const/patch_const_op_test.go new file mode 100644 index 00000000..511850cf --- /dev/null +++ b/runtime/test/patch_const/patch_const_op_test.go @@ -0,0 +1,20 @@ +package patch_const + +import ( + "testing" + "time" + + "github.com/xhd2015/xgo/runtime/mock" +) + +const A = 20 * time.Second + +func TestPatchConstOp(t *testing.T) { + mock.PatchByName("github.com/xhd2015/xgo/runtime/test/patch_const", "A", func() time.Duration { + return 10 * time.Second + }) + a := A + if a != 20*time.Second { + t.Fatalf("expect patch A failed because current xgo does not resolve operation type, actual: a=%v, want: %v", a, 20*time.Second) + } +}