internal ImportNode Compile(ImportModuleHandler importer) { ImportNode impNode = null; foreach (var item in mData) { SortedSet <Type> types = GetTypesForImport(item.Value.Data); foreach (var type in types) { if (CLRObjectMarshler.IsMarshaledAsNativeType(type)) { continue; } ImportNode node = importer.Import(type.Assembly.Location, type.FullName, ""); if (impNode != null && node != null) { impNode.CodeNode.Body.AddRange(node.CodeNode.Body); } else { impNode = node; } } if (impNode == null) { impNode = new ImportNode() { ModuleName = "ExternalContext", CodeNode = new ProtoCore.AST.AssociativeAST.CodeBlockNode() } } ; impNode.CodeNode.Body.Add(ContextDataMethodCallNode(item.Value)); } return(impNode); }
//recursively get all the types this object represents. private SortedSet <Type> GetTypesForImport(Object value) { Type valueType = value.GetType(); SortedSet <Type> set = new SortedSet <Type>(); IEnumerable collection = value as IEnumerable; if (collection != null) { foreach (var item in collection) { set.UnionWith(GetTypesForImport(item)); } } else if (valueType.IsGenericType) { Type generictype = valueType.GetGenericTypeDefinition(); set.UnionWith(generictype.GetGenericArguments()); //also add the valueType to be used as raw data set.Add(valueType); } else { set.Add(CLRObjectMarshler.GetPublicType(valueType)); } return(set); }
public static ProtoCore.Type GetProtoCoreType(Type type, CLRDLLModule module) { ProtoCore.Type protoCoreType; if (mTypeMaps.TryGetValue(type, out protoCoreType)) { return(protoCoreType); } if (type == typeof(object) || !CLRObjectMarshler.IsMarshaledAsNativeType(type)) { if (type.IsEnum) { protoCoreType = CLRModuleType.GetInstance(type, module, string.Empty).ProtoCoreType; } else { protoCoreType = CLRModuleType.GetInstance(type, null, string.Empty).ProtoCoreType; } } else { protoCoreType = CLRObjectMarshler.GetProtoCoreType(type); } lock (mTypeMaps) { mTypeMaps[type] = protoCoreType; } return(protoCoreType); }
/// <summary> /// Private constructor to create empty CLRModuleType. /// </summary> /// <param name="type">System.Type</param> private CLRModuleType(Type type) { CLRType = type; string classname = CLRObjectMarshler.GetTypeName(type); ClassNode = CreateEmptyClassNode(classname); }
/// <summary> /// Dispose event handler. /// </summary> /// <param name="sender">Core object being disposed.</param> void core_Dispose(ProtoCore.Core sender) { CLRObjectMarshler marshaller = null; if (!mObjectMarshlers.TryGetValue(sender, out marshaller)) { throw new KeyNotFoundException(); } mObjectMarshlers.Remove(sender); //Detach from core. sender.Dispose -= core_Dispose; //Dispose all disposable CLR objects. foreach (var item in DSObjectMap) { IDisposable disposable = item.Value as IDisposable; sender.FFIPropertyChangedMonitor.RemoveFFIObject(item.Value); if (null != disposable) { disposable.Dispose(); } } //Clear the maps. DSObjectMap.Clear(); CLRObjectMap.Clear(); }
private Type GetConfigurationType() { Type[] types = GetTypes(string.Empty); foreach (var item in types) { if ("Configuration" == CLRObjectMarshler.GetCategory(item)) { return(item); } } return(null); }
private ClassDeclNode ParseEnumType(Type type, string alias) { //TODO: For now Enum can't be suppressed. Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!"); string classname = alias; if (classname == null | classname == string.Empty) { classname = CLRObjectMarshler.GetTypeName(type); } ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname); classnode.ExternLibName = Module.Name; classnode.className = classname; classnode.Name = type.Name; FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (f.FieldType != type) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } variable.IsStatic = true; classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { func.IsStatic = true; RegisterFunctionPointer(func.Name, f, null, func.ReturnType); classnode.funclist.Add(func); } } //Get all the attributes on this type and set it to the classnode. FFIClassAttributes cattrs = new FFIClassAttributes(type); classnode.ClassAttributes = cattrs; SetTypeAttributes(type, cattrs); return(classnode); }
/// <summary> /// Gets instance of the CLRObjectMarshler for a given core. If marshler /// is not already created, it creates a new one. /// </summary> /// <param name="core">Core object.</param> /// <returns>CLRObjectMarshler</returns> public static CLRObjectMarshler GetInstance(ProtoCore.Core core) { CLRObjectMarshler marshaller = null; if (!mObjectMarshlers.TryGetValue(core, out marshaller)) { IDisposable[] disposables = null; lock (syncroot) { if (mObjectMarshlers.TryGetValue(core, out marshaller)) { return(marshaller); } marshaller = new CLRObjectMarshler(core); object value; if (core.Configurations.TryGetValue(ConfigurationKeys.GeometryXmlProperties, out value)) { marshaller.DumpXmlProperties = value == null ? false : (bool)value; } else { marshaller.DumpXmlProperties = false; } mObjectMarshlers[core] = marshaller; disposables = mPendingDisposables.ToArray(); mPendingDisposables.Clear(); } if (null != disposables) { //Dispose pending disposals foreach (IDisposable obj in disposables) { if (null != obj) { obj.Dispose(); } } } } return(marshaller); }
private ClassDeclNode ParseEnumType(Type type, string alias) { Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!"); string classname = alias; if (classname == null | classname == string.Empty) { classname = CLRObjectMarshler.GetTypeName(type); } ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname); classnode.ExternLibName = Module.Name; classnode.className = classname; classnode.Name = type.Name; FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (f.FieldType != type) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } variable.IsStatic = true; classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { func.IsStatic = true; RegisterFunctionPointer(func.Name, f, func.ReturnType); classnode.funclist.Add(func); } } return(classnode); }
private ClassDeclNode ParseSystemType(Type type, string alias) { Validity.Assert(IsBrowsable(type), "Non browsable type is being imported!!"); string classname = alias; if (classname == null | classname == string.Empty) { classname = CLRObjectMarshler.GetTypeName(type); } ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname); classnode.ExternLibName = Module.Name; classnode.className = classname; classnode.Name = type.Name; Type baseType = GetBaseType(type); if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType)) { string baseTypeName = CLRObjectMarshler.GetTypeName(baseType); classnode.superClass = new List <string>(); classnode.superClass.Add(baseTypeName); //Make sure that base class is imported properly. CLRModuleType.GetInstance(baseType, Module, string.Empty); } ConstructorInfo[] ctors = type.GetConstructors(); foreach (var c in ctors) { if (c.IsPublic && !c.IsGenericMethod && IsBrowsable(c)) { ConstructorDefinitionNode node = ParseConstructor(c, type); classnode.funclist.Add(node); RegisterFunctionPointer(node.Name, c, node.ReturnType); } } BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; bool isDerivedClass = classnode.superClass != null; if (isDerivedClass) //has base class { flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods. } bool isDisposable = typeof(IDisposable).IsAssignableFrom(type); MethodInfo[] methods = type.GetMethods(flags); bool hasDisposeMethod = false; foreach (var m in methods) { if (!IsBrowsable(m)) { continue; } //Don't include overriden methods or generic methods if (m.IsPublic && !m.IsGenericMethod && (m == m.GetBaseDefinition() || (m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(Object)))) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m)) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } } if (!hasDisposeMethod && !isDisposable) { AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod); classnode.funclist.Add(node); } FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (!IsBrowsable(f)) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { RegisterFunctionPointer(func.Name, f, func.ReturnType); } } PropertyInfo[] properties = type.GetProperties(flags); foreach (var p in properties) { AssociativeNode node = ParseProperty(p); if (null != node) { classnode.varlist.Add(node); } } return(classnode); }
public override FFIObjectMarshler GetMarshaller(ProtoCore.Core core) { return(CLRObjectMarshler.GetInstance(core)); }
private ClassDeclNode ParseSystemType(Type type, string alias) { Validity.Assert(!SupressesImport(type), "Supressed type is being imported!!"); string classname = alias; if (classname == null | classname == string.Empty) { classname = CLRObjectMarshler.GetTypeName(type); } ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname); classnode.ExternLibName = Module.Name; classnode.className = classname; classnode.Name = type.Name; Type baseType = GetBaseType(type); if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType)) { string baseTypeName = CLRObjectMarshler.GetTypeName(baseType); classnode.superClass = new List <string>(); classnode.superClass.Add(baseTypeName); //Make sure that base class is imported properly. CLRModuleType.GetInstance(baseType, Module, string.Empty); } // There is no static class in runtime. static class is simply // marked as sealed and abstract. bool isStaticClass = type.IsSealed && type.IsAbstract; if (!isStaticClass) { // If all methods are static, it doesn't make sense to expose // constructor. ConstructorInfo[] ctors = type.GetConstructors(); foreach (var c in ctors) { if (c.IsPublic && !c.IsGenericMethod && !SupressesImport(c)) { ConstructorDefinitionNode node = ParseConstructor(c, type); classnode.funclist.Add(node); List <ProtoCore.Type> argTypes = GetArgumentTypes(node); RegisterFunctionPointer(node.Name, c, argTypes, node.ReturnType); } } } BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; bool isDerivedClass = (classnode.superClass != null) && classnode.superClass.Count > 0; if (isDerivedClass) //has base class { flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods. } bool isDisposable = typeof(IDisposable).IsAssignableFrom(type); MethodInfo[] methods = type.GetMethods(flags); bool hasDisposeMethod = false; foreach (var m in methods) { if (SupressesImport(m)) { continue; } if (isStaticClass && m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(object)) { continue; } //Don't include overriden methods or generic methods if (m.IsPublic && !m.IsGenericMethod && m == m.GetBaseDefinition()) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m)) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } } if (!hasDisposeMethod && !isDisposable) { AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod); classnode.funclist.Add(node); } FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (SupressesImport(f)) { continue; } //Supress if defined in super-type if (isDerivedClass) { FieldInfo[] supertypeFields = baseType.GetFields(); if (supertypeFields.Any(superF => superF.Name == f.Name)) { continue; } } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { RegisterFunctionPointer(func.Name, f, null, func.ReturnType); } } PropertyInfo[] properties = type.GetProperties(flags); foreach (var p in properties) { AssociativeNode node = ParseProperty(p); if (null != node) { classnode.varlist.Add(node); } } FFIClassAttributes cattrs = new FFIClassAttributes(type); classnode.ClassAttributes = cattrs; SetTypeAttributes(type, cattrs); return(classnode); }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <returns></returns> public override ProtoCore.Type GetMarshaledType(Type type) { return(CLRObjectMarshler.GetProtoCoreType(type)); }