Пример #1
0
        public async System.Threading.Tasks.Task GCode_CodeDom_GenerateMethodCode(CodeTypeDeclaration codeClass, LinkPinControl element, GenerateCodeContext_Class context, MethodGenerateData data)
        {
            var csParam = CSParam as MethodOverrideConstructParam;

            Type[] paramTypes = new Type[csParam.MethodInfo.Params.Count];
            for (int i = 0; i < paramTypes.Length; i++)
            {
                switch (csParam.MethodInfo.Params[i].FieldDirection)
                {
                case FieldDirection.In:
                    if (csParam.MethodInfo.Params[i].IsParamsArray)
                    {
                        throw new InvalidOperationException("未实现");
                    }
                    else
                    {
                        paramTypes[i] = csParam.MethodInfo.Params[i].ParameterType;
                    }
                    break;

                case FieldDirection.Out:
                case FieldDirection.Ref:
                    if (csParam.MethodInfo.Params[i].IsParamsArray)
                    {
                        throw new InvalidOperationException("未实现");
                    }
                    else
                    {
                        paramTypes[i] = csParam.MethodInfo.Params[i].ParameterType.MakeByRefType();
                    }
                    break;
                }
            }
            EngineNS.Editor.MacrossMemberAttribute.enMacrossType macrossType = EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Overrideable;
            if (csParam.MethodInfo.IsFromMacross)
            {
                macrossType |= EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Callable;
            }
            else
            {
                var methodInfo = csParam.MethodInfo.ParentClassType.GetMethod(csParam.MethodInfo.MethodName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static, null, paramTypes, null);
                var atts       = methodInfo.GetCustomAttributes(typeof(EngineNS.Editor.MacrossMemberAttribute), false);
                if (atts.Length > 0)
                {
                    var macrossMemberAtt = atts[0] as EngineNS.Editor.MacrossMemberAttribute;
                    macrossType = macrossMemberAtt.MacrossType;
                }
            }

            if (element == null || element == mCtrlMethodPin_Next)
            {
                var methodCode = new CodeGenerateSystem.CodeDom.CodeMemberMethod();
                methodCode.Attributes = MemberAttributes.Override;
                //if (mMethodInfo != null)
                //{
                if (csParam.MethodInfo.IsFamily)
                {
                    methodCode.Attributes |= MemberAttributes.Family;
                }
                if (csParam.MethodInfo.IsFamilyAndAssembly)
                {
                    methodCode.Attributes |= MemberAttributes.FamilyAndAssembly;
                }
                if (csParam.MethodInfo.IsFamilyOrAssembly)
                {
                    methodCode.Attributes |= MemberAttributes.FamilyOrAssembly;
                }
                if (csParam.MethodInfo.IsPublic)
                {
                    methodCode.Attributes |= MemberAttributes.Public;
                }
                //}
                //else
                //    methodCode.Attributes |= MemberAttributes.Public;
                methodCode.Name = NodeName;

                var mcType = EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Unknow;
                if (csParam.MethodInfo.MC_Callable)
                {
                    mcType = mcType | EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Callable;
                }
                if (csParam.MethodInfo.MC_Overrideable)
                {
                    mcType = mcType | EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Overrideable;
                }
                if (mcType != EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Unknow)
                {
                    methodCode.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(EngineNS.Editor.MacrossMemberAttribute)), new CodeAttributeArgument(new CodePrimitiveExpression(mcType))));
                }

                if (data != null)
                {
                    foreach (var localParam in data.LocalParams)
                    {
                        var defVal  = CodeGenerateSystem.Program.GetDefaultValueFromType(localParam.ParamType);
                        var initExp = Program.GetValueCode(methodCode.Statements, localParam.ParamType, defVal);
                        methodCode.Statements.Add(new CodeVariableDeclarationStatement(localParam.ParamType, localParam.ParamName, initExp));
                    }
                }

                string paramPreStr = "temp___";
                //bool needUnsafeFlag = false;
                string catchParamName = "(";
                foreach (var paramNode in mChildNodes)
                {
                    var paramExp = new System.CodeDom.CodeParameterDeclarationExpression();
                    if (paramNode is MethodInvokeParameterControl)
                    {
                        var pm      = paramNode as MethodInvokeParameterControl;
                        var pmParam = pm.CSParam as MethodInvokeParameterControl.MethodInvokeParameterConstructionParams;
                        paramExp.Direction = pm.ParamFlag;
                        if (pmParam.ParamInfo.ParameterDisplayType != null)
                        {
                            paramExp.Name = paramPreStr + pmParam.ParamInfo.ParamName;
                            paramExp.Type = new CodeTypeReference(pmParam.ParamInfo.ParameterType);
                        }
                        else
                        {
                            paramExp.Name = pmParam.ParamInfo.ParamName;
                            paramExp.Type = new System.CodeDom.CodeTypeReference(pm.ParamType);
                        }

                        //if (pm.ParamType.IsPointer)
                        //    needUnsafeFlag = true;
                    }
                    else if (paramNode is ParamParameterControl)
                    {
                        var pm = paramNode as ParamParameterControl;
                        paramExp.Name = pm.ParamName;
                        paramExp.Type = new System.CodeDom.CodeTypeReference(pm.ParamType);

                        //if (pm.ParamType.IsPointer)
                        //    needUnsafeFlag = true;
                    }
                    else if (paramNode is MethodInvoke_DelegateControl)
                    {
                        var pm = paramNode as MethodInvoke_DelegateControl;
                        paramExp.Name = pm.ParamName;
                        paramExp.Type = new System.CodeDom.CodeTypeReference(pm.ParamType);
                    }

                    methodCode.Parameters.Add(paramExp);
                    catchParamName += paramExp.Type + " " + paramExp.Name + ",";
                }
                // 所有函数全部unsafe
                //if (needUnsafeFlag)
                {
                    //var typeName = MethodReturnType.FullName;
                    methodCode.ReturnType = new CodeTypeReference(MethodReturnType);
                    if (MethodReturnType == typeof(System.Threading.Tasks.Task) || MethodReturnType.BaseType == typeof(System.Threading.Tasks.Task))
                    {
                        methodCode.IsAsync = true;
                    }
                    else
                    {
                        if (EngineNS.Editor.MacrossMemberAttribute.HasType(macrossType, EngineNS.Editor.MacrossMemberAttribute.enMacrossType.Unsafe))
                        {
                            methodCode.IsUnsafe = true;
                        }
                    }
                }
                //else
                //    methodCode.ReturnType = new CodeTypeReference(MethodReturnType);

                catchParamName  = catchParamName.TrimEnd(',');
                catchParamName += ")";

                var tryCatchExp = new System.CodeDom.CodeTryCatchFinallyStatement();
                tryCatchExp.TryStatements.Add(new CodeGenerateSystem.CodeDom.CodeMethodInvokeExpression(new CodeVariableReferenceExpression(context.ScopFieldName), "Begin", new CodeExpression[0]));
                var exName = "ex_" + EngineNS.Editor.Assist.GetValuedGUIDString(Id);
                var cah    = new System.CodeDom.CodeCatchClause(exName);
                cah.Statements.Add(new System.CodeDom.CodeExpressionStatement(
                                       new CodeGenerateSystem.CodeDom.CodeMethodInvokeExpression(
                                           new System.CodeDom.CodeSnippetExpression("EngineNS.Profiler.Log"), "WriteException",
                                           new System.CodeDom.CodeVariableReferenceExpression(exName),
                                           new CodePrimitiveExpression("Macross异常"))));
                tryCatchExp.CatchClauses.Add(cah);
                tryCatchExp.FinallyStatements.Add(new CodeGenerateSystem.CodeDom.CodeMethodInvokeExpression(new CodeVariableReferenceExpression(context.ScopFieldName), "End", new CodeExpression[0]));

                string paramComment = "";
                // 设置out参数默认值
                foreach (var param in csParam.MethodInfo.Params)
                {
                    if (param.ParameterDisplayType != null)
                    {
                        if (param.FieldDirection == FieldDirection.Out)
                        {
                            methodCode.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(paramPreStr + param.ParamName),
                                                                              new CodePrimitiveExpression(CodeGenerateSystem.Program.GetDefaultValueFromType(param.ParameterType))));
                        }
                        methodCode.Statements.Add(new CodeVariableDeclarationStatement(param.ParameterDisplayType, param.ParamName, new CodeGenerateSystem.CodeDom.CodeCastExpression(param.ParameterDisplayType, new CodeVariableReferenceExpression(paramPreStr + param.ParamName))));
                    }
                    else
                    {
                        if (param.FieldDirection == FieldDirection.Out)
                        {
                            methodCode.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(param.ParamName),
                                                                              new CodePrimitiveExpression(CodeGenerateSystem.Program.GetDefaultValueFromType(param.ParameterType))));
                        }
                    }

                    paramComment += param.FieldDirection + "," + param.ParameterType.FullName + "|";
                }
                paramComment = paramComment.TrimEnd('|');

                methodCode.Statements.Add(tryCatchExp);
                foreach (var param in csParam.MethodInfo.Params)
                {
                    // ref或out,需要将displayType造成的临时变量再赋给原函数参数
                    if ((param.FieldDirection == FieldDirection.Out || param.FieldDirection == FieldDirection.Ref) && param.ParameterDisplayType != null)
                    {
                        methodCode.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(paramPreStr + param.ParamName), new CodeGenerateSystem.CodeDom.CodeCastExpression(param.ParameterType, new CodeVariableReferenceExpression(param.ParamName))));
                    }
                }

                if (csParam.MethodInfo.ReturnType != typeof(void) && csParam.MethodInfo.ReturnType != typeof(System.Threading.Tasks.Task))
                {
                    var retVal = CodeGenerateSystem.Program.GetDefaultValueFromType(csParam.MethodInfo.ReturnType);
                    methodCode.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(retVal)));
                }


                if (csParam.MethodInfo.IsFromMacross)
                {
                    codeClass.Members.Add(new CodeSnippetTypeMember($"// OverrideStart {csParam.MethodInfo.FuncId.ToString()} {NodeName} {paramComment}"));
                    codeClass.Members.Add(new CodeSnippetTypeMember("#pragma warning disable 1998"));
                    codeClass.Members.Add(methodCode);
                    codeClass.Members.Add(new CodeSnippetTypeMember("#pragma warning restore 1998"));
                    codeClass.Members.Add(new CodeSnippetTypeMember($"// OverrideEnd {csParam.MethodInfo.FuncId.ToString()} {NodeName}"));
                }
                else
                {
                    codeClass.Members.Add(new CodeSnippetTypeMember($"// OverrideStart {NodeName} {paramComment}"));
                    codeClass.Members.Add(new CodeSnippetTypeMember("#pragma warning disable 1998"));
                    codeClass.Members.Add(methodCode);
                    codeClass.Members.Add(new CodeSnippetTypeMember("#pragma warning restore 1998"));
                    codeClass.Members.Add(new CodeSnippetTypeMember($"// OverrideEnd {NodeName}"));
                }

                var methodContext = new CodeGenerateSystem.Base.GenerateCodeContext_Method(context, methodCode);
                // 收集用于调试的数据的代码
                var debugCodes = CodeDomNode.BreakPoint.BeginMacrossDebugCodeStatments(tryCatchExp.TryStatements);
                foreach (var paramNode in mChildNodes)
                {
                    if (paramNode is MethodInvokeParameterControl)
                    {
                        var paramCtrl = paramNode as MethodInvokeParameterControl;
                        CodeDomNode.BreakPoint.GetGatherDataValueCodeStatement(debugCodes, paramCtrl.ParamPin.GetLinkPinKeyName(), paramCtrl.GCode_CodeDom_GetValue(paramCtrl.ParamPin, methodContext), paramCtrl.GCode_GetTypeString(paramCtrl.ParamPin, methodContext), methodContext);
                    }
                    else if (paramNode is ParamParameterControl)
                    {
                        throw new InvalidOperationException();
                    }
                }
                // 断点
                var breakCondStatement = CodeDomNode.BreakPoint.BreakCodeStatement(codeClass, debugCodes, HostNodesContainer.GUID, Id);
                // 设置数据
                foreach (var paramNode in mChildNodes)
                {
                    if (paramNode is MethodInvokeParameterControl)
                    {
                        var paramCtrl = paramNode as MethodInvokeParameterControl;
                        CodeDomNode.BreakPoint.GetSetDataValueCodeStatement(breakCondStatement.TrueStatements, paramCtrl.ParamPin.GetLinkPinKeyName(), paramCtrl.GCode_CodeDom_GetValue(paramCtrl.ParamPin, methodContext), paramCtrl.GCode_GetType(paramCtrl.ParamPin, methodContext));
                    }
                    else if (paramNode is ParamParameterControl)
                    {
                        throw new InvalidOperationException();
                    }
                }
                CodeDomNode.BreakPoint.EndMacrossDebugCodeStatements(tryCatchExp.TryStatements, debugCodes);

                if (mCtrlMethodPin_Next.HasLink)
                {
                    methodContext.ReturnValueType = MethodReturnType;
                    await mCtrlMethodPin_Next.GetLinkedObject(0, false).GCode_CodeDom_GenerateCode(codeClass, tryCatchExp.TryStatements, mCtrlMethodPin_Next.GetLinkedPinControl(0, false), methodContext);
                }
            }
        }
Пример #2
0
 public override async System.Threading.Tasks.Task GCode_CodeDom_GenerateCode(CodeTypeDeclaration codeClass, LinkPinControl element, GenerateCodeContext_Class context)
 {
     await GCode_CodeDom_GenerateMethodCode(codeClass, element, context, null);
 }