package service import ( "go/ast" "go/token" "strings" ) func handleExpr(expr ast.Expr) string { // spew.Dump(expr) code := "" switch e := expr.(type) { case *ast.BasicLit: code += handleBasicLit(e) case *ast.UnaryExpr: code += handleUnaryExpr(e) case *ast.BinaryExpr: code += handleBinaryExpr(e) case *ast.CallExpr: code += handleCallExpr(e) case *ast.Ident: code += handleIdentExpr(e) case *ast.ParenExpr: code += handleParenExpr(e) case *ast.SelectorExpr: code += handleSelectorExpr(e) case *ast.StructType: code += handleStructType(e) case *ast.InterfaceType: code += handleInterfaceType(e) case *ast.ArrayType: code += handleArray(e) } return code } func handleBasicLit(bl *ast.BasicLit) string { return bl.Value } func handleBasicLitType(bl *ast.BasicLit) string { switch bl.Kind { case token.INT: return "int" case token.CHAR: return "char" case token.FLOAT: return "double" case token.STRING: return "std::string" } return "" } func handleUnaryExpr(expr *ast.UnaryExpr) (code string) { cl, ok := expr.X.(*ast.CompositeLit) if ok { code += "new " code += handleIdentExpr(cl.Type.(*ast.Ident)) code += "()" } else { code += expr.Op.String() code += handleExpr(expr.X) } return } func handleBinaryExpr(expr ast.Expr) string { be := expr.(*ast.BinaryExpr) code := handleExpr(be.X) code += be.Op.String() code += handleExpr(be.Y) 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 := "" switch ident.Name { case "nil": code += "NULL" case "uint32": code += "unsigned long" case "uint64": code += "unsigned long long" case "float64": code += "double" case "string": code += "std::string" default: code += ident.Name } return code } func handleParenExpr(stmt *ast.ParenExpr) string { code := "" code += handleExpr(stmt.X) return code } func handleSelectorExpr(s *ast.SelectorExpr) (code string) { switch x := s.X.(type) { case *ast.Ident: if isInMethod { if x.Name == currentReceiverName { code += "this" } else { code += handleIdentExpr(x) } code += "->" } else { code += handleIdentExpr(x) code += "." } case *ast.SelectorExpr: code += "this" code += "->" code += handleIdentExpr(x.Sel) code += "->" } code += handleIdentExpr(s.Sel) if val, ok := mapping[code]; ok { code = val } return } func handleStarExpr(s *ast.StarExpr) (code string) { switch x := s.X.(type) { case *ast.Ident: code += handleIdentExpr(x) } return } func handleArray(s *ast.ArrayType) (code string) { switch x := s.Elt.(type) { case *ast.Ident: code += handleIdentExpr(x) } return }