2024-10-14 12:14:01 +03:00
|
|
|
|
package _VisualDVM.Passes.All;
|
2025-04-13 20:14:25 +03:00
|
|
|
|
import Common.Utils.Utils_;
|
2024-10-07 00:58:29 +03:00
|
|
|
|
import _VisualDVM.Global;
|
2024-10-14 15:19:13 +03:00
|
|
|
|
import _VisualDVM.Passes.PassCode;
|
|
|
|
|
|
import _VisualDVM.Passes.Sapfor.SilentSapforPass;
|
2024-10-09 22:21:57 +03:00
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.FuncCall;
|
|
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.FuncCallH;
|
|
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.FuncInfo;
|
|
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.FunctionType;
|
2025-04-13 20:14:25 +03:00
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.Json.FunctionGraphPositionJson;
|
|
|
|
|
|
import _VisualDVM.ProjectData.SapforData.Functions.Json.FunctionsGraphPositionsJson;
|
2023-09-17 22:13:42 +03:00
|
|
|
|
import javafx.util.Pair;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Vector;
|
|
|
|
|
|
public class SPF_GetGraphFunctionPositions extends SilentSapforPass {
|
|
|
|
|
|
//-ФИЛЬТРАЦИЯ ГРАФА -----------------------------------
|
|
|
|
|
|
public static boolean showStandardFunctions = true;
|
|
|
|
|
|
public static boolean showExternalFunctions = true;
|
|
|
|
|
|
public static boolean showUnreachableFunctions = true;
|
|
|
|
|
|
public static boolean showByCurrentFunction = false;
|
|
|
|
|
|
public static boolean showIn = true;
|
|
|
|
|
|
public static boolean showOut = true;
|
|
|
|
|
|
public static int depth = 1;
|
|
|
|
|
|
public static String filterName = "";
|
|
|
|
|
|
@Override
|
2024-10-14 15:19:13 +03:00
|
|
|
|
public String getIconPath() {
|
|
|
|
|
|
return "/icons/screen.png";
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public String getButtonText() {
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
2023-09-17 22:13:42 +03:00
|
|
|
|
protected boolean canStart(Object... args) throws Exception {
|
2024-10-14 15:19:13 +03:00
|
|
|
|
return Global.mainModule.getPass(PassCode.SPF_GetGraphFunctions).isDone() && super.canStart(args);
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
//--------------------
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public boolean needsConfirmations() {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected boolean needsAnimation() {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
2024-10-09 23:37:58 +03:00
|
|
|
|
protected PassCode necessary() {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
// return PassCode_2021.SPF_GetGraphFunctions;
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void performPreparation() throws Exception {
|
|
|
|
|
|
target.functionsGraph.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void showPreparation() {
|
2024-10-15 02:32:52 +03:00
|
|
|
|
Global.mainModule.getUI().getMainWindow().getProjectWindow().ShowNoFunctions();
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void performDone() throws Exception {
|
|
|
|
|
|
if (!sapfor.getResult().isEmpty())
|
|
|
|
|
|
unpack(sapfor.getResult());
|
|
|
|
|
|
}
|
|
|
|
|
|
public void findFuncMatches_r(FuncCallH level, String funcName, Vector<FuncCallH> matches) {
|
|
|
|
|
|
if (funcName.equals(level.funcName)) {
|
|
|
|
|
|
matches.add(level);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
for (FuncCallH callH : level.calls)
|
|
|
|
|
|
findFuncMatches_r(callH, funcName, matches);
|
|
|
|
|
|
}
|
|
|
|
|
|
public boolean isFunctionUnreachable(String funcName) {
|
|
|
|
|
|
if (target.main_functionH == null) return true; //нет гпе. недостижимо всё!
|
|
|
|
|
|
Vector<FuncCallH> res = new Vector<>();
|
|
|
|
|
|
findFuncMatches_r(target.main_functionH, funcName, res);
|
|
|
|
|
|
return res.isEmpty();
|
|
|
|
|
|
}
|
|
|
|
|
|
public boolean isVisible(FuncInfo fi) {
|
|
|
|
|
|
return (showStandardFunctions || !fi.type.equals(FunctionType.Standard)) &&
|
|
|
|
|
|
(showExternalFunctions || !fi.type.equals(FunctionType.NotFound)) &&
|
|
|
|
|
|
(showUnreachableFunctions || !isFunctionUnreachable(fi.funcName)) &&
|
|
|
|
|
|
fi.funcName.contains(filterName);
|
|
|
|
|
|
}
|
|
|
|
|
|
public void getNeighbors_r(Vector<String> res, String name, int depth, boolean in, boolean out) {
|
|
|
|
|
|
if (!res.contains(name)) {
|
|
|
|
|
|
res.add(name);
|
|
|
|
|
|
if (depth > 0) {
|
|
|
|
|
|
if (out) {
|
2025-04-13 17:19:10 +03:00
|
|
|
|
for (FuncCall call : target.allFunctions.get(name).callsFrom)
|
2023-09-17 22:13:42 +03:00
|
|
|
|
getNeighbors_r(res, call.funcName, depth - 1, in, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (in) {
|
|
|
|
|
|
for (FuncInfo parent : target.allFunctions.values()) {
|
2025-04-13 17:19:10 +03:00
|
|
|
|
for (FuncCall call : parent.callsFrom) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
if (call.funcName.equals(name)) {
|
|
|
|
|
|
getNeighbors_r(res, parent.funcName, depth - 1, true, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void getNeighborsNoDepth_r(Vector<String> res, String name, boolean in, boolean out) {
|
|
|
|
|
|
if (!res.contains(name)) {
|
|
|
|
|
|
res.add(name);
|
|
|
|
|
|
if (out) {
|
2025-04-13 17:19:10 +03:00
|
|
|
|
for (FuncCall call : target.allFunctions.get(name).callsFrom)
|
2023-09-17 22:13:42 +03:00
|
|
|
|
getNeighborsNoDepth_r(res, call.funcName, in, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (in) {
|
|
|
|
|
|
for (FuncInfo parent : target.allFunctions.values()) {
|
2025-04-13 17:19:10 +03:00
|
|
|
|
for (FuncCall call : parent.callsFrom) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
if (call.funcName.equals(name)) {
|
|
|
|
|
|
getNeighborsNoDepth_r(res, parent.funcName, true, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public Vector<String> getNeighbors(String name, int depth, boolean in, boolean out) {
|
|
|
|
|
|
Vector<String> res = new Vector<>();
|
|
|
|
|
|
if (depth > 0)
|
|
|
|
|
|
getNeighbors_r(res, name, depth, in, out);
|
|
|
|
|
|
else getNeighborsNoDepth_r(res, name, in, out);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
public String packFgSettings() {
|
2024-10-15 13:35:33 +03:00
|
|
|
|
Pair<Integer, Integer> screenDims = Global.mainModule.getUI().getMainWindow().getProjectWindow().getFunctionsWindow().getFunctionsGraphPanelSizes();
|
2023-09-17 22:13:42 +03:00
|
|
|
|
int x = (int) (screenDims.getKey() * target.fgScreen);
|
|
|
|
|
|
int y = (int) (screenDims.getValue() * target.fgScreen);
|
|
|
|
|
|
Vector<String> visibleFuncNames = new Vector<>();
|
2024-10-13 22:08:13 +03:00
|
|
|
|
if (showByCurrentFunction && Global.mainModule.HasFunction()) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
Vector<String> rawVisible =
|
2024-10-13 22:08:13 +03:00
|
|
|
|
getNeighbors(Global.mainModule.getFunction().funcName,
|
2023-09-17 22:13:42 +03:00
|
|
|
|
depth,
|
|
|
|
|
|
showIn,
|
|
|
|
|
|
showOut);
|
2024-10-14 15:19:13 +03:00
|
|
|
|
// String text = String.join("\n", rawVisible);
|
|
|
|
|
|
// UI.Info(text);
|
2023-09-17 22:13:42 +03:00
|
|
|
|
for (String funcName : rawVisible)
|
|
|
|
|
|
if (!visibleFuncNames.contains(funcName) && isVisible(target.allFunctions.get(funcName)))
|
|
|
|
|
|
visibleFuncNames.add(funcName);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
for (FuncInfo fi : target.allFunctions.values()) {
|
|
|
|
|
|
if (isVisible(fi))
|
|
|
|
|
|
visibleFuncNames.add(fi.funcName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
String res = "|" + target.fgIterations + "|" + target.fgResistance + "|" + x + "|" + y + "|" + visibleFuncNames.size();
|
|
|
|
|
|
if (visibleFuncNames.size() > 0) res += "|" + String.join("|", visibleFuncNames);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
public static void getNearestFunctions_r(Vector<String> res, String funcName, int depth, boolean in, boolean out) {
|
|
|
|
|
|
if (depth > 0) {
|
|
|
|
|
|
res.add(funcName);
|
|
|
|
|
|
if (out) {
|
|
|
|
|
|
FuncInfo fi = Current.getProject().allFunctions.get(funcName);
|
|
|
|
|
|
for (FuncCall fc : fi.calls) {
|
|
|
|
|
|
if (!res.contains(fc.funcName)) {
|
|
|
|
|
|
res.add(fc.funcName);
|
|
|
|
|
|
getNearestFunctions_r(res, fc.funcName, depth - 1, in, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//!!
|
|
|
|
|
|
if (in) {
|
|
|
|
|
|
//ищем кто нас вызывает
|
|
|
|
|
|
for (FuncInfo fi : Current.getProject().allFunctions.values()) {
|
|
|
|
|
|
for (FuncCall fc : fi.calls)
|
|
|
|
|
|
if (fc.funcName.equals(funcName)) {
|
|
|
|
|
|
res.add(fi.funcName);
|
|
|
|
|
|
getNearestFunctions_r(res, fi.funcName, depth - 1, in, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public static void getNearestFunctions_r(Vector<String> res, String funcName, boolean in, boolean out) {
|
|
|
|
|
|
res.add(funcName);
|
|
|
|
|
|
if (out) {
|
|
|
|
|
|
FuncInfo fi = Current.getProject().allFunctions.get(funcName);
|
|
|
|
|
|
for (FuncCall fc : fi.calls) {
|
|
|
|
|
|
if (!res.contains(fc.funcName)) {
|
|
|
|
|
|
res.add(fc.funcName);
|
|
|
|
|
|
getNearestFunctions_r(res, fc.funcName, in, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (in) {
|
|
|
|
|
|
//ищем кто нас вызывает
|
|
|
|
|
|
for (FuncInfo fi : Current.getProject().allFunctions.values()) {
|
|
|
|
|
|
for (FuncCall fc : fi.calls)
|
|
|
|
|
|
if (fc.funcName.equals(funcName)) {
|
|
|
|
|
|
res.add(fi.funcName);
|
|
|
|
|
|
getNearestFunctions_r(res, fi.funcName, true, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public static Vector<String> getNearestFunctions(String funcName, int depth, boolean in, boolean out) {
|
|
|
|
|
|
Vector<String> res = new Vector<>();
|
|
|
|
|
|
if (depth > 0)
|
|
|
|
|
|
getNearestFunctions_r(res, funcName, depth, in, out);
|
|
|
|
|
|
else
|
|
|
|
|
|
getNearestFunctions_r(res, funcName, in, out);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
*/
|
|
|
|
|
|
protected void unpack(String packed) throws Exception {
|
2025-04-13 20:14:25 +03:00
|
|
|
|
FunctionsGraphPositionsJson positionsJson = Utils_.gson.fromJson(packed, FunctionsGraphPositionsJson.class);
|
|
|
|
|
|
for (FunctionGraphPositionJson positionJson: positionsJson.allPositions)
|
|
|
|
|
|
target.functionsGraph.vertexCoordinates.put(positionJson.functionName, new Pair<>(positionJson.x, positionJson.y));
|
2023-09-17 22:13:42 +03:00
|
|
|
|
//теперь добавить ребер.
|
|
|
|
|
|
for (String funcName : target.functionsGraph.vertexMap.keySet()) {
|
|
|
|
|
|
FuncInfo fi = target.allFunctions.get(funcName);
|
2025-04-13 17:19:10 +03:00
|
|
|
|
for (FuncCall fc : fi.callsFrom) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
if (target.functionsGraph.vertexMap.containsKey(fc.funcName))
|
|
|
|
|
|
target.functionsGraph.addEdge(
|
|
|
|
|
|
funcName,
|
|
|
|
|
|
fc.funcName
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//---
|
|
|
|
|
|
//теперь соотнести с сохранением.
|
2024-10-14 15:19:13 +03:00
|
|
|
|
for (String funcName : target.db.funcCoordinates.Data.keySet()) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
if (target.functionsGraph.vertexCoordinates.containsKey(funcName)) {
|
|
|
|
|
|
target.functionsGraph.vertexCoordinates.replace(funcName,
|
|
|
|
|
|
new Pair<>(
|
|
|
|
|
|
target.db.funcCoordinates.get(funcName).X,
|
|
|
|
|
|
target.db.funcCoordinates.get(funcName).Y
|
|
|
|
|
|
));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void body() throws Exception {
|
|
|
|
|
|
sapfor.RunAnalysis(
|
|
|
|
|
|
getSapforPassName(),
|
|
|
|
|
|
-Global.messagesServer.getPort(),
|
2025-01-16 02:26:51 +03:00
|
|
|
|
target.sapforProperties.pack() +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
packFgSettings(),
|
|
|
|
|
|
target.getProjFile().getAbsolutePath());
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void showDone() throws Exception {
|
2024-10-15 02:32:52 +03:00
|
|
|
|
Global.mainModule.getUI().getMainWindow().getProjectWindow().ShowFunctions();
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|