Пример #1
0
        public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generatorContext, CodeTypeMemberCollection members)
        {
            string className = "AIDX_" + Guid.NewGuid().ToString("N");
            string name      = table.Get("name").String;
            bool   setter    = table.Get("setter").Boolean;

            CodeTypeDeclaration classCode = new CodeTypeDeclaration(className);

            classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed;

            classCode.BaseTypes.Add(typeof(ArrayMemberDescriptor));

            CodeConstructor ctor = new CodeConstructor();

            ctor.Attributes = MemberAttributes.Assembly;
            classCode.Members.Add(ctor);

            ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(name));
            ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(setter));

            DynValue vparams = table.Get("params");

            if (vparams.Type == DataType.Table)
            {
                List <HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(vparams.Table);

                ctor.BaseConstructorArgs.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor), paramDescs.Select(e => e.Expression).ToArray()));
            }

            members.Add(classCode);
            return(new CodeExpression[] { new CodeObjectCreateExpression(className) });
        }
Пример #2
0
        public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members)
        {
            bool   isArray    = table.Get("arraytype").IsNotNil();
            string memberName = table.Get("name").String;

            // Ignore arrays weird special members
            if (isArray)
            {
                if ((memberName == "Get") || (memberName == "Set") || (memberName == "Address"))
                {
                    return(null);
                }
            }

            // Create the descriptor class
            string className = m_Prefix + "_" + Guid.NewGuid().ToString("N");

            CodeTypeDeclaration classCode = new CodeTypeDeclaration(className);

            classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed;
            classCode.BaseTypes.Add(typeof(HardwiredMethodMemberDescriptor));

            // Create the class constructor
            CodeConstructor ctor = new CodeConstructor();

            ctor.Attributes = MemberAttributes.Assembly;
            classCode.Members.Add(ctor);

            // Create the parameters
            List <HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(table.Get("params").Table);

            int paramNum    = paramDescs.Count;
            int optionalNum = paramDescs.Where(p => p.HasDefaultValue).Count();

            // Add initialize call to ctor
            List <CodeExpression> initParams = new List <CodeExpression>();

            initParams.Add(new CodePrimitiveExpression(memberName));
            initParams.Add(new CodePrimitiveExpression(table.Get("static").Boolean || table.Get("ctor").Boolean));

            initParams.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor),
                                                         paramDescs.Select(e => e.Expression).ToArray()));

            initParams.Add(new CodePrimitiveExpression(table.Get("extension").Boolean));

            ctor.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Initialize", initParams.ToArray()));


            // Create the Invoke method : protected override object Invoke(Script script, object obj, object[] pars, int argscount);

            CodeMemberMethod m = new CodeMemberMethod();

            m.Name       = "Invoke";
            m.Attributes = MemberAttributes.Override | MemberAttributes.Family;
            m.ReturnType = new CodeTypeReference(typeof(object));
            m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script"));
            m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj"));
            m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "pars"));
            m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "argscount"));

            // get some meta about the method
            bool isVoid      = table.Get("ret").String == "System.Void";
            bool isCtor      = table.Get("ctor").Boolean;
            bool isStatic    = table.Get("static").Boolean;
            bool isExtension = table.Get("extension").Boolean;
            bool specialName = table.Get("special").Boolean;

            string declType   = table.Get("decltype").String;
            var    paramArray = new CodeVariableReferenceExpression("pars");
            var    paramThis  = isStatic
                                ? (CodeExpression)(new CodeTypeReferenceExpression(declType))
                                : (CodeExpression)(new CodeCastExpression(declType, new CodeVariableReferenceExpression("obj")));

            // Build a list of arguments to the call
            int refparCount = 0;
            List <CodeExpression> paramExps = new List <CodeExpression>();

            for (int i = 0; i < paramDescs.Count; i++)
            {
                var P = paramDescs[i];

                CodeExpression paramExp = new CodeCastExpression(paramDescs[i].ParamType, new CodeArrayIndexerExpression(paramArray, new CodePrimitiveExpression(i)));

                if (P.IsOut)
                {
                    string varName = GenerateRefParamVariable(refparCount++);
                    var    vd      = new CodeVariableDeclarationStatement(P.ParamType, varName);
                    m.Statements.Add(vd);
                    paramExp = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(varName));
                }
                else if (P.IsRef)
                {
                    string varName = GenerateRefParamVariable(refparCount++);
                    var    vd      = new CodeVariableDeclarationStatement(P.ParamType, varName, paramExp);
                    m.Statements.Add(vd);
                    paramExp = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(varName));
                }

                paramExps.Add(paramExp);
            }



            // build a list of possible dispatching to default params
            List <CodeExpression[]> calls = new List <CodeExpression[]>();
            var paramArgsCount            = new CodeVariableReferenceExpression("argscount");

            for (int callidx = paramNum - optionalNum; callidx <= paramNum; callidx++)
            {
                List <CodeExpression> pars = new List <CodeExpression>();

                // Build the array of parameters expressions
                for (int i = 0; i < callidx; i++)
                {
                    pars.Add(paramExps[i]);
                }

                calls.Add(pars.ToArray());
            }


            // foreach "overload" of default pars, dispatch a call
            for (int i = 0; i < calls.Count - 1; i++)
            {
                int argcnt = calls[i].Length;

                CodeExpression condition = new CodeBinaryOperatorExpression(paramArgsCount,
                                                                            CodeBinaryOperatorType.LessThanOrEqual, new CodePrimitiveExpression(argcnt));

                var ifs = new CodeConditionStatement(condition, GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[i], paramThis, declType, specialName, refparCount).OfType <CodeStatement>().ToArray());

                m.Statements.Add(ifs);
            }

            m.Statements.AddRange(GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[calls.Count - 1], paramThis, declType, specialName, refparCount));


            // close
            classCode.Members.Add(m);
            members.Add(classCode);
            return(new CodeExpression[] { new CodeObjectCreateExpression(className) });
        }