private static void BuildClassDeclaration(TypeDecl decl, CodeWriter writer) { var settings = GeneratorSettingsProvider.Get(decl.Module.ModuleName); var type = decl.Name.Underscore(); // forwards writer.AppendLine($"class {type}_key_impl; using {type}_key = dot::ptr<{type}_key_impl>;"); writer.AppendLine($"class {type}_data_impl; using {type}_data = dot::ptr<{type}_data_impl>;"); // Get unique keys and data from elements var keyElements = decl.Elements.Where(e => decl.Keys.Contains(e.Name)).ToList(); var dataForwards = keyElements.Where(e => e.Data != null) .Where(e => e.Data.Module.ModuleName == decl.Module.ModuleName) .Select(e => $"{e.Data.Name.Underscore()}_data").ToList(); var keysForwards = keyElements.Where(e => e.Key != null) .Where(e => e.Key.Module.ModuleName == decl.Module.ModuleName) .Select(e => $"{e.Key.Name.Underscore()}_key").ToList(); var forwards = keysForwards.Union(dataForwards).Distinct(); // Appends forwards foreach (var f in forwards) { writer.AppendLine($"class {f}_impl; using {f} = dot::ptr<{f}_impl>;"); } writer.AppendNewLineWithoutIndent(); writer.AppendLine($"inline {type}_key make_{type}_key();"); writer.AppendNewLineWithoutIndent(); writer.AppendLines(CommentHelper.FormatComment(decl.Comment)); writer.AppendLine($"class {settings.DeclSpec} {type}_key_impl : public key_impl<{type}_key_impl,{type}_data_impl>"); writer.AppendLine("{"); writer.PushIndent(); writer.AppendLine($"typedef {type}_key_impl self;"); writer.AppendLine($"friend {type}_key make_{type}_key();"); writer.PopIndent(); writer.AppendNewLineWithoutIndent(); writer.AppendLine("public: // FIELDS"); writer.AppendNewLineWithoutIndent(); if (keyElements.Any()) { writer.PushIndent(); CppElementBuilder.WriteElements(keyElements, writer); writer.PopIndent(); } writer.AppendLine("public:"); writer.PushIndent(); writer.AppendLine("virtual dot::type_t type();"); writer.AppendLine("static dot::type_t typeof();"); writer.PopIndent(); writer.AppendLine("};"); writer.AppendNewLineWithoutIndent(); writer.AppendLine("/// Create an empty instance."); writer.AppendLine($"inline {type}_key make_{type}_key() {{ return new {type}_key_impl; }}"); }