package _VisualDVM.Passes.All; import _VisualDVM.Global; import _VisualDVM.Passes.PassCode; import _VisualDVM.Passes.Sapfor.SilentSapforPass; 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 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 public String getIconPath() { return "/icons/screen.png"; } @Override public String getButtonText() { return ""; } @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() { Global.mainModule.getUI().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 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 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 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 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 getNeighbors(String name, int depth, boolean in, boolean out) { Vector 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 screenDims = Global.mainModule.getUI().getMainWindow().getProjectWindow().getFunctionsWindow().getFunctionsGraphPanelSizes(); int x = (int) (screenDims.getKey() * target.fgScreen); int y = (int) (screenDims.getValue() * target.fgScreen); Vector visibleFuncNames = new Vector<>(); if (showByCurrentFunction && Global.mainModule.HasFunction()) { Vector 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 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 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 getNearestFunctions(String funcName, int depth, boolean in, boolean out) { Vector 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 { Global.mainModule.getUI().getMainWindow().getProjectWindow().ShowFunctions(); } }