Beispiel #1
0
        /// <summary>
        /// find c api name
        /// </summary>
        /// <param name="met"></param>
        /// <returns></returns>
        static string FindCApiName(CodeMethodDeclaration met)
        {
            Token[] lineComments = met.LineComments;
            if (lineComments == null)
            {
                return(null);
            }
            //
            string capi_name = "/*cef(capi_name=";
            int    len       = capi_name.Length;

            for (int i = lineComments.Length - 1; i >= 0; --i)
            {
                //analyze line-by-line
                string line  = lineComments[i].Content;
                int    index = line.IndexOf(capi_name);
                if (index > -1)
                {
                    int comma = line.IndexOf(',', index);
                    if (comma > -1)
                    {
                        return(line.Substring(index + len, comma - (index + len)));
                    }
                    int closeParen = line.IndexOf(')', index);
                    if (closeParen > -1)
                    {
                        return(line.Substring(index + len, closeParen - (index + len)));
                    }
                }
            }
            return(null);
        }
Beispiel #2
0
        void GenerateCppImplMethodDeclarationForNs(MethodPlan met, CodeStringBuilder stbuilder)
        {
            CodeMethodDeclaration metDecl = met.metDecl;

            stbuilder.AppendLine("//CefHandlerTx::GenerateCppImplMethodDeclarationForNs ," + (++codeGenNum));
            stbuilder.AppendLine("//gen! " + metDecl.ToString());
            //---------------------------

            //temp
            switch (metDecl.ReturnType.ToString())
            {
            case "FilterStatus":
                stbuilder.Append(metDecl.ReturnType.ResolvedType + " " + metDecl.Name + "(");
                break;

            case "ReturnValue":
                string ownerType = met.metDecl.OwnerTypeDecl.Name;
                stbuilder.Append(ownerType + "::" + metDecl.ReturnType + " " + metDecl.Name + "(");
                break;

            default:
                stbuilder.Append(metDecl.ReturnType + " " + metDecl.Name + "(");
                break;
            }

            List <CodeMethodParameter> pars = metDecl.Parameters;

            //first par is managed callback
            stbuilder.Append("managed_callback mcallback");
            int j = pars.Count;

            for (int i = 0; i < j; ++i)
            {
                stbuilder.Append(",");
                CodeMethodParameter par = pars[i];

                if (par.IsConstPar)
                {
                    stbuilder.Append("const ");
                }
                //parameter type

                stbuilder.Append(par.ParameterType.ResolvedType.FullName + " ");
                stbuilder.Append(par.ParameterName);
            }
            stbuilder.AppendLine(");");
        }
Beispiel #3
0
        public static void AddComments(CodeTypeDeclaration orgDecl, CodeTypeDeclaration implTypeDecl)
        {
            //copy comment from orgDecl to implTypeDecl
            List <CodeMethodDeclaration> results = new List <CodeMethodDeclaration>();

            foreach (CodeMethodDeclaration orgMet in orgDecl.GetMethodIter())
            {
                Token[] lineComments = orgMet.LineComments;

                if (lineComments != null)
                {
                    results.Clear();
                    implTypeDecl.FindMethod(orgMet.Name, results);
                    switch (results.Count)
                    {
                    case 0:    //not found
                        break;

                    case 1:
                        //found 1
                    {
                        CodeMethodDeclaration implMethodDecl = results[0];
                        if (implMethodDecl.LineComments == null)
                        {
                            implMethodDecl.LineComments = lineComments;
                        }
                        else
                        {
                        }
                    }
                    break;

                    default:
                        break;
                    }
                }
            }
        }
Beispiel #4
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();
                    }
            }
        }
