/// <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); }
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(");"); }
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; } } } }
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(); } } }
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)); }
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); } } } //----------------------- }
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()); //------------------------------------------------------------------ }
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 }