private AssociativeNode ParseAndRegisterFunctionPointer(bool isDisposable, ref bool hasDisposeMethod, MethodInfo m)
        {
            AssociativeNode        node = ParseMethod(m);
            FunctionDefinitionNode func = node as FunctionDefinitionNode;

            if (func != null)
            {
                //Rename the Dispose method to _Dispose, as required by DS.
                if (isDisposable && isDisposeMethod(m))
                {
                    hasDisposeMethod     = true;
                    func.Name            = ProtoCore.DSDefinitions.Keyword.Dispose;
                    func.IsStatic        = false;
                    func.IsAutoGenerated = true;
                }

                RegisterFunctionPointer(func.Name, m, func.ReturnType);
            }
            else if (node is ConstructorDefinitionNode)
            {
                ConstructorDefinitionNode constr = node as ConstructorDefinitionNode;
                RegisterFunctionPointer(constr.Name, m, constr.ReturnType);
            }
            return(node);
        }
Beispiel #2
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);
        }
Beispiel #3
0
        private static FunctionDescriptorParams FunctionParamsFromConstructor(ConstructorDefinitionNode constructorDefinitionNode, string asmLoc, string className)
        {
            var functionParams = new FunctionDescriptorParams
            {
                Assembly     = asmLoc,
                ClassName    = className,
                FunctionName = constructorDefinitionNode.Name,
                ReturnType   = constructorDefinitionNode.ReturnType,
                Parameters   = BuildParameters(constructorDefinitionNode.Signature),
                FunctionType = FunctionType.Constructor,
            };

            return(functionParams);
        }
Beispiel #4
0
 public virtual void VisitConstructorDefinitionNode(ConstructorDefinitionNode node)
 {
     DefaultVisit(node);
 }
        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);
        }
Beispiel #6
0
 public virtual TAssociative VisitConstructorDefinitionNode(ConstructorDefinitionNode node)
 {
     return(VisitAssociativeNode(node));
 }
 public virtual bool VisitConstructorDefinitionNode(ConstructorDefinitionNode node)
 {
     return(DefaultVisit(node));
 }
Beispiel #8
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);
        }