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

namespace MonoManagedToNative.Generators
{
    public class AstGenerator
    {
        public TranslationUnit unit;
        Options options;

        public AstGenerator(Options options)
        {
            unit = new TranslationUnit();
            this.options = options;
        }

        public TranslationUnit Visit(Assembly assembly)
        {
            var name = options.LibraryName ?? assembly.GetName().Name;
            unit.FilePath = name;

            foreach (var type in assembly.ExportedTypes)
            {
                var typeInfo = type.GetTypeInfo();
                var decl = Visit(typeInfo);
                var @namespace = VisitNamespace(typeInfo);
                decl.Namespace = @namespace;
                @namespace.Declarations.Add(decl);
            }

            return unit;
        }

        public Namespace VisitNamespace(TypeInfo typeInfo)
        {
            if (string.IsNullOrWhiteSpace(typeInfo.Namespace))
                return unit;

            var namespaces = typeInfo.Namespace.Split('.');

            Namespace currentNamespace = unit;

            foreach (var @namespace in namespaces)
                currentNamespace = currentNamespace.FindCreateNamespace(@namespace);

            return currentNamespace;
        }

        public Declaration Visit(TypeInfo typeInfo)
        {
            if (typeInfo.IsEnum)
                return VisitEnum(typeInfo);
            else if (typeInfo.IsClass || typeInfo.IsInterface || typeInfo.IsValueType)
                return VisitRecord(typeInfo);

            throw new Exception("Could not visit type: " + typeInfo.ToString());
        }
<commit_msg>Deal with duplicated declarations when generating the AST.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using IKVM.Reflection;
using CppSharp.AST;
using CppSharp.AST.Extensions;

namespace MonoManagedToNative.Generators
{
    public class AstGenerator
    {
        public TranslationUnit unit;
        Options options;

        public AstGenerator(Options options)
        {
            unit = new TranslationUnit();
            this.options = options;
        }

        public TranslationUnit Visit(Assembly assembly)
        {
            var name = options.LibraryName ?? assembly.GetName().Name;
            unit.FilePath = name;

            foreach (var type in assembly.ExportedTypes)
            {
                var typeInfo = type.GetTypeInfo();
                Visit(typeInfo);
            }

            return unit;
        }

        public Namespace VisitNamespace(TypeInfo typeInfo)
        {
            if (string.IsNullOrWhiteSpace(typeInfo.Namespace))
                return unit;

            var namespaces = typeInfo.Namespace.Split('.');

            Namespace currentNamespace = unit;

            foreach (var @namespace in namespaces)
                currentNamespace = currentNamespace.FindCreateNamespace(@namespace);

            return currentNamespace;
        }

        public Declaration Visit(TypeInfo typeInfo)
        {
            var @namespace = VisitNamespace(typeInfo);
            var decl = @namespace.Declarations.FirstOrDefault(
                d => d.Name == typeInfo.Name);

            // If we have already processed this declaration, return it.
            if (decl != null)
                return decl;

            if (typeInfo.IsEnum)
                decl = VisitEnum(typeInfo);
            else if (typeInfo.IsClass || typeInfo.IsInterface || typeInfo.IsValueType)
                decl = VisitRecord(typeInfo);
            else
                throw new Exception ("Could not visit type: " + typeInfo.ToString ());

            decl.Namespace = @namespace;
            @namespace.Declarations.Add (decl);

            return decl;
        }

{'fraction_non_alphanumeric': 0.07848615697231394, 'fraction_numerical': 0.0, 'mean_word_length': 1.8371757925072045, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, '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': '1862319', 'n_tokens_mistral': 957, 'n_tokens_neox': 907, 'n_words': 236}