Files
VisualSapfor/src/Visual_DVM_2021/Passes/All/SPF_GetGraphFunctions.java

145 lines
6.6 KiB
Java
Raw Normal View History

package Visual_DVM_2021.Passes.All;
import Common_old.Current;
import Common_old.UI.UI;
2023-09-17 22:13:42 +03:00
import Common.Utils.Index;
import Common_old.Utils.Utils;
2023-09-17 22:13:42 +03:00
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;
2023-09-17 22:13:42 +03:00
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(); //удаление интеррупта.
Current.set(Current.Function, null);
Current.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<String, FuncInfo> 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<String> done_programs = new Vector<>();
for (int i = 0; i < numOfFiles; ++i) {
String fileName = Utils.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);
2023-11-26 16:11:17 +03:00
fc.parent_offset = nf.line - fc.line;
2023-09-17 22:13:42 +03:00
nf.calls.add(fc);
}
}
file.CallGraphTitle = "Объявлений : " + file.function_decls.size() + "; Вызовов : " + call_count;
}
}
//---
//вторая фаза распаковки. дополняем список стандартными и не найденными функциями
//------
LinkedHashMap<String, FuncInfo> 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<String, FuncInfo> 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));
//------
//теперь когда известны все объявления, ищем где они вызвались
//<editor-fold desc="Функции и их вызовы по файлам">
target.BuildInlineGraph();
//</editor-fold>
//<editor-fold desc="иерархический граф.">
target.BuildInlineGraph2();
//--
//</editor-fold>
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();
}
}