package Visual_DVM_2021.Passes.All; import Common.CurrentAnchestor; import Common.Utils.CommonUtils; import Common_old.Current; import Common_old.UI.UI; import Common.Utils.Index; import ProjectData.Files.DBProjectFile; import ProjectData.SapforData.Functions.FuncCall; import ProjectData.SapforData.Functions.FuncInfo; import ProjectData.SapforData.Functions.FunctionType; import Visual_DVM_2021.Passes.PassCode_2021; import Visual_DVM_2021.Passes.SapforAnalysis; import java.util.LinkedHashMap; import java.util.Vector; public class SPF_GetGraphFunctions extends SapforAnalysis { @Override protected void showPreparation() { if (Current.HasFile()) Current.getFile().form.ShowNoFunctions(); UI.getMainWindow().getProjectWindow().ShowNoFunctions(); if (SPF_GetGraphFunctionPositions.showByCurrentFunction) UI.getMainWindow().getProjectWindow().getFunctionsWindow().ShowNoCurrentFunction(); } @Override protected boolean alwaysCheck() { return true; } @Override protected boolean isAtomic() { return false; } @Override protected void performPreparation() throws Exception { super.performPreparation(); //удаление интеррупта. CurrentAnchestor.set(Current.Function, null); CurrentAnchestor.set(Current.SelectedFunction,null); target.main_function = null; target.main_functionH = null; target.allFunctions.clear(); target.functionsGraph.Clear(); target.inline_root.removeAllChildren(); target.inline_root2.removeAllChildren(); //- target.numFunctions = 0; for (DBProjectFile file : target.db.files.Data.values()) file.function_decls.clear(); } @Override protected void unpack(String packed) throws Exception { LinkedHashMap declarated_functions = new LinkedHashMap<>(); String[] splited = packed.split("\\|"); Index idx = new Index(); // new version of function graph reading, availible from Sapfor version 156 int numOfFiles = Integer.parseInt(splited[idx.Inc()]); Vector done_programs = new Vector<>(); for (int i = 0; i < numOfFiles; ++i) { String fileName = CommonUtils.toW(splited[idx.Inc()]); int functions_count = Integer.parseInt(splited[idx.Inc()]); DBProjectFile file = target.db.files.Data.get(fileName); if (!done_programs.contains(fileName)) { int call_count = 0; done_programs.add(fileName); for (int k = 0; k < functions_count; ++k) { String f_name = splited[idx.Inc()]; Index calls_number = new Index(); //тело функции FuncInfo nf = new FuncInfo(f_name, file, splited[idx.Inc()].split("#"), calls_number); if (nf.isMain()) { file.isMain = 1; target.main_function = nf; target.db.Update(file); } declarated_functions.put(nf.funcName, nf); //-------------------------------- file.function_decls.put(nf.funcName, nf); //-------------------------------- call_count += calls_number.getValue(); for (int j = 0; j < calls_number.getValue(); ++j) { String call_name = splited[idx.Inc()]; int c_line = Integer.parseInt(splited[idx.Inc()]); //- FuncCall fc = new FuncCall(file, call_name, c_line); fc.parent_offset = nf.line - fc.line; nf.calls.add(fc); } } file.CallGraphTitle = "Объявлений : " + file.function_decls.size() + "; Вызовов : " + call_count; } } //--- //вторая фаза распаковки. дополняем список стандартными и не найденными функциями //------ LinkedHashMap special_functions = new LinkedHashMap<>(); for (FuncInfo funcInfo : declarated_functions.values()) { for (FuncCall funcCall : funcInfo.calls) { if (!declarated_functions.containsKey(funcCall.funcName) && ( !special_functions.containsKey(funcCall.funcName) )) { //нет среди объявленных и еще не встречалась. значит это стандартная либо не найдено объявление. special_functions.put(funcCall.funcName, new FuncInfo(funcCall.funcName, sapfor.isIntrinsic(funcCall.funcName) ? FunctionType.Standard : FunctionType.NotFound )); } } } //------ //составляем единый список функций. LinkedHashMap all_functions = target.allFunctions; declarated_functions.values().forEach(funcInfo -> all_functions.put(funcInfo.funcName, funcInfo)); special_functions.values().forEach(funcInfo -> all_functions.put(funcInfo.funcName, funcInfo)); //------ //теперь когда известны все объявления, ищем где они вызвались // target.BuildInlineGraph(); // // target.BuildInlineGraph2(); //-- // target.numFunctions += target.allFunctions.size(); target.UpdateFunctionsCount(); } @Override public String phase() { return "CALL_GRAPH2"; } @Override protected void FocusResult() { super.FocusResult(); if (Current.HasFile()) Current.getFile().form.FocusFunctions(); UI.getMainWindow().getProjectWindow().FocusFunctions(); } @Override protected void showDone() throws Exception { super.showDone(); UI.getMainWindow().getProjectWindow().getAnalysisWindow().ShowFunctionsCount(); UI.getMainWindow().getProjectWindow().getAnalysisWindow().ShowRegions(); if (Current.HasFile()) Current.getFile().form.ShowFunctions(); passes.get(PassCode_2021.SPF_GetGraphFunctionPositions).Do(); } }