<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cxxi.Types;

namespace Cxxi.Generators.CSharp
{
    public class CSharpTextTemplate : TextTemplate
    {
        public ITypePrinter TypePrinter { get; set; }

        public CSharpTextTemplate(Driver driver, TranslationUnit unit)
            : base(driver, unit)
        {
            TypePrinter = new CSharpTypePrinter(driver.TypeDatabase, driver.Library);
        }

        // from https://github.com/mono/mono/blob/master/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs
        private static string[] keywords = new string[]
            {
                "abstract", "event", "new", "struct", "as", "explicit", "null", "switch", "base", "extern",
                "this", "false", "operator", "throw", "break", "finally", "out", "true",
                "fixed", "override", "try", "case", "params", "typeof", "catch", "for",
                "private", "foreach", "protected", "checked", "goto", "public",
                "unchecked", "class", "if", "readonly", "unsafe", "const", "implicit", "ref",
                "continue", "in", "return", "using", "virtual", "default",
                "interface", "sealed", "volatile", "delegate", "internal", "do", "is",
                "sizeof", "while", "lock", "stackalloc", "else", "static", "enum",
                "namespace",
                "object", "bool", "byte", "float", "uint", "char", "ulong", "ushort",
                "decimal", "int", "sbyte", "short", "double", "long", "string", "void",
                "partial", "yield", "where"
            };

        public static string SafeIdentifier(string proposedName)
        {
            proposedName =
                new string(((IEnumerable<char>) proposedName).Select(c => char.IsLetterOrDigit(c) ? c : '_').ToArray());
            return keywords.Contains(proposedName) ? "@" + proposedName : proposedName;
        }

        public override string FileExtension
        {
            get { return "cs"; }
        }

        public override void Generate()
        {
            GenerateStart();

            WriteLine("using System;");
            WriteLine("using System.Runtime.InteropServices;");
            NewLine();

            WriteLine("namespace {0}", SafeIdentifier(Driver.Options.LibraryName));
            WriteStartBraceIndent();

            GenerateDeclarations();

            WriteCloseBraceIndent();
        }

        public void GenerateStart()
        {
            if (Transform != null)
            {
                Transform.GenerateStart(this);
                return;
            }

            WriteLine("//----------------------------------------------------------------------------");
            WriteLine("// This is autogenerated code by Cxxi.");
            WriteLine("// Do not edit this file or all your changes will be lost after re-generation.");
            WriteLine("//----------------------------------------------------------------------------");
        }

        public void GenerateDeclarations()
        {
            // Generate all the enum declarations for the module.
            foreach (var @enum in TranslationUnit.Enums)
            {
                if (@enum.Ignore || @enum.IsIncomplete)
                    continue;

                GenerateEnum(@enum);
                NewLine();
            }

            // Generate all the typedef declarations for the module.
            foreach (var typedef in TranslationUnit.Typedefs)
            {
                if (typedef.Ignore) continue;

                if (!GenerateTypedef(typedef))
                    continue;

                NewLine();
            }

            // Generate all the struct/class declarations for the module.
            foreach (var @class in TranslationUnit.Classes)
            {
                if (@class.Ignore) continue;

                GenerateClass(@class);
                NewLine();
            }

            if (TranslationUnit.HasFunctions)
            {
                WriteLine("public partial class " + SafeIdentifier(Options.LibraryName));
                WriteStartBraceIndent();

                // Generate all the function declarations for the module.
                foreach (var function in TranslationUnit.Functions)
                    GenerateFunction(function);

                WriteCloseBraceIndent();
            }
        }

        public void GenerateDeclarationCommon(Declaration T)
        {
            GenerateSummary(T.BriefComment);
            GenerateDebug(T);
        }

        #region Classes<commit_msg>Added proper support for namespaces in the C# backend.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cxxi.Types;

namespace Cxxi.Generators.CSharp
{
    public class CSharpTextTemplate : TextTemplate
    {
        public ITypePrinter TypePrinter { get; set; }

