コード例 #1
0
        private ProtoCore.AST.AssociativeAST.VarDeclNode ParseArgumentDeclaration(string parameterName, Type parameterType)
        {
            ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode();
            varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.kMemStack;
            varDeclNode.access    = ProtoCore.DSASM.AccessSpecifier.kPublic;

            ProtoCore.AST.AssociativeAST.IdentifierNode identifierNode = new ProtoCore.AST.AssociativeAST.IdentifierNode
            {
                Value    = parameterName,
                Name     = parameterName,
                datatype = new ProtoCore.Type()
                {
                    Name        = "var",
                    IsIndexable = false,
                    rank        = 0,
                    UID         = (int)ProtoCore.PrimitiveType.kTypeVar
                }
            };
            //Lets emit native DS type object
            ProtoCore.Type argtype = CLRModuleType.GetProtoCoreType(parameterType, Module);

            varDeclNode.NameNode     = identifierNode;
            varDeclNode.ArgumentType = argtype;
            return(varDeclNode);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: CLRDLLModule.cs プロジェクト: whztt07/Dynamo
        /// <summary>
        /// Gets CLRModuleType for given Type. If CLRModuleType instance for the
        /// given type is not found, it creates a new one. If CLRDLLModule is
        /// passed as null, it creates empty CLRModuleType.
        /// </summary>
        /// <param name="module">CLRDLLModule which imports this type</param>
        /// <param name="type">System.Type to be imported in DesignScript</param>
        /// <param name="alias">Alias name, if any. For now its not supported.</param>
        public static CLRModuleType GetInstance(Type type, CLRDLLModule module, string alias)
        {
            CLRModuleType mtype;
            if (!mTypes.TryGetValue(type, out mtype))
            {
                lock (mTypes)
                {
                    if (!mTypes.TryGetValue(type, out mtype))
                    {
                        mtype = new CLRModuleType(type);
                        //Now check that a type with same name is not imported.
                        Type otherType;
                        if (mTypeNames.TryGetValue(mtype.FullName, out otherType))
                            throw new InvalidOperationException(string.Format("Can't import {0}, {1} is already imported as {2}, namespace support needed.", type.FullName, type.Name, otherType.FullName));

                        mTypes.Add(type, mtype);
                        mTypeNames.Add(mtype.FullName, type);
                    }
                }
            }

            if (module != null && mtype.Module == null)
            {
                mtype.Module = module;
                if (type.IsEnum)
                    mtype.ClassNode = mtype.ParseEnumType(type, alias);
                else
                    mtype.ClassNode = mtype.ParseSystemType(type, alias);
            }

            return mtype;
        }
コード例 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        /// <param name="protoCoreType"></param>
        private static void GetProtoCoreType(Type type, ref ProtoCore.Type protoCoreType)
        {
            FFIObjectMarshler marshaler;

            if (type.IsArray)
            {
                Type elemType = type.GetElementType();
                GetProtoCoreType(elemType, ref protoCoreType);
                protoCoreType.rank       += type.GetArrayRank(); //set the rank.
                protoCoreType.IsIndexable = true;
            }
            else if (type.IsInterface && (typeof(ICollection).IsAssignableFrom(type) || typeof(IEnumerable).IsAssignableFrom(type)))
            {
                protoCoreType.rank       += 1;
                protoCoreType.IsIndexable = true;
            }
            else if (type.IsGenericType && (typeof(ICollection).IsAssignableFrom(type) || typeof(IEnumerable).IsAssignableFrom(type)))
            {
                Type[] args  = type.GetGenericArguments();
                int    nArgs = args.Length;
                if (nArgs != 1)
                {
                    protoCoreType.Name = GetTypeName(type);
                    protoCoreType.UID  = (int)ProtoCore.PrimitiveType.kTypePointer;
                    return;
                }
                Type elemType = args[0];
                //TODO: Ideally we shouldn't be calling this method on CLRModuleType,
                //but we want to import this elemType, hence we do this.
                protoCoreType             = CLRModuleType.GetProtoCoreType(elemType, null);
                protoCoreType.rank       += 1;
                protoCoreType.IsIndexable = true;
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                protoCoreType = CLRModuleType.GetProtoCoreType(Nullable.GetUnderlyingType(type), null);
            }
            else if (type == typeof(object))
            {
                protoCoreType = PrimitiveMarshler.CreateType(ProtoCore.PrimitiveType.kTypeVar);
            }
            else if (type == typeof(void))
            {
                protoCoreType = PrimitiveMarshler.CreateType(ProtoCore.PrimitiveType.kTypeVoid);
            }
            else if (protoCoreType.UID == (int)ProtoCore.PrimitiveType.kTypePointer)
            {
                protoCoreType.Name = GetTypeName(type);
            }
            else if (mPrimitiveMarshalers.TryGetValue(type, out marshaler))
            {
                protoCoreType = marshaler.GetMarshaledType(type);
            }
            else
            {
                protoCoreType.Name = GetTypeName(type);
                protoCoreType.UID  = (int)ProtoCore.PrimitiveType.kTypePointer;
            }
        }
コード例 #5
0
        private ProtoCore.AST.AssociativeAST.AssociativeNode ParseMethod(MethodInfo method)
        {
            ProtoCore.Type retype       = CLRModuleType.GetProtoCoreType(method.ReturnType, Module);
            bool           propaccessor = isPropertyAccessor(method);
            bool           isOperator   = isOverloadedOperator(method);

            FFIMethodAttributes mattrs = new FFIMethodAttributes(method);

            if (method.IsStatic &&
                method.DeclaringType == method.ReturnType &&
                !propaccessor &&
                !isOperator)
            {
                //case for named constructor. Must return a pointer type
                if (!Object.Equals(method.ReturnType, CLRType))
                {
                    throw new InvalidOperationException("Unexpected type for constructor {0D28FC00-F8F4-4049-AD1F-BBC34A68073F}");
                }

                retype = ProtoCoreType;
                ConstructorDefinitionNode node = ParsedNamedConstructor(method, method.Name, retype);
                node.MethodAttributes = mattrs;
                return(node);
            }

            //Need to hide property accessor from design script users, prefix with %
            string prefix = (isOperator || propaccessor) ? "%" : "";
            var    func   = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode();

            if (isOperator)
            {
                func.Name = string.Format("{0}{1}", prefix, GetDSOperatorName(method.Name));
            }
            else
            {
                func.Name = string.Format("{0}{1}", prefix, method.Name);
            }
            func.Pattern   = null;
            func.Signature = ParseArgumentSignature(method);

            if ((retype.IsIndexable && mattrs.AllowRankReduction) ||
                (typeof(object).Equals(method.ReturnType)))
            {
                retype.rank = Constants.kArbitraryRank;
            }
            func.ReturnType       = retype;
            func.FunctionBody     = null;
            func.access           = ProtoCore.Compiler.AccessSpecifier.kPublic;
            func.IsDNI            = false;
            func.IsExternLib      = true;
            func.ExternLibName    = Module.Name;
            func.IsStatic         = method.IsStatic;
            func.MethodAttributes = mattrs;

            return(func);
        }
コード例 #6
0
        //this is incomplete todo: implement
        public override List <FFIFunctionPointer> GetFunctionPointers(string className, string name)
        {
            CLRModuleType type = null;

            if (mTypes.TryGetValue(className, out type))
            {
                return(type.GetFunctionPointers(name));
            }

            if (name == ProtoCore.DSDefinitions.Keyword.Dispose)
            {
                List <FFIFunctionPointer> pointers = new List <FFIFunctionPointer>();
                pointers.Add(new DisposeFunctionPointer(this, CLRModuleType.DisposeMethod, CLRModuleType.GetProtoCoreType(CLRModuleType.DisposeMethod.ReturnType, this)));
                return(pointers);
            }

            throw new KeyNotFoundException(string.Format("Function definition for {0}.{1}, not found", className, name));
        }
コード例 #7
0
        public FFIMethodAttributes(MethodInfo method)
        {
            if (method == null)
            {
                throw new ArgumentException("method");
            }

            FFIClassAttributes baseAttributes = null;
            Type type = method.DeclaringType;

            if (!CLRModuleType.TryGetTypeAttributes(type, out baseAttributes))
            {
                baseAttributes = new FFIClassAttributes(type);
                CLRModuleType.SetTypeAttributes(type, baseAttributes);
            }

            if (null != baseAttributes)
            {
                HiddenInLibrary = baseAttributes.HiddenInLibrary;
            }

            attributes = method.GetCustomAttributes(false).Cast <Attribute>().ToArray();
            foreach (var attr in attributes)
            {
                if (attr is AllowRankReductionAttribute)
                {
                    AllowRankReduction = true;
                }
                else if (attr is RuntimeRequirementAttribute)
                {
                    RequireTracing = (attr as RuntimeRequirementAttribute).RequireTracing;
                }
                else if (attr is MultiReturnAttribute)
                {
                    var multiReturnAttr = (attr as MultiReturnAttribute);
                    returnKeys = multiReturnAttr.ReturnKeys.ToList();
                }
                else if (attr is IsVisibleInDynamoLibraryAttribute)
                {
                    var visibleInLibraryAttr = attr as IsVisibleInDynamoLibraryAttribute;
                    HiddenInLibrary = (visibleInLibraryAttr.Visible == false);
                }
            }
        }
コード例 #8
0
        private ProtoCore.AST.AssociativeAST.VarDeclNode ParseArgumentDeclaration(string parameterName, Type parameterType)
        {
            ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode();
            varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.kMemStack;
            varDeclNode.access    = ProtoCore.Compiler.AccessSpecifier.kPublic;

            ProtoCore.AST.AssociativeAST.IdentifierNode identifierNode = new ProtoCore.AST.AssociativeAST.IdentifierNode
            {
                Value    = parameterName,
                Name     = parameterName,
                datatype = ProtoCore.TypeSystem.BuildPrimitiveTypeObject(ProtoCore.PrimitiveType.kTypeVar, 0)
            };
            //Lets emit native DS type object
            ProtoCore.Type argtype = CLRModuleType.GetProtoCoreType(parameterType, Module);

            varDeclNode.NameNode     = identifierNode;
            varDeclNode.ArgumentType = argtype;
            return(varDeclNode);
        }
コード例 #9
0
        private ProtoCore.AST.AssociativeAST.VarDeclNode ParseFieldDeclaration(FieldInfo f)
        {
            if (null == f || !IsBrowsable(f))
            {
                return(null);
            }

            ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = ParseArgumentDeclaration(f.Name, f.FieldType);
            //TODO: temporary limitation, can't have variable name matching with class name.
            if (null != CLRModuleType.GetImportedType(f.Name))
            {
                return(null);
            }
            if (null != varDeclNode)
            {
                varDeclNode.IsStatic = f.IsStatic;
            }
            return(varDeclNode);
        }
コード例 #10
0
        private ProtoCore.AST.AssociativeAST.FunctionDefinitionNode ParseFieldAccessor(FieldInfo f)
        {
            if (null == f || !IsBrowsable(f))
            {
                return(null);
            }

            ProtoCore.AST.AssociativeAST.FunctionDefinitionNode func = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode();
            func.Name          = string.Format("%get_{0}", f.Name);
            func.Pattern       = null;
            func.Singnature    = new ProtoCore.AST.AssociativeAST.ArgumentSignatureNode();
            func.ReturnType    = CLRModuleType.GetProtoCoreType(f.FieldType, Module);
            func.FunctionBody  = null;
            func.access        = ProtoCore.DSASM.AccessSpecifier.kPublic;
            func.IsDNI         = false;
            func.IsExternLib   = true;
            func.ExternLibName = Module.Name;
            func.IsStatic      = f.IsStatic;

            return(func);
        }
コード例 #11
0
        /// <summary>
        /// Gets CLRModuleType for given Type. If CLRModuleType instance for the
        /// given type is not found, it creates a new one. If CLRDLLModule is
        /// passed as null, it creates empty CLRModuleType.
        /// </summary>
        /// <param name="module">CLRDLLModule which imports this type</param>
        /// <param name="type">System.Type to be imported in DesignScript</param>
        /// <param name="alias">Alias name, if any. For now its not supported.</param>
        public static CLRModuleType GetInstance(Type type, CLRDLLModule module, string alias)
        {
            CLRModuleType mtype;

            if (!mTypes.TryGetValue(type, out mtype))
            {
                lock (mTypes)
                {
                    if (!mTypes.TryGetValue(type, out mtype))
                    {
                        mtype = new CLRModuleType(type);
                        //Now check that a type with same name is not imported.
                        Type otherType;
                        if (mTypeNames.TryGetValue(mtype.ClassName, out otherType))
                        {
                            throw new InvalidOperationException(string.Format("Can't import {0}, {1} is already imported as {2}, namespace support needed.", type.FullName, type.Name, otherType.FullName));
                        }

                        mTypes.Add(type, mtype);
                        mTypeNames.Add(mtype.ClassName, type);
                    }
                }
            }

            if (module != null && mtype.Module == null)
            {
                mtype.Module = module;
                if (type.IsEnum)
                {
                    mtype.ClassNode = mtype.ParseEnumType(type, alias);
                }
                else
                {
                    mtype.ClassNode = mtype.ParseSystemType(type, alias);
                }
            }

            return(mtype);
        }
コード例 #12
0
        private ProtoCore.AST.AssociativeAST.AssociativeNode ParseMethod(MethodInfo method)
        {
            ProtoCore.Type retype       = CLRModuleType.GetProtoCoreType(method.ReturnType, Module);
            bool           propaccessor = isPropertyAccessor(method);

            if (method.IsStatic && method.DeclaringType == method.ReturnType && !propaccessor)
            {
                //case for named constructor. Must return a pointer type
                if (!Object.Equals(method.ReturnType, CLRType))
                {
                    throw new InvalidOperationException("Unexpected type for constructor {0D28FC00-F8F4-4049-AD1F-BBC34A68073F}");
                }

                retype = ProtoCoreType;
                return(ParsedNamedConstructor(method, method.Name, retype));
            }

            //Need to hide property accessor from design script users, prefix with %
            string prefix = propaccessor ? "%" : "";

            ProtoCore.AST.AssociativeAST.FunctionDefinitionNode func = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode();
            func.Name       = string.Format("{0}{1}", prefix, method.Name);
            func.Pattern    = null;
            func.Singnature = ParseArgumentSignature(method);
            if (retype.IsIndexable && AllowsRankReduction(method))
            {
                retype.rank = -1;
            }
            func.ReturnType    = retype;
            func.FunctionBody  = null;
            func.access        = ProtoCore.DSASM.AccessSpecifier.kPublic;
            func.IsDNI         = false;
            func.IsExternLib   = true;
            func.ExternLibName = Module.Name;
            func.IsStatic      = method.IsStatic;

            return(func);
        }
コード例 #13
0
 private ProtoCore.Type[] GetArgumentTypes(FFIMemberInfo member)
 {
     return(member.GetParameters().Select(
                pi => CLRModuleType.GetProtoCoreType(pi.ParameterType, Module)
                ).ToArray());
 }
コード例 #14
0
        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);
        }
