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