        public CSharpTextTemplate(Driver driver, TranslationUnit unit)
            : base(driver, unit)
        {
            TypePrinter = new CSharpTypePrinter(driver.TypeDatabase, driver.Library);
        }

        // from https://github.com/mono/mono/blob/master/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs
        private static string[] keywords = new string[]
            {
                "abstract", "event", "new", "struct", "as", "explicit", "null", "switch", "base", "extern",
                "this", "false", "operator", "throw", "break", "finally", "out", "true",
                "fixed", "override", "try", "case", "params", "typeof", "catch", "for",
                "private", "foreach", "protected", "checked", "goto", "public",
                "unchecked", "class", "if", "readonly", "unsafe", "const", "implicit", "ref",
                "continue", "in", "return", "using", "virtual", "default",
                "interface", "sealed", "volatile", "delegate", "internal", "do", "is",
                "sizeof", "while", "lock", "stackalloc", "else", "static", "enum",
                "namespace",
                "object", "bool", "byte", "float", "uint", "char", "ulong", "ushort",
                "decimal", "int", "sbyte", "short", "double", "long", "string", "void",
                "partial", "yield", "where"
            };

        public static string SafeIdentifier(string proposedName)
        {
            proposedName =
                new string(((IEnumerable<char>) proposedName).Select(c => char.IsLetterOrDigit(c) ? c : '_').ToArray());
            return keywords.Contains(proposedName) ? "@" + proposedName : proposedName;
        }

        public override string FileExtension
        {
            get { return "cs"; }
        }

        public override void Generate()
        {
            GenerateStart();

            WriteLine("using System;");
            WriteLine("using System.Runtime.InteropServices;");
            NewLine();

            WriteLine("namespace {0}", SafeIdentifier(Driver.Options.LibraryName));
            WriteStartBraceIndent();

            GenerateDeclarations();

            WriteCloseBraceIndent();
        }

        public void GenerateStart()
        {
            if (Transform != null)
            {
                Transform.GenerateStart(this);
                return;
            }

            WriteLine("//----------------------------------------------------------------------------");
            WriteLine("// This is autogenerated code by Cxxi.");
            WriteLine("// Do not edit this file or all your changes will be lost after re-generation.");
            WriteLine("//----------------------------------------------------------------------------");
        }

        public void GenerateDeclarations()
        {
            GenerateNamespace(TranslationUnit);
        }

        private void GenerateNamespace(Namespace @namespace)
        {
            // Generate all the enum declarations for the module.
            foreach (var @enum in @namespace.Enums)
            {
                if (@enum.Ignore || @enum.IsIncomplete)
                    continue;

                GenerateEnum(@enum);
                NewLine();
            }

            // Generate all the typedef declarations for the module.
            foreach (var typedef in @namespace.Typedefs)
            {
                if (typedef.Ignore) continue;

                if (!GenerateTypedef(typedef))
                    continue;

                NewLine();
            }

            // Generate all the struct/class declarations for the module.
            foreach (var @class in @namespace.Classes)
            {
                if (@class.Ignore) continue;

                GenerateClass(@class);
                NewLine();
            }

            if (@namespace.HasFunctions)
            {
                WriteLine("public partial class " + SafeIdentifier(Options.LibraryName));
                WriteStartBraceIndent();

                // Generate all the function declarations for the module.
                foreach (var function in @namespace.Functions)
                    GenerateFunction(function);

                WriteCloseBraceIndent();
            }

            foreach(var childNamespace in @namespace.Namespaces)
                GenerateNamespace(childNamespace);
        }

        public void GenerateDeclarationCommon(Declaration T)
        {
            GenerateSummary(T.BriefComment);
            GenerateDebug(T);
        }

        #region Classes
{'fraction_non_alphanumeric': 0.15080789946140036, 'fraction_numerical': 0.00021121554546414616, 'mean_word_length': 1.6023632866172026, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2398615', 'n_tokens_mistral': 2352, 'n_tokens_neox': 2166, 'n_words': 575}