예제 #1
0
        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; }}");
        }