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