mirror of https://github.com/mono/CppSharp.git
				
				
			
				 2 changed files with 190 additions and 175 deletions
			
			
		@ -0,0 +1,190 @@
				@@ -0,0 +1,190 @@
					 | 
				
			||||
using System; | 
				
			||||
using System.Collections.Generic; | 
				
			||||
using CppSharp.AST; | 
				
			||||
using CppSharp.AST.Extensions; | 
				
			||||
using CppSharp.Generators; | 
				
			||||
using CppSharp.Generators.AST; | 
				
			||||
using CppSharp.Generators.CLI; | 
				
			||||
using CppSharp.Generators.CSharp; | 
				
			||||
using Attribute = System.Attribute; | 
				
			||||
using Type = CppSharp.AST.Type; | 
				
			||||
 | 
				
			||||
namespace CppSharp.Types | 
				
			||||
{ | 
				
			||||
    public class TypeMapDatabase : ITypeMapDatabase | 
				
			||||
    { | 
				
			||||
        public IDictionary<string, System.Type> TypeMaps { get; set; } | 
				
			||||
 | 
				
			||||
        public TypeMapDatabase() | 
				
			||||
        { | 
				
			||||
            TypeMaps = new Dictionary<string, System.Type>(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public void SetupTypeMaps(GeneratorKind generatorKind) | 
				
			||||
        { | 
				
			||||
            var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); | 
				
			||||
 | 
				
			||||
            foreach (var assembly in loadedAssemblies) | 
				
			||||
            { | 
				
			||||
                try | 
				
			||||
                { | 
				
			||||
                    var types = assembly.FindDerivedTypes(typeof(TypeMap)); | 
				
			||||
                    SetupTypeMaps(types, generatorKind); | 
				
			||||
                } | 
				
			||||
                catch (System.Reflection.ReflectionTypeLoadException ex) | 
				
			||||
                { | 
				
			||||
                    Diagnostics.Error("Error loading type maps from assembly '{0}': {1}", | 
				
			||||
                        assembly.GetName().Name, ex.Message); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        private void SetupTypeMaps(IEnumerable<System.Type> types, GeneratorKind generatorKind) | 
				
			||||
        { | 
				
			||||
            foreach (var typeMap in types) | 
				
			||||
            { | 
				
			||||
                var attrs = typeMap.GetCustomAttributes(typeof(TypeMapAttribute), true); | 
				
			||||
                foreach (TypeMapAttribute attr in attrs) | 
				
			||||
                { | 
				
			||||
                    if (attr.GeneratorKind == 0 || attr.GeneratorKind == generatorKind) | 
				
			||||
                    { | 
				
			||||
                        TypeMaps[attr.Type] = typeMap; | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public bool FindTypeMap(Declaration decl, Type type, out TypeMap typeMap) | 
				
			||||
        { | 
				
			||||
            // We try to find type maps from the most qualified to less qualified
 | 
				
			||||
            // types. Example: '::std::vector', 'std::vector' and 'vector'
 | 
				
			||||
 | 
				
			||||
            var typePrinter = new CppTypePrinter { PrintLogicalNames = true }; | 
				
			||||
 | 
				
			||||
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            typePrinter.PrintScopeKind = TypePrintScopeKind.Qualified; | 
				
			||||
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            typePrinter.ResolveTypedefs = true; | 
				
			||||
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
            typePrinter.ResolveTypedefs = false; | 
				
			||||
 | 
				
			||||
            typePrinter.PrintScopeKind = TypePrintScopeKind.Local; | 
				
			||||
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            var specialization = decl as ClassTemplateSpecialization; | 
				
			||||
            if (specialization != null && | 
				
			||||
                FindTypeMap(specialization.TemplatedDecl.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            var typedef = decl as TypedefDecl; | 
				
			||||
            return typedef != null && FindTypeMap(typedef.Type, out typeMap); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public bool FindTypeMap(Type type, out TypeMap typeMap) | 
				
			||||
        { | 
				
			||||
            var typePrinter = new CppTypePrinter | 
				
			||||
            { | 
				
			||||
                PrintTypeQualifiers = false, | 
				
			||||
                PrintTypeModifiers = false, | 
				
			||||
                PrintLogicalNames = true | 
				
			||||
            }; | 
				
			||||
 | 
				
			||||
            var template = type as TemplateSpecializationType; | 
				
			||||
            if (template != null) | 
				
			||||
            { | 
				
			||||
                var specialization = template.GetClassTemplateSpecialization(); | 
				
			||||
                if (specialization != null && FindTypeMap(specialization, type, out typeMap)) | 
				
			||||
                    return true; | 
				
			||||
                if (template.Template.TemplatedDecl != null) | 
				
			||||
                    return FindTypeMap(template.Template.TemplatedDecl, type, | 
				
			||||
                        out typeMap); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (FindTypeMap(type.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (FindTypeMap(type.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            typePrinter.PrintScopeKind = TypePrintScopeKind.Qualified; | 
				
			||||
            if (FindTypeMap(type.Visit(typePrinter), out typeMap)) | 
				
			||||
            { | 
				
			||||
                typeMap.Type = type; | 
				
			||||
                return true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            var typedef = type as TypedefType; | 
				
			||||
            return typedef != null && FindTypeMap(typedef.Declaration, type, out typeMap); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public bool FindTypeMap(Declaration decl, out TypeMap typeMap) | 
				
			||||
        { | 
				
			||||
            return FindTypeMap(decl, null, out typeMap); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public bool FindTypeMapRecursive(Type type, out TypeMap typeMap) | 
				
			||||
        { | 
				
			||||
            while (true) | 
				
			||||
            { | 
				
			||||
                if (FindTypeMap(type, out typeMap)) | 
				
			||||
                    return true; | 
				
			||||
 | 
				
			||||
                var desugaredType = type.Desugar(); | 
				
			||||
                if (desugaredType == type) | 
				
			||||
                    return false; | 
				
			||||
 | 
				
			||||
                type = desugaredType; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        public bool FindTypeMap(string name, out TypeMap typeMap) | 
				
			||||
        { | 
				
			||||
            if (string.IsNullOrWhiteSpace(name)) | 
				
			||||
            { | 
				
			||||
                typeMap = null; | 
				
			||||
                return false; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            System.Type type; | 
				
			||||
            TypeMaps.TryGetValue(name, out type); | 
				
			||||
 | 
				
			||||
            if (type == null) | 
				
			||||
            { | 
				
			||||
                typeMap = null; | 
				
			||||
                return false; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            typeMap = (TypeMap)Activator.CreateInstance(type); | 
				
			||||
            typeMap.TypeMapDatabase = this; | 
				
			||||
 | 
				
			||||
            return true; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue