示例#1
0
        CodeCompilationUnit ParseCppFile(string filename)
        {
            //-----
            //this is for Cef3 cpp-to-c .cc file only!!!
            //test_cpptoc_List -> this version we need some pre-precessing step
            //-----

            List <string> lines         = new List <string>(System.IO.File.ReadAllLines(filename));
            List <string> selectedLines = new List <string>();
            int           j             = lines.Count;

            for (int i = 0; i < j; ++i)
            {
                string line = lines[i].Trim();
                if (line.StartsWith("//"))
                {
                    //this is comment
                    //read the comment
                    if (line.Contains("CONSTRUCTOR"))
                    {
                        //stop here
                        break;
                    }
                }
                selectedLines.Add(line);
            }

            CodeCompilationUnit cu = Parse(filename, selectedLines);

            return(cu);
        }
示例#2
0
        public void GenerateBridge(string cefSrcFolder)
        {
            string cefDir = cefSrcFolder;
            List <CodeCompilationUnit> totalCuList_capi = new List <CodeCompilationUnit>();
            List <CodeCompilationUnit> totalCuList      = new List <CodeCompilationUnit>();
            List <CodeCompilationUnit> test_cpptoc_List = new List <CodeCompilationUnit>();
            //-----------------------------
            {
                //cpptoc folder
                string   libcef_dll_folder = cefDir + @"\libcef_dll";
                string[] onlyCppFiles      = System.IO.Directory.GetFiles(libcef_dll_folder + @"\cpptoc", "*.cc");
                //we skip some files
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[] {
                    "base_ref_counted_cpptoc.cc",
                    "base_scoped_cpptoc.cc"
                });
                int j = onlyCppFiles.Length;

                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyCppFiles[i])))
                    {
                        continue;
                    }
                    CodeCompilationUnit cu = ParseCppFile(onlyCppFiles[i]);
                    test_cpptoc_List.Add(cu);

                    //
                    CppToCsImplCodeGen cppToCsImplCodeGen = new CppToCsImplCodeGen();
                    string             onlyFileName       = System.IO.Path.GetFileName(cu.Filename);
                    if (onlyFileName == "v8interceptor_cpptoc.cc")
                    {
                        continue;
                    }


                    //cppToCsImplCodeGen.PatchCppMethod(cu, cefDir + @"\libcef_dll\cpptoc\" + onlyFileName, cefDir + @"\cpptoc");
                    cppToCsImplCodeGen.PatchCppMethod(cu, null, libcef_dll_folder + @"\cpptoc");
                }
            }
            //-----------------------------

            //-----------------------------
            {
                //cef capi
                string[] onlyHeaderFiles            = System.IO.Directory.GetFiles(cefDir + @"\include\capi", "*.h");
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[0]);
                int j = onlyHeaderFiles.Length;
                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyHeaderFiles[i])))
                    {
                        continue;
                    }
                    CodeCompilationUnit cu = Parse(onlyHeaderFiles[i]);
                    totalCuList_capi.Add(cu);
                }
            }
            {
                //cef capi/views
                string[] onlyHeaderFiles            = System.IO.Directory.GetFiles(cefDir + @"\include\capi\views", "*.h");
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[0]);
                int j = onlyHeaderFiles.Length;
                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyHeaderFiles[i])))
                    {
                        continue;
                    }
                    CodeCompilationUnit cu = Parse(onlyHeaderFiles[i]);
                    totalCuList_capi.Add(cu);
                }
            }


            {
                //include/internal
                totalCuList.Add(Parse(cefDir + @"\include\internal\cef_types.h"));
                totalCuList.Add(Parse(cefDir + @"\include\internal\cef_types_wrappers.h"));
                totalCuList.Add(Parse(cefDir + @"\include\internal\cef_win.h")); //for windows
            }


            {
                //include folder
                string[] onlyHeaderFiles            = System.IO.Directory.GetFiles(cefDir + @"\include\", "*.h");
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[0]);

                int j = onlyHeaderFiles.Length;
                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyHeaderFiles[i])))
                    {
                        continue;
                    }

                    CodeCompilationUnit cu = Parse(onlyHeaderFiles[i]);
                    totalCuList.Add(cu);
                }
            }

            //c to cpp
            {
                string[] onlyHeaderFiles            = System.IO.Directory.GetFiles(cefDir + @"\libcef_dll\ctocpp", "*.h");
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[0]);

                int j = onlyHeaderFiles.Length;
                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyHeaderFiles[i])))
                    {
                        continue;
                    }
                    CodeCompilationUnit cu = Parse(onlyHeaderFiles[i]);
                    totalCuList.Add(cu);
                }
            }

            //cpp to c
            {
                string[] onlyHeaderFiles            = System.IO.Directory.GetFiles(cefDir + @"\libcef_dll\cpptoc", "*.h");
                Dictionary <string, bool> skipFiles = CreateSkipFiles(new string[0]);

                int j = onlyHeaderFiles.Length;
                for (int i = 0; i < j; ++i)
                {
                    if (skipFiles.ContainsKey(System.IO.Path.GetFileName(onlyHeaderFiles[i])))
                    {
                        continue;
                    }
                    CodeCompilationUnit cu = Parse(onlyHeaderFiles[i]);
                    totalCuList.Add(cu);
                }
            }

            //
            CefTypeCollection cefTypeCollection = new CefTypeCollection();

            cefTypeCollection.RootFolder = cefDir;
            cefTypeCollection.SetTypeSystem(totalCuList);



            //
            TypeTranformPlanner txPlanner = new TypeTranformPlanner();

            txPlanner.CefTypeCollection = cefTypeCollection;


            Dictionary <string, CefTypeTx> allTxPlans         = new Dictionary <string, CefTypeTx>();
            List <CefHandlerTx>            handlerPlans       = new List <CefHandlerTx>();
            List <CefCallbackTx>           callbackPlans      = new List <CefCallbackTx>();
            List <CefInstanceElementTx>    instanceClassPlans = new List <CefInstanceElementTx>();
            List <CefEnumTx>    enumTxPlans  = new List <CefEnumTx>();
            List <CefCStructTx> cstructPlans = new List <CefCStructTx>();
            //--

            //--
            int             typeName       = 1;
            List <TypePlan> typeTxInfoList = new List <TypePlan>();


            foreach (CodeTypeDeclaration typedecl in cefTypeCollection._v_instanceClasses)
            {
                //eg. CefApp, CefBrowser, CefCommandLine, CefFrame
                CefInstanceElementTx instanceClassPlan = new CefInstanceElementTx(typedecl);
                instanceClassPlans.Add(instanceClassPlan);
                allTxPlans.Add(typedecl.Name, instanceClassPlan);
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                instanceClassPlan.CsInterOpTypeNameId = typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;
                typeTxInfoList.Add(typeTxPlan);
            }


            foreach (CodeTypeDeclaration typedecl in cefTypeCollection._v_handlerClasses)
            {
                //eg. CefDisplayHandler, CefDownloadHandler
                CefHandlerTx handlerPlan = new CefHandlerTx(typedecl);
                handlerPlans.Add(handlerPlan);
                allTxPlans.Add(typedecl.Name, handlerPlan);
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                handlerPlan.CsInterOpTypeNameId = typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;
                typeTxInfoList.Add(typeTxPlan);
            }
            foreach (CodeTypeDeclaration typedecl in cefTypeCollection._v_callBackClasses)
            {
                //eg. CefAuthenCallback, CefPdfCallback
                CefCallbackTx callbackPlan = new CefCallbackTx(typedecl);
                callbackPlans.Add(callbackPlan);
                allTxPlans.Add(typedecl.Name, callbackPlan);
                ////
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                callbackPlan.CsInterOpTypeNameId = typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;
                typeTxInfoList.Add(typeTxPlan);
            }
            //
            foreach (CodeTypeDeclaration typedecl in cefTypeCollection._enumClasses)
            {
                CefEnumTx enumTxPlan = new CefEnumTx(typedecl);
                enumTxPlans.Add(enumTxPlan);
                allTxPlans.Add(typedecl.Name, enumTxPlan);
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                enumTxPlan.CsInterOpTypeNameId = typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;
            }

            List <CodeTypeDeclaration> notFoundAbstractClasses = new List <CodeTypeDeclaration>();

            foreach (CodeTypeDeclaration typedecl in cefTypeCollection.cToCppClasses)
            {
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;

                //cef -specific
                TemplateTypeSymbol3 baseType0 = (TemplateTypeSymbol3)typedecl.BaseTypes[0].ResolvedType;
                //add information to our model
                SimpleTypeSymbol abstractType      = (SimpleTypeSymbol)baseType0.Item1;
                SimpleTypeSymbol underlying_c_type = (SimpleTypeSymbol)baseType0.Item2;

                CefTypeTx found;
                if (!allTxPlans.TryGetValue(abstractType.Name, out found))
                {
                    notFoundAbstractClasses.Add(typedecl);
                    continue;
                }
                found.UnderlyingCType = underlying_c_type;
                found.ImplTypeDecl    = typedecl;

                abstractType.CefTxPlan = found;
                ////[chrome] cpp<-to<-c  <--- ::::: <--- c-interface-to[external - user - lib] ....
            }
            foreach (CodeTypeDeclaration typedecl in cefTypeCollection.cppToCClasses)
            {
                //callback, handle, visitor etc
                TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                typeTxPlan.CsInterOpTypeNameId = typeName++;
                typedecl.TypePlan = typeTxPlan;
                //cef -specific
                TemplateTypeSymbol3 baseType0         = (TemplateTypeSymbol3)typedecl.BaseTypes[0].ResolvedType;
                SimpleTypeSymbol    abstractType      = (SimpleTypeSymbol)baseType0.Item1;
                SimpleTypeSymbol    underlying_c_type = (SimpleTypeSymbol)baseType0.Item2;
                CefTypeTx           found;
                if (!allTxPlans.TryGetValue(abstractType.Name, out found))
                {
                    notFoundAbstractClasses.Add(typedecl);
                    continue;
                }

                found.UnderlyingCType  = underlying_c_type;
                found.ImplTypeDecl     = typedecl;
                abstractType.CefTxPlan = found;

                ////[chrome]  cpp->to->c  ---> ::::: ---> c-interface-to [external-user-lib] ....
                ////eg. handlers and callbacks
            }
            //--------
            foreach (CodeTypeDeclaration typedecl in cefTypeCollection._plainCStructs)
            {
                //create raw type
                if (!typedecl.Name.EndsWith("Traits") &&
                    typedecl.Name.StartsWith("_"))
                {
                    //
                    CefCStructTx cstructTx = new CefCStructTx(typedecl);
                    cstructPlans.Add(cstructTx);
                    TypePlan typeTxPlan = txPlanner.MakeTransformPlan(typedecl);
                    cstructTx.CsInterOpTypeNameId = typeTxPlan.CsInterOpTypeNameId = typeName++;
                    typedecl.TypePlan             = typeTxPlan;
                    //
                    typeTxInfoList.Add(typeTxPlan);
                }
                else
                {
                }
            }

            //--------
            //code gen

            List <CefTypeTx> customImplClasses = new List <CefTypeTx>();
            StringBuilder    cppCodeStBuilder  = new StringBuilder();

            AddCppBuiltInBeginCode(cppCodeStBuilder);

            CodeStringBuilder cppHeaderInternalForExportFunc = new CodeStringBuilder();

            cppHeaderInternalForExportFunc.AppendLine(
                "//MIT, 2017, WinterDev\r\n" +
                "//AUTOGEN");


            foreach (TypePlan txinfo in typeTxInfoList)
            {
                cppHeaderInternalForExportFunc.AppendLine("const int CefTypeName_" + txinfo.TypeDecl.Name + " = " + txinfo.CsInterOpTypeNameId.ToString() + ";");
            }


            StringBuilder csCodeStBuilder = new StringBuilder();

            AddCsCodeHeader(csCodeStBuilder);
            CefCodeGenOutput codeGenOutput = null;

            foreach (CefTypeTx tx in enumTxPlans)
            {
                codeGenOutput = new CefCodeGenOutput();
                tx.GenerateCode(codeGenOutput);
                //get cs output
                csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
            }
            csCodeStBuilder.Append("}"); //close namespace
            //save to file
            System.IO.File.WriteAllText("CefEnums.cs", csCodeStBuilder.ToString());

            //-------------------------
            CodeStringBuilder cppHeaderExportFuncAuto = new CodeStringBuilder();

            cppHeaderExportFuncAuto.AppendLine("//AUTOGEN");
            //-------------------------

            //cef instance is quite large
            //so we spit the code gen into 2 sections
            int instance_count = instanceClassPlans.Count;
            int mid            = instance_count / 2;

            {
                //1st part
                csCodeStBuilder = new StringBuilder();
                AddCsCodeHeader(csCodeStBuilder);
                //-------------------------
                for (int cc = 0; cc < mid; ++cc)
                {
                    CefInstanceElementTx tx = instanceClassPlans[cc];
                    codeGenOutput = new CefCodeGenOutput();
                    tx.GenerateCode(codeGenOutput);
                    //----------------------------------------------------
                    cppCodeStBuilder.AppendLine();
                    cppCodeStBuilder.AppendLine("// " + tx.OriginalDecl.ToString());
                    cppCodeStBuilder.Append(codeGenOutput._cppCode.ToString());
                    cppCodeStBuilder.AppendLine();
                    //----------------------------------------------------
                    csCodeStBuilder.AppendLine();
                    csCodeStBuilder.AppendLine("// " + tx.OriginalDecl.ToString());
                    csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
                    csCodeStBuilder.AppendLine();
                    //--------------------------------------------

                    cppHeaderExportFuncAuto.Append(codeGenOutput._cppHeaderExportFuncAuto.ToString());
                    cppHeaderInternalForExportFunc.Append(codeGenOutput._cppHeaderInternalForExportFuncAuto.ToString());
                    //----------
                    if (tx.CppImplClassNameId > 0)
                    {
                        customImplClasses.Add(tx);
                    }
                }
                csCodeStBuilder.Append("}");
                //save to file
                System.IO.File.WriteAllText("CefInstances_P1.cs", csCodeStBuilder.ToString());
                //-------------------------
            }
            {
                //2nd part
                //1st part
                csCodeStBuilder = new StringBuilder();
                AddCsCodeHeader(csCodeStBuilder);

                for (int cc = mid; cc < instance_count; ++cc)
                {
                    CefInstanceElementTx tx = instanceClassPlans[cc];
                    codeGenOutput = new CefCodeGenOutput();
                    tx.GenerateCode(codeGenOutput);
                    //----------------------------------------------------
                    cppCodeStBuilder.AppendLine();
                    cppCodeStBuilder.AppendLine("// " + tx.OriginalDecl.ToString());
                    cppCodeStBuilder.Append(codeGenOutput._cppCode.ToString());
                    cppCodeStBuilder.AppendLine();
                    //----------------------------------------------------
                    csCodeStBuilder.AppendLine();
                    csCodeStBuilder.AppendLine("// " + tx.OriginalDecl.ToString());
                    csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
                    csCodeStBuilder.AppendLine();
                    //--------------------------------------------

                    cppHeaderExportFuncAuto.Append(codeGenOutput._cppHeaderExportFuncAuto.ToString());
                    cppHeaderInternalForExportFunc.Append(codeGenOutput._cppHeaderInternalForExportFuncAuto.ToString());
                    //----------
                    if (tx.CppImplClassNameId > 0)
                    {
                        customImplClasses.Add(tx);
                    }
                }
                csCodeStBuilder.Append("}");
                //save to file
                System.IO.File.WriteAllText("CefInstances_P2.cs", csCodeStBuilder.ToString());
                //-------------------------
            }



            csCodeStBuilder = new StringBuilder();
            AddCsCodeHeader(csCodeStBuilder);
            foreach (CefCallbackTx tx in callbackPlans)
            {
                codeGenOutput = new CefCodeGenOutput();
                tx.GenerateCode(codeGenOutput);

                cppCodeStBuilder.Append(codeGenOutput._cppCode.ToString());
                csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
                //----------
                cppHeaderExportFuncAuto.Append(codeGenOutput._cppHeaderExportFuncAuto.ToString());
                cppHeaderInternalForExportFunc.Append(codeGenOutput._cppHeaderInternalForExportFuncAuto.ToString());
                //----------
                if (tx.CppImplClassNameId > 0)
                {
                    customImplClasses.Add(tx);
                }
            }
            csCodeStBuilder.Append("}");
            //save to file
            System.IO.File.WriteAllText("CefCallbacks.cs", csCodeStBuilder.ToString());
            //-------------------------
            csCodeStBuilder = new StringBuilder();
            AddCsCodeHeader(csCodeStBuilder);
            foreach (CefHandlerTx tx in handlerPlans)
            {
                codeGenOutput = new CefCodeGenOutput();
                tx.GenerateCode(codeGenOutput);

                cppCodeStBuilder.Append(codeGenOutput._cppCode.ToString());
                csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
                //----------
                cppHeaderExportFuncAuto.Append(codeGenOutput._cppHeaderExportFuncAuto.ToString());
                cppHeaderInternalForExportFunc.Append(codeGenOutput._cppHeaderInternalForExportFuncAuto.ToString());
                //----------
            }
            csCodeStBuilder.Append("}");
            //save to file
            System.IO.File.WriteAllText("CefHandlers.cs", csCodeStBuilder.ToString());
            //-------------------------
            csCodeStBuilder = new StringBuilder();
            AddCsCodeHeader(csCodeStBuilder);
            foreach (CefCStructTx tx in cstructPlans)
            {
                codeGenOutput = new CefCodeGenOutput();
                tx.GenerateCode(codeGenOutput);
                csCodeStBuilder.Append(codeGenOutput._csCode.ToString());
            }
            csCodeStBuilder.Append("}");
            //save to file
            System.IO.File.WriteAllText("CefPlainCStructs.cs", csCodeStBuilder.ToString());
            //-------------------------
            csCodeStBuilder = new StringBuilder();
            AddCsCodeHeader(csCodeStBuilder);
            CsNativeHandlerSwitchTableCodeGen csNativeHandlerSwitchTableCodeGen = new CsNativeHandlerSwitchTableCodeGen();

            csNativeHandlerSwitchTableCodeGen.GenerateCefNativeRequestHandlers(handlerPlans, csCodeStBuilder);
            //cs...
            csCodeStBuilder.AppendLine("}");
            System.IO.File.WriteAllText("CefApiSwitchTables.cs", csCodeStBuilder.ToString());
            //--------
            //cpp
            CppSwicthTableCodeGen cppSwitchTableCodeGen = new CppSwicthTableCodeGen();

            cppSwitchTableCodeGen.CreateCppSwitchTableForInstanceMethods(cppCodeStBuilder, instanceClassPlans);
            cppSwitchTableCodeGen.CreateCppSwitchTableForStaticMethods(cppCodeStBuilder, instanceClassPlans);
            //
            CppInstanceMethodCodeGen instanceMetCodeGen = new CppInstanceMethodCodeGen();

            instanceMetCodeGen.CreateCppNewInstanceMethod(cppCodeStBuilder, customImplClasses);
            //--------
            cppCodeStBuilder.AppendLine("/////////////////////////////////////////////////");
            //
        }
示例#3
0
        public void PatchCppMethod(CodeCompilationUnit cu, string writeNewCodeToFile, string backupFolder)
        {
            //cef specific code
            firstNamespaceStartAt = 0;
            this.cu = cu;
            methods = new List <CodeMethodDeclaration>();
            CollectImplMethods();

            string onlyFileName = Path.GetFileName(cu.Filename);

            simpleLineList.Clear();
            simpleLineList.AddRange(File.ReadAllLines(cu.Filename));
            //
            //check if this file is patched or not
            if (CheckIfThisFileIsPatched(simpleLineList))
            {
                throw new NotSupportedException();
            }

            int    classCutAt          = onlyFileName.IndexOf("_cpptoc.");
            string c_className         = onlyFileName.Substring(0, classCutAt);
            int    c_classNameLen      = c_className.Length;
            string cppClassName        = "Cef" + ConvertToCppName(c_className);
            string cppExtNamespaceName = cppClassName + "Ext";


            for (int i = methods.Count - 1; i >= 0; --i) //backward, since we are going to insert a new line to the line list
            {
                CodeMethodDeclaration   metDecl = methods[i];
                MultiPartCodeMethodBody metBody = ParseCppMethodBody(metDecl);
                //


                StringBuilder newCodeStBuilder = new StringBuilder();
                int           methodCutAt      = c_classNameLen + 1;
                string        c_methodName     = metDecl.Name.Substring(methodCutAt);
                string        cppMethodName    = ConvertToCppName(c_methodName);

                //eg.
                //(CefDisplayHandlerExt::_typeName << 16) | CefDisplayHandlerExt::CefDisplayHandlerExt_OnAddressChange_1, &args1.arg);
                string metNameConst = "(" + cppExtNamespaceName + "::_typeName << 16) | " + cppExtNamespaceName + "::" + cppExtNamespaceName + "_" + cppMethodName + "_" + (i + 1);


                newCodeStBuilder.AppendLine("//---kneadium-ext-begin" + (++codeNum));

                newCodeStBuilder.AppendLine("#if ENABLE_KNEADIUM_EXT");
                //some method parameters may need special preparation.
                newCodeStBuilder.AppendLine("auto me = " + cppClassName + "CppToC::Get(self);");
                newCodeStBuilder.AppendLine("const int CALLER_CODE=" + metNameConst + ";");
                newCodeStBuilder.AppendLine("auto m_callback= me->GetManagedCallBack(CALLER_CODE);");
                newCodeStBuilder.AppendLine("if(m_callback){"); //TODO: + method filter

                int           parCount    = metDecl.Parameters.Count;
                List <string> argCodeList = new List <string>();

                for (int a = 1; a < parCount; ++a)
                {
                    //start at 1
                    CodeMethodParameter par = metDecl.Parameters[a];
                    string parType          = par.ParameterType.ToString();
                    //check if we need parameter translation
                    switch (parType)
                    {
                    default:
                    {
                        CodeMethodBodyCodePart found;
                        if (metBody.TryGetTranslateParameter(par.ParameterName, out found))
                        {
                            if (found.IsList)
                            {
                                //cef-specific
                                //note the prev var
                                CodeMethodParameter prev_par = metDecl.Parameters[a - 1];
                                prev_par.SkipCodeGen = true;
                            }
                            argCodeList.Add(found.ReplacedParExpression);
                        }
                        else
                        {
                            argCodeList.Add(par.ParameterName);
                        }
                        //-----------------
                    }
                    break;

                    case "_cef_v8value_t**":
                    {
                        argCodeList.Add(par.ParameterName);
                    }
                    break;

                    case "cef_string_list_t":
                    {
                        //cef-specific
                        //new var name
                        argCodeList.Add("&" + par.ParameterName + "List");
                    }
                    break;

                    case "cef_string_t*":
                    {
                        string newArgName = "tmp_arg" + a;
                        newCodeStBuilder.AppendLine("CefString " + newArgName + " (" + par.ParameterName + ");");
                        if (par.IsConstPar)
                        {
                            argCodeList.Add(newArgName);
                        }
                        else
                        {
                            argCodeList.Add("&" + newArgName);
                        }
                    }
                    break;
                    }
                }

                //prepare cpp' method args
                //convention
                if (parCount < 2)
                {
                    newCodeStBuilder.AppendLine(cppExtNamespaceName + "::" + cppMethodName + "Args args1;");
                }
                else
                {
                    newCodeStBuilder.Append(cppExtNamespaceName + "::" + cppMethodName + "Args args1(");
                    for (int a = 1; a < parCount; ++a)
                    {
                        CodeMethodParameter par = metDecl.Parameters[a];
                        if (par.SkipCodeGen)
                        {
                            continue;
                        }
                        //
                        if (a > 1)
                        {
                            newCodeStBuilder.Append(',');
                        }
                        //start at 1
                        newCodeStBuilder.Append(argCodeList[a - 1]);
                    }
                    newCodeStBuilder.AppendLine(");");
                }
                //
                //invoke managed del
                //cef-specific

                newCodeStBuilder.Append("m_callback(CALLER_CODE, &args1.arg);");
                newCodeStBuilder.AppendLine();
                //----------------------------------------------------------------------------
                newCodeStBuilder.AppendLine(" if (((args1.arg.myext_flags >> 21) & 1) == 1){");
                string retType = metDecl.ReturnType.ToString();
                if (retType != "void")
                {
                    //the event is handled by user code
                    //before return we must check some restore parts

                    List <CodeMethodBodyCodePart> restoreParts = metBody.GetRestoreParts();
                    if (restoreParts != null)
                    {
                        int rcount = restoreParts.Count;
                        for (int r = 0; r < rcount; ++r)
                        {
                            newCodeStBuilder.AppendLine(restoreParts[r].GetStringBlock());
                        }
                    }


                    //check some special value
                    if (retType.EndsWith("_t*"))
                    {
                        //
                        string cppNm = ConvertToCppName(retType.Substring(0, retType.Length - 3));

                        //temp fix, TODO: review here again
                        //CefCookieManager
                        if (cppNm == "CefCookieManager")
                        {
                            newCodeStBuilder.AppendLine(" return " + cppNm + "CToCpp::Unwrap(args1.arg.myext_ret_value);");
                        }
                        else
                        {
                            newCodeStBuilder.AppendLine(" return " + cppNm + "CppToC::Wrap(args1.arg.myext_ret_value);");
                        }
                    }
                    else
                    {
                        newCodeStBuilder.AppendLine(" return args1.arg.myext_ret_value;");
                    }
                }
                else
                {
                    newCodeStBuilder.AppendLine("return;");
                }
                newCodeStBuilder.AppendLine("}");



                //method return value may need special preparation.
                newCodeStBuilder.AppendLine("}");      //TODO: + method filter
                newCodeStBuilder.AppendLine("#endif"); //#if ENABLE_KNEADIUM_EXT");
                newCodeStBuilder.AppendLine("//---kneadium-ext-end");
                //-----
                //find insert point
                if (!metDecl.HasMethodBody)
                {
                    throw new NotSupportedException();
                }

                int insertAtLine = FindProperInsertPoint(simpleLineList, metDecl.StartAtLine, metDecl.EndAtLine);
                if (insertAtLine > 0)
                {
                    //just replace
                    simpleLineList.Insert(insertAtLine, newCodeStBuilder.ToString());
                }
                //-----
            }

            //insert header
            simpleLineList.Insert(firstNamespaceStartAt,
                                  "//---kneadium-ext-begin\r\n" +
                                  "#include \"../myext/ExportFuncAuto.h\"\r\n" +
                                  "#include \"../myext/InternalHeaderForExportFunc.h\"\r\n" +
                                  "//---kneadium-ext-end\r\n");

            simpleLineList.Insert(0, "//---THIS-FILE-WAS-PATCHED , org=" + cu.Filename);

            ////save the modified file
            if (writeNewCodeToFile != null)
            {
                //target must exist
                if (!File.Exists(writeNewCodeToFile))
                {
                    throw new NotSupportedException();
                }
                //backup org file
                File.Copy(writeNewCodeToFile, backupFolder + "\\" + onlyFileName + ".backup.txt", true);
                //then write the new one
                using (FileStream fs = new FileStream(writeNewCodeToFile, FileMode.Create))
                    using (StreamWriter w = new StreamWriter(fs))
                    {
                        int j = simpleLineList.Count;
                        for (int i = 0; i < j; ++i)
                        {
                            w.WriteLine(simpleLineList[i]);
                        }
                        w.Close();
                    }
            }
        }