Beispiel #5
0
        MultiPartCodeMethodBody ParseCppMethodBody(CodeMethodDeclaration metDecl)
        {
            List <CodeMethodBodyCodePart> codeParts = new List <CodeMethodBodyCodePart>();
            int endAt = metDecl.EndAtLine;
            CodeMethodBodyCodePart currentPart = null;

            for (int lineNo = metDecl.StartAtLine + 1; lineNo <= endAt; ++lineNo)
            {
                string line = simpleLineList[lineNo].Trim();
                //parse special mx parameter
                if (line.StartsWith("// Translate param:"))
                {
                    //begin new
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.TranslateParam, beginAtLine = lineNo
                    };
                    AddPartParameterDetail(currentPart, line);
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else if (line.StartsWith("// Restore param:"))
                {
                    //begin new
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.RestoreParam, beginAtLine = lineNo
                    };
                    AddPartParameterDetail(currentPart, line);
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else if (line.StartsWith("// Verify param:"))
                {
                    //begin new
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.VerifyParam, beginAtLine = lineNo
                    };
                    AddPartParameterDetail(currentPart, line);
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else if (line.StartsWith("// Return type:"))
                {
                    //begin new
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.Return, beginAtLine = lineNo
                    };
                    AddPartReturnDetail(currentPart, line);
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else if (line.StartsWith("// Execute"))
                {
                    //begin new
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.Execute, beginAtLine = lineNo
                    };
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else if (line.StartsWith("//"))
                {
                    //other block
                    currentPart = new CodeMethodBodyCodePart()
                    {
                        PartKind = MethodBodyCodePartKind.Other, beginAtLine = lineNo
                    };
                    currentPart.PartLines.Add(line);
                    codeParts.Add(currentPart);
                }
                else
                {
                    //other
                    if (currentPart == null)
                    {
                        currentPart = new CodeMethodBodyCodePart()
                        {
                            PartKind = MethodBodyCodePartKind.Other, beginAtLine = lineNo
                        };
                        codeParts.Add(currentPart);
                    }
                    currentPart.PartLines.Add(line);
                }
            }

            return(new MultiPartCodeMethodBody(codeParts));
        }
