<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST.Extensions;

namespace CppSharp.AST
{
    public enum CppTypePrintFlavorKind
    {
        C,
        Cpp,
        ObjC
    } 

    public enum CppTypePrintScopeKind
    {
        Local,
        Qualified,
        GlobalQualified
    }

    public class CppTypePrinter : ITypePrinter<string>, IDeclVisitor<string>
    {
        public CppTypePrintFlavorKind PrintFlavorKind;
        public CppTypePrintScopeKind PrintScopeKind;
        public bool PrintLogicalNames;
        public bool PrintTypeQualifiers;

        public bool PrintTypeModifiers { get; set; }

        public CppTypePrinter(bool printTypeQualifiers = true, bool printTypeModifiers = true)
        {
            PrintFlavorKind = CppTypePrintFlavorKind.Cpp;
            PrintScopeKind = CppTypePrintScopeKind.GlobalQualified;
            PrintTypeQualifiers = printTypeQualifiers;
            PrintTypeModifiers = printTypeModifiers;
        }

        public bool ResolveTypedefs { get; set; }

        public string VisitTagType(TagType tag, TypeQualifiers quals)
        {
            var qual = PrintTypeQualifiers && quals.IsConst ? "const " : string.Empty;
            return string.Format("{0}{1}", qual, tag.Declaration.Visit(this));
        }

        public string VisitArrayType(ArrayType array, TypeQualifiers quals)
        {
            var typeName = array.Type.Visit(this);

            switch (array.SizeType)
            {
            case ArrayType.ArraySize.Constant:
                return string.Format("{0}[{1}]", typeName, array.Size);
            case ArrayType.ArraySize.Variable:
            case ArrayType.ArraySize.Dependent:
            case ArrayType.ArraySize.Incomplete:
                return string.Format("{0}[]", typeName);
            }

            throw new NotSupportedException();
        }

        static string ConvertModifierToString(PointerType.TypeModifier modifier)
        {
            switch (modifier)
            {
                case PointerType.TypeModifier.Value: return string.Empty;
                case PointerType.TypeModifier.Pointer: return "*";
                case PointerType.TypeModifier.LVReference: return "&";
                case PointerType.TypeModifier.RVReference: return "&&";
            }

            return string.Empty;
        }

        public string VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

            var function = pointee as FunctionType;
            if (function != null)
            {
                var arguments = function.Parameters;
                var returnType = function.ReturnType;
                var args = string.Empty;

                if (arguments.Count > 0)
                    args = VisitParameters(function.Parameters, hasNames: false);

                return string.Format("{0} (*)({1})", returnType.Visit(this), args);
            }

            var qual = PrintTypeQualifiers && quals.IsConst ? "const " : string.Empty;
            var pointeeType = pointer.Pointee.Visit(this, quals);
            var mod = PrintTypeModifiers ? ConvertModifierToString(pointer.Modifier) : string.Empty;
            return string.Format("{0}{1}{2}", qual, pointeeType, mod);
        }

        public string VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals)
        {
            return string.Empty;
        }

        public string VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
        {
            return VisitPrimitiveType(builtin.Type);
        }

        public string VisitPrimitiveType(PrimitiveType primitive)
        {
            switch (primitive)
            {
                case PrimitiveType.Bool: return "bool";
                case PrimitiveType.Void: return "void";
                case PrimitiveType.Char16: return "char16_t";
                case PrimitiveType.Char32: return "char32_t";
                case PrimitiveType.WideChar: return "wchar_t";
                case PrimitiveType.Char: return "char";<commit_msg>Added support for printing variable arrays as pointers in C type printer.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST.Extensions;

namespace CppSharp.AST
{
    public enum CppTypePrintFlavorKind
    {
        C,
        Cpp,
        ObjC
    } 

    public enum CppTypePrintScopeKind
    {
        Local,
        Qualified,
        GlobalQualified
    }

    public class CppTypePrinter : ITypePrinter<string>, IDeclVisitor<string>
    {
        public CppTypePrintFlavorKind PrintFlavorKind;
        public CppTypePrintScopeKind PrintScopeKind;
        public bool PrintLogicalNames;
        public bool PrintTypeQualifiers;

        public bool PrintTypeModifiers { get; set; }
        public bool PrintVariableArrayAsPointers { get; set; }

        public CppTypePrinter(bool printTypeQualifiers = true, bool printTypeModifiers = true)
        {
            PrintFlavorKind = CppTypePrintFlavorKind.Cpp;
            PrintScopeKind = CppTypePrintScopeKind.GlobalQualified;
            PrintTypeQualifiers = printTypeQualifiers;
            PrintTypeModifiers = printTypeModifiers;
        }

        public bool ResolveTypedefs { get; set; }

        public string VisitTagType(TagType tag, TypeQualifiers quals)
        {
            var qual = PrintTypeQualifiers && quals.IsConst ? "const " : string.Empty;
            return string.Format("{0}{1}", qual, tag.Declaration.Visit(this));
        }

        public string VisitArrayType(ArrayType array, TypeQualifiers quals)
        {
            var typeName = array.Type.Visit(this);

            switch (array.SizeType)
            {
            case ArrayType.ArraySize.Constant:
                return string.Format("{0}[{1}]", typeName, array.Size);
            case ArrayType.ArraySize.Variable:
            case ArrayType.ArraySize.Dependent:
            case ArrayType.ArraySize.Incomplete:
                return string.Format("{0}{1}", typeName,
                                     PrintVariableArrayAsPointers ? "*" : "[]");
            }

            throw new NotSupportedException();
        }

        static string ConvertModifierToString(PointerType.TypeModifier modifier)
        {
            switch (modifier)
            {
                case PointerType.TypeModifier.Value: return string.Empty;
                case PointerType.TypeModifier.Pointer: return "*";
                case PointerType.TypeModifier.LVReference: return "&";
                case PointerType.TypeModifier.RVReference: return "&&";
            }

            return string.Empty;
        }

        public string VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

            var function = pointee as FunctionType;
            if (function != null)
            {
                var arguments = function.Parameters;
                var returnType = function.ReturnType;
                var args = string.Empty;

                if (arguments.Count > 0)
                    args = VisitParameters(function.Parameters, hasNames: false);

                return string.Format("{0} (*)({1})", returnType.Visit(this), args);
            }

            var qual = PrintTypeQualifiers && quals.IsConst ? "const " : string.Empty;
            var pointeeType = pointee.Visit(this, quals);
            var mod = PrintTypeModifiers ? ConvertModifierToString(pointer.Modifier) : string.Empty;
            return string.Format("{0}{1}{2}", qual, pointeeType, mod);
        }

        public string VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals)
        {
            return string.Empty;
        }

        public string VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
        {
            return VisitPrimitiveType(builtin.Type);
        }

        public string VisitPrimitiveType(PrimitiveType primitive)
        {
            switch (primitive)
            {
                case PrimitiveType.Bool: return "bool";
                case PrimitiveType.Void: return "void";
                case PrimitiveType.Char16: return "char16_t";
                case PrimitiveType.Char32: return "char32_t";
                case PrimitiveType.WideChar: return "wchar_t";
                case PrimitiveType.Char: return "char";
{'fraction_non_alphanumeric': 0.08068343616516374, 'fraction_numerical': 0.004627432368296156, 'mean_word_length': 2.0049910873440284, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '891564', 'n_tokens_mistral': 2216, 'n_tokens_neox': 2137, 'n_words': 484}