From 2445189e0e5a2c3790cbd12d5969870e543a8461 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Tue, 18 Jun 2024 17:17:11 +0300 Subject: [PATCH 01/14] fix after merge --- internal/tlcodegen/type_rw_bool_cpp.go | 2 +- internal/tlcodegen/type_rw_struct.go | 28 ------------------------ internal/tlcodegen/type_rw_struct_cpp.go | 4 +--- internal/tlcodegen/type_rw_union_cpp.go | 6 +++-- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/internal/tlcodegen/type_rw_bool_cpp.go b/internal/tlcodegen/type_rw_bool_cpp.go index 3adc5889..e9352cec 100644 --- a/internal/tlcodegen/type_rw_bool_cpp.go +++ b/internal/tlcodegen/type_rw_bool_cpp.go @@ -47,7 +47,7 @@ func (trw *TypeRWBool) CPPTypeWritingCode(bytesVersion bool, val string, bare bo func (trw *TypeRWBool) CPPTypeReadingCode(bytesVersion bool, val string, bare bool, natArgs []string, last bool) string { goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - return fmt.Sprintf("\tif (!::%s::%sRead%s(s, %s%s) { return false; }", trw.wr.gen.DetailsCPPNamespace, goGlobalName, addBare(bare), val, joinWithCommas(natArgs)) + return fmt.Sprintf("\tif (!::%s::%sRead%s(s, %s%s)) { return false; }", trw.wr.gen.DetailsCPPNamespace, goGlobalName, addBare(bare), val, joinWithCommas(natArgs)) } func (trw *TypeRWBool) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncludesCPP, hppIncFwd *DirectIncludesCPP, hppDet *strings.Builder, hppDetInc *DirectIncludesCPP, cppDet *strings.Builder, cppDetInc *DirectIncludesCPP, bytesVersion bool, forwardDeclaration bool) { diff --git a/internal/tlcodegen/type_rw_struct.go b/internal/tlcodegen/type_rw_struct.go index 36ed107e..4b801c92 100644 --- a/internal/tlcodegen/type_rw_struct.go +++ b/internal/tlcodegen/type_rw_struct.go @@ -457,34 +457,6 @@ outer: return result } -func (trw *TypeRWWrapper) replaceUnwrapHalfResolvedName(topHalfResolved HalfResolvedArgument, name string) string { - if name == "" { - return "" - } - for i, arg := range trw.origTL[0].TemplateArguments { - if arg.FieldName == name { - return topHalfResolved.Args[i].Name - } - } - return "" -} - -// same code as in func (w *TypeRWWrapper) transformNatArgsToChild, replaceUnwrapArgs -func (trw *TypeRWWrapper) replaceUnwrapHalfResolved(topHalfResolved HalfResolvedArgument, halfResolved HalfResolvedArgument) HalfResolvedArgument { - // example - // tuple#9770768a {t:Type} {n:#} [t] = Tuple t n; - // innerMaybe {X:#} a:(Maybe (tuple int X)) = InnerMaybe X; - // when unwrapping we need to change tuple into __tuple - // halfResolved references in field of tuple are to "n", "t" local template args - // we must look up in tuple to replace "n" "t" into "X", "" - var result HalfResolvedArgument - result.Name = trw.replaceUnwrapHalfResolvedName(topHalfResolved, halfResolved.Name) - for _, arg := range halfResolved.Args { - result.Args = append(result.Args, trw.replaceUnwrapHalfResolved(topHalfResolved, arg)) - } - return result -} - func (trw *TypeRWStruct) typeResettingCode(bytesVersion bool, directImports *DirectImports, ins *InternalNamespace, val string, ref bool) string { if trw.isUnwrapType() { return trw.Fields[0].t.TypeResettingCode(bytesVersion, directImports, ins, val, ref) diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index 60320d3a..84cd974e 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -327,9 +327,7 @@ bool %[7]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { trw.wr.gen.DetailsCPPNamespace, formatNatArgsCallCPP(trw.wr.NatParams), trw.wr.tlTag, - ) - cppDet.WriteString(s) - + )) } cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } diff --git a/internal/tlcodegen/type_rw_union_cpp.go b/internal/tlcodegen/type_rw_union_cpp.go index bd41340a..7aa71def 100644 --- a/internal/tlcodegen/type_rw_union_cpp.go +++ b/internal/tlcodegen/type_rw_union_cpp.go @@ -53,7 +53,7 @@ func (trw *TypeRWUnion) CPPTypeWritingCode(bytesVersion bool, val string, bare b func (trw *TypeRWUnion) CPPTypeReadingCode(bytesVersion bool, val string, bare bool, natArgs []string, last bool) string { goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - return fmt.Sprintf("\tif (!::%s::%sRead%s(s, %s%s) { return false; }", trw.wr.gen.DetailsCPPNamespace, goGlobalName, addBare(bare), val, joinWithCommas(natArgs)) + return fmt.Sprintf("\tif (!::%s::%sRead%s(s, %s%s)) { return false; }", trw.wr.gen.DetailsCPPNamespace, goGlobalName, addBare(bare), val, joinWithCommas(natArgs)) } func (trw *TypeRWUnion) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncludesCPP, hppIncFwd *DirectIncludesCPP, hppDet *strings.Builder, hppDetInc *DirectIncludesCPP, cppDet *strings.Builder, cppDetInc *DirectIncludesCPP, bytesVersion bool, forwardDeclaration bool) { @@ -176,7 +176,9 @@ void %[7]s::%[1]sReset(%[2]s& item) { } bool %[7]s::%[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s) { - switch (s.nat_read()) { + uint32_t nat; + s.nat_read(nat); + switch (nat) { %[5]s default: return s.set_error_union_tag(); } From b549dd8d70a5dfdbbaa923d17a2d17b364b0074b Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Tue, 18 Jun 2024 17:36:22 +0300 Subject: [PATCH 02/14] static check fix --- internal/tlcodegen/tlgen.go | 39 +--------------------------- internal/tlcodegen/type_rw.go | 24 ++++++++--------- internal/tlcodegen/type_rw_struct.go | 2 +- 3 files changed, 14 insertions(+), 51 deletions(-) diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index 01526f98..f1acf975 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -1303,7 +1303,7 @@ func findAllTypesDependencyComponents(types []*TypeRWWrapper) (map[int]map[int]b for componentId, itsDeps := range componentsDeps { componentsOrdered = append(componentsOrdered, componentId) list := make([]int, len(itsDeps)) - for dep, _ := range itsDeps { + for dep := range itsDeps { list = append(list, dep) } sort.Ints(list) @@ -1506,43 +1506,6 @@ func processCombinators(types map[string]*tlast.Combinator) *TypesInfo { return &ti } -func printResults(ti TypesInfo) { - for tp, rds := range ti.TypeReductions { - suffix := "" - for i, tpArg := range tp.TypeArguments { - if i != 0 { - suffix += "," - } - if tpArg.IsNat { - suffix += "#" - } else { - suffix += "*" - } - } - if len(tp.TypeArguments) != 0 { - suffix = "<" + suffix + ">" - } - fmt.Println(tp.Name.String() + suffix) - for _, trd := range *rds { - fmt.Println("\t", trd) - if !trd.IsType { - for i, f := range trd.Constructor.Fields { - ftrd := ti.FieldTypeReduction(trd, i) - s := "" - if ftrd.Index == TypeVariable { - s = "[" + ftrd.TypeVariable + "]" - } else if ftrd.Index == TypeConstant { - if ftrd.Type != nil { - s = ftrd.Type.String() - } - } - fmt.Println("\t\t", "\""+f.FieldName+"\":", s) - } - } - } - } -} - func reduce( targetTypeReduction TypeReduction, visitedReductions *map[*TypeDefinition]*map[string]*TypeReduction, diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index 1400e4ba..a3c0ee77 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -8,6 +8,7 @@ package tlcodegen import ( "fmt" + "golang.org/x/exp/slices" "regexp" "sort" "strconv" @@ -181,9 +182,10 @@ func (w *TypeRWWrapper) NatArgs(result []ActualNatArg, prefix string) []ActualNa func (w *TypeRWWrapper) ActualTypeDependencies(evalType EvaluatedType) (res []*TypeRWWrapper) { r := make(map[*TypeRWWrapper]bool) w.actualTypeDependenciesRecur(evalType, &r) - for arg, _ := range r { + for arg := range r { res = append(res, arg) } + slices.SortFunc(res, TypeComparator) return } @@ -241,14 +243,14 @@ type DirectIncludesCPP struct { ns map[string]CppIncludeInfo } -func (d DirectIncludesCPP) sortedNames() []string { - var sortedNames []string - for im := range d.ns { // Imports of this file. - sortedNames = append(sortedNames, im) - } - sort.Strings(sortedNames) - return sortedNames -} +//func (d DirectIncludesCPP) sortedNames() []string { +// var sortedNames []string +// for im := range d.ns { // Imports of this file. +// sortedNames = append(sortedNames, im) +// } +// sort.Strings(sortedNames) +// return sortedNames +//} func (d DirectIncludesCPP) sortedIncludes(componentOrder []int) (result []string) { compIdToPosition := make(map[int]int) @@ -269,9 +271,7 @@ func (d DirectIncludesCPP) sortedIncludes(componentOrder []int) (result []string for _, files := range filesByCID { sort.Strings(files) - for _, f := range files { - result = append(result, f) - } + result = append(result, files...) } return diff --git a/internal/tlcodegen/type_rw_struct.go b/internal/tlcodegen/type_rw_struct.go index 4b801c92..ae9730e2 100644 --- a/internal/tlcodegen/type_rw_struct.go +++ b/internal/tlcodegen/type_rw_struct.go @@ -160,7 +160,7 @@ func (trw *TypeRWStruct) AllTypeDependencies() (res []*TypeRWWrapper) { } } - for tp, _ := range used { + for tp := range used { res = append(res, tp) } return From 2f76a68c3fea666c4d089d0762f3c8102fb17601 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Tue, 18 Jun 2024 21:54:50 +0300 Subject: [PATCH 03/14] namespace separation --- internal/tlcodegen/tlgen_cpp.go | 34 +++++++++++++++++++----- internal/tlcodegen/type_rw.go | 27 ++++++++++++++++++- internal/tlcodegen/type_rw_bool_cpp.go | 4 +-- internal/tlcodegen/type_rw_maybe_cpp.go | 4 +-- internal/tlcodegen/type_rw_struct_cpp.go | 4 +-- internal/tlcodegen/type_rw_tuple_cpp.go | 5 +++- 6 files changed, 64 insertions(+), 14 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index b429817b..bd2a5c8d 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -68,7 +68,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { continue } - cppAllInc.ns[ff.fileName] = CppIncludeInfo{types[0].typeComponent} + cppAllInc.ns[ff.fileName] = CppIncludeInfo{types[0].typeComponent, types[0].tlName.Namespace} hppStr := hpp.String() hppDetStr := hppDet.String() cppDetStr := cppDet.String() @@ -118,12 +118,31 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { var cppMake strings.Builder var cppMakeO strings.Builder var cppMake1 strings.Builder - for _, n := range cppAllInc.sortedIncludes(gen.componentsOrder) { - cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n+"_details", cppExt)) - cppMake1.WriteString(fmt.Sprintf("%s.o: details/%s%s details/%s%s\n", n+"_details", n+"_details", cppExt, n+"_details", hppExt)) - cppMake1.WriteString(fmt.Sprintf("\t$(CC) $(CFLAGS) -c details/%s%s\n", n+"_details", cppExt)) - cppMakeO.WriteString(fmt.Sprintf("%s.o ", n+"_details")) + + for _, nf := range cppAllInc.splitByNamespaces() { + namespace := nf.Namespace + if namespace == "" { + namespace = "__common" + } + + var cppMake1UsedFiles strings.Builder + var cppMake1Namespace strings.Builder + + for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder) { + cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n+"_details", cppExt)) + cppMake1Namespace.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n+"_details", cppExt)) + cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n+"_details", cppExt, n+"_details", hppExt)) + } + + cppMake1.WriteString(fmt.Sprintf("build/%s.o: %s\n", namespace+"_namespace_details", cppMake1UsedFiles.String())) + cppMake1.WriteString(fmt.Sprintf("\t$(CC) $(CFLAGS) -o build/%[1]s.o -c details/%[1]s%[2]s\n", namespace+"_namespace_details", cppExt)) + cppMakeO.WriteString(fmt.Sprintf("build/%s.o ", namespace+"_namespace_details")) + + if err := gen.addCodeFile(fmt.Sprintf("details/%s%s", namespace+"_namespace_details", cppExt), cppMake1Namespace.String()); err != nil { + return err + } } + cppMake.WriteString(` CC = g++ CFLAGS = -std=c++17 -O3 -Wno-noexcept-type -g -Wall -Wextra -Werror=return-type -Wno-unused-parameter @@ -144,6 +163,9 @@ main.o: main.cpp if err := gen.addCodeFile("Makefile", cppMake.String()); err != nil { return err } + if err := gen.addCodeFile("build/info.txt", ".o files here!"); err != nil { + return err + } // if gen.options.Verbose { // log.Printf("generation of serialization code finished, %d constructors processed, %d types generated", len(gen.allConstructors), typesCounter) // if len(generateByteVersions) != 0 { diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index a3c0ee77..bc8bc6f7 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -236,6 +236,7 @@ type DirectImports struct { type CppIncludeInfo struct { componentId int + namespace string } // for C++ includes @@ -252,6 +253,30 @@ type DirectIncludesCPP struct { // return sortedNames //} +type NamespaceFiles struct { + Namespace string + Includes DirectIncludesCPP +} + +func (d DirectIncludesCPP) splitByNamespaces() (result []NamespaceFiles) { + namespaces := make(map[string]int) + + for file, include := range d.ns { + ns := include.namespace + if namespaces[ns] == 0 { + namespaces[ns] = len(namespaces) + 1 + result = append(result, NamespaceFiles{Namespace: ns, Includes: DirectIncludesCPP{ns: map[string]CppIncludeInfo{}}}) + } + result[namespaces[ns]-1].Includes.ns[file] = include + } + + slices.SortFunc(result, func(a, b NamespaceFiles) int { + return strings.Compare(a.Namespace, b.Namespace) + }) + + return +} + func (d DirectIncludesCPP) sortedIncludes(componentOrder []int) (result []string) { compIdToPosition := make(map[int]int) @@ -507,7 +532,7 @@ func (w *TypeRWWrapper) cppTypeArguments(bytesVersion bool, typeRedaction *TypeR } func (w *TypeRWWrapper) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolve bool, halfResolved HalfResolvedArgument) (string, string, string) { - hppInc.ns[w.fileName] = CppIncludeInfo{w.typeComponent} + hppInc.ns[w.fileName] = CppIncludeInfo{w.typeComponent, w.tlName.Namespace} bName := strings.Builder{} // bName.WriteString(w.cppNamespaceQualifier()) bName.WriteString(w.tlName.Name) diff --git a/internal/tlcodegen/type_rw_bool_cpp.go b/internal/tlcodegen/type_rw_bool_cpp.go index e9352cec..839ef8ae 100644 --- a/internal/tlcodegen/type_rw_bool_cpp.go +++ b/internal/tlcodegen/type_rw_bool_cpp.go @@ -15,12 +15,12 @@ func (trw *TypeRWBool) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrapper] } func (trw *TypeRWBool) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent} + hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "bool" } func (trw *TypeRWBool) cppTypeStringInNamespaceHalfResolved(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolved HalfResolvedArgument) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent} + hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "bool" } diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index 971960f9..6518695c 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -16,12 +16,12 @@ func (trw *TypeRWMaybe) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrapper } func (trw *TypeRWMaybe) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent} + hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "std::optional<" + trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc) + ">" } func (trw *TypeRWMaybe) cppTypeStringInNamespaceHalfResolved(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolved HalfResolvedArgument) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent} + hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "std::optional<" + trw.element.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, halfResolved.Args[0]) + ">" } diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index 84cd974e..13182689 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -160,7 +160,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc typeDependencies := field.t.ActualTypeDependencies(typeRed) for _, typeRw := range typeDependencies { if typeRw.cppLocalName != "" { - hppInc.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent} + hppInc.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } } hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed))) @@ -178,7 +178,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc if typeRw.trw.IsWrappingType() { continue } - hppIncByField.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent} + hppIncByField.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed) diff --git a/internal/tlcodegen/type_rw_tuple_cpp.go b/internal/tlcodegen/type_rw_tuple_cpp.go index e01d5ab4..eda20860 100644 --- a/internal/tlcodegen/type_rw_tuple_cpp.go +++ b/internal/tlcodegen/type_rw_tuple_cpp.go @@ -19,7 +19,7 @@ func (trw *TypeRWBrackets) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrap } func (trw *TypeRWBrackets) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent} + hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} //if trw.dictLike && !bytesVersion { // TODO - which arguments must map have is very complicated //return fmt.Sprintf("std::map<%s, %s>", @@ -59,6 +59,9 @@ func (trw *TypeRWBrackets) cppTypeStringInNamespaceHalfResolved2(bytesVersion bo if typeReduction.Type.Arguments[0].VariableActsAsConstant { return fmt.Sprintf("std::array<%s, %s>", trw.element.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeReduction.Type.Arguments[1]), typeReduction.Type.Arguments[0].Variable) } + if typeReduction.Type.Arguments[0].Index == NumberConstant { + return fmt.Sprintf("std::array<%s, %d>", trw.element.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeReduction.Type.Arguments[1]), typeReduction.Type.Arguments[0].Constant) + } return fmt.Sprintf("std::vector<%s>", trw.element.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeReduction.Type.Arguments[1])) } return "" From 2207e08c778fb4a6a6ed35a33a8717c4f38efb1e Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Wed, 19 Jun 2024 13:51:11 +0300 Subject: [PATCH 04/14] resolved issue with file namespace relation because of multiple types in one file --- internal/tlcodegen/tlgen_cpp.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index bd2a5c8d..639cefee 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -68,7 +68,14 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { continue } + // default value cppAllInc.ns[ff.fileName] = CppIncludeInfo{types[0].typeComponent, types[0].tlName.Namespace} + for _, typeInFile := range types { + if ff.fileName == typeInFile.tlName.String() { + cppAllInc.ns[ff.fileName] = CppIncludeInfo{typeInFile.typeComponent, typeInFile.tlName.Namespace} + break + } + } hppStr := hpp.String() hppDetStr := hppDet.String() cppDetStr := cppDet.String() @@ -134,7 +141,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n+"_details", cppExt, n+"_details", hppExt)) } - cppMake1.WriteString(fmt.Sprintf("build/%s.o: %s\n", namespace+"_namespace_details", cppMake1UsedFiles.String())) + cppMake1.WriteString(fmt.Sprintf("build/%s.o: details/%s%s %s\n", namespace+"_namespace_details", namespace+"_namespace_details", cppExt, cppMake1UsedFiles.String())) cppMake1.WriteString(fmt.Sprintf("\t$(CC) $(CFLAGS) -o build/%[1]s.o -c details/%[1]s%[2]s\n", namespace+"_namespace_details", cppExt)) cppMakeO.WriteString(fmt.Sprintf("build/%s.o ", namespace+"_namespace_details")) From eed3e1d558adbfcbf486c33d7082c44c3653c6a6 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Wed, 19 Jun 2024 15:59:58 +0300 Subject: [PATCH 05/14] moved namespaces to another foldler --- internal/tlcodegen/tlgen_cpp.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 639cefee..43fd4bb8 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -137,15 +137,19 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder) { cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n+"_details", cppExt)) - cppMake1Namespace.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n+"_details", cppExt)) + cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n+"_details", cppExt)) cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n+"_details", cppExt, n+"_details", hppExt)) } - cppMake1.WriteString(fmt.Sprintf("build/%s.o: details/%s%s %s\n", namespace+"_namespace_details", namespace+"_namespace_details", cppExt, cppMake1UsedFiles.String())) - cppMake1.WriteString(fmt.Sprintf("\t$(CC) $(CFLAGS) -o build/%[1]s.o -c details/%[1]s%[2]s\n", namespace+"_namespace_details", cppExt)) - cppMakeO.WriteString(fmt.Sprintf("build/%s.o ", namespace+"_namespace_details")) + namespaceDetails := namespace + "_details" + namespaceFilePath := "details/namespaces/" + namespaceDetails + cppExt + buildFilePath := "build/" + namespaceDetails + ".o" - if err := gen.addCodeFile(fmt.Sprintf("details/%s%s", namespace+"_namespace_details", cppExt), cppMake1Namespace.String()); err != nil { + cppMake1.WriteString(fmt.Sprintf("%s: %s %s\n", buildFilePath, namespaceFilePath, cppMake1UsedFiles.String())) + cppMake1.WriteString(fmt.Sprintf("\t$(CC) $(CFLAGS) -o %s -c %s\n", buildFilePath, namespaceFilePath)) + cppMakeO.WriteString(fmt.Sprintf("%s ", buildFilePath)) + + if err := gen.addCodeFile(namespaceFilePath, cppMake1Namespace.String()); err != nil { return err } } From 8790fa86c911b41e1f1f3ce0e8db2801f229fd63 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Fri, 21 Jun 2024 17:37:03 +0300 Subject: [PATCH 06/14] change to group cpp file with any strategy --- internal/tlcodegen/tlgen.go | 15 ++ internal/tlcodegen/tlgen_cpp.go | 182 +++++++++++++---------- internal/tlcodegen/tlgen_kernel.go | 4 +- internal/tlcodegen/type_rw.go | 64 +++++--- internal/tlcodegen/type_rw_bool_cpp.go | 4 +- internal/tlcodegen/type_rw_maybe_cpp.go | 4 +- internal/tlcodegen/type_rw_struct_cpp.go | 8 +- internal/tlcodegen/type_rw_tuple_cpp.go | 2 +- 8 files changed, 176 insertions(+), 107 deletions(-) diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index f1acf975..4f8ff5e3 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -1747,3 +1747,18 @@ func (ti *TypesInfo) TypeNameToGenericTypeReduction(t TypeName) TypeReduction { return rd } + +func (ti *TypesInfo) TypeRWWrapperToTypeReduction(t *TypeRWWrapper) TypeReduction { + tr := ti.TypeNameToGenericTypeReduction(t.tlName) + for i, arg := range t.arguments { + if arg.tip != nil { + evalArg := ti.TypeRWWrapperToTypeReduction(arg.tip) + tr.Arguments[i] = EvaluatedType{Index: TypeConstant, Type: &evalArg} + } else { + if arg.isArith { + tr.Arguments[i] = EvaluatedType{Index: NumberConstant, Constant: arg.Arith.Res} + } + } + } + return tr +} diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 43fd4bb8..108e6350 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -26,107 +26,131 @@ func cppFinishNamespace(s *strings.Builder, ns []string) { func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { const basicTLFilepathName = "a_tlgen_helpers_code" + hppExt // TODO decollision - cppAllInc := &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} + cppAllInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} var hpp strings.Builder - var hppDet strings.Builder - var cppDet strings.Builder + typesCounter := 0 - typesCounterBytes := 0 - internalFiles := map[InsFile][]*TypeRWWrapper{} + for _, typeRw := range gen.generatedTypesList { - ff := InsFile{ins: typeRw.ins, fileName: typeRw.fileName} - internalFiles[ff] = append(internalFiles[ff], typeRw) + gen.decideCppCodeDestinations(typeRw) } - for ff, types := range internalFiles { - hppInc := &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} - hppIncFwd := &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} - hppDetInc := &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} - cppDetInc := &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} - multipleDefinitions := map[string]struct{}{} - for _, typeRw := range types { - // log.Printf("type: %s\n", typeRw.tlName.String()) - // log.Printf(" %s\n", typeRw.resolvedType.String()) - typesCounter++ - var hppDefinition strings.Builder - typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, false, false) - def := hppDefinition.String() - if _, ok := multipleDefinitions[def]; !ok { - multipleDefinitions[def] = struct{}{} - hpp.WriteString(def) + + internalFiles2 := map[InsFile]map[string][]*TypeRWWrapper{} + + for _, typeRw := range gen.generatedTypesList { + hppDef := InsFile{ins: typeRw.ins, fileName: typeRw.fileName} + if _, ok := internalFiles2[hppDef]; !ok { + internalFiles2[hppDef] = make(map[string][]*TypeRWWrapper) + } + internalFiles2[hppDef][typeRw.detailsFileName] = append(internalFiles2[hppDef][typeRw.detailsFileName], typeRw) + } + + // for each type header ~ tl combinator + for ff, details := range internalFiles2 { + hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + hppIncFwd := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + typeDefinitions := map[string]bool{} + + // for each file with specifications + for detailFile, specs := range details { + hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + var hppDet strings.Builder + var cppDet strings.Builder + + // for each specification + for _, typeRw := range specs { + // init all variants for specification (ex. byte version) + typeDefVariations := make([]TypeDefinitionVariation, 1) + { + if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { + typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) + } + } + + for _, typeDefVariation := range typeDefVariations { + typesCounter++ + var hppDefinition strings.Builder + typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) + def := hppDefinition.String() + if !typeDefinitions[def] { + typeDefinitions[def] = true + hpp.WriteString(def) + } + } + } + + if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { + continue + } + + // all specs in one file must be in group + cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} + + hppDetStr := hppDet.String() + cppDetStr := cppDet.String() + + hppDet.Reset() + cppDet.Reset() + + hppDet.WriteString("#pragma once\n\n") + hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) + + hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", ff.fileName, hppExt)) + for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { + if n == ff.fileName { + continue + } + hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) } - if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { - hppDefinition.Reset() - typesCounterBytes++ - typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, true, false) - def = hppDefinition.String() - if _, ok := multipleDefinitions[def]; !ok { - multipleDefinitions[def] = struct{}{} - hpp.WriteString(def) + hppDet.WriteString("\n") + + cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailFile, hppExt)) + for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { + if n == detailFile { + continue } + cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + } + cppDet.WriteString("\n") + + filepathName := filepath.Join("details", detailFile+hppExt) + if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { + return err + } + filepathName = filepath.Join("details", detailFile+cppExt) + if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { + return err } } - if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { + + if hpp.Len() == 0 { continue } - // default value - cppAllInc.ns[ff.fileName] = CppIncludeInfo{types[0].typeComponent, types[0].tlName.Namespace} - for _, typeInFile := range types { - if ff.fileName == typeInFile.tlName.String() { - cppAllInc.ns[ff.fileName] = CppIncludeInfo{typeInFile.typeComponent, typeInFile.tlName.Namespace} - break - } - } + hppStr := hpp.String() - hppDetStr := hppDet.String() - cppDetStr := cppDet.String() hpp.Reset() - hppDet.Reset() - cppDet.Reset() hpp.WriteString("#pragma once\n\n") - hppDet.WriteString("#pragma once\n\n") hpp.WriteString(fmt.Sprintf("#include \"%s\"\n", basicTLFilepathName)) - for _, n := range hppInc.sortedIncludes(gen.componentsOrder) { + for _, n := range hppInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) } hpp.WriteString("\n\n") - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", ff.fileName, hppExt)) - hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) hpp.WriteString(hppStr) - // for _, n := range hppIncFwd.sortedNames() { - // hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) - // } - for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder) { - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) - } - cppDet.WriteString(fmt.Sprintf("#include \"%s_details%s\"\n", ff.fileName, hppExt)) - for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder) { - if n == ff.fileName { - continue - } - cppDet.WriteString(fmt.Sprintf("#include \"%s_details%s\"\n", n, hppExt)) - } filepathName := ff.fileName + hppExt if err := gen.addCodeFile(filepathName, gen.copyrightText+hpp.String()); err != nil { return err } hpp.Reset() - filepathName = filepath.Join("details", ff.fileName+"_details"+hppExt) - if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { - return err - } - hppDet.Reset() - filepathName = filepath.Join("details", ff.fileName+"_details"+cppExt) - if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { - return err - } - cppDet.Reset() } + var cppAll strings.Builder var cppMake strings.Builder var cppMakeO strings.Builder var cppMake1 strings.Builder for _, nf := range cppAllInc.splitByNamespaces() { + // it is a group namespace := nf.Namespace if namespace == "" { namespace = "__common" @@ -135,13 +159,13 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { var cppMake1UsedFiles strings.Builder var cppMake1Namespace strings.Builder - for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder) { - cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n+"_details", cppExt)) - cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n+"_details", cppExt)) - cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n+"_details", cppExt, n+"_details", hppExt)) + for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { + cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n, cppExt)) + cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, cppExt)) + cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n, cppExt, n, hppExt)) } - namespaceDetails := namespace + "_details" + namespaceDetails := namespace namespaceFilePath := "details/namespaces/" + namespaceDetails + cppExt buildFilePath := "build/" + namespaceDetails + ".o" @@ -222,3 +246,9 @@ main.o: main.cpp // } return nil } + +func (gen *Gen2) decideCppCodeDestinations(t *TypeRWWrapper) { + // TODO + t.detailsFileName = t.fileName + "_details" + t.groupName = t.tlName.Namespace +} diff --git a/internal/tlcodegen/tlgen_kernel.go b/internal/tlcodegen/tlgen_kernel.go index 7a38b97a..e263462e 100644 --- a/internal/tlcodegen/tlgen_kernel.go +++ b/internal/tlcodegen/tlgen_kernel.go @@ -280,7 +280,7 @@ func (gen *Gen2) generateType(myWrapper *TypeRWWrapper) error { head, tail = myWrapper.resolvedT2GoName(myWrapper.tlName.Namespace) myWrapper.goLocalName = namespace.decGo.deconflictName(head + tail) //actualName, _, _ := myWrapper.cppTypeStringInNamespace(false, &DirectIncludesCPP{ns: map[string]struct{}{}}, false, HalfResolvedArgument{}) - actualName, canonicalName, _ := myWrapper.cppTypeStringInNamespace(false, &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}}, false, HalfResolvedArgument{}) + actualName, canonicalName, _ := myWrapper.cppTypeStringInNamespace(false, &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}}, false, HalfResolvedArgument{}) otherRW, ok := namespace.cppTemplates[canonicalName] if ok { myWrapper.cppLocalName = otherRW.cppLocalName @@ -356,7 +356,7 @@ func (gen *Gen2) generateType(myWrapper *TypeRWWrapper) error { myWrapper.goGlobalName = gen.globalDec.deconflictName(head + tail) head, tail = myWrapper.resolvedT2GoName(myWrapper.tlName.Namespace) myWrapper.goLocalName = namespace.decGo.deconflictName(head + tail) - actualName, canonicalName, _ := myWrapper.cppTypeStringInNamespace(false, &DirectIncludesCPP{ns: map[string]CppIncludeInfo{}}, false, HalfResolvedArgument{}) + actualName, canonicalName, _ := myWrapper.cppTypeStringInNamespace(false, &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}}, false, HalfResolvedArgument{}) otherRW, ok := namespace.cppTemplates[canonicalName] if ok { myWrapper.cppLocalName = otherRW.cppLocalName diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index bc8bc6f7..a3e12ca7 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -10,7 +10,6 @@ import ( "fmt" "golang.org/x/exp/slices" "regexp" - "sort" "strconv" "strings" @@ -80,9 +79,13 @@ type TypeRWWrapper struct { hasErrorInWriteMethods bool fileName string - tlTag uint32 // TODO - turn into function - tlName tlast.Name // TODO - turn into function constructor name or union name for code generation - origTL []*tlast.Combinator + + detailsFileName string + groupName string + + tlTag uint32 // TODO - turn into function + tlName tlast.Name // TODO - turn into function constructor name or union name for code generation + origTL []*tlast.Combinator unionParent *TypeRWUnion // a bit hackish, but simple unionIndex int @@ -241,7 +244,11 @@ type CppIncludeInfo struct { // for C++ includes type DirectIncludesCPP struct { - ns map[string]CppIncludeInfo + ns map[*TypeRWWrapper]CppIncludeInfo +} + +type TypeDefinitionVariation struct { + NeedBytesVersion bool } //func (d DirectIncludesCPP) sortedNames() []string { @@ -265,7 +272,7 @@ func (d DirectIncludesCPP) splitByNamespaces() (result []NamespaceFiles) { ns := include.namespace if namespaces[ns] == 0 { namespaces[ns] = len(namespaces) + 1 - result = append(result, NamespaceFiles{Namespace: ns, Includes: DirectIncludesCPP{ns: map[string]CppIncludeInfo{}}}) + result = append(result, NamespaceFiles{Namespace: ns, Includes: DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}}}) } result[namespaces[ns]-1].Includes.ns[file] = include } @@ -277,26 +284,43 @@ func (d DirectIncludesCPP) splitByNamespaces() (result []NamespaceFiles) { return } -func (d DirectIncludesCPP) sortedIncludes(componentOrder []int) (result []string) { - compIdToPosition := make(map[int]int) +type Pair[L, R any] struct { + left L + right R +} - for i, cId := range componentOrder { - compIdToPosition[cId] = i +// not stable +func mapToPairArray[L comparable, R any](m *map[L]R) (res []Pair[L, R]) { + for k, v := range *m { + res = append(res, Pair[L, R]{k, v}) } + return +} - filesByCID := make([][]string, len(componentOrder)) - used := make(map[string]bool) +func (d DirectIncludesCPP) sortedIncludes(componentOrder []int, typeToFile func(wrapper *TypeRWWrapper) string) (result []string) { + includeNamesToTypes := make(map[string]int) - for im, cppInfo := range d.ns { // Imports of this file. - if !used[im] { - used[im] = true - filesByCID[compIdToPosition[cppInfo.componentId]] = append(filesByCID[compIdToPosition[cppInfo.componentId]], im) + for tp, _ := range d.ns { + include := typeToFile(tp) + if _, ok := includeNamesToTypes[include]; !ok { + includeNamesToTypes[include] = tp.typeComponent + } else { + includeNamesToTypes[include] = min(includeNamesToTypes[include], tp.typeComponent) } } - for _, files := range filesByCID { - sort.Strings(files) - result = append(result, files...) + includeNamesToTypesList := mapToPairArray(&includeNamesToTypes) + slices.SortFunc(includeNamesToTypesList, func(a, b Pair[string, int]) int { + typeDiff := a.right - b.right + if typeDiff == 0 { + return strings.Compare(a.left, b.left) + } else { + return typeDiff + } + }) + + for _, includeInfo := range includeNamesToTypesList { + result = append(result, includeInfo.left) } return @@ -532,7 +556,7 @@ func (w *TypeRWWrapper) cppTypeArguments(bytesVersion bool, typeRedaction *TypeR } func (w *TypeRWWrapper) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolve bool, halfResolved HalfResolvedArgument) (string, string, string) { - hppInc.ns[w.fileName] = CppIncludeInfo{w.typeComponent, w.tlName.Namespace} + hppInc.ns[w] = CppIncludeInfo{w.typeComponent, w.tlName.Namespace} bName := strings.Builder{} // bName.WriteString(w.cppNamespaceQualifier()) bName.WriteString(w.tlName.Name) diff --git a/internal/tlcodegen/type_rw_bool_cpp.go b/internal/tlcodegen/type_rw_bool_cpp.go index 839ef8ae..282ef086 100644 --- a/internal/tlcodegen/type_rw_bool_cpp.go +++ b/internal/tlcodegen/type_rw_bool_cpp.go @@ -15,12 +15,12 @@ func (trw *TypeRWBool) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrapper] } func (trw *TypeRWBool) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} + hppInc.ns[trw.wr] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "bool" } func (trw *TypeRWBool) cppTypeStringInNamespaceHalfResolved(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolved HalfResolvedArgument) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} + hppInc.ns[trw.wr] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "bool" } diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index 6518695c..b24ef565 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -16,12 +16,12 @@ func (trw *TypeRWMaybe) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrapper } func (trw *TypeRWMaybe) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} + hppInc.ns[trw.wr] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "std::optional<" + trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc) + ">" } func (trw *TypeRWMaybe) cppTypeStringInNamespaceHalfResolved(bytesVersion bool, hppInc *DirectIncludesCPP, halfResolved HalfResolvedArgument) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} + hppInc.ns[trw.wr] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} return "std::optional<" + trw.element.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, halfResolved.Args[0]) + ">" } diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index 13182689..f2c6c857 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -160,7 +160,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc typeDependencies := field.t.ActualTypeDependencies(typeRed) for _, typeRw := range typeDependencies { if typeRw.cppLocalName != "" { - hppInc.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} + hppInc.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } } hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed))) @@ -171,14 +171,14 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc } else { hpp.WriteString("struct " + trw.wr.cppLocalName + " {\n") for i, field := range trw.Fields { - hppIncByField := DirectIncludesCPP{ns: map[string]CppIncludeInfo{}} + hppIncByField := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} typeRed := ti.FieldTypeReduction(&typeReduction, i) for _, typeRw := range trw.Fields[i].t.ActualTypeDependencies(typeRed) { if typeRw.trw.IsWrappingType() { continue } - hppIncByField.ns[typeRw.fileName] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} + hppIncByField.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed) @@ -189,7 +189,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc if field.recursive { // TODO make better for includeType, includeInfo := range hppIncByField.ns { - if includeInfo.componentId == trw.wr.typeComponent { + if includeInfo.componentId == trw.wr.typeComponent || includeType.cppLocalName == "" { delete(hppIncByField.ns, includeType) } } diff --git a/internal/tlcodegen/type_rw_tuple_cpp.go b/internal/tlcodegen/type_rw_tuple_cpp.go index eda20860..e238ff72 100644 --- a/internal/tlcodegen/type_rw_tuple_cpp.go +++ b/internal/tlcodegen/type_rw_tuple_cpp.go @@ -19,7 +19,7 @@ func (trw *TypeRWBrackets) CPPFillRecursiveChildren(visitedNodes map[*TypeRWWrap } func (trw *TypeRWBrackets) cppTypeStringInNamespace(bytesVersion bool, hppInc *DirectIncludesCPP) string { - hppInc.ns[trw.wr.fileName] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} + hppInc.ns[trw.wr] = CppIncludeInfo{componentId: trw.wr.typeComponent, namespace: trw.wr.tlName.Namespace} //if trw.dictLike && !bytesVersion { // TODO - which arguments must map have is very complicated //return fmt.Sprintf("std::map<%s, %s>", From a0fa8f14c3c6f7e2e147fe34b80c8b997ea209ec Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Fri, 21 Jun 2024 23:50:45 +0300 Subject: [PATCH 07/14] add cpp details distribution algorithm + fix includes in maybe --- internal/tlcodegen/tlgen.go | 4 +- internal/tlcodegen/tlgen_cpp.go | 146 +++++++++++++++++++++-- internal/tlcodegen/type_rw.go | 2 +- internal/tlcodegen/type_rw_bool.go | 2 +- internal/tlcodegen/type_rw_maybe.go | 7 +- internal/tlcodegen/type_rw_maybe_cpp.go | 9 +- internal/tlcodegen/type_rw_primitive.go | 2 +- internal/tlcodegen/type_rw_struct.go | 2 +- internal/tlcodegen/type_rw_struct_cpp.go | 2 +- internal/tlcodegen/type_rw_tuple.go | 7 +- internal/tlcodegen/type_rw_union.go | 2 +- internal/tlcodegen/type_rw_union_cpp.go | 2 +- 12 files changed, 166 insertions(+), 21 deletions(-) diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index 4f8ff5e3..2c02863f 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -1247,7 +1247,7 @@ func findAllTypesDependencyComponents(types []*TypeRWWrapper) (map[int]map[int]b reverseDependencyGraph := make(map[*TypeRWWrapper][]*TypeRWWrapper) for _, tpU := range types { - dependencies := tpU.trw.AllTypeDependencies() + dependencies := tpU.trw.AllTypeDependencies(true) for _, tpV := range dependencies { dependencyGraph[tpU] = append(dependencyGraph[tpU], tpV) reverseDependencyGraph[tpV] = append(reverseDependencyGraph[tpV], tpU) @@ -1290,7 +1290,7 @@ func findAllTypesDependencyComponents(types []*TypeRWWrapper) (map[int]map[int]b if _, ok := componentsDeps[tpU.typeComponent]; !ok { componentsDeps[tpU.typeComponent] = make(map[int]bool) } - for _, tpV := range tpU.trw.AllTypeDependencies() { + for _, tpV := range tpU.trw.AllTypeDependencies(true) { if tpU.typeComponent != tpV.typeComponent { componentsDeps[tpU.typeComponent][tpV.typeComponent] = true } diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 108e6350..0d88494e 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -31,9 +31,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { typesCounter := 0 - for _, typeRw := range gen.generatedTypesList { - gen.decideCppCodeDestinations(typeRw) - } + gen.decideCppCodeDestinations(gen.generatedTypesList) internalFiles2 := map[InsFile]map[string][]*TypeRWWrapper{} @@ -247,8 +245,142 @@ main.o: main.cpp return nil } -func (gen *Gen2) decideCppCodeDestinations(t *TypeRWWrapper) { - // TODO - t.detailsFileName = t.fileName + "_details" - t.groupName = t.tlName.Namespace +func sliceToSet[T comparable](s []T) map[T]bool { + m := make(map[T]bool) + for _, e := range s { + m[e] = true + } + return m +} + +// unstable +func setToSlice[T comparable](s map[T]bool) []T { + m := make([]T, 0) + for k, _ := range s { + m = append(m, k) + } + return m +} + +func mapSlice[A, B any](in []A, f func(A) B) (out []B) { + for _, e := range in { + out = append(out, f(e)) + } + return +} + +func filterSlice[A any](in []A, f func(A) bool) (out []A) { + for _, e := range in { + if f(e) { + out = append(out, e) + } + } + return +} + +func putPairToSetOfPairs[K, V comparable](in *map[K]map[V]bool, k K, v V) { + if _, ok := (*in)[k]; !ok { + (*in)[k] = make(map[V]bool) + } + (*in)[k][v] = true +} + +func reverseSetOfPairs[K, V comparable](in map[K]map[V]bool) map[V]map[K]bool { + m := make(map[V]map[K]bool) + + for k, vs := range in { + for v, _ := range vs { + putPairToSetOfPairs(&m, v, k) + } + } + + return m +} + +func findAllReachableTypeByGroup(v *TypeRWWrapper, visited *map[*TypeRWWrapper]bool, result *[]*TypeRWWrapper) { + if v.groupName != "" { + return + } + if (*visited)[v] { + return + } + (*visited)[v] = true + *result = append(*result, v) + + for _, w := range v.trw.AllTypeDependencies(false) { + findAllReachableTypeByGroup(w, visited, result) + } +} + +func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { + const IndependentTypes = "__independent_types" + const NoNamespaceGroup = "" + + for _, t := range allTypes { + t.detailsFileName = t.fileName + "_details" + t.groupName = t.tlName.Namespace + if t.fileName != t.tlName.String() { + for _, t2 := range allTypes { + if t.fileName == t2.tlName.String() { + t.groupName = t2.tlName.Namespace + break + } + } + } + } + + allTypesWithoutGroup := make([]*TypeRWWrapper, 0) + allTypesWithoutGroupMap := make(map[*TypeRWWrapper]bool) + + allTypesWithoutGroupUsages := make(map[*TypeRWWrapper]map[string]bool) + + for _, t := range allTypes { + if t.groupName != NoNamespaceGroup { + continue + } + allTypesWithoutGroup = append(allTypesWithoutGroup, t) + allTypesWithoutGroupMap[t] = true + } + + for _, t := range allTypes { + //if t.groupName == "" { + // continue + //} + for _, dep := range t.trw.AllTypeDependencies(false) { + if dep.groupName == NoNamespaceGroup { + if _, ok := allTypesWithoutGroupUsages[dep]; !ok { + allTypesWithoutGroupUsages[dep] = make(map[string]bool) + } + allTypesWithoutGroupUsages[dep][t.groupName] = true + } + } + } + + groupToFirstVisits := reverseSetOfPairs(allTypesWithoutGroupUsages) + for group, firstLayer := range groupToFirstVisits { + visited := make(map[*TypeRWWrapper]bool) + result := make([]*TypeRWWrapper, 0) + + for v, _ := range firstLayer { + findAllReachableTypeByGroup(v, &visited, &result) + } + + for _, v := range result { + putPairToSetOfPairs(&allTypesWithoutGroupUsages, v, group) + } + } + + for _, t := range allTypesWithoutGroup { + usages := allTypesWithoutGroupUsages[t] + + if len(usages) == 0 { + t.groupName = IndependentTypes + } else if len(usages) == 1 { + usage := setToSlice(usages)[0] + if usage != NoNamespaceGroup { + t.groupName = usage + t.detailsFileName = usage + "_" + t.detailsFileName + } + } + } } diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index a3e12ca7..c2154025 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -697,7 +697,7 @@ type TypeRW interface { FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) AllPossibleRecursionProducers() []*TypeRWWrapper - AllTypeDependencies() []*TypeRWWrapper + AllTypeDependencies(generic bool) []*TypeRWWrapper IsWrappingType() bool BeforeCodeGenerationStep1() // during first phase, some wr.trw are nil due to recursive types. So we delay some diff --git a/internal/tlcodegen/type_rw_bool.go b/internal/tlcodegen/type_rw_bool.go index d112ce4f..2417759d 100644 --- a/internal/tlcodegen/type_rw_bool.go +++ b/internal/tlcodegen/type_rw_bool.go @@ -46,7 +46,7 @@ func (trw *TypeRWBool) AllPossibleRecursionProducers() []*TypeRWWrapper { return nil } -func (trw *TypeRWBool) AllTypeDependencies() []*TypeRWWrapper { +func (trw *TypeRWBool) AllTypeDependencies(generic bool) []*TypeRWWrapper { return nil } diff --git a/internal/tlcodegen/type_rw_maybe.go b/internal/tlcodegen/type_rw_maybe.go index 6b863daa..01e695f4 100644 --- a/internal/tlcodegen/type_rw_maybe.go +++ b/internal/tlcodegen/type_rw_maybe.go @@ -44,8 +44,11 @@ func (trw *TypeRWMaybe) AllPossibleRecursionProducers() []*TypeRWWrapper { return trw.element.t.trw.AllPossibleRecursionProducers() } -func (trw *TypeRWMaybe) AllTypeDependencies() []*TypeRWWrapper { - return nil +func (trw *TypeRWMaybe) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { + if !generic { + res = append(res, trw.element.t) + } + return } func (trw *TypeRWMaybe) IsWrappingType() bool { diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index b24ef565..957c8e96 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -59,7 +59,14 @@ func (trw *TypeRWMaybe) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncl return } goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) + newTypeDeps := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + + myFullType := trw.cppTypeStringInNamespace(bytesVersion, &newTypeDeps) + + for k, v := range newTypeDeps.ns { + (*hppDetInc).ns[k] = v + (*cppDetInc).ns[k] = v + } cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) diff --git a/internal/tlcodegen/type_rw_primitive.go b/internal/tlcodegen/type_rw_primitive.go index 5ce4e0b8..916816aa 100644 --- a/internal/tlcodegen/type_rw_primitive.go +++ b/internal/tlcodegen/type_rw_primitive.go @@ -62,7 +62,7 @@ func (trw *TypeRWPrimitive) AllPossibleRecursionProducers() []*TypeRWWrapper { return nil } -func (trw *TypeRWPrimitive) AllTypeDependencies() []*TypeRWWrapper { +func (trw *TypeRWPrimitive) AllTypeDependencies(generic bool) []*TypeRWWrapper { return nil } diff --git a/internal/tlcodegen/type_rw_struct.go b/internal/tlcodegen/type_rw_struct.go index ae9730e2..75e79e93 100644 --- a/internal/tlcodegen/type_rw_struct.go +++ b/internal/tlcodegen/type_rw_struct.go @@ -148,7 +148,7 @@ func (trw *TypeRWStruct) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWStruct) AllTypeDependencies() (res []*TypeRWWrapper) { +func (trw *TypeRWStruct) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { used := make(map[*TypeRWWrapper]bool) red := trw.wr.gen.typesInfo.TypeNameToGenericTypeReduction(trw.wr.tlName) diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index f2c6c857..b0f1071d 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -106,7 +106,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc } if !forwardDeclaration { - deps := trw.AllTypeDependencies() + deps := trw.AllTypeDependencies(true) slices.SortFunc(deps, TypeComparator) for _, typeDep := range deps { diff --git a/internal/tlcodegen/type_rw_tuple.go b/internal/tlcodegen/type_rw_tuple.go index ace31aea..e8db11b1 100644 --- a/internal/tlcodegen/type_rw_tuple.go +++ b/internal/tlcodegen/type_rw_tuple.go @@ -90,8 +90,11 @@ func (trw *TypeRWBrackets) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWBrackets) AllTypeDependencies() (res []*TypeRWWrapper) { - return nil +func (trw *TypeRWBrackets) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { + if !generic { + res = append(res, trw.element.t) + } + return } func (trw *TypeRWBrackets) IsWrappingType() bool { diff --git a/internal/tlcodegen/type_rw_union.go b/internal/tlcodegen/type_rw_union.go index 2dcefc50..7753a02f 100644 --- a/internal/tlcodegen/type_rw_union.go +++ b/internal/tlcodegen/type_rw_union.go @@ -78,7 +78,7 @@ func (trw *TypeRWUnion) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWUnion) AllTypeDependencies() (res []*TypeRWWrapper) { +func (trw *TypeRWUnion) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { for _, f := range trw.Fields { res = append(res, f.t) } diff --git a/internal/tlcodegen/type_rw_union_cpp.go b/internal/tlcodegen/type_rw_union_cpp.go index 7aa71def..72c3e608 100644 --- a/internal/tlcodegen/type_rw_union_cpp.go +++ b/internal/tlcodegen/type_rw_union_cpp.go @@ -90,7 +90,7 @@ bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - for _, typeDep := range trw.AllTypeDependencies() { + for _, typeDep := range trw.AllTypeDependencies(true) { if typeDep.typeComponent == trw.wr.typeComponent { typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) } From a8c51389016897f14d2ad54ec3e2877c3dce2c7d Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Thu, 27 Jun 2024 23:10:46 +0300 Subject: [PATCH 08/14] change to union in one .cpp --- cmd/tlgen/main2.go | 2 + internal/tlcodegen/tlgen.go | 1 + internal/tlcodegen/tlgen_cpp.go | 305 +++++++++++++-------- internal/tlcodegen/type_rw_bool_cpp.go | 21 +- internal/tlcodegen/type_rw_maybe_cpp.go | 146 ++++++----- internal/tlcodegen/type_rw_struct_cpp.go | 320 ++++++++++++----------- internal/tlcodegen/type_rw_tuple_cpp.go | 242 ++++++++--------- internal/tlcodegen/type_rw_union_cpp.go | 165 ++++++------ internal/utils/maps.go | 61 +++++ 9 files changed, 719 insertions(+), 544 deletions(-) create mode 100644 internal/utils/maps.go diff --git a/cmd/tlgen/main2.go b/cmd/tlgen/main2.go index 89175f0a..db332a36 100644 --- a/cmd/tlgen/main2.go +++ b/cmd/tlgen/main2.go @@ -66,6 +66,8 @@ func parseFlags(opt *tlcodegen.Gen2Options) { // C++ flag.StringVar(&opt.RootCPPNamespace, "cpp-namespace", "", `c++ root namespace, separated by '::' if more than 1 element`) + flag.BoolVar(&opt.SeparateFiles, "cpp-separate-files", false, + `separate .cpp files for types in one namespace`) // .tlo flag.StringVar(&opt.TLOPath, "tloPath", "", diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index 2c02863f..567989f3 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -332,6 +332,7 @@ type Gen2Options struct { // C++ RootCPPNamespace string + SeparateFiles bool // .tlo TLOPath string diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 0d88494e..13dabde1 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -8,6 +8,8 @@ package tlcodegen import ( "fmt" + "github.com/vkcom/tl/internal/utils" + "golang.org/x/exp/slices" "path/filepath" "strings" ) @@ -27,38 +29,87 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { const basicTLFilepathName = "a_tlgen_helpers_code" + hppExt // TODO decollision cppAllInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - var hpp strings.Builder - typesCounter := 0 gen.decideCppCodeDestinations(gen.generatedTypesList) - internalFiles2 := map[InsFile]map[string][]*TypeRWWrapper{} + typeHeadersByFileName := make(map[string][]*TypeRWWrapper) + detailsToSpecs := make(map[string][]*TypeRWWrapper) + groupsToDetails := make(map[string]map[string]bool) + + for _, t := range gen.generatedTypesList { + typeHeadersByFileName[t.fileName] = append(typeHeadersByFileName[t.fileName], t) + utils.PutPairToSetOfPairs(&groupsToDetails, t.groupName, t.detailsFileName) + detailsToSpecs[t.detailsFileName] = append(detailsToSpecs[t.detailsFileName], t) + } - for _, typeRw := range gen.generatedTypesList { - hppDef := InsFile{ins: typeRw.ins, fileName: typeRw.fileName} - if _, ok := internalFiles2[hppDef]; !ok { - internalFiles2[hppDef] = make(map[string][]*TypeRWWrapper) + for group, groupDetails := range groupsToDetails { + for det, _ := range groupDetails { + for _, spec := range detailsToSpecs[det] { + if spec.groupName != group { + return fmt.Errorf(`in details "%s" has different groups mentioned: "%s" and "%s"`, det, group, spec.groupName) + } + } } - internalFiles2[hppDef][typeRw.detailsFileName] = append(internalFiles2[hppDef][typeRw.detailsFileName], typeRw) } - // for each type header ~ tl combinator - for ff, details := range internalFiles2 { + for header, typeDefs := range typeHeadersByFileName { + var hpp strings.Builder hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} hppIncFwd := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} typeDefinitions := map[string]bool{} - // for each file with specifications - for detailFile, specs := range details { + for _, typeRw := range typeDefs { + typeDefVariations := make([]TypeDefinitionVariation, 1) + { + if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { + typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) + } + } + + for _, typeDefVariation := range typeDefVariations { + typesCounter++ + var hppDefinition strings.Builder + typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, nil, nil, nil, nil, typeDefVariation.NeedBytesVersion, false) + def := hppDefinition.String() + if !typeDefinitions[def] { + typeDefinitions[def] = true + hpp.WriteString(def) + } + } + } + + if hpp.Len() == 0 { + continue + } + + hppStr := hpp.String() + hpp.Reset() + hpp.WriteString("#pragma once\n\n") + hpp.WriteString(fmt.Sprintf("#include \"%s\"\n", basicTLFilepathName)) + for _, n := range hppInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { + hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + } + hpp.WriteString("\n\n") + hpp.WriteString(hppStr) + filepathName := header + hppExt + if err := gen.addCodeFile(filepathName, gen.copyrightText+hpp.String()); err != nil { + return err + } + hpp.Reset() + } + + for group, groupDetails := range groupsToDetails { + for detailsFile, _ := range groupDetails { + specs := detailsToSpecs[detailsFile] + hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} var hppDet strings.Builder var cppDet strings.Builder - // for each specification + slices.SortFunc(specs, TypeComparator) for _, typeRw := range specs { - // init all variants for specification (ex. byte version) typeDefVariations := make([]TypeDefinitionVariation, 1) { if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { @@ -68,22 +119,16 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, typeDefVariation := range typeDefVariations { typesCounter++ - var hppDefinition strings.Builder - typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) - def := hppDefinition.String() - if !typeDefinitions[def] { - typeDefinitions[def] = true - hpp.WriteString(def) - } + typeRw.trw.CPPGenerateCode(nil, nil, nil, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) } } - if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { + if hppDet.Len() == 0 && cppDet.Len() == 0 { continue } // all specs in one file must be in group - cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} + cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, group} hppDetStr := hppDet.String() cppDetStr := cppDet.String() @@ -94,54 +139,145 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { hppDet.WriteString("#pragma once\n\n") hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", ff.fileName, hppExt)) + hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", specs[0].fileName, hppExt)) for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { - if n == ff.fileName { + if n == specs[0].fileName { continue } hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) } hppDet.WriteString("\n") - cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailFile, hppExt)) + cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailsFile, hppExt)) for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { - if n == detailFile { + if n == detailsFile { continue } cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) } cppDet.WriteString("\n") - filepathName := filepath.Join("details", detailFile+hppExt) + filepathName := filepath.Join("details", detailsFile+hppExt) if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { return err } - filepathName = filepath.Join("details", detailFile+cppExt) + filepathName = filepath.Join("details", detailsFile+cppExt) if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { return err } } - - if hpp.Len() == 0 { - continue - } - - hppStr := hpp.String() - hpp.Reset() - hpp.WriteString("#pragma once\n\n") - hpp.WriteString(fmt.Sprintf("#include \"%s\"\n", basicTLFilepathName)) - for _, n := range hppInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { - hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) - } - hpp.WriteString("\n\n") - hpp.WriteString(hppStr) - filepathName := ff.fileName + hppExt - if err := gen.addCodeFile(filepathName, gen.copyrightText+hpp.String()); err != nil { - return err - } - hpp.Reset() } + //internalFiles2 := map[InsFile]map[string][]*TypeRWWrapper{} + // + //for _, typeRw := range gen.generatedTypesList { + // hppDef := InsFile{ins: typeRw.ins, fileName: typeRw.fileName} + // if _, ok := internalFiles2[hppDef]; !ok { + // internalFiles2[hppDef] = make(map[string][]*TypeRWWrapper) + // } + // internalFiles2[hppDef][typeRw.detailsFileName] = append(internalFiles2[hppDef][typeRw.detailsFileName], typeRw) + //} + // + //// for each type header ~ tl combinator + //for ff, details := range internalFiles2 { + // var hpp strings.Builder + // hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + // hppIncFwd := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + // typeDefinitions := map[string]bool{} + // + // // for each file with specifications + // for detailFile, specs := range details { + // hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + // cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + // var hppDet strings.Builder + // var cppDet strings.Builder + // + // // for each specification + // for _, typeRw := range specs { + // // init all variants for specification (ex. byte version) + // typeDefVariations := make([]TypeDefinitionVariation, 1) + // { + // if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { + // typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) + // } + // } + // + // for _, typeDefVariation := range typeDefVariations { + // typesCounter++ + // var hppDefinition strings.Builder + // typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) + // def := hppDefinition.String() + // if !typeDefinitions[def] { + // typeDefinitions[def] = true + // hpp.WriteString(def) + // } + // } + // } + // + // if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { + // continue + // } + // + // // all specs in one file must be in group + // cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} + // + // hppDetStr := hppDet.String() + // cppDetStr := cppDet.String() + // + // hppDet.Reset() + // cppDet.Reset() + // + // hppDet.WriteString("#pragma once\n\n") + // hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) + // + // hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", ff.fileName, hppExt)) + // for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { + // if n == ff.fileName { + // continue + // } + // hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) + // } + // hppDet.WriteString("\n") + // + // cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailFile, hppExt)) + // for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { + // if n == detailFile { + // continue + // } + // cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + // } + // cppDet.WriteString("\n") + // + // filepathName := filepath.Join("details", detailFile+hppExt) + // if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { + // return err + // } + // filepathName = filepath.Join("details", detailFile+cppExt) + // if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { + // return err + // } + // } + // + // if hpp.Len() == 0 { + // continue + // } + // + // hppStr := hpp.String() + // hpp.Reset() + // hpp.WriteString("#pragma once\n\n") + // hpp.WriteString(fmt.Sprintf("#include \"%s\"\n", basicTLFilepathName)) + // for _, n := range hppInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { + // hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + // } + // hpp.WriteString("\n\n") + // hpp.WriteString(hppStr) + // filepathName := ff.fileName + hppExt + // if err := gen.addCodeFile(filepathName, gen.copyrightText+hpp.String()); err != nil { + // return err + // } + // hpp.Reset() + //} + var cppAll strings.Builder var cppMake strings.Builder var cppMakeO strings.Builder @@ -245,58 +381,6 @@ main.o: main.cpp return nil } -func sliceToSet[T comparable](s []T) map[T]bool { - m := make(map[T]bool) - for _, e := range s { - m[e] = true - } - return m -} - -// unstable -func setToSlice[T comparable](s map[T]bool) []T { - m := make([]T, 0) - for k, _ := range s { - m = append(m, k) - } - return m -} - -func mapSlice[A, B any](in []A, f func(A) B) (out []B) { - for _, e := range in { - out = append(out, f(e)) - } - return -} - -func filterSlice[A any](in []A, f func(A) bool) (out []A) { - for _, e := range in { - if f(e) { - out = append(out, e) - } - } - return -} - -func putPairToSetOfPairs[K, V comparable](in *map[K]map[V]bool, k K, v V) { - if _, ok := (*in)[k]; !ok { - (*in)[k] = make(map[V]bool) - } - (*in)[k][v] = true -} - -func reverseSetOfPairs[K, V comparable](in map[K]map[V]bool) map[V]map[K]bool { - m := make(map[V]map[K]bool) - - for k, vs := range in { - for v, _ := range vs { - putPairToSetOfPairs(&m, v, k) - } - } - - return m -} - func findAllReachableTypeByGroup(v *TypeRWWrapper, visited *map[*TypeRWWrapper]bool, result *[]*TypeRWWrapper) { if v.groupName != "" { return @@ -319,7 +403,15 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { for _, t := range allTypes { t.detailsFileName = t.fileName + "_details" t.groupName = t.tlName.Namespace + if t.unionParent != nil { + t.groupName = t.unionParent.wr.tlName.Namespace + } if t.fileName != t.tlName.String() { + //if t.tlName.String() == "" { + // t.detailsFileName = "builtin_" + t.cppLocalName + //} else { + // t.detailsFileName = t.tlName.String() + "_details" + //} for _, t2 := range allTypes { if t.fileName == t2.tlName.String() { t.groupName = t2.tlName.Namespace @@ -356,7 +448,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { } } - groupToFirstVisits := reverseSetOfPairs(allTypesWithoutGroupUsages) + groupToFirstVisits := utils.ReverseSetOfPairs(allTypesWithoutGroupUsages) for group, firstLayer := range groupToFirstVisits { visited := make(map[*TypeRWWrapper]bool) result := make([]*TypeRWWrapper, 0) @@ -366,7 +458,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { } for _, v := range result { - putPairToSetOfPairs(&allTypesWithoutGroupUsages, v, group) + utils.PutPairToSetOfPairs(&allTypesWithoutGroupUsages, v, group) } } @@ -375,12 +467,19 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { if len(usages) == 0 { t.groupName = IndependentTypes + t.detailsFileName = IndependentTypes + "_" + t.detailsFileName } else if len(usages) == 1 { - usage := setToSlice(usages)[0] + usage := utils.SetToSlice(&usages)[0] if usage != NoNamespaceGroup { t.groupName = usage t.detailsFileName = usage + "_" + t.detailsFileName } } } + + if !gen.options.SeparateFiles { + for _, t := range allTypes { + t.detailsFileName = t.groupName + "_group_details" + } + } } diff --git a/internal/tlcodegen/type_rw_bool_cpp.go b/internal/tlcodegen/type_rw_bool_cpp.go index 282ef086..6a797e4e 100644 --- a/internal/tlcodegen/type_rw_bool_cpp.go +++ b/internal/tlcodegen/type_rw_bool_cpp.go @@ -55,21 +55,23 @@ func (trw *TypeRWBool) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInclu if trw.wr.tlName.Namespace != "" { typeNamespace = append(typeNamespace, trw.wr.tlName.Namespace) } - cppStartNamespace(hpp, typeNamespace) - // TODO - better names of enums - hpp.WriteString(fmt.Sprintf(` + if hpp != nil { + cppStartNamespace(hpp, typeNamespace) + // TODO - better names of enums + hpp.WriteString(fmt.Sprintf(` enum { %[4]s = 0x%[2]x, %[5]s = 0x%[3]x }; `, addBytes(trw.wr.goGlobalName, bytesVersion), trw.falseTag, trw.trueTag, trw.falseGoName, trw.trueGoName)) - cppFinishNamespace(hpp, typeNamespace) - - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + cppFinishNamespace(hpp, typeNamespace) + } + if hppDet != nil && cppDet != nil { + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDet.WriteString(fmt.Sprintf(` + hppDet.WriteString(fmt.Sprintf(` bool %[1]sReadBoxed(::basictl::tl_istream & s, bool& item); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, bool item); `, addBytes(trw.wr.goGlobalName, bytesVersion))) - cppDet.WriteString(fmt.Sprintf(` + cppDet.WriteString(fmt.Sprintf(` bool %[6]s::%[1]sReadBoxed(::basictl::tl_istream & s, bool& item) { return s.bool_read(item, 0x%[2]x, 0x%[3]x); } @@ -79,5 +81,6 @@ bool %[6]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, bool item) { } `, addBytes(trw.wr.goGlobalName, bytesVersion), trw.falseTag, trw.trueTag, trw.falseGoName, trw.trueGoName, trw.wr.gen.DetailsCPPNamespace)) - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } } diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index 957c8e96..9467cea6 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -58,29 +58,30 @@ func (trw *TypeRWMaybe) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncl trw.element.t.trw.CPPGenerateCode(hpp, hppInc, hppIncFwd, hppDet, hppDetInc, cppDet, cppDetInc, bytesVersion, true) return } - goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - newTypeDeps := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + if hppDet != nil && cppDet != nil { + goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) + newTypeDeps := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - myFullType := trw.cppTypeStringInNamespace(bytesVersion, &newTypeDeps) + myFullType := trw.cppTypeStringInNamespace(bytesVersion, &newTypeDeps) - for k, v := range newTypeDeps.ns { - (*hppDetInc).ns[k] = v - (*cppDetInc).ns[k] = v - } + for k, v := range newTypeDeps.ns { + (*hppDetInc).ns[k] = v + (*cppDetInc).ns[k] = v + } - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDet.WriteString(fmt.Sprintf(` + hppDet.WriteString(fmt.Sprintf(` bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); `, goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams), - formatNatArgsCallCPP(trw.wr.NatParams), - trw.wr.tlTag)) + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams), + formatNatArgsCallCPP(trw.wr.NatParams), + trw.wr.tlTag)) - cppDet.WriteString(fmt.Sprintf(` + cppDet.WriteString(fmt.Sprintf(` bool %[6]s::%[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s) { bool has_item = false; if (!s.bool_read(has_item, 0x%[4]x, 0x%[5]x)) { return false; } @@ -103,67 +104,68 @@ bool %[6]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { return true; } `, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.emptyTag, - trw.okTag, - trw.wr.gen.DetailsCPPNamespace, - trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), - trw.element.t.trw.CPPTypeWritingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), - )) - - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - - /* - _ = fmt.Sprintf(`type %[1]s struct { - Value %[2]s // Значение имеет смысл при Ok=true - Ok bool - } - - func (item *%[1]s) Reset() { - item.Ok = false - } + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.emptyTag, + trw.okTag, + trw.wr.gen.DetailsCPPNamespace, + trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), + trw.element.t.trw.CPPTypeWritingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), + )) + + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + + /* + _ = fmt.Sprintf(`type %[1]s struct { + Value %[2]s // Значение имеет смысл при Ok=true + Ok bool + } - func (item *%[1]s) ReadBoxed(r *bytes.Buffer%[8]s) error { - if err := readBool(r, &item.Ok, %#[6]x, %#[7]x); err != nil { - return err + func (item *%[1]s) Reset() { + item.Ok = false } - if item.Ok { - %[3]s + + func (item *%[1]s) ReadBoxed(r *bytes.Buffer%[8]s) error { + if err := readBool(r, &item.Ok, %#[6]x, %#[7]x); err != nil { + return err + } + if item.Ok { + %[3]s + } + %[5]s + return nil } - %[5]s - return nil - } - func (item *%[1]s) WriteBoxed(w *bytes.Buffer%[8]s) error { - writeBool(w, item.Ok, %#[6]x, %#[7]x) - if item.Ok { - %[4]s + func (item *%[1]s) WriteBoxed(w *bytes.Buffer%[8]s) error { + writeBool(w, item.Ok, %#[6]x, %#[7]x) + if item.Ok { + %[4]s + } + return nil } - return nil - } - `, - addBytes(trw.goGlobalName, bytesVersion), - trw.element.t.TypeString(bytesVersion), - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "item.Value", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - true, - ), - trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, - "item.Value", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - true, - ), - trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "item.Value", false), - trw.emptyTag, - trw.okTag, - formatNatArgsDeclCPP(trw.wr.NatParams), - ) - */ + `, + addBytes(trw.goGlobalName, bytesVersion), + trw.element.t.TypeString(bytesVersion), + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "item.Value", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + true, + ), + trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, + "item.Value", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + true, + ), + trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "item.Value", false), + trw.emptyTag, + trw.okTag, + formatNatArgsDeclCPP(trw.wr.NatParams), + ) + */ + } } diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index b0f1071d..c32545dc 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -90,140 +90,155 @@ func (trw *TypeRWStruct) CPPTypeReadingCode(bytesVersion bool, val string, bare func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncludesCPP, hppIncFwd *DirectIncludesCPP, hppDet *strings.Builder, hppDetInc *DirectIncludesCPP, cppDet *strings.Builder, cppDetInc *DirectIncludesCPP, bytesVersion bool, forwardDeclaration bool) { goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - //if trw.wr.unionParent != nil && trw.wr.unionParentIsEnum { - // return - //} + _, myArgsDecl := trw.wr.fullyResolvedClassCppNameArgs() - myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) - // fmt.Printf("Ts: %s %s\n", myFullType, strings.Join(myArgsDecl, ", ")) - // fmt.Printf(" %s\n", trw.wr.cppLocalName) - myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions anyRecursive := false typeNamespace := trw.wr.gen.RootCPPNamespaceElements if trw.wr.tlName.Namespace != "" { typeNamespace = append(typeNamespace, trw.wr.tlName.Namespace) } - - if !forwardDeclaration { - deps := trw.AllTypeDependencies(true) - slices.SortFunc(deps, TypeComparator) - - for _, typeDep := range deps { - if typeDep.typeComponent == trw.wr.typeComponent { - typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) + if hpp != nil { + if !forwardDeclaration { + deps := trw.AllTypeDependencies(true) + slices.SortFunc(deps, TypeComparator) + + for _, typeDep := range deps { + if typeDep.typeComponent == trw.wr.typeComponent { + typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) + } } } - } - cppStartNamespace(hpp, typeNamespace) - // hpp.WriteString("// " + goLocalName + "\n") - uncommenting will lead to multiple definition error - if len(myArgsDecl) != 0 { - hpp.WriteString("template<" + strings.Join(myArgsDecl, ", ") + ">\n") - } - if forwardDeclaration { // TODO - does not work for typedef - hpp.WriteString("struct " + trw.wr.cppLocalName + ";") - cppFinishNamespace(hpp, typeNamespace) - return - } + cppStartNamespace(hpp, typeNamespace) + // hpp.WriteString("// " + goLocalName + "\n") - uncommenting will lead to multiple definition error + if len(myArgsDecl) != 0 { + hpp.WriteString("template<" + strings.Join(myArgsDecl, ", ") + ">\n") + } + if forwardDeclaration { // TODO - does not work for typedef + hpp.WriteString("struct " + trw.wr.cppLocalName + ";") + cppFinishNamespace(hpp, typeNamespace) + return + } - ti := trw.wr.gen.typesInfo - tlName := trw.wr.tlName + ti := trw.wr.gen.typesInfo + tlName := trw.wr.tlName - _, isType := ti.Types[tlName] - typeReduction := TypeReduction{IsType: isType} - if isType { - typeReduction.Type = ti.Types[tlName] - } else { - typeReduction.Constructor = ti.Constructors[tlName] - } - for i, arg := range typeReduction.ReferenceType().TypeArguments { - evalArg := EvaluatedType{} - if arg.IsNat { - evalArg.Index = 1 - evalArg.Variable = arg.FieldName - if trw.wr.arguments[i].isArith { - // set true only here - evalArg.VariableActsAsConstant = true - } + _, isType := ti.Types[tlName] + typeReduction := TypeReduction{IsType: isType} + if isType { + typeReduction.Type = ti.Types[tlName] } else { - evalArg.Index = 3 - evalArg.TypeVariable = arg.FieldName + typeReduction.Constructor = ti.Constructors[tlName] } - typeReduction.Arguments = append(typeReduction.Arguments, evalArg) - } - - if trw.isTypeDef() { - field := trw.Fields[0] - - //if !field.t.origTL[0].Builtin && len(trw.wr.arguments) != 0 { - typeRed := ti.FieldTypeReduction(&typeReduction, 0) - typeDependencies := field.t.ActualTypeDependencies(typeRed) - for _, typeRw := range typeDependencies { - if typeRw.cppLocalName != "" { - hppInc.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} + for i, arg := range typeReduction.ReferenceType().TypeArguments { + evalArg := EvaluatedType{} + if arg.IsNat { + evalArg.Index = 1 + evalArg.Variable = arg.FieldName + if trw.wr.arguments[i].isArith { + // set true only here + evalArg.VariableActsAsConstant = true + } + } else { + evalArg.Index = 3 + evalArg.TypeVariable = arg.FieldName } + typeReduction.Arguments = append(typeReduction.Arguments, evalArg) } - hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed))) - //} else { - // fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, field.halfResolved) - // hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, fieldFullType)) - //} - } else { - hpp.WriteString("struct " + trw.wr.cppLocalName + " {\n") - for i, field := range trw.Fields { - hppIncByField := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - - typeRed := ti.FieldTypeReduction(&typeReduction, i) - for _, typeRw := range trw.Fields[i].t.ActualTypeDependencies(typeRed) { - if typeRw.trw.IsWrappingType() { - continue + + if trw.isTypeDef() { + field := trw.Fields[0] + + //if !field.t.origTL[0].Builtin && len(trw.wr.arguments) != 0 { + typeRed := ti.FieldTypeReduction(&typeReduction, 0) + typeDependencies := field.t.ActualTypeDependencies(typeRed) + for _, typeRw := range typeDependencies { + if typeRw.cppLocalName != "" { + hppInc.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } - hppIncByField.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } - - fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed) - fieldsMaskComment := "" - //if field.fieldMask != nil { - // fieldsMaskComment = fmt.Sprintf(" // Conditional: %s.%d", formatNatArgCPP(trw.Fields, *field.fieldMask), field.BitNumber) + hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed))) + //} else { + // fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, field.halfResolved) + // hpp.WriteString(fmt.Sprintf("using %s = %s;", trw.wr.cppLocalName, fieldFullType)) //} - if field.recursive { - // TODO make better - for includeType, includeInfo := range hppIncByField.ns { - if includeInfo.componentId == trw.wr.typeComponent || includeType.cppLocalName == "" { - delete(hppIncByField.ns, includeType) + } else { + hpp.WriteString("struct " + trw.wr.cppLocalName + " {\n") + for i, field := range trw.Fields { + hppIncByField := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + + typeRed := ti.FieldTypeReduction(&typeReduction, i) + for _, typeRw := range trw.Fields[i].t.ActualTypeDependencies(typeRed) { + if typeRw.trw.IsWrappingType() { + continue } + hppIncByField.ns[typeRw] = CppIncludeInfo{componentId: typeRw.typeComponent, namespace: typeRw.tlName.Namespace} } - anyRecursive = true // requires destructor in cpp file - hpp.WriteString(fmt.Sprintf("\tstd::shared_ptr<%s> %s{};%s\n", fieldFullType, field.cppName, fieldsMaskComment)) - } else { - hpp.WriteString(fmt.Sprintf("\t%s %s%s;%s\n", fieldFullType, field.cppName, field.t.CPPDefaultInitializer(field.halfResolved, true), fieldsMaskComment)) + + fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved2(bytesVersion, typeRed) + fieldsMaskComment := "" + //if field.fieldMask != nil { + // fieldsMaskComment = fmt.Sprintf(" // Conditional: %s.%d", formatNatArgCPP(trw.Fields, *field.fieldMask), field.BitNumber) + //} + if field.recursive { + // TODO make better + for includeType, includeInfo := range hppIncByField.ns { + if includeInfo.componentId == trw.wr.typeComponent || includeType.cppLocalName == "" { + delete(hppIncByField.ns, includeType) + } + } + anyRecursive = true // requires destructor in cpp file + hpp.WriteString(fmt.Sprintf("\tstd::shared_ptr<%s> %s{};%s\n", fieldFullType, field.cppName, fieldsMaskComment)) + } else { + hpp.WriteString(fmt.Sprintf("\t%s %s%s;%s\n", fieldFullType, field.cppName, field.t.CPPDefaultInitializer(field.halfResolved, true), fieldsMaskComment)) + } + for includeType, includeInfo := range hppIncByField.ns { + hppInc.ns[includeType] = includeInfo + } + //hpp.WriteString(fmt.Sprintf("\t// DebugString: %s\n", field.resolvedType.DebugString())) } - for includeType, includeInfo := range hppIncByField.ns { - hppInc.ns[includeType] = includeInfo + if anyRecursive { // && len(trw.cppArgs) != 0 + hpp.WriteString(fmt.Sprintf("\n\t~%s() {}\n", trw.wr.cppLocalName)) // TODO - move destructor to cpp + // cppDet.WriteString(fmt.Sprintf("%s%s::~%s() {}\n", trw.wr.cppNamespaceQualifier, goLocalName, goLocalName)) } - //hpp.WriteString(fmt.Sprintf("\t// DebugString: %s\n", field.resolvedType.DebugString())) - } - if anyRecursive { // && len(trw.cppArgs) != 0 - hpp.WriteString(fmt.Sprintf("\n\t~%s() {}\n", trw.wr.cppLocalName)) // TODO - move destructor to cpp - // cppDet.WriteString(fmt.Sprintf("%s%s::~%s() {}\n", trw.wr.cppNamespaceQualifier, goLocalName, goLocalName)) - } - if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type - hpp.WriteString(fmt.Sprintf(` + if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type + hpp.WriteString(fmt.Sprintf(` std::string_view tl_name() const { return "%s"; } uint32_t tl_tag() const { return 0x%08x; } `, trw.wr.tlName, trw.wr.tlTag)) - } - if len(myArgsDecl) == 0 { - // cppStartNamespace(cppDet, trw.wr.gen.RootCPPNamespaceElements) - hpp.WriteString(fmt.Sprintf(` + } + if len(myArgsDecl) == 0 { + // cppStartNamespace(cppDet, trw.wr.gen.RootCPPNamespaceElements) + hpp.WriteString(fmt.Sprintf(` bool read(::basictl::tl_istream & s%[1]s); bool write(::basictl::tl_ostream & s%[1]s)const; `, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true))) - cppDet.WriteString(fmt.Sprintf(` + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPTypeResettingCode(bytesVersion, "*this"), + trw.CPPTypeReadingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true))) + if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type + hpp.WriteString(fmt.Sprintf(` + bool read_boxed(::basictl::tl_istream & s%[1]s); + bool write_boxed(::basictl::tl_ostream & s%[1]s)const; +`, + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPTypeResettingCode(bytesVersion, "*this"), + trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true))) + } + } + hpp.WriteString("};\n") + } + cppFinishNamespace(hpp, typeNamespace) + } + if hppDet != nil && cppDet != nil { + myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) + myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + + if !trw.isTypeDef() { + if len(myArgsDecl) == 0 { + cppDet.WriteString(fmt.Sprintf(` bool %[5]s::read(::basictl::tl_istream & s%[1]s) { %[3]s return true; @@ -233,22 +248,14 @@ bool %[5]s::write(::basictl::tl_ostream & s%[1]s)const { %[4]s return true; } -`, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), - myFullTypeNoPrefix)) - if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type - hpp.WriteString(fmt.Sprintf(` - bool read_boxed(::basictl::tl_istream & s%[1]s); - bool write_boxed(::basictl::tl_ostream & s%[1]s)const; `, formatNatArgsDeclCPP(trw.wr.NatParams), trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true))) - cppDet.WriteString(fmt.Sprintf(` + trw.CPPTypeReadingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", true, formatNatArgsAddNat(trw.wr.NatParams), true), + myFullTypeNoPrefix)) + if trw.wr.tlTag != 0 { + cppDet.WriteString(fmt.Sprintf(` bool %[5]s::read_boxed(::basictl::tl_istream & s%[1]s) { %[3]s return true; @@ -259,19 +266,15 @@ bool %[5]s::write_boxed(::basictl::tl_ostream & s%[1]s)const { return true; } `, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - myFullTypeNoPrefix)) + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPTypeResettingCode(bytesVersion, "*this"), + trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + myFullTypeNoPrefix)) + } } - // cppFinishNamespace(cppDet, trw.wr.gen.RootCPPNamespaceElements) } - hpp.WriteString("};\n") - } - cppFinishNamespace(hpp, typeNamespace) - - cppDet.WriteString(fmt.Sprintf(` + cppDet.WriteString(fmt.Sprintf(` void %[7]s::%[1]sReset(%[2]s& item) { %[4]s} @@ -283,31 +286,31 @@ bool %[7]s::%[1]sWrite(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { %[6]s return true; } `, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPResetFields(bytesVersion), - trw.CPPReadFields(bytesVersion, hppDetInc, cppDetInc), - trw.CPPWriteFields(bytesVersion), - trw.wr.gen.DetailsCPPNamespace, - )) - - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDet.WriteString(fmt.Sprintf(` + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPResetFields(bytesVersion), + trw.CPPReadFields(bytesVersion, hppDetInc, cppDetInc), + trw.CPPWriteFields(bytesVersion), + trw.wr.gen.DetailsCPPNamespace, + )) + + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + hppDet.WriteString(fmt.Sprintf(` void %[1]sReset(%[2]s& item); bool %[1]sRead(::basictl::tl_istream & s, %[2]s& item%[3]s); bool %[1]sWrite(::basictl::tl_ostream & s, const %[2]s& item%[3]s); `, goGlobalName, myFullType, formatNatArgsDeclCPP(trw.wr.NatParams))) - if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type - hppDet.WriteString(fmt.Sprintf(`bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); + if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type + hppDet.WriteString(fmt.Sprintf(`bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); `, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams))) + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams))) - cppDet.WriteString(fmt.Sprintf(` + cppDet.WriteString(fmt.Sprintf(` bool %[7]s::%[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s) { if (!s.nat_read_exact_tag(0x%08[9]x)) { return false; } return %[7]s::%[1]sRead(s, item%[8]s); @@ -318,18 +321,19 @@ bool %[7]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { return %[7]s::%[1]sWrite(s, item%[8]s); } `, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPResetFields(bytesVersion), - trw.CPPReadFields(bytesVersion, hppDetInc, cppDetInc), - trw.CPPWriteFields(bytesVersion), - trw.wr.gen.DetailsCPPNamespace, - formatNatArgsCallCPP(trw.wr.NatParams), - trw.wr.tlTag, - )) + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPResetFields(bytesVersion), + trw.CPPReadFields(bytesVersion, hppDetInc, cppDetInc), + trw.CPPWriteFields(bytesVersion), + trw.wr.gen.DetailsCPPNamespace, + formatNatArgsCallCPP(trw.wr.NatParams), + trw.wr.tlTag, + )) + } + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } func (trw *TypeRWStruct) CPPResetFields(bytesVersion bool) string { diff --git a/internal/tlcodegen/type_rw_tuple_cpp.go b/internal/tlcodegen/type_rw_tuple_cpp.go index e238ff72..4837e90e 100644 --- a/internal/tlcodegen/type_rw_tuple_cpp.go +++ b/internal/tlcodegen/type_rw_tuple_cpp.go @@ -104,14 +104,15 @@ func (trw *TypeRWBrackets) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectI trw.element.t.trw.CPPGenerateCode(hpp, hppInc, hppIncFwd, hppDet, hppDetInc, cppDet, cppDetInc, bytesVersion, true) return } - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + if hppDet != nil && cppDet != nil { + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDetCode := ` + hppDetCode := ` void %[1]sReset(std::array<%[2]s, %[3]d>& item); bool %[1]sRead(::basictl::tl_istream & s, std::array<%[2]s, %[3]d>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::array<%[2]s, %[3]d>& item%[4]s); ` - cppCode := ` + cppCode := ` void %[8]s::%[1]sReset(std::array<%[2]s, %[3]d>& item) { for(auto && el : item) { %[7]s @@ -132,66 +133,66 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::array<%[2]s, %[3]d> return true; } ` - // keyTypeString := "" - // valueTypeString := "" - // keyFieldName := "" - // valueFieldName := "" - switch { - // TODO - does not work yet - /* - case trw.dictLike && !bytesVersion: - keyTypeString = trw.dictKeyField.t.TypeString(bytesVersion) - valueTypeString = trw.dictValueField.t.TypeString(bytesVersion) - keyFieldName = trw.dictKeyField.cppName - valueFieldName = trw.dictValueField.cppName + // keyTypeString := "" + // valueTypeString := "" + // keyFieldName := "" + // valueFieldName := "" + switch { + // TODO - does not work yet + /* + case trw.dictLike && !bytesVersion: + keyTypeString = trw.dictKeyField.t.TypeString(bytesVersion) + valueTypeString = trw.dictValueField.t.TypeString(bytesVersion) + keyFieldName = trw.dictKeyField.cppName + valueFieldName = trw.dictValueField.cppName - code = `func %[1]sReset(m map[%[10]s]%[11]s) { - for k := range m { - delete(m, k) + code = `func %[1]sReset(m map[%[10]s]%[11]s) { + for k := range m { + delete(m, k) + } } - } - func %[1]sRead(r *bytes.Buffer, m *map[%[10]s]%[11]s %[6]s) error { - var l uint32 - if err := basictl.NatRead(r, &l); err != nil { // No sanity check required for map - return err - } - var data map[%[10]s]%[11]s - if *m == nil { - data = make(map[%[10]s]%[11]s, l) - *m = data - } else { - data = *m - for k := range data { - delete(data, k) + func %[1]sRead(r *bytes.Buffer, m *map[%[10]s]%[11]s %[6]s) error { + var l uint32 + if err := basictl.NatRead(r, &l); err != nil { // No sanity check required for map + return err } + var data map[%[10]s]%[11]s + if *m == nil { + data = make(map[%[10]s]%[11]s, l) + *m = data + } else { + data = *m + for k := range data { + delete(data, k) + } + } + for i := 0; i < int(l); i++ { + var elem %[2]s + %[14]s + data[elem.%[12]s] = elem.%[13]s + } + return nil } - for i := 0; i < int(l); i++ { - var elem %[2]s - %[14]s - data[elem.%[12]s] = elem.%[13]s - } - return nil - } - func %[1]sWrite(w *bytes.Buffer, m map[%[10]s]%[11]s %[6]s) error { - basictl.NatWrite(w, uint32(len(m))) - for key, val := range m { - elem := %[2]s{%[12]s:key, %[13]s:val} - %[5]s + func %[1]sWrite(w *bytes.Buffer, m map[%[10]s]%[11]s %[6]s) error { + basictl.NatWrite(w, uint32(len(m))) + for key, val := range m { + elem := %[2]s{%[12]s:key, %[13]s:val} + %[5]s + } + return nil } - return nil - } - ` - */ - case trw.vectorLike: - hppDetCode = ` + ` + */ + case trw.vectorLike: + hppDetCode = ` void %[1]sReset(std::vector<%[2]s>& item); bool %[1]sRead(::basictl::tl_istream & s, std::vector<%[2]s>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item%[4]s); ` - cppCode = ` + cppCode = ` void %[8]s::%[1]sReset(std::vector<%[2]s>& item) { item.resize(0); // TODO - unwrap } @@ -215,13 +216,13 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item return true; } ` - case trw.dynamicSize: - hppDetCode = ` + case trw.dynamicSize: + hppDetCode = ` void %[1]sReset(std::vector<%[2]s>& item); bool %[1]sRead(::basictl::tl_istream & s, std::vector<%[2]s>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item%[4]s); ` - cppCode = ` + cppCode = ` void %[8]s::%[1]sReset(std::vector<%[2]s>& item) { item.resize(0); } @@ -244,74 +245,75 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item return true; } ` - } - /* - _ = fmt.Sprintf(code, - addBytes(trw.goGlobalName, bytesVersion), - trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc, trw.wr.resolvedType.Args[0].T, false), + } + /* + _ = fmt.Sprintf(code, + addBytes(trw.goGlobalName, bytesVersion), + trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc, trw.wr.resolvedType.Args[0].T, false), + trw.size, + trw.element.t.TypeString(bytesVersion), + trw.wr.tlTag, + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "(*vec)[i]", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, + "elem", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.typeString(bytesVersion, false), + formatNatArgsCallCPP(trw.wr.NatParams), + trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "(*vec)[i]", false), + keyTypeString, + valueTypeString, + keyFieldName, + valueFieldName, + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "elem", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + ) + */ + + hppDet.WriteString(fmt.Sprintf(hppDetCode, + addBytes(trw.wr.goGlobalName, bytesVersion), + trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc), trw.size, - trw.element.t.TypeString(bytesVersion), - trw.wr.tlTag, - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "(*vec)[i]", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), - trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, - "elem", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), formatNatArgsDeclCPP(trw.wr.NatParams), - trw.typeString(bytesVersion, false), - formatNatArgsCallCPP(trw.wr.NatParams), - trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "(*vec)[i]", false), - keyTypeString, - valueTypeString, - keyFieldName, - valueFieldName, - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "elem", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), - ) - */ - - hppDet.WriteString(fmt.Sprintf(hppDetCode, - addBytes(trw.wr.goGlobalName, bytesVersion), - trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc), - trw.size, - formatNatArgsDeclCPP(trw.wr.NatParams), - )) - tt := trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc) - tr := trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "el", - trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), - true) - tw := trw.element.t.trw.CPPTypeWritingCode(bytesVersion, "el", - trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), - true) - if tt == "bool" { - // std::vector has special value-like reference type - tr = "\tbool tmp = false;\n\t" + trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "tmp", + )) + tt := trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc) + tr := trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "el", + trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), + true) + tw := trw.element.t.trw.CPPTypeWritingCode(bytesVersion, "el", trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), - true) + "\n\t\tel = tmp;" + true) + if tt == "bool" { + // std::vector has special value-like reference type + tr = "\tbool tmp = false;\n\t" + trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "tmp", + trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), + true) + "\n\t\tel = tmp;" + } + cppDet.WriteString(fmt.Sprintf(cppCode, + addBytes(trw.wr.goGlobalName, bytesVersion), + tt, + trw.size, + formatNatArgsDeclCPP(trw.wr.NatParams), + tr, + tw, + trw.element.t.trw.CPPTypeResettingCode(bytesVersion, "el"), + trw.wr.gen.DetailsCPPNamespace, + )) + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } - cppDet.WriteString(fmt.Sprintf(cppCode, - addBytes(trw.wr.goGlobalName, bytesVersion), - tt, - trw.size, - formatNatArgsDeclCPP(trw.wr.NatParams), - tr, - tw, - trw.element.t.trw.CPPTypeResettingCode(bytesVersion, "el"), - trw.wr.gen.DetailsCPPNamespace, - )) - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } diff --git a/internal/tlcodegen/type_rw_union_cpp.go b/internal/tlcodegen/type_rw_union_cpp.go index 72c3e608..4bc7c8c6 100644 --- a/internal/tlcodegen/type_rw_union_cpp.go +++ b/internal/tlcodegen/type_rw_union_cpp.go @@ -57,93 +57,96 @@ func (trw *TypeRWUnion) CPPTypeReadingCode(bytesVersion bool, val string, bare b } func (trw *TypeRWUnion) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncludesCPP, hppIncFwd *DirectIncludesCPP, hppDet *strings.Builder, hppDetInc *DirectIncludesCPP, cppDet *strings.Builder, cppDetInc *DirectIncludesCPP, bytesVersion bool, forwardDeclaration bool) { - // goLocalName := addBytes(trw.goLocalName, bytesVersion) goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) _, myArgsDecl := trw.wr.fullyResolvedClassCppNameArgs() - myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) - //fmt.Printf("Ts: %s %s\n", myFullType, strings.Join(myArgsDecl, ", ")) - //fmt.Printf(" %s\n", trw.wr.cppLocalName) - myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions typeNamespace := trw.wr.gen.RootCPPNamespaceElements if trw.wr.tlName.Namespace != "" { typeNamespace = append(typeNamespace, trw.wr.tlName.Namespace) } + if hpp != nil { + if forwardDeclaration { + cppStartNamespace(hpp, typeNamespace) + if len(myArgsDecl) != 0 { + hpp.WriteString("template<" + strings.Join(myArgsDecl, ", ") + ">\n") + } + hpp.WriteString("struct " + trw.wr.cppLocalName + ";") + cppFinishNamespace(hpp, typeNamespace) + return + } + + for _, typeDep := range trw.AllTypeDependencies(true) { + if typeDep.typeComponent == trw.wr.typeComponent { + typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) + } + } - if forwardDeclaration { cppStartNamespace(hpp, typeNamespace) if len(myArgsDecl) != 0 { hpp.WriteString("template<" + strings.Join(myArgsDecl, ", ") + ">\n") } - hpp.WriteString("struct " + trw.wr.cppLocalName + ";") + hpp.WriteString("struct " + trw.wr.cppLocalName + " {\n") + hpp.WriteString("\tstd::variant<") + for filedIndex, field := range trw.Fields { + if filedIndex != 0 { + hpp.WriteString(", ") + } + if field.recursive { + fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppIncFwd, field.halfResolved) + hpp.WriteString(fmt.Sprintf("std::shared_ptr<%s>", fieldFullType)) + } else { + fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, field.halfResolved) + hpp.WriteString(fieldFullType) + //hpp.WriteString(fmt.Sprintf("\t// DebugString: %s\n", field.resolvedType.DebugString())) + } + } + hpp.WriteString("> value;\n\n") + hpp.WriteString(trw.CPPGetters(bytesVersion)) + hpp.WriteString("\n") + hpp.WriteString(trw.CPPSetters(bytesVersion)) + + hpp.WriteString(` + std::string_view tl_name() const; + uint32_t tl_tag() const; +`) + + if len(myArgsDecl) == 0 { + // cppStartNamespace(cppDet, trw.wr.gen.RootCPPNamespaceElements) + hpp.WriteString(fmt.Sprintf(` + bool read_boxed(::basictl::tl_istream & s%[1]s); + bool write_boxed(::basictl::tl_ostream & s%[1]s)const; +`, + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPTypeResettingCode(bytesVersion, "*this"), + trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true))) + } + hpp.WriteString("};\n") cppFinishNamespace(hpp, typeNamespace) - return } - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDet.WriteString(fmt.Sprintf(` + if hppDet != nil && cppDet != nil { + myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) + myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + hppDet.WriteString(fmt.Sprintf(` void %[1]sReset(%[2]s& item); bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); `, goGlobalName, myFullType, formatNatArgsDeclCPP(trw.wr.NatParams))) + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - - for _, typeDep := range trw.AllTypeDependencies(true) { - if typeDep.typeComponent == trw.wr.typeComponent { - typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) - } - } - - cppStartNamespace(hpp, typeNamespace) - if len(myArgsDecl) != 0 { - hpp.WriteString("template<" + strings.Join(myArgsDecl, ", ") + ">\n") - } - hpp.WriteString("struct " + trw.wr.cppLocalName + " {\n") - hpp.WriteString("\tstd::variant<") - for filedIndex, field := range trw.Fields { - if filedIndex != 0 { - hpp.WriteString(", ") - } - if field.recursive { - fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppIncFwd, field.halfResolved) - hpp.WriteString(fmt.Sprintf("std::shared_ptr<%s>", fieldFullType)) - } else { - fieldFullType := field.t.CPPTypeStringInNamespaceHalfResolved(bytesVersion, hppInc, field.halfResolved) - hpp.WriteString(fieldFullType) - //hpp.WriteString(fmt.Sprintf("\t// DebugString: %s\n", field.resolvedType.DebugString())) - } - } - hpp.WriteString("> value;\n\n") - hpp.WriteString(trw.CPPGetters(bytesVersion)) - hpp.WriteString("\n") - hpp.WriteString(trw.CPPSetters(bytesVersion)) - - hpp.WriteString(` - std::string_view tl_name() const; - uint32_t tl_tag() const; -`) - - cppDet.WriteString(fmt.Sprintf(` + cppDet.WriteString(fmt.Sprintf(` static const std::string_view %[1]s_tbl_tl_name[]{%[2]s}; static const uint32_t %[1]s_tbl_tl_tag[]{%[3]s}; `, - goGlobalName, - trw.CPPAllNames(bytesVersion), - trw.CPPAllTags(bytesVersion))) - - if len(myArgsDecl) == 0 { - // cppStartNamespace(cppDet, trw.wr.gen.RootCPPNamespaceElements) - hpp.WriteString(fmt.Sprintf(` - bool read_boxed(::basictl::tl_istream & s%[1]s); - bool write_boxed(::basictl::tl_ostream & s%[1]s)const; -`, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true))) - cppDet.WriteString(fmt.Sprintf(` + goGlobalName, + trw.CPPAllNames(bytesVersion), + trw.CPPAllTags(bytesVersion))) + if len(myArgsDecl) == 0 { + cppDet.WriteString(fmt.Sprintf(` bool %[5]s::read_boxed(::basictl::tl_istream & s%[1]s) { %[3]s return true; @@ -160,17 +163,14 @@ uint32_t %[5]s::tl_tag() const { } `, - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.CPPTypeResettingCode(bytesVersion, "*this"), - trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), - myFullTypeNoPrefix, - goGlobalName)) - } - hpp.WriteString("};\n") - cppFinishNamespace(hpp, typeNamespace) - - cppDet.WriteString(fmt.Sprintf(` + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.CPPTypeResettingCode(bytesVersion, "*this"), + trw.CPPTypeReadingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + trw.CPPTypeWritingCode(bytesVersion, "*this", false, formatNatArgsAddNat(trw.wr.NatParams), true), + myFullTypeNoPrefix, + goGlobalName)) + } + cppDet.WriteString(fmt.Sprintf(` void %[7]s::%[1]sReset(%[2]s& item) { item.value.emplace<0>(); // TODO - optimize, if already 0, call Reset function } @@ -192,14 +192,15 @@ bool %[7]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { return true; } `, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams), - "", - trw.CPPReadFields(bytesVersion, hppInc, cppDetInc), - trw.CPPWriteFields(bytesVersion), - trw.wr.gen.DetailsCPPNamespace, - )) + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams), + "", + trw.CPPReadFields(bytesVersion, hppInc, cppDetInc), + trw.CPPWriteFields(bytesVersion), + trw.wr.gen.DetailsCPPNamespace, + )) + } /* code := `type %[1]s struct {%[2]s} diff --git a/internal/utils/maps.go b/internal/utils/maps.go new file mode 100644 index 00000000..1e917426 --- /dev/null +++ b/internal/utils/maps.go @@ -0,0 +1,61 @@ +package utils + +func SliceToSet[T comparable](s *[]T) map[T]bool { + m := make(map[T]bool) + for _, e := range *s { + m[e] = true + } + return m +} + +// unstable +func Keys[K comparable, V any](m *map[K]V) (res []K) { + for k, _ := range *m { + res = append(res, k) + } + return +} + +// unstable +func SetToSlice[T comparable](s *map[T]bool) []T { + m := make([]T, 0) + for k, _ := range *s { + m = append(m, k) + } + return m +} + +func MapSlice[A, B any](in *[]A, f func(A) B) (out []B) { + for _, e := range *in { + out = append(out, f(e)) + } + return +} + +func FilterSlice[A any](in []A, f func(A) bool) (out []A) { + for _, e := range in { + if f(e) { + out = append(out, e) + } + } + return +} + +func PutPairToSetOfPairs[K, V comparable](in *map[K]map[V]bool, k K, v V) { + if _, ok := (*in)[k]; !ok { + (*in)[k] = make(map[V]bool) + } + (*in)[k][v] = true +} + +func ReverseSetOfPairs[K, V comparable](in map[K]map[V]bool) map[V]map[K]bool { + m := make(map[V]map[K]bool) + + for k, vs := range in { + for v, _ := range vs { + PutPairToSetOfPairs(&m, v, k) + } + } + + return m +} From ff66d034c6233ea0007c0f72c0ab299ec0a0101b Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Fri, 28 Jun 2024 16:47:59 +0300 Subject: [PATCH 09/14] remove old code --- internal/tlcodegen/tlgen_cpp.go | 117 ++------------------------------ 1 file changed, 4 insertions(+), 113 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 13dabde1..589067a6 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -168,116 +168,6 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { } } - //internalFiles2 := map[InsFile]map[string][]*TypeRWWrapper{} - // - //for _, typeRw := range gen.generatedTypesList { - // hppDef := InsFile{ins: typeRw.ins, fileName: typeRw.fileName} - // if _, ok := internalFiles2[hppDef]; !ok { - // internalFiles2[hppDef] = make(map[string][]*TypeRWWrapper) - // } - // internalFiles2[hppDef][typeRw.detailsFileName] = append(internalFiles2[hppDef][typeRw.detailsFileName], typeRw) - //} - // - //// for each type header ~ tl combinator - //for ff, details := range internalFiles2 { - // var hpp strings.Builder - // hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - // hppIncFwd := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - // typeDefinitions := map[string]bool{} - // - // // for each file with specifications - // for detailFile, specs := range details { - // hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - // cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - // var hppDet strings.Builder - // var cppDet strings.Builder - // - // // for each specification - // for _, typeRw := range specs { - // // init all variants for specification (ex. byte version) - // typeDefVariations := make([]TypeDefinitionVariation, 1) - // { - // if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { - // typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) - // } - // } - // - // for _, typeDefVariation := range typeDefVariations { - // typesCounter++ - // var hppDefinition strings.Builder - // typeRw.trw.CPPGenerateCode(&hppDefinition, hppInc, hppIncFwd, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) - // def := hppDefinition.String() - // if !typeDefinitions[def] { - // typeDefinitions[def] = true - // hpp.WriteString(def) - // } - // } - // } - // - // if hpp.Len() == 0 && hppDet.Len() == 0 && cppDet.Len() == 0 { - // continue - // } - // - // // all specs in one file must be in group - // cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} - // - // hppDetStr := hppDet.String() - // cppDetStr := cppDet.String() - // - // hppDet.Reset() - // cppDet.Reset() - // - // hppDet.WriteString("#pragma once\n\n") - // hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) - // - // hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", ff.fileName, hppExt)) - // for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { - // if n == ff.fileName { - // continue - // } - // hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) - // } - // hppDet.WriteString("\n") - // - // cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailFile, hppExt)) - // for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { - // if n == detailFile { - // continue - // } - // cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) - // } - // cppDet.WriteString("\n") - // - // filepathName := filepath.Join("details", detailFile+hppExt) - // if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { - // return err - // } - // filepathName = filepath.Join("details", detailFile+cppExt) - // if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { - // return err - // } - // } - // - // if hpp.Len() == 0 { - // continue - // } - // - // hppStr := hpp.String() - // hpp.Reset() - // hpp.WriteString("#pragma once\n\n") - // hpp.WriteString(fmt.Sprintf("#include \"%s\"\n", basicTLFilepathName)) - // for _, n := range hppInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { - // hpp.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) - // } - // hpp.WriteString("\n\n") - // hpp.WriteString(hppStr) - // filepathName := ff.fileName + hppExt - // if err := gen.addCodeFile(filepathName, gen.copyrightText+hpp.String()); err != nil { - // return err - // } - // hpp.Reset() - //} - var cppAll strings.Builder var cppMake strings.Builder var cppMakeO strings.Builder @@ -286,9 +176,6 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, nf := range cppAllInc.splitByNamespaces() { // it is a group namespace := nf.Namespace - if namespace == "" { - namespace = "__common" - } var cppMake1UsedFiles strings.Builder var cppMake1Namespace strings.Builder @@ -399,6 +286,7 @@ func findAllReachableTypeByGroup(v *TypeRWWrapper, visited *map[*TypeRWWrapper]b func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { const IndependentTypes = "__independent_types" const NoNamespaceGroup = "" + const CommonGroup = "__common" for _, t := range allTypes { t.detailsFileName = t.fileName + "_details" @@ -479,6 +367,9 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { if !gen.options.SeparateFiles { for _, t := range allTypes { + if t.groupName == "" { + t.groupName = CommonGroup + } t.detailsFileName = t.groupName + "_group_details" } } From 035147e466cb3f70f9894a35cf6d1992438e8523 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Mon, 1 Jul 2024 13:44:09 +0300 Subject: [PATCH 10/14] split cppDet and hppDet code --- internal/tlcodegen/tlgen_cpp.go | 20 +-- internal/tlcodegen/type_rw.go | 6 +- internal/tlcodegen/type_rw_bool_cpp.go | 7 +- internal/tlcodegen/type_rw_maybe_cpp.go | 112 ++++++------- internal/tlcodegen/type_rw_struct_cpp.go | 44 ++--- internal/tlcodegen/type_rw_tuple_cpp.go | 196 ++++++++++++----------- internal/tlcodegen/type_rw_union_cpp.go | 12 +- internal/utils/maps.go | 16 ++ 8 files changed, 229 insertions(+), 184 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 589067a6..a8c1cefd 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -39,8 +39,8 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, t := range gen.generatedTypesList { typeHeadersByFileName[t.fileName] = append(typeHeadersByFileName[t.fileName], t) - utils.PutPairToSetOfPairs(&groupsToDetails, t.groupName, t.detailsFileName) - detailsToSpecs[t.detailsFileName] = append(detailsToSpecs[t.detailsFileName], t) + utils.PutPairToSetOfPairs(&groupsToDetails, t.groupName, t.cppDetailsFileName) + detailsToSpecs[t.cppDetailsFileName] = append(detailsToSpecs[t.cppDetailsFileName], t) } for group, groupDetails := range groupsToDetails { @@ -149,7 +149,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { hppDet.WriteString("\n") cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailsFile, hppExt)) - for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { + for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.cppDetailsFileName }) { if n == detailsFile { continue } @@ -180,7 +180,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { var cppMake1UsedFiles strings.Builder var cppMake1Namespace strings.Builder - for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.detailsFileName }) { + for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.cppDetailsFileName }) { cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n, cppExt)) cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, cppExt)) cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n, cppExt, n, hppExt)) @@ -289,16 +289,16 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { const CommonGroup = "__common" for _, t := range allTypes { - t.detailsFileName = t.fileName + "_details" + t.cppDetailsFileName = t.fileName + "_details" t.groupName = t.tlName.Namespace if t.unionParent != nil { t.groupName = t.unionParent.wr.tlName.Namespace } if t.fileName != t.tlName.String() { //if t.tlName.String() == "" { - // t.detailsFileName = "builtin_" + t.cppLocalName + // t.cppDetailsFileName = "builtin_" + t.cppLocalName //} else { - // t.detailsFileName = t.tlName.String() + "_details" + // t.cppDetailsFileName = t.tlName.String() + "_details" //} for _, t2 := range allTypes { if t.fileName == t2.tlName.String() { @@ -355,12 +355,12 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { if len(usages) == 0 { t.groupName = IndependentTypes - t.detailsFileName = IndependentTypes + "_" + t.detailsFileName + t.cppDetailsFileName = IndependentTypes + "_" + t.cppDetailsFileName } else if len(usages) == 1 { usage := utils.SetToSlice(&usages)[0] if usage != NoNamespaceGroup { t.groupName = usage - t.detailsFileName = usage + "_" + t.detailsFileName + t.cppDetailsFileName = usage + "_" + t.cppDetailsFileName } } } @@ -370,7 +370,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { if t.groupName == "" { t.groupName = CommonGroup } - t.detailsFileName = t.groupName + "_group_details" + t.cppDetailsFileName = t.groupName + "_group_details" } } } diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index c2154025..c9084901 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -80,8 +80,10 @@ type TypeRWWrapper struct { fileName string - detailsFileName string - groupName string + // cpp info + hppDetailsFileName string + cppDetailsFileName string + groupName string tlTag uint32 // TODO - turn into function tlName tlast.Name // TODO - turn into function constructor name or union name for code generation diff --git a/internal/tlcodegen/type_rw_bool_cpp.go b/internal/tlcodegen/type_rw_bool_cpp.go index 6a797e4e..360c17c6 100644 --- a/internal/tlcodegen/type_rw_bool_cpp.go +++ b/internal/tlcodegen/type_rw_bool_cpp.go @@ -63,7 +63,7 @@ func (trw *TypeRWBool) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInclu `, addBytes(trw.wr.goGlobalName, bytesVersion), trw.falseTag, trw.trueTag, trw.falseGoName, trw.trueGoName)) cppFinishNamespace(hpp, typeNamespace) } - if hppDet != nil && cppDet != nil { + if hppDet != nil { cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) hppDet.WriteString(fmt.Sprintf(` @@ -71,6 +71,10 @@ bool %[1]sReadBoxed(::basictl::tl_istream & s, bool& item); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, bool item); `, addBytes(trw.wr.goGlobalName, bytesVersion))) + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } + + if cppDet != nil { cppDet.WriteString(fmt.Sprintf(` bool %[6]s::%[1]sReadBoxed(::basictl::tl_istream & s, bool& item) { return s.bool_read(item, 0x%[2]x, 0x%[3]x); @@ -81,6 +85,5 @@ bool %[6]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, bool item) { } `, addBytes(trw.wr.goGlobalName, bytesVersion), trw.falseTag, trw.trueTag, trw.falseGoName, trw.trueGoName, trw.wr.gen.DetailsCPPNamespace)) - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } } diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index 9467cea6..a685b139 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -58,15 +58,13 @@ func (trw *TypeRWMaybe) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncl trw.element.t.trw.CPPGenerateCode(hpp, hppInc, hppIncFwd, hppDet, hppDetInc, cppDet, cppDetInc, bytesVersion, true) return } - if hppDet != nil && cppDet != nil { - goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) - newTypeDeps := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - - myFullType := trw.cppTypeStringInNamespace(bytesVersion, &newTypeDeps) + goGlobalName := addBytes(trw.wr.goGlobalName, bytesVersion) + newTypeDeps := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + myFullType := trw.cppTypeStringInNamespace(bytesVersion, &newTypeDeps) + if hppDet != nil { // hpp details for k, v := range newTypeDeps.ns { (*hppDetInc).ns[k] = v - (*cppDetInc).ns[k] = v } cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) @@ -81,6 +79,14 @@ bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); formatNatArgsCallCPP(trw.wr.NatParams), trw.wr.tlTag)) + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } + + if cppDet != nil { // cpp details + for k, v := range newTypeDeps.ns { + (*hppDetInc).ns[k] = v + } + cppDet.WriteString(fmt.Sprintf(` bool %[6]s::%[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s) { bool has_item = false; @@ -113,59 +119,57 @@ bool %[6]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), trw.element.t.trw.CPPTypeWritingCode(bytesVersion, "*item", trw.element.Bare(), formatNatArgs(nil, trw.element.natArgs), true), )) + } + /* + _ = fmt.Sprintf(`type %[1]s struct { + Value %[2]s // Значение имеет смысл при Ok=true + Ok bool + } - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + func (item *%[1]s) Reset() { + item.Ok = false + } - /* - _ = fmt.Sprintf(`type %[1]s struct { - Value %[2]s // Значение имеет смысл при Ok=true - Ok bool + func (item *%[1]s) ReadBoxed(r *bytes.Buffer%[8]s) error { + if err := readBool(r, &item.Ok, %#[6]x, %#[7]x); err != nil { + return err } - - func (item *%[1]s) Reset() { - item.Ok = false + if item.Ok { + %[3]s } + %[5]s + return nil + } - func (item *%[1]s) ReadBoxed(r *bytes.Buffer%[8]s) error { - if err := readBool(r, &item.Ok, %#[6]x, %#[7]x); err != nil { - return err - } - if item.Ok { - %[3]s - } - %[5]s - return nil + func (item *%[1]s) WriteBoxed(w *bytes.Buffer%[8]s) error { + writeBool(w, item.Ok, %#[6]x, %#[7]x) + if item.Ok { + %[4]s } + return nil + } + `, + addBytes(trw.goGlobalName, bytesVersion), + trw.element.t.TypeString(bytesVersion), + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "item.Value", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + true, + ), + trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, + "item.Value", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + true, + ), + trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "item.Value", false), + trw.emptyTag, + trw.okTag, + formatNatArgsDeclCPP(trw.wr.NatParams), + ) + */ - func (item *%[1]s) WriteBoxed(w *bytes.Buffer%[8]s) error { - writeBool(w, item.Ok, %#[6]x, %#[7]x) - if item.Ok { - %[4]s - } - return nil - } - `, - addBytes(trw.goGlobalName, bytesVersion), - trw.element.t.TypeString(bytesVersion), - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "item.Value", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - true, - ), - trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, - "item.Value", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - true, - ), - trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "item.Value", false), - trw.emptyTag, - trw.okTag, - formatNatArgsDeclCPP(trw.wr.NatParams), - ) - */ - } } diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index c32545dc..4f1f395a 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -8,6 +8,7 @@ package tlcodegen import ( "fmt" + "github.com/vkcom/tl/internal/utils" "golang.org/x/exp/slices" "strings" ) @@ -232,10 +233,32 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc } cppFinishNamespace(hpp, typeNamespace) } - if hppDet != nil && cppDet != nil { - myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) - myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + hppTmpInclude := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + myFullType := trw.cppTypeStringInNamespace(bytesVersion, &hppTmpInclude) + myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + + if hppDet != nil { + utils.AppendMap(&hppTmpInclude.ns, &hppDetInc.ns) + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + hppDet.WriteString(fmt.Sprintf(` +void %[1]sReset(%[2]s& item); +bool %[1]sRead(::basictl::tl_istream & s, %[2]s& item%[3]s); +bool %[1]sWrite(::basictl::tl_ostream & s, const %[2]s& item%[3]s); +`, goGlobalName, myFullType, formatNatArgsDeclCPP(trw.wr.NatParams))) + + if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type + hppDet.WriteString(fmt.Sprintf(`bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); +bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); +`, + goGlobalName, + myFullType, + formatNatArgsDeclCPP(trw.wr.NatParams))) + } + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } + + if cppDet != nil { if !trw.isTypeDef() { if len(myArgsDecl) == 0 { cppDet.WriteString(fmt.Sprintf(` @@ -295,21 +318,7 @@ bool %[7]s::%[1]sWrite(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { trw.wr.gen.DetailsCPPNamespace, )) - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDet.WriteString(fmt.Sprintf(` -void %[1]sReset(%[2]s& item); -bool %[1]sRead(::basictl::tl_istream & s, %[2]s& item%[3]s); -bool %[1]sWrite(::basictl::tl_ostream & s, const %[2]s& item%[3]s); -`, goGlobalName, myFullType, formatNatArgsDeclCPP(trw.wr.NatParams))) - if trw.wr.tlTag != 0 { // anonymous square brackets citizens or other exotic type - hppDet.WriteString(fmt.Sprintf(`bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); -bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); -`, - goGlobalName, - myFullType, - formatNatArgsDeclCPP(trw.wr.NatParams))) - cppDet.WriteString(fmt.Sprintf(` bool %[7]s::%[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s) { if (!s.nat_read_exact_tag(0x%08[9]x)) { return false; } @@ -332,7 +341,6 @@ bool %[7]s::%[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s) { trw.wr.tlTag, )) } - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } } diff --git a/internal/tlcodegen/type_rw_tuple_cpp.go b/internal/tlcodegen/type_rw_tuple_cpp.go index 4837e90e..f099fb00 100644 --- a/internal/tlcodegen/type_rw_tuple_cpp.go +++ b/internal/tlcodegen/type_rw_tuple_cpp.go @@ -104,15 +104,13 @@ func (trw *TypeRWBrackets) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectI trw.element.t.trw.CPPGenerateCode(hpp, hppInc, hppIncFwd, hppDet, hppDetInc, cppDet, cppDetInc, bytesVersion, true) return } - if hppDet != nil && cppDet != nil { - cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) - hppDetCode := ` + hppDetCode := ` void %[1]sReset(std::array<%[2]s, %[3]d>& item); bool %[1]sRead(::basictl::tl_istream & s, std::array<%[2]s, %[3]d>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::array<%[2]s, %[3]d>& item%[4]s); ` - cppCode := ` + cppCode := ` void %[8]s::%[1]sReset(std::array<%[2]s, %[3]d>& item) { for(auto && el : item) { %[7]s @@ -133,66 +131,66 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::array<%[2]s, %[3]d> return true; } ` - // keyTypeString := "" - // valueTypeString := "" - // keyFieldName := "" - // valueFieldName := "" - switch { - // TODO - does not work yet - /* - case trw.dictLike && !bytesVersion: - keyTypeString = trw.dictKeyField.t.TypeString(bytesVersion) - valueTypeString = trw.dictValueField.t.TypeString(bytesVersion) - keyFieldName = trw.dictKeyField.cppName - valueFieldName = trw.dictValueField.cppName + // keyTypeString := "" + // valueTypeString := "" + // keyFieldName := "" + // valueFieldName := "" + switch { + // TODO - does not work yet + /* + case trw.dictLike && !bytesVersion: + keyTypeString = trw.dictKeyField.t.TypeString(bytesVersion) + valueTypeString = trw.dictValueField.t.TypeString(bytesVersion) + keyFieldName = trw.dictKeyField.cppName + valueFieldName = trw.dictValueField.cppName - code = `func %[1]sReset(m map[%[10]s]%[11]s) { - for k := range m { - delete(m, k) - } + code = `func %[1]sReset(m map[%[10]s]%[11]s) { + for k := range m { + delete(m, k) } + } - func %[1]sRead(r *bytes.Buffer, m *map[%[10]s]%[11]s %[6]s) error { - var l uint32 - if err := basictl.NatRead(r, &l); err != nil { // No sanity check required for map - return err - } - var data map[%[10]s]%[11]s - if *m == nil { - data = make(map[%[10]s]%[11]s, l) - *m = data - } else { - data = *m - for k := range data { - delete(data, k) - } - } - for i := 0; i < int(l); i++ { - var elem %[2]s - %[14]s - data[elem.%[12]s] = elem.%[13]s + func %[1]sRead(r *bytes.Buffer, m *map[%[10]s]%[11]s %[6]s) error { + var l uint32 + if err := basictl.NatRead(r, &l); err != nil { // No sanity check required for map + return err + } + var data map[%[10]s]%[11]s + if *m == nil { + data = make(map[%[10]s]%[11]s, l) + *m = data + } else { + data = *m + for k := range data { + delete(data, k) } - return nil } + for i := 0; i < int(l); i++ { + var elem %[2]s + %[14]s + data[elem.%[12]s] = elem.%[13]s + } + return nil + } - func %[1]sWrite(w *bytes.Buffer, m map[%[10]s]%[11]s %[6]s) error { - basictl.NatWrite(w, uint32(len(m))) - for key, val := range m { - elem := %[2]s{%[12]s:key, %[13]s:val} - %[5]s - } - return nil + func %[1]sWrite(w *bytes.Buffer, m map[%[10]s]%[11]s %[6]s) error { + basictl.NatWrite(w, uint32(len(m))) + for key, val := range m { + elem := %[2]s{%[12]s:key, %[13]s:val} + %[5]s } + return nil + } - ` - */ - case trw.vectorLike: - hppDetCode = ` + ` + */ + case trw.vectorLike: + hppDetCode = ` void %[1]sReset(std::vector<%[2]s>& item); bool %[1]sRead(::basictl::tl_istream & s, std::vector<%[2]s>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item%[4]s); ` - cppCode = ` + cppCode = ` void %[8]s::%[1]sReset(std::vector<%[2]s>& item) { item.resize(0); // TODO - unwrap } @@ -216,13 +214,13 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item return true; } ` - case trw.dynamicSize: - hppDetCode = ` + case trw.dynamicSize: + hppDetCode = ` void %[1]sReset(std::vector<%[2]s>& item); bool %[1]sRead(::basictl::tl_istream & s, std::vector<%[2]s>& item%[4]s); bool %[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item%[4]s); ` - cppCode = ` + cppCode = ` void %[8]s::%[1]sReset(std::vector<%[2]s>& item) { item.resize(0); } @@ -245,45 +243,49 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item return true; } ` - } - /* - _ = fmt.Sprintf(code, - addBytes(trw.goGlobalName, bytesVersion), - trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc, trw.wr.resolvedType.Args[0].T, false), - trw.size, - trw.element.t.TypeString(bytesVersion), - trw.wr.tlTag, - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "(*vec)[i]", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), - trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, - "elem", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), - formatNatArgsDeclCPP(trw.wr.NatParams), - trw.typeString(bytesVersion, false), - formatNatArgsCallCPP(trw.wr.NatParams), - trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "(*vec)[i]", false), - keyTypeString, - valueTypeString, - keyFieldName, - valueFieldName, - trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, - "elem", - trw.element.bare, - formatNatArgsCPP(nil, trw.element.natArgs), - false, - false, - ), - ) - */ + } + // TODO remove such giant comments... + /* + _ = fmt.Sprintf(code, + addBytes(trw.goGlobalName, bytesVersion), + trw.element.t.CPPTypeStringInNamespace(bytesVersion, hppInc, trw.wr.resolvedType.Args[0].T, false), + trw.size, + trw.element.t.TypeString(bytesVersion), + trw.wr.tlTag, + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "(*vec)[i]", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + trw.element.t.TypeWritingCode(bytesVersion, trw.wr.ins, + "elem", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + formatNatArgsDeclCPP(trw.wr.NatParams), + trw.typeString(bytesVersion, false), + formatNatArgsCallCPP(trw.wr.NatParams), + trw.element.t.TypeResettingCode(bytesVersion, trw.wr.ins, "(*vec)[i]", false), + keyTypeString, + valueTypeString, + keyFieldName, + valueFieldName, + trw.element.t.TypeReadingCode(bytesVersion, trw.wr.ins, + "elem", + trw.element.bare, + formatNatArgsCPP(nil, trw.element.natArgs), + false, + false, + ), + ) + */ + + if hppDet != nil { + cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) hppDet.WriteString(fmt.Sprintf(hppDetCode, addBytes(trw.wr.goGlobalName, bytesVersion), @@ -291,6 +293,11 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item trw.size, formatNatArgsDeclCPP(trw.wr.NatParams), )) + + cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } + + if cppDet != nil { tt := trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc) tr := trw.element.t.trw.CPPTypeReadingCode(bytesVersion, "el", trw.element.Bare(), formatNatArgsCPP(nil, trw.element.natArgs), @@ -314,6 +321,5 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item trw.element.t.trw.CPPTypeResettingCode(bytesVersion, "el"), trw.wr.gen.DetailsCPPNamespace, )) - cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) } } diff --git a/internal/tlcodegen/type_rw_union_cpp.go b/internal/tlcodegen/type_rw_union_cpp.go index 4bc7c8c6..d8f9eaa3 100644 --- a/internal/tlcodegen/type_rw_union_cpp.go +++ b/internal/tlcodegen/type_rw_union_cpp.go @@ -8,6 +8,7 @@ package tlcodegen import ( "fmt" + "github.com/vkcom/tl/internal/utils" "strings" ) @@ -126,9 +127,12 @@ func (trw *TypeRWUnion) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncl cppFinishNamespace(hpp, typeNamespace) } - if hppDet != nil && cppDet != nil { - myFullType := trw.cppTypeStringInNamespace(bytesVersion, hppDetInc) - myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + hppTmpInclude := DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + myFullType := trw.cppTypeStringInNamespace(bytesVersion, &hppTmpInclude) + myFullTypeNoPrefix := strings.TrimPrefix(myFullType, "::") // Stupid C++ has sometimes problems with name resolution of definitions + + if hppDet != nil { + utils.AppendMap(&hppTmpInclude.ns, &hppDetInc.ns) cppStartNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) hppDet.WriteString(fmt.Sprintf(` @@ -137,7 +141,9 @@ bool %[1]sReadBoxed(::basictl::tl_istream & s, %[2]s& item%[3]s); bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); `, goGlobalName, myFullType, formatNatArgsDeclCPP(trw.wr.NatParams))) cppFinishNamespace(hppDet, trw.wr.gen.DetailsCPPNamespaceElements) + } + if cppDet != nil { cppDet.WriteString(fmt.Sprintf(` static const std::string_view %[1]s_tbl_tl_name[]{%[2]s}; static const uint32_t %[1]s_tbl_tl_tag[]{%[3]s}; diff --git a/internal/utils/maps.go b/internal/utils/maps.go index 1e917426..0add5819 100644 --- a/internal/utils/maps.go +++ b/internal/utils/maps.go @@ -59,3 +59,19 @@ func ReverseSetOfPairs[K, V comparable](in map[K]map[V]bool) map[V]map[K]bool { return m } + +func AppendMap[K comparable, V any](values, to *map[K]V) { + for k, v := range *values { + (*to)[k] = v + } +} + +func AppendMapWithResolving[K comparable, V any](values, to *map[K]V, resolver func(key K, value1, value2 V) V) { + for k, v := range *values { + if v2, ok := (*to)[k]; ok { + (*to)[k] = resolver(k, v, v2) + } else { + (*to)[k] = v + } + } +} From 07689116913e043f00440adec90ea994703a09e6 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Mon, 1 Jul 2024 14:24:29 +0300 Subject: [PATCH 11/14] split generation to hpps and cpps --- internal/tlcodegen/tlgen_cpp.go | 138 +++++++++++++---------- internal/tlcodegen/type_rw_maybe_cpp.go | 2 +- internal/tlcodegen/type_rw_struct_cpp.go | 8 +- internal/tlcodegen/type_rw_tuple_cpp.go | 2 +- 4 files changed, 89 insertions(+), 61 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index a8c1cefd..715d2277 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -33,19 +33,22 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { gen.decideCppCodeDestinations(gen.generatedTypesList) - typeHeadersByFileName := make(map[string][]*TypeRWWrapper) - detailsToSpecs := make(map[string][]*TypeRWWrapper) + hpps := make(map[string][]*TypeRWWrapper) + detailsHpps := make(map[string][]*TypeRWWrapper) + detailsCpps := make(map[string][]*TypeRWWrapper) groupsToDetails := make(map[string]map[string]bool) for _, t := range gen.generatedTypesList { - typeHeadersByFileName[t.fileName] = append(typeHeadersByFileName[t.fileName], t) + hpps[t.fileName] = append(hpps[t.fileName], t) + detailsHpps[t.hppDetailsFileName] = append(detailsHpps[t.hppDetailsFileName], t) + detailsCpps[t.cppDetailsFileName] = append(detailsCpps[t.cppDetailsFileName], t) + utils.PutPairToSetOfPairs(&groupsToDetails, t.groupName, t.cppDetailsFileName) - detailsToSpecs[t.cppDetailsFileName] = append(detailsToSpecs[t.cppDetailsFileName], t) } for group, groupDetails := range groupsToDetails { for det, _ := range groupDetails { - for _, spec := range detailsToSpecs[det] { + for _, spec := range detailsCpps[det] { if spec.groupName != group { return fmt.Errorf(`in details "%s" has different groups mentioned: "%s" and "%s"`, det, group, spec.groupName) } @@ -53,7 +56,7 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { } } - for header, typeDefs := range typeHeadersByFileName { + for header, typeDefs := range hpps { var hpp strings.Builder hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} hppIncFwd := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} @@ -99,73 +102,93 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { hpp.Reset() } - for group, groupDetails := range groupsToDetails { - for detailsFile, _ := range groupDetails { - specs := detailsToSpecs[detailsFile] - - hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} - var hppDet strings.Builder - var cppDet strings.Builder - - slices.SortFunc(specs, TypeComparator) - for _, typeRw := range specs { - typeDefVariations := make([]TypeDefinitionVariation, 1) - { - if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { - typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) - } - } + for detailsHeader, specs := range detailsHpps { + hppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + var hppDet strings.Builder - for _, typeDefVariation := range typeDefVariations { - typesCounter++ - typeRw.trw.CPPGenerateCode(nil, nil, nil, &hppDet, hppDetInc, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) + slices.SortFunc(specs, TypeComparator) + for _, typeRw := range specs { + typeDefVariations := make([]TypeDefinitionVariation, 1) + { + if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { + typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) } } - if hppDet.Len() == 0 && cppDet.Len() == 0 { - continue + for _, typeDefVariation := range typeDefVariations { + typesCounter++ + typeRw.trw.CPPGenerateCode(nil, nil, nil, &hppDet, hppDetInc, nil, nil, typeDefVariation.NeedBytesVersion, false) } + } - // all specs in one file must be in group - cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, group} - - hppDetStr := hppDet.String() - cppDetStr := cppDet.String() + if hppDet.Len() == 0 { + continue + } - hppDet.Reset() - cppDet.Reset() + hppDetStr := hppDet.String() + hppDet.Reset() - hppDet.WriteString("#pragma once\n\n") - hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) + hppDet.WriteString("#pragma once\n\n") + hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", specs[0].fileName, hppExt)) - for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { - if n == specs[0].fileName { - continue - } - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) + hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", specs[0].fileName, hppExt)) + for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { + if n == specs[0].fileName { + continue } - hppDet.WriteString("\n") + hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) + } + hppDet.WriteString("\n") + + filepathName := filepath.Join("details", detailsHeader+hppExt) + if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { + return err + } + } - cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", detailsFile, hppExt)) - for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.cppDetailsFileName }) { - if n == detailsFile { - continue + for detailsFile, specs := range detailsCpps { + + cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} + var cppDet strings.Builder + + slices.SortFunc(specs, TypeComparator) + for _, typeRw := range specs { + typeDefVariations := make([]TypeDefinitionVariation, 1) + { + if typeRw.wantsBytesVersion && typeRw.trw.CPPHasBytesVersion() { + typeDefVariations = append(typeDefVariations, TypeDefinitionVariation{NeedBytesVersion: true}) } - cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) } - cppDet.WriteString("\n") - filepathName := filepath.Join("details", detailsFile+hppExt) - if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { - return err - } - filepathName = filepath.Join("details", detailsFile+cppExt) - if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { - return err + for _, typeDefVariation := range typeDefVariations { + typesCounter++ + typeRw.trw.CPPGenerateCode(nil, nil, nil, nil, nil, &cppDet, cppDetInc, typeDefVariation.NeedBytesVersion, false) } } + + if cppDet.Len() == 0 { + continue + } + + // all specs in one file must be in group + cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} + + cppDetStr := cppDet.String() + + cppDet.Reset() + + for _, spec := range specs { + cppDetInc.ns[spec] = CppIncludeInfo{componentId: spec.typeComponent, namespace: spec.groupName} + } + for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.hppDetailsFileName }) { + cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + } + cppDet.WriteString("\n") + + filepathName := filepath.Join("details", detailsFile+cppExt) + if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { + return err + } } var cppAll strings.Builder @@ -371,6 +394,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { t.groupName = CommonGroup } t.cppDetailsFileName = t.groupName + "_group_details" + t.hppDetailsFileName = t.cppDetailsFileName } } } diff --git a/internal/tlcodegen/type_rw_maybe_cpp.go b/internal/tlcodegen/type_rw_maybe_cpp.go index a685b139..cf5200c0 100644 --- a/internal/tlcodegen/type_rw_maybe_cpp.go +++ b/internal/tlcodegen/type_rw_maybe_cpp.go @@ -84,7 +84,7 @@ bool %[1]sWriteBoxed(::basictl::tl_ostream & s, const %[2]s& item%[3]s); if cppDet != nil { // cpp details for k, v := range newTypeDeps.ns { - (*hppDetInc).ns[k] = v + (*cppDetInc).ns[k] = v } cppDet.WriteString(fmt.Sprintf(` diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index 4f1f395a..fc515ae5 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -415,8 +415,12 @@ func (trw *TypeRWStruct) CPPReadFields(bytesVersion bool, hppDetInc *DirectInclu s.WriteString(fmt.Sprintf("\t"+`if (!item.%[2]s) { item.%[2]s = std::make_shared<%[1]s>(); } `, field.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc), field.cppName)) } - _ = field.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc) // only fill includes - _ = field.t.CPPTypeStringInNamespace(bytesVersion, hppDetInc) // only fill includes + if cppDetInc != nil { + _ = field.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc) // only fill includes + } + if hppDetInc != nil { + _ = field.t.CPPTypeStringInNamespace(bytesVersion, hppDetInc) // only fill includes + } s.WriteString(strings.Repeat("\t", indent)) s.WriteString( field.t.trw.CPPTypeReadingCode(bytesVersion, addAsterisk(field.recursive, "item."+field.cppName), diff --git a/internal/tlcodegen/type_rw_tuple_cpp.go b/internal/tlcodegen/type_rw_tuple_cpp.go index f099fb00..d651ca44 100644 --- a/internal/tlcodegen/type_rw_tuple_cpp.go +++ b/internal/tlcodegen/type_rw_tuple_cpp.go @@ -289,7 +289,7 @@ bool %[8]s::%[1]sWrite(::basictl::tl_ostream & s, const std::vector<%[2]s>& item hppDet.WriteString(fmt.Sprintf(hppDetCode, addBytes(trw.wr.goGlobalName, bytesVersion), - trw.element.t.CPPTypeStringInNamespace(bytesVersion, cppDetInc), + trw.element.t.CPPTypeStringInNamespace(bytesVersion, &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}}), trw.size, formatNatArgsDeclCPP(trw.wr.NatParams), )) From 1151008fecfdb26e5f11297e7719db6306d93f6a Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Mon, 1 Jul 2024 16:10:35 +0300 Subject: [PATCH 12/14] separate hpps --- internal/tlcodegen/tlgen_cpp.go | 39 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 715d2277..7a0e2bfc 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -56,6 +56,10 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { } } + createdHpps := map[string]bool{} + createdDetailsHpps := map[string]bool{} + createdDetailsCpps := map[string]bool{} + for header, typeDefs := range hpps { var hpp strings.Builder hppInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} @@ -100,6 +104,8 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { return err } hpp.Reset() + + createdHpps[header] = true } for detailsHeader, specs := range detailsHpps { @@ -129,25 +135,25 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { hppDet.Reset() hppDet.WriteString("#pragma once\n\n") - hppDet.WriteString(fmt.Sprintf("#include \"../%s\"\n", basicTLFilepathName)) + hppDet.WriteString(fmt.Sprintf("#include \"../../%s\"\n", basicTLFilepathName)) - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", specs[0].fileName, hppExt)) + hppDet.WriteString(fmt.Sprintf("#include \"../../%s%s\"\n", specs[0].fileName, hppExt)) for _, n := range hppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.fileName }) { if n == specs[0].fileName { continue } - hppDet.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, hppExt)) + hppDet.WriteString(fmt.Sprintf("#include \"../../%s%s\"\n", n, hppExt)) } hppDet.WriteString("\n") - filepathName := filepath.Join("details", detailsHeader+hppExt) + filepathName := filepath.Join("details", "headers", detailsHeader+hppExt) if err := gen.addCodeFile(filepathName, gen.copyrightText+hppDet.String()+hppDetStr); err != nil { return err } + createdDetailsHpps[detailsHeader] = true } for detailsFile, specs := range detailsCpps { - cppDetInc := &DirectIncludesCPP{ns: map[*TypeRWWrapper]CppIncludeInfo{}} var cppDet strings.Builder @@ -172,23 +178,25 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { // all specs in one file must be in group cppAllInc.ns[specs[0]] = CppIncludeInfo{-1, specs[0].groupName} - cppDetStr := cppDet.String() - cppDet.Reset() for _, spec := range specs { + if !createdDetailsHpps[spec.hppDetailsFileName] { + continue + } cppDetInc.ns[spec] = CppIncludeInfo{componentId: spec.typeComponent, namespace: spec.groupName} } for _, n := range cppDetInc.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.hppDetailsFileName }) { - cppDet.WriteString(fmt.Sprintf("#include \"%s%s\"\n", n, hppExt)) + cppDet.WriteString(fmt.Sprintf("#include \"../headers/%s%s\"\n", n, hppExt)) } cppDet.WriteString("\n") - filepathName := filepath.Join("details", detailsFile+cppExt) + filepathName := filepath.Join("details", "code", detailsFile+cppExt) if err := gen.addCodeFile(filepathName, gen.copyrightText+cppDet.String()+cppDetStr); err != nil { return err } + createdDetailsCpps[detailsFile] = true } var cppAll strings.Builder @@ -205,8 +213,9 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.cppDetailsFileName }) { cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n, cppExt)) - cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../%s%s\"\n", n, cppExt)) - cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n, cppExt, n, hppExt)) + cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../code/%s%s\"\n", n, cppExt)) + //cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n, cppExt, n, hppExt)) + cppMake1UsedFiles.WriteString(fmt.Sprintf("details/code/%s%s", n, cppExt)) } namespaceDetails := namespace @@ -313,6 +322,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { for _, t := range allTypes { t.cppDetailsFileName = t.fileName + "_details" + t.hppDetailsFileName = t.cppDetailsFileName t.groupName = t.tlName.Namespace if t.unionParent != nil { t.groupName = t.unionParent.wr.tlName.Namespace @@ -334,7 +344,6 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { allTypesWithoutGroup := make([]*TypeRWWrapper, 0) allTypesWithoutGroupMap := make(map[*TypeRWWrapper]bool) - allTypesWithoutGroupUsages := make(map[*TypeRWWrapper]map[string]bool) for _, t := range allTypes { @@ -346,9 +355,6 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { } for _, t := range allTypes { - //if t.groupName == "" { - // continue - //} for _, dep := range t.trw.AllTypeDependencies(false) { if dep.groupName == NoNamespaceGroup { if _, ok := allTypesWithoutGroupUsages[dep]; !ok { @@ -379,11 +385,13 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { if len(usages) == 0 { t.groupName = IndependentTypes t.cppDetailsFileName = IndependentTypes + "_" + t.cppDetailsFileName + t.hppDetailsFileName = t.cppDetailsFileName } else if len(usages) == 1 { usage := utils.SetToSlice(&usages)[0] if usage != NoNamespaceGroup { t.groupName = usage t.cppDetailsFileName = usage + "_" + t.cppDetailsFileName + t.hppDetailsFileName = t.cppDetailsFileName } } } @@ -394,7 +402,6 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { t.groupName = CommonGroup } t.cppDetailsFileName = t.groupName + "_group_details" - t.hppDetailsFileName = t.cppDetailsFileName } } } From d7091a3139dea2906bd443bf165b04d0b9cc2b6e Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Tue, 2 Jul 2024 14:04:18 +0300 Subject: [PATCH 13/14] fix bug with templates in recursion --- internal/tlcodegen/tlgen.go | 5 ++--- internal/tlcodegen/type_rw.go | 2 +- internal/tlcodegen/type_rw_bool.go | 2 +- internal/tlcodegen/type_rw_maybe.go | 4 ++-- internal/tlcodegen/type_rw_primitive.go | 2 +- internal/tlcodegen/type_rw_struct.go | 18 +++++++++++++----- internal/tlcodegen/type_rw_tuple.go | 4 ++-- internal/tlcodegen/type_rw_union.go | 6 ++---- 8 files changed, 24 insertions(+), 19 deletions(-) diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index 567989f3..e1b4ddcd 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -1150,15 +1150,14 @@ func GenerateCode(tl tlast.TL, options Gen2Options) (*Gen2, error) { _, order := findAllTypesDependencyComponents(sortedTypes) gen.componentsOrder = order - // in BeforeCodeGenerationStep we split recursion. Which links will be broken depends on order of nodes visited for _, v := range sortedTypes { if len(v.arguments) == 0 { visitedNodes := make(map[*TypeRWWrapper]int) - currentPath := make([]*TypeRWWrapper, 0) - v.trw.FillRecursiveChildren(visitedNodes, ¤tPath) + v.trw.FillRecursiveChildren(visitedNodes, true) } } + // in BeforeCodeGenerationStep we split recursion. Which links will be broken depends on order of nodes visited for _, v := range sortedTypes { v.trw.BeforeCodeGenerationStep1() } diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index c9084901..7392669c 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -697,7 +697,7 @@ type TypeRW interface { markWantsBytesVersion(visitedNodes map[*TypeRWWrapper]bool) fillRecursiveUnwrap(vistrwitedNodes map[*TypeRWWrapper]bool) - FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) + FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) AllPossibleRecursionProducers() []*TypeRWWrapper AllTypeDependencies(generic bool) []*TypeRWWrapper IsWrappingType() bool diff --git a/internal/tlcodegen/type_rw_bool.go b/internal/tlcodegen/type_rw_bool.go index 2417759d..a94a4053 100644 --- a/internal/tlcodegen/type_rw_bool.go +++ b/internal/tlcodegen/type_rw_bool.go @@ -54,7 +54,7 @@ func (trw *TypeRWBool) IsWrappingType() bool { return true } -func (trw *TypeRWBool) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWBool) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { } func (trw *TypeRWBool) BeforeCodeGenerationStep1() { diff --git a/internal/tlcodegen/type_rw_maybe.go b/internal/tlcodegen/type_rw_maybe.go index 01e695f4..64f7f105 100644 --- a/internal/tlcodegen/type_rw_maybe.go +++ b/internal/tlcodegen/type_rw_maybe.go @@ -55,9 +55,9 @@ func (trw *TypeRWMaybe) IsWrappingType() bool { return true } -func (trw *TypeRWMaybe) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWMaybe) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { visitedNodes[trw.wr] = 1 - trw.element.t.trw.FillRecursiveChildren(visitedNodes, currentPath) + trw.element.t.trw.FillRecursiveChildren(visitedNodes, generic) visitedNodes[trw.wr] = 2 } diff --git a/internal/tlcodegen/type_rw_primitive.go b/internal/tlcodegen/type_rw_primitive.go index 916816aa..fa6e786e 100644 --- a/internal/tlcodegen/type_rw_primitive.go +++ b/internal/tlcodegen/type_rw_primitive.go @@ -70,7 +70,7 @@ func (trw *TypeRWPrimitive) IsWrappingType() bool { return true } -func (trw *TypeRWPrimitive) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWPrimitive) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { } func (trw *TypeRWPrimitive) BeforeCodeGenerationStep1() { diff --git a/internal/tlcodegen/type_rw_struct.go b/internal/tlcodegen/type_rw_struct.go index 75e79e93..522777a8 100644 --- a/internal/tlcodegen/type_rw_struct.go +++ b/internal/tlcodegen/type_rw_struct.go @@ -170,25 +170,33 @@ func (trw *TypeRWStruct) IsWrappingType() bool { return trw.isUnwrapType() } -func (trw *TypeRWStruct) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWStruct) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { if visitedNodes[trw.wr] != 0 { return } - *currentPath = append(*currentPath, trw.wr) visitedNodes[trw.wr] = 1 + + ti := trw.wr.gen.typesInfo + red := ti.TypeNameToGenericTypeReduction(trw.wr.tlName) + for i, f := range trw.Fields { if f.recursive { continue } - for _, typeDep := range f.t.trw.AllPossibleRecursionProducers() { + var typeDeps []*TypeRWWrapper + if generic { + typeDeps = f.t.ActualTypeDependencies(ti.FieldTypeReduction(&red, i)) + } else { + typeDeps = f.t.trw.AllPossibleRecursionProducers() + } + for _, typeDep := range typeDeps { if visitedNodes[typeDep] == 1 { trw.Fields[i].recursive = true } else { - typeDep.trw.FillRecursiveChildren(visitedNodes, currentPath) + typeDep.trw.FillRecursiveChildren(visitedNodes, generic) } } } - *currentPath = (*currentPath)[:len(*currentPath)-1] visitedNodes[trw.wr] = 2 } diff --git a/internal/tlcodegen/type_rw_tuple.go b/internal/tlcodegen/type_rw_tuple.go index e8db11b1..5f1927a1 100644 --- a/internal/tlcodegen/type_rw_tuple.go +++ b/internal/tlcodegen/type_rw_tuple.go @@ -74,9 +74,9 @@ func isDictionaryElement(wr *TypeRWWrapper) (bool, bool, Field, Field) { return ok, isString, structElement.Fields[0], structElement.Fields[1] } -func (trw *TypeRWBrackets) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWBrackets) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { for _, typeDep := range trw.AllPossibleRecursionProducers() { - typeDep.trw.FillRecursiveChildren(visitedNodes, currentPath) + typeDep.trw.FillRecursiveChildren(visitedNodes, generic) } } diff --git a/internal/tlcodegen/type_rw_union.go b/internal/tlcodegen/type_rw_union.go index 7753a02f..ee9716c5 100644 --- a/internal/tlcodegen/type_rw_union.go +++ b/internal/tlcodegen/type_rw_union.go @@ -51,19 +51,17 @@ func (trw *TypeRWUnion) markWantsBytesVersion(visitedNodes map[*TypeRWWrapper]bo } } -func (trw *TypeRWUnion) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, currentPath *[]*TypeRWWrapper) { +func (trw *TypeRWUnion) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) { if visitedNodes[trw.wr] != 0 { return } - *currentPath = append(*currentPath, trw.wr) visitedNodes[trw.wr] = 1 for _, f := range trw.Fields { if f.recursive { continue } - f.t.trw.FillRecursiveChildren(visitedNodes, currentPath) + f.t.trw.FillRecursiveChildren(visitedNodes, generic) } - *currentPath = (*currentPath)[:len(*currentPath)-1] visitedNodes[trw.wr] = 2 } From bf92a83d146ccdaaef1da111064b2815f19164c6 Mon Sep 17 00:00:00 2001 From: Brat-vseznamus Date: Wed, 3 Jul 2024 16:41:44 +0300 Subject: [PATCH 14/14] bfs for namespaces unions --- internal/tlcodegen/tlgen.go | 4 +- internal/tlcodegen/tlgen_cpp.go | 135 +++++++++++------- internal/tlcodegen/type_rw.go | 4 +- internal/tlcodegen/type_rw_bool.go | 2 +- internal/tlcodegen/type_rw_maybe.go | 2 +- internal/tlcodegen/type_rw_primitive.go | 2 +- internal/tlcodegen/type_rw_struct.go | 21 ++- internal/tlcodegen/type_rw_struct_cpp.go | 2 +- internal/tlcodegen/type_rw_tuple.go | 2 +- internal/tlcodegen/type_rw_union.go | 2 +- internal/tlcodegen/type_rw_union_cpp.go | 2 +- .../utils/{maps.go => data_structures.go} | 8 ++ 12 files changed, 120 insertions(+), 66 deletions(-) rename internal/utils/{maps.go => data_structures.go} (91%) diff --git a/internal/tlcodegen/tlgen.go b/internal/tlcodegen/tlgen.go index e1b4ddcd..33a5885e 100644 --- a/internal/tlcodegen/tlgen.go +++ b/internal/tlcodegen/tlgen.go @@ -1247,7 +1247,7 @@ func findAllTypesDependencyComponents(types []*TypeRWWrapper) (map[int]map[int]b reverseDependencyGraph := make(map[*TypeRWWrapper][]*TypeRWWrapper) for _, tpU := range types { - dependencies := tpU.trw.AllTypeDependencies(true) + dependencies := tpU.trw.AllTypeDependencies(true, false) for _, tpV := range dependencies { dependencyGraph[tpU] = append(dependencyGraph[tpU], tpV) reverseDependencyGraph[tpV] = append(reverseDependencyGraph[tpV], tpU) @@ -1290,7 +1290,7 @@ func findAllTypesDependencyComponents(types []*TypeRWWrapper) (map[int]map[int]b if _, ok := componentsDeps[tpU.typeComponent]; !ok { componentsDeps[tpU.typeComponent] = make(map[int]bool) } - for _, tpV := range tpU.trw.AllTypeDependencies(true) { + for _, tpV := range tpU.trw.AllTypeDependencies(true, false) { if tpU.typeComponent != tpV.typeComponent { componentsDeps[tpU.typeComponent][tpV.typeComponent] = true } diff --git a/internal/tlcodegen/tlgen_cpp.go b/internal/tlcodegen/tlgen_cpp.go index 7a0e2bfc..c61ea19b 100644 --- a/internal/tlcodegen/tlgen_cpp.go +++ b/internal/tlcodegen/tlgen_cpp.go @@ -11,6 +11,7 @@ import ( "github.com/vkcom/tl/internal/utils" "golang.org/x/exp/slices" "path/filepath" + "sort" "strings" ) @@ -214,8 +215,24 @@ func (gen *Gen2) generateCodeCPP(generateByteVersions []string) error { for _, n := range nf.Includes.sortedIncludes(gen.componentsOrder, func(wrapper *TypeRWWrapper) string { return wrapper.cppDetailsFileName }) { cppAll.WriteString(fmt.Sprintf("#include \"details/%s%s\"\n", n, cppExt)) cppMake1Namespace.WriteString(fmt.Sprintf("#include \"../code/%s%s\"\n", n, cppExt)) - //cppMake1UsedFiles.WriteString(fmt.Sprintf("details/%s%s details/%s%s ", n, cppExt, n, hppExt)) cppMake1UsedFiles.WriteString(fmt.Sprintf("details/code/%s%s", n, cppExt)) + + usedTypes := detailsCpps[n] + usedTypes = utils.FilterSlice(usedTypes, func(w *TypeRWWrapper) bool { + return createdDetailsHpps[w.hppDetailsFileName] + }) + + hppDets := utils.MapSlice(&usedTypes, func(a *TypeRWWrapper) string { + return a.hppDetailsFileName + }) + + hppDetsSet := utils.SliceToSet(&hppDets) + hppDetsList := utils.SetToSlice(&hppDetsSet) + + sort.Strings(hppDetsList) + for _, h := range hppDetsList { + cppMake1UsedFiles.WriteString(fmt.Sprintf(" details/headers/%s%s", h, hppExt)) + } } namespaceDetails := namespace @@ -300,21 +317,6 @@ main.o: main.cpp return nil } -func findAllReachableTypeByGroup(v *TypeRWWrapper, visited *map[*TypeRWWrapper]bool, result *[]*TypeRWWrapper) { - if v.groupName != "" { - return - } - if (*visited)[v] { - return - } - (*visited)[v] = true - *result = append(*result, v) - - for _, w := range v.trw.AllTypeDependencies(false) { - findAllReachableTypeByGroup(w, visited, result) - } -} - func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { const IndependentTypes = "__independent_types" const NoNamespaceGroup = "" @@ -324,15 +326,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { t.cppDetailsFileName = t.fileName + "_details" t.hppDetailsFileName = t.cppDetailsFileName t.groupName = t.tlName.Namespace - if t.unionParent != nil { - t.groupName = t.unionParent.wr.tlName.Namespace - } if t.fileName != t.tlName.String() { - //if t.tlName.String() == "" { - // t.cppDetailsFileName = "builtin_" + t.cppLocalName - //} else { - // t.cppDetailsFileName = t.tlName.String() + "_details" - //} for _, t2 := range allTypes { if t.fileName == t2.tlName.String() { t.groupName = t2.tlName.Namespace @@ -345,6 +339,7 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { allTypesWithoutGroup := make([]*TypeRWWrapper, 0) allTypesWithoutGroupMap := make(map[*TypeRWWrapper]bool) allTypesWithoutGroupUsages := make(map[*TypeRWWrapper]map[string]bool) + reverseDepsEdges := make(map[*TypeRWWrapper]map[*TypeRWWrapper]bool) for _, t := range allTypes { if t.groupName != NoNamespaceGroup { @@ -355,52 +350,90 @@ func (gen *Gen2) decideCppCodeDestinations(allTypes []*TypeRWWrapper) { } for _, t := range allTypes { - for _, dep := range t.trw.AllTypeDependencies(false) { + for _, dep := range t.trw.AllTypeDependencies(false, true) { if dep.groupName == NoNamespaceGroup { - if _, ok := allTypesWithoutGroupUsages[dep]; !ok { - allTypesWithoutGroupUsages[dep] = make(map[string]bool) - } - allTypesWithoutGroupUsages[dep][t.groupName] = true + utils.PutPairToSetOfPairs(&allTypesWithoutGroupUsages, dep, t.groupName) + utils.PutPairToSetOfPairs(&reverseDepsEdges, dep, t) } } } - groupToFirstVisits := utils.ReverseSetOfPairs(allTypesWithoutGroupUsages) - for group, firstLayer := range groupToFirstVisits { - visited := make(map[*TypeRWWrapper]bool) - result := make([]*TypeRWWrapper, 0) + // bfs + edges := make(map[*TypeRWWrapper][]*TypeRWWrapper) + reverseEdges := make(map[*TypeRWWrapper][]*TypeRWWrapper) - for v, _ := range firstLayer { - findAllReachableTypeByGroup(v, &visited, &result) + for _, from := range allTypes { + for _, to := range from.trw.AllTypeDependencies(false, true) { + if to.groupName == NoNamespaceGroup { + edges[from] = append(edges[from], to) + reverseEdges[to] = append(reverseEdges[to], from) + } } + } - for _, v := range result { - utils.PutPairToSetOfPairs(&allTypesWithoutGroupUsages, v, group) + for _, t := range allTypes { + if t.groupName == NoNamespaceGroup && edges[t] == nil && reverseEdges[t] == nil { + t.groupName = IndependentTypes } } - for _, t := range allTypesWithoutGroup { - usages := allTypesWithoutGroupUsages[t] + visited := make(map[*TypeRWWrapper]bool) + front := make(map[*TypeRWWrapper]bool) - if len(usages) == 0 { + for t, _ := range edges { + if t.groupName != NoNamespaceGroup { + front[t] = true + } else if t.groupName == NoNamespaceGroup && len(reverseEdges[t]) == 0 { + front[t] = true t.groupName = IndependentTypes - t.cppDetailsFileName = IndependentTypes + "_" + t.cppDetailsFileName - t.hppDetailsFileName = t.cppDetailsFileName - } else if len(usages) == 1 { - usage := utils.SetToSlice(&usages)[0] - if usage != NoNamespaceGroup { - t.groupName = usage - t.cppDetailsFileName = usage + "_" + t.cppDetailsFileName - t.hppDetailsFileName = t.cppDetailsFileName + } + } + + utils.AppendMap(&front, &visited) + + edgesCount := make(map[*TypeRWWrapper]int) + + for len(front) != 0 { + newFront := make(map[*TypeRWWrapper]bool) + for v, _ := range front { + for _, to := range edges[v] { + if visited[to] { + continue + } + if _, ok := edgesCount[to]; !ok { + edgesCount[to] = len(reverseEdges[to]) + } + edgesCount[to]-- + if edgesCount[to] == 0 { + visited[to] = true + newFront[to] = true + groups := make(map[string]bool) + for _, from := range reverseEdges[to] { + groups[from.groupName] = true + } + if len(groups) == 1 { + to.groupName = utils.SetToSlice(&groups)[0] + if to.groupName != CommonGroup && to.groupName != IndependentTypes { + to.cppDetailsFileName = to.groupName + "_" + to.cppDetailsFileName + } + to.hppDetailsFileName = to.cppDetailsFileName + } else if len(groups) > 1 { + to.groupName = CommonGroup + } + } } } + front = newFront + } + + for _, t := range allTypes { + if t.groupName == NoNamespaceGroup { + t.groupName = CommonGroup + } } if !gen.options.SeparateFiles { for _, t := range allTypes { - if t.groupName == "" { - t.groupName = CommonGroup - } t.cppDetailsFileName = t.groupName + "_group_details" } } diff --git a/internal/tlcodegen/type_rw.go b/internal/tlcodegen/type_rw.go index 7392669c..ded6062a 100644 --- a/internal/tlcodegen/type_rw.go +++ b/internal/tlcodegen/type_rw.go @@ -695,11 +695,11 @@ outer: type TypeRW interface { // methods below are target language independent markWantsBytesVersion(visitedNodes map[*TypeRWWrapper]bool) - fillRecursiveUnwrap(vistrwitedNodes map[*TypeRWWrapper]bool) + fillRecursiveUnwrap(visitedNodes map[*TypeRWWrapper]bool) FillRecursiveChildren(visitedNodes map[*TypeRWWrapper]int, generic bool) AllPossibleRecursionProducers() []*TypeRWWrapper - AllTypeDependencies(generic bool) []*TypeRWWrapper + AllTypeDependencies(generic, countFunctions bool) []*TypeRWWrapper IsWrappingType() bool BeforeCodeGenerationStep1() // during first phase, some wr.trw are nil due to recursive types. So we delay some diff --git a/internal/tlcodegen/type_rw_bool.go b/internal/tlcodegen/type_rw_bool.go index a94a4053..cf6b578d 100644 --- a/internal/tlcodegen/type_rw_bool.go +++ b/internal/tlcodegen/type_rw_bool.go @@ -46,7 +46,7 @@ func (trw *TypeRWBool) AllPossibleRecursionProducers() []*TypeRWWrapper { return nil } -func (trw *TypeRWBool) AllTypeDependencies(generic bool) []*TypeRWWrapper { +func (trw *TypeRWBool) AllTypeDependencies(generic, countFunctions bool) []*TypeRWWrapper { return nil } diff --git a/internal/tlcodegen/type_rw_maybe.go b/internal/tlcodegen/type_rw_maybe.go index 64f7f105..0df7ff30 100644 --- a/internal/tlcodegen/type_rw_maybe.go +++ b/internal/tlcodegen/type_rw_maybe.go @@ -44,7 +44,7 @@ func (trw *TypeRWMaybe) AllPossibleRecursionProducers() []*TypeRWWrapper { return trw.element.t.trw.AllPossibleRecursionProducers() } -func (trw *TypeRWMaybe) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { +func (trw *TypeRWMaybe) AllTypeDependencies(generic, countFunctions bool) (res []*TypeRWWrapper) { if !generic { res = append(res, trw.element.t) } diff --git a/internal/tlcodegen/type_rw_primitive.go b/internal/tlcodegen/type_rw_primitive.go index fa6e786e..2f3ee4d2 100644 --- a/internal/tlcodegen/type_rw_primitive.go +++ b/internal/tlcodegen/type_rw_primitive.go @@ -62,7 +62,7 @@ func (trw *TypeRWPrimitive) AllPossibleRecursionProducers() []*TypeRWWrapper { return nil } -func (trw *TypeRWPrimitive) AllTypeDependencies(generic bool) []*TypeRWWrapper { +func (trw *TypeRWPrimitive) AllTypeDependencies(generic, countFunctions bool) []*TypeRWWrapper { return nil } diff --git a/internal/tlcodegen/type_rw_struct.go b/internal/tlcodegen/type_rw_struct.go index 522777a8..c276a769 100644 --- a/internal/tlcodegen/type_rw_struct.go +++ b/internal/tlcodegen/type_rw_struct.go @@ -148,18 +148,31 @@ func (trw *TypeRWStruct) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWStruct) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { +func (trw *TypeRWStruct) AllTypeDependencies(generic, countFunctions bool) (res []*TypeRWWrapper) { used := make(map[*TypeRWWrapper]bool) - red := trw.wr.gen.typesInfo.TypeNameToGenericTypeReduction(trw.wr.tlName) + ti := trw.wr.gen.typesInfo + red := ti.TypeNameToGenericTypeReduction(trw.wr.tlName) for i, f := range trw.Fields { - fieldRed := trw.wr.gen.typesInfo.FieldTypeReduction(&red, i) - deps := f.t.ActualTypeDependencies(fieldRed) + var deps []*TypeRWWrapper + if generic { + fieldRed := ti.FieldTypeReduction(&red, i) + deps = f.t.ActualTypeDependencies(fieldRed) + } else { + deps = append(deps, f.t) + } for _, dep := range deps { used[dep] = true } } + if countFunctions && trw.ResultType != nil { + returnRed := ti.TypeNameToGenericTypeReduction(trw.ResultType.tlName) + for _, t := range trw.ResultType.ActualTypeDependencies(EvaluatedType{Index: TypeConstant, Type: &returnRed}) { + used[t] = true + } + } + for tp := range used { res = append(res, tp) } diff --git a/internal/tlcodegen/type_rw_struct_cpp.go b/internal/tlcodegen/type_rw_struct_cpp.go index fc515ae5..256e8edf 100644 --- a/internal/tlcodegen/type_rw_struct_cpp.go +++ b/internal/tlcodegen/type_rw_struct_cpp.go @@ -101,7 +101,7 @@ func (trw *TypeRWStruct) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectInc } if hpp != nil { if !forwardDeclaration { - deps := trw.AllTypeDependencies(true) + deps := trw.AllTypeDependencies(true, false) slices.SortFunc(deps, TypeComparator) for _, typeDep := range deps { diff --git a/internal/tlcodegen/type_rw_tuple.go b/internal/tlcodegen/type_rw_tuple.go index 5f1927a1..1e2ba0c6 100644 --- a/internal/tlcodegen/type_rw_tuple.go +++ b/internal/tlcodegen/type_rw_tuple.go @@ -90,7 +90,7 @@ func (trw *TypeRWBrackets) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWBrackets) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { +func (trw *TypeRWBrackets) AllTypeDependencies(generic, countFunctions bool) (res []*TypeRWWrapper) { if !generic { res = append(res, trw.element.t) } diff --git a/internal/tlcodegen/type_rw_union.go b/internal/tlcodegen/type_rw_union.go index ee9716c5..64153bf3 100644 --- a/internal/tlcodegen/type_rw_union.go +++ b/internal/tlcodegen/type_rw_union.go @@ -76,7 +76,7 @@ func (trw *TypeRWUnion) AllPossibleRecursionProducers() []*TypeRWWrapper { return result } -func (trw *TypeRWUnion) AllTypeDependencies(generic bool) (res []*TypeRWWrapper) { +func (trw *TypeRWUnion) AllTypeDependencies(generic, countFunctions bool) (res []*TypeRWWrapper) { for _, f := range trw.Fields { res = append(res, f.t) } diff --git a/internal/tlcodegen/type_rw_union_cpp.go b/internal/tlcodegen/type_rw_union_cpp.go index d8f9eaa3..f19cdd1b 100644 --- a/internal/tlcodegen/type_rw_union_cpp.go +++ b/internal/tlcodegen/type_rw_union_cpp.go @@ -77,7 +77,7 @@ func (trw *TypeRWUnion) CPPGenerateCode(hpp *strings.Builder, hppInc *DirectIncl return } - for _, typeDep := range trw.AllTypeDependencies(true) { + for _, typeDep := range trw.AllTypeDependencies(true, false) { if typeDep.typeComponent == trw.wr.typeComponent { typeDep.trw.CPPGenerateCode(hpp, nil, nil, nil, hppDetInc, nil, cppDetInc, bytesVersion, true) } diff --git a/internal/utils/maps.go b/internal/utils/data_structures.go similarity index 91% rename from internal/utils/maps.go rename to internal/utils/data_structures.go index 0add5819..840baeff 100644 --- a/internal/utils/maps.go +++ b/internal/utils/data_structures.go @@ -8,6 +8,14 @@ func SliceToSet[T comparable](s *[]T) map[T]bool { return m } +func CopyMap[K comparable, V any](m *map[K]V) map[K]V { + m2 := make(map[K]V) + for k, v := range *m { + m2[k] = v + } + return m2 +} + // unstable func Keys[K comparable, V any](m *map[K]V) (res []K) { for k, _ := range *m {