Beispiel #6
0
        public void SetTypeSystem(List <CodeCompilationUnit> compilationUnits)
        {
            Reset();
            //-----------------------
            this.compilationUnits = compilationUnits;
            //-----------------------
            //resolve cu's file path

            foreach (CodeCompilationUnit cu in compilationUnits)
            {
                //check absolute path for include file
                foreach (IncludeFileDirective includeDirective in cu._includeFiles)
                {
                    //remove " from begin and end of the original IncludeFile
                    if (includeDirective.SystemFolder)
                    {
                        continue;
                    }
                    //
                    string include_file = includeDirective.IncludeFile.Substring(1, includeDirective.IncludeFile.Length - 2);
                    includeDirective.ResolvedAbsoluteFilePath = RootFolder + "\\" + include_file;
                    //check
                    if (!System.IO.File.Exists(includeDirective.ResolvedAbsoluteFilePath))
                    {
                        //file not found
                        if (!(includeDirective.ResolvedAbsoluteFilePath.EndsWith("mac.h") ||
                              includeDirective.ResolvedAbsoluteFilePath.EndsWith("linux.h")))
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
                //
                _compilationUnitDics.Add(cu.Filename, cu);
            }


            List <CodeMethodDeclaration> cppMethodList = new List <CodeMethodDeclaration>();

            //-----------------------
            //1. collect
            foreach (CodeCompilationUnit cu in compilationUnits)
            {
                //
                RegisterTypeDeclaration(cu.GlobalTypeDecl);
                //extract type from global typedecl
                foreach (CodeMemberDeclaration mb in cu.GlobalTypeDecl.GetMemberIter())
                {
                    switch (mb.MemberKind)
                    {
                    case CodeMemberKind.Method:
                    {
                        //check if this method has C++ explicit ower type
                        CodeMethodDeclaration metDecl = (CodeMethodDeclaration)mb;
                        if (metDecl.CppExplicitOwnerType != null)
                        {
                            //add this to typedecl later
                            cppMethodList.Add(metDecl);
                        }
                    }
                    break;

                    case CodeMemberKind.TypeDef:
                    {
                        CodeCTypeDef ctypeDef = (CodeCTypeDef)mb;
                        //
                        CTypeDefTypeSymbol ctypedefTypeSymbol = new CTypeDefTypeSymbol(ctypeDef.Name, ctypeDef.From);
                        ctypedefTypeSymbol.CreatedTypeCTypeDef = ctypeDef;
                        //---

                        TypeSymbol existing;
                        if (TryGetType(ctypeDef.Name, out existing))
                        {
                            throw new NotSupportedException();
                        }
                        RegisterType(ctypeDef.Name, ctypedefTypeSymbol);
                    }
                    break;

                    case CodeMemberKind.Type:
                    {
                        RegisterTypeDeclaration((CodeTypeDeclaration)mb);
                    }
                    break;
                    }
                }

                int typeCount = cu.TypeCount;
                for (int i = 0; i < typeCount; ++i)
                {
                    RegisterTypeDeclaration(cu.GetTypeDeclaration(i));
                }
            }
            //-----------------------
            //temp fix
            int methodCount = cppMethodList.Count;

            if (methodCount > 0)
            {
                //find owner and add the implementation
                for (int i = 0; i < methodCount; ++i)
                {
                    CodeMethodDeclaration metdecl = cppMethodList[i];
                    if (metdecl.LineComments != null)
                    {
                        //for cef, some line comment has transformation info
                    }
                }
            }
            //-----------------------
            ResolveBaseTypes();
            ResolveTypeMembers();
            //-----------------------

            AddMoreTypeInfo();
            //
            var cefTypeBridgeTxPlanner = new CefTypeBridgeTransformPlanner();

            cefTypeBridgeTxPlanner.AssignTypeBridgeInfo(this.typeSymbols);
            //
            this.Planner = cefTypeBridgeTxPlanner;

            //-----------------------
            //do class classification


            foreach (CodeTypeDeclaration t in typedeclDic.Values)
            {
                string name = t.Name;
                if (name.EndsWith("Callback"))
                {
                    _v_callBackClasses.Add(t);
                }
                else if (name.EndsWith("Handler"))
                {
                    _v_handlerClasses.Add(t);
                }
                else if (name.EndsWith("CToCpp"))
                {
                    //implementation
                    cToCppClasses.Add(t);
                }
                else if (name.EndsWith("CppToC"))
                {
                    //implementation
                    cppToCClasses.Add(t);
                }
                else
                {
                    switch (t.Kind)
                    {
                    default:
                    {
                        if (t.IsGlobalCompilationUnitType)
                        {
                            _fileModuleClasses.Add(t);
                        }
                        else if (t.IsTemplateTypeDefinition)
                        {
                            _templateClasses.Add(t);
                        }
                        else if (t.BaseIsVirtual)
                        {
                            _v_instanceClasses.Add(t);
                        }
                        else
                        {
                            if (t.BaseTypes != null && t.BaseTypes.Count > 0)
                            {
                                CodeTypeReference baseType = t.BaseTypes[0];
                                if (baseType.ResolvedType != null)
                                {
                                    switch (baseType.Name)
                                    {
                                    default:

                                        break;

                                    case "CefStructBase":
                                    case "CefBaseScoped":
                                    case "CefBaseRefCounted":
                                        _cefBaseTypes.Add(t);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                switch (t.Name)
                                {
                                default:
                                    break;

                                case "CefScopedSandboxInfo":
                                case "CefBaseRefCounted":
                                case "CefBaseScoped":
                                case "CefRefCount":
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case TypeKind.Enum:
                        if (!CefResolvingContext.IsAllLowerLetter(name))
                        {
                        }
                        _enumClasses.Add(t);
                        break;

                    case TypeKind.Struct:
                        if (!CefResolvingContext.IsAllLowerLetter(name))
                        {
                            if (name.EndsWith("Traits"))
                            {
                            }
                            else
                            {
                            }
                        }
                        _plainCStructs.Add(t);
                        break;
                    }
                }
            }
            //-----------------------
            //for analysis

            foreach (CodeTypeDeclaration t in typedeclDic.Values)
            {
                TypeSymbol resolvedType = t.ResolvedType;
                if (t.BaseTypes.Count == 0)
                {
                    //
                }
                else
                {
                    TypeSymbol        baseType = t.BaseTypes[0].ResolvedType;
                    TypeHierarchyNode found;
                    if (!hierarchy.TryGetValue(baseType, out found))
                    {
                        found = new TypeHierarchyNode(baseType);
                        hierarchy.Add(baseType, found);
                    }

                    if (found.Type != resolvedType)
                    {
                        found.AddTypeSymbol(resolvedType);
                    }
                }
            }
            //-----------------------
        }
Beispiel #7
0
        public override void GenerateCode(CefCodeGenOutput output)
        {
            _cppHeaderExportFuncAuto            = output._cppHeaderExportFuncAuto;
            _cppHeaderInternalForExportFuncAuto = output._cppHeaderInternalForExportFuncAuto;


            //cpp
            CodeTypeDeclaration orgDecl         = this.OriginalDecl;
            CodeTypeDeclaration implTypeDecl    = this.ImplTypeDecl;
            CodeStringBuilder   totalTypeMethod = new CodeStringBuilder();

            if (implTypeDecl.Name.Contains("CppToC"))
            {
                _typePlan = orgDecl.TypePlan;
            }
            else
            {
                _typePlan = implTypeDecl.TypePlan;
            }

            //-----------------------------------------------------------------------
            List <MethodPlan> callToDotNetMets  = new List <MethodPlan>();
            CodeStringBuilder const_methodNames = new CodeStringBuilder();
            int maxPar = 0;
            int j      = _typePlan.methods.Count;

            for (int i = 0; i < j; ++i)
            {
                MethodPlan metTx = _typePlan.methods[i];
                metTx.CppMethodSwitchCaseName = orgDecl.Name + "_" + metTx.Name + "_" + (i + 1);
                //-----------------
                CodeMethodDeclaration codeMethodDecl = metTx.metDecl;
                if (codeMethodDecl.IsAbstract || codeMethodDecl.IsVirtual)
                {
                    callToDotNetMets.Add(metTx);
                }
                //-----------------

                if (metTx.pars.Count > maxPar)
                {
                    maxPar = metTx.pars.Count;
                }
                const_methodNames.AppendLine("const int " + metTx.CppMethodSwitchCaseName + "=" + (i + 1) + ";");
            }
            totalTypeMethod.AppendLine(const_methodNames.ToString());
            //-----------------------------------------------------------------------
            if (callToDotNetMets.Count > 0)
            {
                GenerateCppImplNamespace(orgDecl, callToDotNetMets, output._cppCode);
            }
            //-----------------------------------------------------------------------

            //C# part
            CsStructModuleCodeGen structModuleCodeGen = new CsStructModuleCodeGen();

            if (callToDotNetMets.Count > 0)
            {
                structModuleCodeGen.GenerateCsStructClass(orgDecl, callToDotNetMets, output._csCode, false);
            }

            //back to cpp again...
            CppToCsMethodArgsClassGen cppMetArgClassGen = new CppToCsMethodArgsClassGen();
            //------------------------------------------------------------------
            CodeStringBuilder cppArgClassStBuilder = new CodeStringBuilder();

            cppArgClassStBuilder.AppendLine("namespace " + orgDecl.Name + "Ext{");
            for (int i = 0; i < j; ++i)
            {
                MethodPlan met = _typePlan.methods[i];
                cppMetArgClassGen.GenerateCppMethodArgsClass(met, cppArgClassStBuilder);
            }
            cppArgClassStBuilder.AppendLine("}");
            _cppHeaderExportFuncAuto.Append(cppArgClassStBuilder.ToString());
            //------------------------------------------------------------------
        }
Beispiel #8
0
        void GenerateCppImplMethodForNs(MethodPlan met, CodeStringBuilder stbuilder)
        {
            CodeMethodDeclaration metDecl = met.metDecl;

            stbuilder.AppendLine("//CefHandlerTx::GenerateCppImplMethodForNs ," + (++codeGenNum));
            stbuilder.AppendLine("//gen! " + metDecl.ToString());
            //---------------------------

            //temp
            if (metDecl.ReturnType.ToString() == "FilterStatus")
            {
                stbuilder.Append(metDecl.ReturnType.ResolvedType + " " + metDecl.Name + "(");
            }
            else if (metDecl.ReturnType.ToString() == "ReturnValue")
            {
                string ownerName = metDecl.OwnerTypeDecl.Name;
                stbuilder.Append(ownerName + "::" + metDecl.ReturnType + " " + metDecl.Name + "(");
            }
            else
            {
                stbuilder.Append(metDecl.ReturnType + " " + metDecl.Name + "(");
            }


            List <CodeMethodParameter> pars = metDecl.Parameters;
            int j = pars.Count;
            //transfer data slot
            bool hasSomeOutVars = false;

            CppTempParameterSlot[] dataTransferSlots = new CppTempParameterSlot[j];
            for (int i = 0; i < j; ++i)
            {
                CppTempParameterSlot transferSlot = new CppTempParameterSlot();
                CodeMethodParameter  par          = pars[i];
                transferSlot.par     = pars[i];
                dataTransferSlots[i] = transferSlot;
                //
                //
                string parTypeName = par.ParameterType.ToString();
                if (parTypeName == "CefRefPtr<CefV8Value>&")
                {
                    if (!par.IsConstPar)
                    {
                        transferSlot.newVarName  = "temp_" + i;
                        transferSlot.preStmt     = "auto " + transferSlot.newVarName + "=" + "CefV8ValueCToCpp::Unwrap(" + transferSlot.par.ParameterName + ");";
                        transferSlot.postStmt    = transferSlot.par.ParameterName + "= CefV8ValueCToCpp::Wrap(" + transferSlot.newVarName + ");";
                        transferSlot.isCppOutVar = true;
                        hasSomeOutVars           = true;
                    }
                }
                else if (parTypeName == "CefString&")
                {
                    if (!par.IsConstPar)
                    {
                        transferSlot.newVarName  = "temp_" + i;
                        transferSlot.preStmt     = "auto " + transferSlot.newVarName + "=" + transferSlot.par.ParameterName + ";";
                        transferSlot.postStmt    = transferSlot.par.ParameterName + "=" + transferSlot.newVarName + ";";
                        transferSlot.isCppOutVar = true;
                        hasSomeOutVars           = true;
                    }
                }
            }


            //first par is managed callback
            stbuilder.Append("managed_callback mcallback");
            for (int i = 0; i < j; ++i)
            {
                stbuilder.Append(",");
                CodeMethodParameter par = pars[i];
                if (par.IsConstPar)
                {
                    stbuilder.Append("const ");
                }
                //parameter type
                stbuilder.Append(par.ParameterType.ResolvedType.FullName + " ");
                stbuilder.Append(par.ParameterName);
            }
            stbuilder.AppendLine("){");
            //-----------

            for (int i = 0; i < j; ++i)
            {
                MethodParameter parTx = met.pars[i];
                parTx.ClearExtractCode();
                PrepareDataFromNativeToCs(parTx, "&vargs[" + (i + 1) + "]", parTx.Name, true);
            }
            //method body

            //-----------------------------
            //use native C data slot
            stbuilder.AppendLine("if(mcallback){");

            //'out' vars
            if (hasSomeOutVars)
            {
                //temp,
                for (int i = 0; i < j; ++i)
                {
                    CppTempParameterSlot transferSlot = dataTransferSlots[i];
                    if (transferSlot.isCppOutVar)
                    {
                        stbuilder.AppendLine(transferSlot.preStmt);
                    }
                }
            }
            //-----------------------------
            //
            string metArgsClassName = metDecl.Name + "Args";

            stbuilder.Append(metArgsClassName + " args1");
            //with ctors
            if (j == 0)
            {
                stbuilder.AppendLine(";");
            }
            else
            {
                stbuilder.Append("(");
                for (int i = 0; i < j; ++i)
                {
                    if (i > 0)
                    {
                        stbuilder.Append(",");
                    }
                    //
                    MethodParameter      par          = met.pars[i];
                    CppTempParameterSlot transferSlot = dataTransferSlots[i];
                    if (transferSlot.isCppOutVar)
                    {
                        stbuilder.Append("&" + transferSlot.newVarName);
                    }
                    else
                    {
                        //temp
                        string parType = par.TypeSymbol.ToString();
                        if (parType.EndsWith("&"))
                        {
                            stbuilder.Append("&");
                        }
                        stbuilder.Append(par.Name);
                    }
                }
                stbuilder.AppendLine(");");
            }
            stbuilder.AppendLine("mcallback( (_typeName << 16) | " + met.CppMethodSwitchCaseName + ",&args1.arg);");


            //------
            //'out' vars
            if (hasSomeOutVars)
            {
                //temp,
                for (int i = 0; i < j; ++i)
                {
                    CppTempParameterSlot transferSlot = dataTransferSlots[i];
                    if (transferSlot.isCppOutVar)
                    {
                        stbuilder.AppendLine(transferSlot.postStmt);
                    }
                }
            }

            //temp fix, arg extract code
            if (!met.ReturnPlan.IsVoid)
            {
                stbuilder.AppendLine("return args1.arg.myext_ret_value;");
            }
            stbuilder.AppendLine("}");


            //-------------------
            //default return if no managed callback
            if (!met.ReturnPlan.IsVoid)
            {
                string retTypeName = metDecl.ReturnType.ToString();
                if (retTypeName.StartsWith("CefRefPtr<"))
                {
                    stbuilder.Append("return nullptr;");
                }
                else
                {
                    switch (metDecl.ReturnType.ToString())
                    {
                    case "bool":
                        stbuilder.Append("return false;");
                        break;

                    case "FilterStatus":     //TODO: revisit here
                        stbuilder.Append("return (FilterStatus)0;");
                        break;

                    case "ReturnValue":
                    {
                        string ownerName = metDecl.OwnerTypeDecl.Name;
                        stbuilder.Append("return (" + ownerName + "::ReturnValue)0;");
                    }
                    break;

                    case "CefSize":
                        stbuilder.Append("return CefSize();");
                        break;

                    case "size_t":
                        stbuilder.Append("return 0;");
                        break;

                    case "int":
                        stbuilder.Append("return 0;");
                        break;

                    case "int64":
                        stbuilder.Append("return 0;");
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }
            }

            stbuilder.AppendLine("}"); //method
        }