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) }