Files
VisualSapfor/src/_VisualDVM/Passes/All/SPF_GetGraphFunctionPositions.java
2024-10-14 12:14:01 +03:00

275 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package _VisualDVM.Passes.All;
import _VisualDVM.Global;
import _VisualDVM.Visual.UI;
import _VisualDVM.ProjectData.SapforData.Functions.FuncCall;
import _VisualDVM.ProjectData.SapforData.Functions.FuncCallH;
import _VisualDVM.ProjectData.SapforData.Functions.FuncInfo;
import _VisualDVM.ProjectData.SapforData.Functions.FunctionType;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.Passes.Sapfor.SilentSapforPass;
import javafx.util.Pair;
import java.util.Vector;
public class SPF_GetGraphFunctionPositions extends SilentSapforPass {
@Override
public String getIconPath() {
return "/icons/screen.png";
}
@Override
public String getButtonText() {
return "";
}
//-ФИЛЬТРАЦИЯ ГРАФА -----------------------------------
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
protected boolean canStart(Object... args) throws Exception {
return Global.mainModule.getPass(PassCode.SPF_GetGraphFunctions).isDone() && super.canStart(args);
}
//--------------------
@Override
public boolean needsConfirmations() {
return false;
}
@Override
protected boolean needsAnimation() {
return false;
}
@Override
protected PassCode necessary() {
return null;
}
// return PassCode_2021.SPF_GetGraphFunctions;
@Override
protected void performPreparation() throws Exception {
target.functionsGraph.Clear();
}
@Override
protected void showPreparation() {
UI.getMainWindow().getProjectWindow().ShowNoFunctions();
}
@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) {
for (FuncCall call : target.allFunctions.get(name).calls)
getNeighbors_r(res, call.funcName, depth - 1, in, true);
}
if (in) {
for (FuncInfo parent : target.allFunctions.values()) {
for (FuncCall call : parent.calls) {
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) {
for (FuncCall call : target.allFunctions.get(name).calls)
getNeighborsNoDepth_r(res, call.funcName, in, true);
}
if (in) {
for (FuncInfo parent : target.allFunctions.values()) {
for (FuncCall call : parent.calls) {
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() {
Pair<Integer, Integer> screenDims = UI.getMainWindow().getProjectWindow().getFunctionsWindow().getFunctionsGraphPanelSizes();
int x = (int) (screenDims.getKey() * target.fgScreen);
int y = (int) (screenDims.getValue() * target.fgScreen);
Vector<String> visibleFuncNames = new Vector<>();
if (showByCurrentFunction && Global.mainModule.HasFunction()) {
Vector<String> rawVisible =
getNeighbors(Global.mainModule.getFunction().funcName,
depth,
showIn,
showOut);
// String text = String.join("\n", rawVisible);
// UI.Info(text);
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 {
String[] splited = packed.split("\\|");
int j = 0;
//-
String currentFuncName = "";
double x = 0;
double y = 0;
//-
for (int i = 1; i < splited.length; ++i) {
switch (j) {
case 0:
currentFuncName = splited[i];
target.functionsGraph.addVertex(currentFuncName);
j++;
break;
case 1:
x = Double.parseDouble(splited[i]);
j++;
break;
case 2:
y = Double.parseDouble(splited[i]);
target.functionsGraph.vertexCoordinates.put(currentFuncName, new Pair<>(x, y));
j = 0;
break;
}
}
//теперь добавить ребер.
for (String funcName : target.functionsGraph.vertexMap.keySet()) {
FuncInfo fi = target.allFunctions.get(funcName);
for (FuncCall fc : fi.calls) {
if (target.functionsGraph.vertexMap.containsKey(fc.funcName))
target.functionsGraph.addEdge(
funcName,
fc.funcName
);
}
}
//---
//теперь соотнести с сохранением.
for (String funcName: target.db.funcCoordinates.Data.keySet()){
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(),
Global.packSapforSettings() +
packFgSettings(),
target.getProjFile().getAbsolutePath());
}
@Override
protected void showDone() throws Exception {
UI.getMainWindow().getProjectWindow().ShowFunctions();
}
}