コード例 #15
0
ファイル: CLRDLLModule.cs プロジェクト: whztt07/Dynamo
 private static bool isEmpty(CLRModuleType type)
 {
     return null == type.Module;
 }
コード例 #16
0
 private ProtoCore.Type[] GetArgumentTypes()
 {
     return(ReflectionInfo.GetParameters().Select(
                pi => CLRModuleType.GetProtoCoreType(pi.Info.ParameterType, Module)).ToArray());
 }
コード例 #17
0
        public override CodeBlockNode ImportCodeBlock(string typeName, string alias, CodeBlockNode refNode)
        {
            Type[] types   = GetTypes(typeName);
            Type   exttype = typeof(IExtensionApplication);

#if PARALLEL
            System.Threading.Tasks.Parallel.ForEach(types, type =>
            {
                //For now there is no support for generic type.
                if (!type.IsGenericType && type.IsPublic && !exttype.IsAssignableFrom(type) && CLRModuleType.IsBrowsable(type))
                {
                    CLRModuleType importedType = CLRModuleType.GetInstance(type, this, alias);
                }
            });
#else
            foreach (var type in types)
            {
                //For now there is no support for generic type.
                if (!type.IsGenericType && type.IsPublic && !exttype.IsAssignableFrom(type) && CLRModuleType.IsBrowsable(type))
                {
                    CLRModuleType importedType = CLRModuleType.GetInstance(type, this, alias);
                    Type[]        nestedTypes  = type.GetNestedTypes();
                    if (null != nestedTypes && nestedTypes.Length > 0)
                    {
                        foreach (var item in nestedTypes)
                        {
                            importedType = CLRModuleType.GetInstance(item, this, string.Empty);
                        }
                    }
                }
            }
#endif

            CodeBlockNode node = new CodeBlockNode();
            //Get all the types available on this module.
            //TODO: need to optimize for performance.
            List <CLRModuleType> moduleTypes = CLRModuleType.GetTypes((CLRModuleType mtype) => { return(mtype.Module == this); });
            foreach (var item in moduleTypes)
            {
                node.Body.Add(item.ClassNode);
                mTypes[item.ClassName] = item; //update Type dictionary.
            }

            //Also add all the available empty class nodes.
            List <CLRModuleType> emptyTypes = CLRModuleType.GetEmptyTypes();
            foreach (var item in emptyTypes)
            {
                item.EnsureDisposeMethod(this);
                node.Body.Add(item.ClassNode);
            }

            string ffidump = Environment.GetEnvironmentVariable("FFIDUMP");
            if (string.Compare(ffidump, "1") == 0)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                foreach (var item in node.Body)
                {
                    sb.Append(item.ToString());
                    sb.AppendLine();
                }
                using (System.IO.FileStream fs = new System.IO.FileStream(string.Format("{0}.ds", this.Name), System.IO.FileMode.Create))
                {
                    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(sb.ToString());
                    fs.Write(bytes, 0, bytes.Length);
                }
            }

            return(node);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
 private static bool isEmpty(CLRModuleType type)
 {
     return(null == type.Module);
 }