From 9b117e16768b778e0b27bfb03079b903652b072d Mon Sep 17 00:00:00 2001 From: Softonik Date: Wed, 14 Feb 2024 04:48:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B9:=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=20memchecker.DeletePoi?= =?UTF-8?q?nter()=20=D0=BC=D0=B5=D0=BD=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BD=D0=B0=20delete=20this;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/service/class.go | 2 +- pkg/service/class_abstract.go | 2 +- pkg/service/expr.go | 23 +++-------------- pkg/service/features/app.feature | 23 +++++++++++++++++ pkg/service/func.go | 43 ++++++++++++++++++++++++++++++++ pkg/service/stmt.go | 13 +++++----- 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/pkg/service/class.go b/pkg/service/class.go index 3a0a352..97b03d7 100644 --- a/pkg/service/class.go +++ b/pkg/service/class.go @@ -50,7 +50,7 @@ func (c *class) classDefinitionToString() (code string) { code += ": public " + c.baseInterface } - code += " {" + code += " {\n" code += "public:\n" code += c.structToString() diff --git a/pkg/service/class_abstract.go b/pkg/service/class_abstract.go index 7432ac9..cd8bc71 100644 --- a/pkg/service/class_abstract.go +++ b/pkg/service/class_abstract.go @@ -27,7 +27,7 @@ func (c *abstractClass) MethodsString() (code string) { } func (c *abstractClass) abstractClassDefinitionToString() (code string) { - code = "class " + c.name + " {" + code = "class " + c.name + " {\n" code += "public:\n" code += c.methodDeclarationsToString() diff --git a/pkg/service/expr.go b/pkg/service/expr.go index feba1a5..3a6860c 100644 --- a/pkg/service/expr.go +++ b/pkg/service/expr.go @@ -3,7 +3,6 @@ package service import ( "go/ast" "go/token" - "strings" ) func handleExpr(expr ast.Expr) (code string) { @@ -77,20 +76,7 @@ func handleBinaryExpr(expr ast.Expr) string { return code } -func handleCallExpr(expr *ast.CallExpr) (code string) { - code = handleExpr(expr.Fun) - code += "(" - args := make([]string, 0) - for _, arg := range expr.Args { - args = append(args, handleExpr(arg)) - } - code += strings.Join(args, ",") - code += ")" - return -} - -func handleIdentExpr(ident *ast.Ident) string { - code := "" +func handleIdentExpr(ident *ast.Ident) (code string) { switch ident.Name { case "nil": code += "NULL" @@ -105,13 +91,12 @@ func handleIdentExpr(ident *ast.Ident) string { default: code += ident.Name } - return code + return } -func handleParenExpr(stmt *ast.ParenExpr) string { - code := "" +func handleParenExpr(stmt *ast.ParenExpr) (code string) { code += handleExpr(stmt.X) - return code + return } func handleSelectorExpr(s *ast.SelectorExpr) (code string) { diff --git a/pkg/service/features/app.feature b/pkg/service/features/app.feature index 47776ac..0c7dd4c 100644 --- a/pkg/service/features/app.feature +++ b/pkg/service/features/app.feature @@ -182,6 +182,29 @@ public: }; void device::doSomething(int* a) { } +``` + + Сценарий: Структура с деструктором Close: вызов memchecker.DeletePointer() меняется на delete this; + * Исходник: +``` +package test + +type device struct { +} + +func (d *device) Close() { + memchecker.DeletePointer(d) +} +``` + * Результат: +``` +class device { +public: + void Close(); +}; +void device::Close() { +delete this; +} ``` Сценарий: Структура с вызовом метода diff --git a/pkg/service/func.go b/pkg/service/func.go index b1f13f3..e2ffaa5 100644 --- a/pkg/service/func.go +++ b/pkg/service/func.go @@ -157,3 +157,46 @@ func addFunctionDeclaration(f string) { funcDeclarations = append(funcDeclarations, f) } + +func handleCallExpr(expr *ast.CallExpr) (code string) { + // println() + // spew.Dump(expr) + + if isMemcheckerDeletePointerCall(expr.Fun) { + return handleCallAsDelete(expr) + } + return handleCallExprNormal(expr) +} +func isMemcheckerDeletePointerCall(expr ast.Expr) bool { + // println() + // spew.Dump(expr) + + s, ok := expr.(*ast.SelectorExpr) + if !ok { + return false + } + if handleExpr(s.X) != "memchecker" { + return false + } + if handleIdentExpr(s.Sel) != "DeletePointer" { + return false + } + + return true +} + +func handleCallAsDelete(expr *ast.CallExpr) (code string) { + code += "delete this" + return +} +func handleCallExprNormal(expr *ast.CallExpr) (code string) { + code += handleExpr(expr.Fun) + code += "(" + args := make([]string, 0) + for _, arg := range expr.Args { + args = append(args, handleExpr(arg)) + } + code += strings.Join(args, ",") + code += ")" + return +} diff --git a/pkg/service/stmt.go b/pkg/service/stmt.go index e37a31e..ad87fa7 100644 --- a/pkg/service/stmt.go +++ b/pkg/service/stmt.go @@ -166,17 +166,18 @@ func addGoHelperDeclaration(f string) { helpersForDeclarations = append(helpersForDeclarations, f) } -func handleExprStmt(stmt *ast.ExprStmt) string { - code := "" +func handleExprStmt(stmt *ast.ExprStmt) (code string) { + // println() + // spew.Dump(stmt) + switch x := stmt.X.(type) { case *ast.CallExpr: code += handleCallExpr(x) } - return code + return } -func handleForStmt(stmt *ast.ForStmt) string { - code := "" +func handleForStmt(stmt *ast.ForStmt) (code string) { is_while := false if stmt.Init == nil && stmt.Post == nil { is_while = true @@ -203,7 +204,7 @@ func handleForStmt(stmt *ast.ForStmt) string { code += ") {\n" code += handleBlockStmt(stmt.Body) code += "}" - return code + return } func handleIfStmt(stmt *ast.IfStmt) string {