Перенос.
This commit is contained in:
49
src/ProjectData/DBArray/ArraysDBTable.java
Normal file
49
src/ProjectData/DBArray/ArraysDBTable.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ProjectData.DBArray;
|
||||
import Common.Current;
|
||||
import Common.Database.DBTable;
|
||||
import Common.UI.DataSetControlForm;
|
||||
public class ArraysDBTable extends DBTable<String, DBArray> {
|
||||
public ArraysDBTable() {
|
||||
super(String.class, DBArray.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "массив";
|
||||
}
|
||||
@Override
|
||||
public String getPluralDescription() {
|
||||
return "сохранённые состояния";
|
||||
}
|
||||
@Override
|
||||
protected DataSetControlForm createUI() {
|
||||
return new DataSetControlForm(this) {
|
||||
@Override
|
||||
public boolean hasCheckBox() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
protected void AdditionalInitColumns() {
|
||||
columns.get(1).setEditable(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public String[] getUIColumnNames() {
|
||||
return new String[]{"Имя"};
|
||||
}
|
||||
@Override
|
||||
public Object getFieldAt(DBArray array, int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 1:
|
||||
return array.State;
|
||||
case 2:
|
||||
return array.shortName;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.DBArray;
|
||||
}
|
||||
}
|
||||
28
src/ProjectData/DBArray/DBArray.java
Normal file
28
src/ProjectData/DBArray/DBArray.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package ProjectData.DBArray;
|
||||
import Common.Database.DBObject;
|
||||
import ProjectData.SapforData.Arrays.ArrayState;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
|
||||
import javax.swing.*;
|
||||
public class DBArray extends DBObject {
|
||||
@Description("PRIMARY KEY, UNIQUE")
|
||||
public String UniqKey;
|
||||
public String shortName;
|
||||
public ArrayState State;
|
||||
public DBArray() {
|
||||
}
|
||||
public DBArray(ProjectArray array) {
|
||||
UniqKey = array.UniqKey;
|
||||
shortName = array.shortName;
|
||||
State = array.State;
|
||||
}
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return UniqKey;
|
||||
}
|
||||
@Override
|
||||
public ImageIcon GetSelectionIcon() {
|
||||
return State.GetIcon();
|
||||
}
|
||||
}
|
||||
596
src/ProjectData/Files/DBProjectFile.java
Normal file
596
src/ProjectData/Files/DBProjectFile.java
Normal file
@@ -0,0 +1,596 @@
|
||||
package ProjectData.Files;
|
||||
import Common.Current;
|
||||
import Common.Database.DBObject;
|
||||
import Common.Global;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.GCOV.GCOV_info;
|
||||
import ProjectData.LanguageName;
|
||||
import ProjectData.Messages.Errors.MessageError;
|
||||
import ProjectData.Messages.Message;
|
||||
import ProjectData.Messages.Notes.MessageNote;
|
||||
import ProjectData.Messages.Warnings.MessageWarning;
|
||||
import ProjectData.Project.db_project_info;
|
||||
import ProjectData.SapforData.Arrays.ArrayDecl;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
import ProjectData.SapforData.Functions.FuncCall;
|
||||
import ProjectData.SapforData.Functions.FuncInfo;
|
||||
import ProjectData.SapforData.Loops.Loop;
|
||||
import Visual_DVM_2021.UI.Main.FileForm;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
//по файлам нет смысла делать совместимость.
|
||||
//так что переименую
|
||||
public class DBProjectFile extends DBObject {
|
||||
public static final String no_data = "Нет данных";
|
||||
public static final String dep = ".dep";
|
||||
public static final String out = ".out";
|
||||
public static final String err = ".err";
|
||||
//</editor-fold>
|
||||
//<editor-fold desc="хранимые в бд поля">
|
||||
|
||||
@Description("PRIMARY KEY, UNIQUE") @Expose
|
||||
public String name; //имя относительно корневой папки проекта. нужно только как ключ для бд!!
|
||||
@Description("IGNORE")
|
||||
public String last_assembly_name = ""; //имя объектника.
|
||||
//--------------------------------------
|
||||
//в сотальных случаях используем file.
|
||||
@Expose
|
||||
public FileType fileType = FileType.none;
|
||||
@Expose
|
||||
public LanguageName languageName = LanguageName.n;
|
||||
@Expose
|
||||
public LanguageStyle style = LanguageStyle.none;
|
||||
public String options = ""; //пользовательские опции для парсера.
|
||||
// public int caretPosition = 0;
|
||||
//---
|
||||
@Description("DEFAULT 0")
|
||||
public int lastLine = 0;
|
||||
@Description("DEFAULT ''")
|
||||
public String GCOVLog = "";
|
||||
//---
|
||||
public FileState state = FileState.Undefined; //состояние файла.
|
||||
public int isMain = 0; //содержит ли ГПЕ
|
||||
@Description("IGNORE")
|
||||
public int lines_count = 0;
|
||||
@Description("IGNORE")
|
||||
public boolean NeedsSave = false;
|
||||
@Description("IGNORE")
|
||||
public String LoopGraphTitle = no_data;
|
||||
@Description("IGNORE")
|
||||
public String CallGraphTitle = no_data;
|
||||
@Description("IGNORE")
|
||||
public String ArrayGraphTitle = no_data;
|
||||
public db_project_info father = null;
|
||||
public File file = null;
|
||||
public DefaultMutableTreeNode node = null; //узел файла в дереве
|
||||
public FileForm form = null; //отображение.
|
||||
//сообщения.
|
||||
//----------------
|
||||
//анализы
|
||||
public Vector<Loop> LoopNests = new Vector<>();
|
||||
public LinkedHashMap<Integer, Loop> AllLoops = new LinkedHashMap<>();
|
||||
public LinkedHashMap<String, FuncInfo> function_decls = new LinkedHashMap<>(); //объявления
|
||||
public Vector<ArrayDecl> array_decls = new Vector<>();
|
||||
public LinkedHashMap<String, DBProjectFile> relativeHeaders = new LinkedHashMap<>();
|
||||
public GCOV_info gcov_info = new GCOV_info();
|
||||
public DBProjectFile() {
|
||||
}
|
||||
public DBProjectFile(File file_, db_project_info father_) {
|
||||
Init(file_, father_);
|
||||
//имя относительно папки проекта.
|
||||
RefreshName();
|
||||
AutoDetectProperties();
|
||||
}
|
||||
public static Pair<Integer, String> decodeParserMessage(String S, String file_in) {
|
||||
Integer line = 1;
|
||||
String file = file_in;
|
||||
String[] data = S.split("on line ");
|
||||
if (data.length > 1) {
|
||||
String[] data1 = data[1].split(" ");
|
||||
if (data1.length > 0)
|
||||
line = Integer.parseInt(data1[0]);
|
||||
}
|
||||
data = S.split("of");
|
||||
if (data.length > 1) {
|
||||
String[] data1 = data[1].split(":");
|
||||
if (data1.length > 0) {
|
||||
file = Utils.toW(data1[0].substring(1)); //первый символ тут всегда пробел. слеши всегда виндовые.
|
||||
}
|
||||
}
|
||||
return new Pair<>(line, file);
|
||||
}
|
||||
public void UpdateLastLine(int line_in) {
|
||||
if (lastLine != line_in) {
|
||||
try {
|
||||
lastLine = line_in;
|
||||
father.db.Update(this);
|
||||
} catch (Exception ex) {
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
//наследуем от объекта, чтобы использовать интерфейс выбора.
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return name;
|
||||
}
|
||||
@Description("IGNORE")
|
||||
public boolean IsMain() {
|
||||
return isMain != 0;
|
||||
}
|
||||
/*
|
||||
* получить имя относительно домашней папки проекта, в рамках текущей ОС *
|
||||
*/
|
||||
public String getLocalName() {
|
||||
return file.getAbsolutePath().substring(father.Home.getAbsolutePath().length());
|
||||
}
|
||||
public void Init(File file_, db_project_info father_) {
|
||||
father = father_;
|
||||
file = file_;
|
||||
}
|
||||
public void RefreshName() {
|
||||
String path = file.getAbsolutePath();
|
||||
//для совместимости пусть палки будут от винды всегда.
|
||||
name = path.substring(father.Home.getAbsolutePath().length() + 1).replace('/', '\\');
|
||||
}
|
||||
public void AutoDetectProperties() {
|
||||
//проверка запретных имен.
|
||||
String[] forbiddenNames = new String[]{
|
||||
db_project_info.interrupt,
|
||||
db_project_info.launch_script_name,
|
||||
db_project_info.default_binary_name,
|
||||
//--
|
||||
db_project_info.DONE,
|
||||
db_project_info.TIMEOUT,
|
||||
db_project_info.out_file,
|
||||
db_project_info.err_file,
|
||||
db_project_info.time_file,
|
||||
"Makefile"
|
||||
};
|
||||
for (String forbidden : forbiddenNames) {
|
||||
if (file.getName().equalsIgnoreCase(forbidden)) {
|
||||
fileType = FileType.forbidden;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//-
|
||||
switch (Utils.getExtension(file)) {
|
||||
case "f":
|
||||
case "fdv":
|
||||
case "for":
|
||||
case "f77":
|
||||
fileType = FileType.program;
|
||||
languageName = LanguageName.fortran;
|
||||
style = LanguageStyle.fixed;
|
||||
break;
|
||||
case "f90":
|
||||
fileType = FileType.program;
|
||||
languageName = LanguageName.fortran;
|
||||
style = LanguageStyle.free;
|
||||
break;
|
||||
case "c":
|
||||
case "cdv":
|
||||
fileType = FileType.program;
|
||||
languageName = LanguageName.c;
|
||||
break;
|
||||
case "cpp":
|
||||
fileType = FileType.program;
|
||||
languageName = LanguageName.cpp;
|
||||
break;
|
||||
case "h":
|
||||
fileType = FileType.header;
|
||||
break;
|
||||
case "fh":
|
||||
fileType = FileType.header;
|
||||
languageName = LanguageName.fortran;
|
||||
break;
|
||||
case "o":
|
||||
case "gcda":
|
||||
case "gcno":
|
||||
case "gcov":
|
||||
case "exe":
|
||||
case "pdf":
|
||||
fileType = FileType.forbidden;
|
||||
break;
|
||||
case "":
|
||||
if (Utils.isDigit(file.getName())) {
|
||||
fileType = FileType.forbidden;
|
||||
} else {
|
||||
state = FileState.Excluded;
|
||||
fileType = FileType.none;
|
||||
languageName = LanguageName.n;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//все остальное считаем исключенными из рассмотрения.
|
||||
//если юзеру надо сам их разблочит.
|
||||
state = FileState.Excluded;
|
||||
fileType = FileType.none;
|
||||
languageName = LanguageName.n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public boolean isMakefile() {
|
||||
return file.getName().equalsIgnoreCase("makefile");
|
||||
}
|
||||
public String ImageKey() {
|
||||
//icons/files/Excludeddata.png
|
||||
String pref = "/icons/files/";
|
||||
String body;
|
||||
switch (fileType) {
|
||||
case program:
|
||||
body = state.toString() + languageName.toString();
|
||||
break;
|
||||
case data:
|
||||
body= "Undefined"; // иных состояний у данных не бывает. ситуация возникает если по ошибке поменяли тип
|
||||
//нормальных файлов с сообщениями на дату.
|
||||
break;
|
||||
default:
|
||||
body = state.toString();
|
||||
break;
|
||||
}
|
||||
return pref + body + fileType + ".png";
|
||||
}
|
||||
public ImageIcon GetIcon() {
|
||||
URL imageUrl = getClass().getResource(ImageKey());
|
||||
if (imageUrl == null) {
|
||||
System.out.println(ImageKey() + "not found");
|
||||
}
|
||||
return new ImageIcon(imageUrl);
|
||||
}
|
||||
public boolean isActiveProgram() {
|
||||
return fileType.equals(FileType.program)
|
||||
&& languageName.equals(father.languageName) && !state.equals(FileState.Excluded);
|
||||
}
|
||||
//у хедера язык может быть неизвестен. потому что зависимости еще не искались.
|
||||
public boolean isActiveHeader() {
|
||||
return fileType.equals(FileType.header) && !state.equals(FileState.Excluded);
|
||||
}
|
||||
public boolean isActive() {
|
||||
return isActiveProgram() || isActiveHeader();
|
||||
}
|
||||
public File getDepFile() {
|
||||
return Paths.get(father.getOptionsDirectory().getAbsolutePath(), getLocalName() + dep).toFile();
|
||||
}
|
||||
public File getParserOutFile() {
|
||||
return Paths.get(father.getOptionsDirectory().getAbsolutePath(), getLocalName() + out).toFile();
|
||||
}
|
||||
public File getParserErrFile() {
|
||||
return Paths.get(father.getOptionsDirectory().getAbsolutePath(), getLocalName() + err).toFile();
|
||||
}
|
||||
public File getOptionsFile() {
|
||||
String path = file.getAbsolutePath().substring(father.Home.getAbsolutePath().length());
|
||||
return Paths.get(father.getOptionsDirectory().getAbsolutePath(), path + ".opt").toFile();
|
||||
}
|
||||
public void CreateParserOptions() throws IOException {
|
||||
String default_options = "";
|
||||
switch (languageName) {
|
||||
case fortran:
|
||||
default_options += " -spf -noProject -o " + Utils.DQuotes(getDepFile().getAbsolutePath());
|
||||
switch (style) {
|
||||
case free:
|
||||
default_options += " -f90";
|
||||
break;
|
||||
case fixed:
|
||||
default_options += " -FI";
|
||||
break;
|
||||
case extended:
|
||||
default_options += " -extend_source";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case c:
|
||||
//TODO
|
||||
break;
|
||||
}
|
||||
Utils.WriteToFile(getOptionsFile(), (default_options + " " + options + "\n"));
|
||||
}
|
||||
public void ReadMessages(String text) throws Exception {
|
||||
String[] nw = text.split("\n");
|
||||
for (String S : nw) {
|
||||
Pair<Integer, String> p = decodeParserMessage(S, name);
|
||||
if (S.toLowerCase().startsWith("note")) {
|
||||
father.db.files.Data.get(p.getValue()).CreateAndAddNewMessage(2, S, p.getKey(), Message.parser_group);
|
||||
} else if (S.toLowerCase().startsWith("warning")) {
|
||||
father.db.files.Data.get(p.getValue()).CreateAndAddNewMessage(0, S, p.getKey(), Message.parser_group);
|
||||
} else if (S.toLowerCase().startsWith("error"))
|
||||
father.db.files.Data.get(p.getValue()).CreateAndAddNewMessage(1, S, p.getKey(), Message.parser_group);
|
||||
}
|
||||
}
|
||||
public void ReadParseMessages() throws Exception {
|
||||
if (getParserOutFile().exists())
|
||||
ReadMessages(Utils.ReadAllText(getParserOutFile()));
|
||||
if (getParserErrFile().exists())
|
||||
ReadMessages(Utils.ReadAllText(getParserErrFile()));
|
||||
}
|
||||
//важно. тут транзакция своя, оборачивать ее нельзя!
|
||||
public void CleanMessages() throws Exception {
|
||||
if (!state.equals(FileState.Excluded)) state = FileState.Undefined;
|
||||
father.db.BeginTransaction();
|
||||
father.db.Update(this);
|
||||
Vector<Message> to_delete = new Vector<>();
|
||||
for (Message message : father.db.notes.Data.values()) {
|
||||
if (message.file.equalsIgnoreCase(name))
|
||||
to_delete.add(message);
|
||||
}
|
||||
for (Message message : father.db.warnings.Data.values()) {
|
||||
if (message.file.equalsIgnoreCase(name))
|
||||
to_delete.add(message);
|
||||
}
|
||||
for (Message message : father.db.errors.Data.values()) {
|
||||
if (message.file.equalsIgnoreCase(name))
|
||||
to_delete.add(message);
|
||||
}
|
||||
for (Message message : to_delete)
|
||||
father.db.Delete(message);
|
||||
father.db.Commit();
|
||||
}
|
||||
public void CleanAll() throws Exception {
|
||||
lines_count = 0;
|
||||
isMain = 0;
|
||||
CleanMessages();
|
||||
LoopGraphTitle = no_data;
|
||||
LoopNests.clear();
|
||||
;
|
||||
AllLoops.clear();
|
||||
CallGraphTitle = no_data;
|
||||
function_decls.clear();
|
||||
relativeHeaders.clear();
|
||||
ArrayGraphTitle = no_data;
|
||||
array_decls.clear();
|
||||
gcov_info.clear();
|
||||
}
|
||||
public void CreateAndAddNewMessage(int m_type, String m_value, int m_line, int m_group) throws Exception {
|
||||
switch (m_type) {
|
||||
case 0:
|
||||
MessageWarning warning = new MessageWarning(name, m_line, m_value, m_group);
|
||||
father.db.Insert(warning);
|
||||
father.db.recommendations.addRecommendation(m_group);
|
||||
if (state != FileState.HasErrors)
|
||||
state = FileState.HasWarnings;
|
||||
break;
|
||||
case 1:
|
||||
MessageError error = new MessageError(name, m_line, m_value, m_group);
|
||||
father.db.Insert(error);
|
||||
father.db.recommendations.addRecommendation(m_group);
|
||||
state = FileState.HasErrors;
|
||||
break;
|
||||
case 2:
|
||||
MessageNote note = new MessageNote(name, m_line, m_value, m_group);
|
||||
father.db.Insert(note);
|
||||
father.db.recommendations.addRecommendation(m_group);
|
||||
if (state != FileState.HasWarnings && state != FileState.HasErrors)
|
||||
state = FileState.HasNotes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public DefaultMutableTreeNode show_loop_graph_r(FileObjectWithMessages element) {
|
||||
DefaultMutableTreeNode res = new DefaultMutableTreeNode(element);
|
||||
if (element instanceof Loop) {
|
||||
for (FileObjectWithMessages child : ((Loop) element).children)
|
||||
res.add(show_loop_graph_r(child));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public DefaultMutableTreeNode getLoopsTree() {
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode(LoopGraphTitle);
|
||||
for (Loop nest : LoopNests)
|
||||
root.add(show_loop_graph_r(nest));
|
||||
return root;
|
||||
}
|
||||
public DefaultMutableTreeNode getFunctionsTree() {
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode(CallGraphTitle);
|
||||
for (FuncInfo fi : function_decls.values()) {
|
||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode(fi);
|
||||
for (FuncCall fc : fi.calls)
|
||||
node.add(new DefaultMutableTreeNode(fc));
|
||||
root.add(node);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
public DefaultMutableTreeNode getArraysTree() {
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode(ArrayGraphTitle);
|
||||
for (ArrayDecl a : array_decls)
|
||||
root.add(new DefaultMutableTreeNode(a));
|
||||
return root;
|
||||
}
|
||||
public boolean UpdateType(FileType type_in) {
|
||||
if (!fileType.equals(type_in)) {
|
||||
fileType = type_in;
|
||||
try {
|
||||
father.db.Update(this);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Global.Log.PrintException(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean UpdateLanguage(LanguageName lang_in) {
|
||||
if (!languageName.equals(lang_in)) {
|
||||
languageName = lang_in;
|
||||
try {
|
||||
father.db.Update(this);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Global.Log.PrintException(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean UpdateStyle(LanguageStyle s_in) {
|
||||
if (!style.equals(s_in)) {
|
||||
style = s_in;
|
||||
try {
|
||||
father.db.Update(this);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Global.Log.PrintException(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public int getFirstBadLine() {
|
||||
for (MessageError error : father.db.errors.Data.values())
|
||||
if (error.file.equals(this.name)) return error.line;
|
||||
return -1;
|
||||
}
|
||||
public int FragmentLoopCount(int first, int second) {
|
||||
int res = 0;
|
||||
for (Loop l : AllLoops.values()) {
|
||||
if ((l.line >= first) && (l.line <= second))
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public int FragmentFunctionDeclsCount(int first, int second) {
|
||||
int res = 0;
|
||||
for (FuncInfo fi : function_decls.values()) {
|
||||
if ((fi.line >= first) && (fi.line <= second))
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public int FragmentFunctionCallsCount(int first, int second) {
|
||||
int res = 0;
|
||||
for (FuncInfo fi : function_decls.values())
|
||||
for (FuncCall fc : fi.calls) {
|
||||
if ((fc.line >= first) && (fc.line <= second))
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public FuncCall find_current_func_call() {
|
||||
//-------------
|
||||
for (FuncInfo fi : function_decls.values()) {
|
||||
for (FuncCall fc : fi.calls) {
|
||||
if ((fc.line == form.getEditor().getCurrentLine()) &&
|
||||
!Current.getSapfor().isIntrinsic(fc.funcName)
|
||||
) {
|
||||
return fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------
|
||||
return null;
|
||||
}
|
||||
public FuncCall find_func_call(String funcName) {
|
||||
for (FuncInfo fi : function_decls.values()) {
|
||||
for (FuncCall fc : fi.calls) {
|
||||
if (fc.funcName.equalsIgnoreCase(funcName) &&
|
||||
(fc.line == form.getEditor().getCurrentLine()
|
||||
)) {
|
||||
return fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Loop find_current_loop() {
|
||||
int line = form.getEditor().getCurrentLine();
|
||||
return AllLoops.getOrDefault(line, null);
|
||||
}
|
||||
public void Exclude() throws Exception {
|
||||
state = FileState.Excluded;
|
||||
father.db.Update(this);
|
||||
}
|
||||
public void Include() throws Exception {
|
||||
state = FileState.Undefined;
|
||||
father.db.Update(this);
|
||||
}
|
||||
public String getUnixName() {
|
||||
return Utils.toU(name);
|
||||
}
|
||||
public String getQObjectName() {
|
||||
return Utils.DQuotes(getUnixName() + ".o");
|
||||
}
|
||||
public String getQSourceName() {
|
||||
return Utils.DQuotes(getUnixName());
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
public String getProjectNameWithoutExtension() {
|
||||
String extension = Utils.getExtension(file);
|
||||
return name.substring(0, name.length() - (extension.length() + 1));
|
||||
}
|
||||
public void importSettings(DBProjectFile parent, boolean sapforStyle) throws Exception {
|
||||
fileType = parent.fileType;
|
||||
switch (parent.state) {
|
||||
case Undefined:
|
||||
case Excluded:
|
||||
state = parent.state;
|
||||
break;
|
||||
default:
|
||||
state = FileState.Undefined;
|
||||
break;
|
||||
}
|
||||
languageName = parent.languageName;
|
||||
if (sapforStyle) style = Current.getSapfor().getStyle();
|
||||
else style = parent.style;
|
||||
}
|
||||
public void importSourceCodeSettings(DBProjectFile parent, boolean sapforStyle) throws Exception {
|
||||
switch (parent.state) {
|
||||
case Undefined:
|
||||
case Excluded:
|
||||
state = parent.state;
|
||||
break;
|
||||
default:
|
||||
state = FileState.Undefined;
|
||||
break;
|
||||
}
|
||||
languageName = parent.languageName;
|
||||
if (sapforStyle) style = Current.getSapfor().getStyle();
|
||||
else style = parent.style;
|
||||
}
|
||||
//------------------
|
||||
public void CheckStateByMessageType(int m_type) throws Exception {
|
||||
switch (m_type) {
|
||||
case 0:
|
||||
if (state != FileState.HasErrors) state = FileState.HasWarnings;
|
||||
break;
|
||||
case 1:
|
||||
state = FileState.HasErrors;
|
||||
break;
|
||||
case 2:
|
||||
if (state != FileState.HasWarnings && state != FileState.HasErrors) state = FileState.HasNotes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//------------------
|
||||
public void ReadMessagesNoSave(String text, LinkedHashMap<String, DBProjectFile> files) throws Exception {
|
||||
String[] nw = text.split("\n");
|
||||
for (String S : nw) {
|
||||
Pair<Integer, String> p = decodeParserMessage(S, name);
|
||||
if (S.toLowerCase().startsWith("note")) {
|
||||
files.get(p.getValue()).CheckStateByMessageType(2);
|
||||
} else if (S.toLowerCase().startsWith("warning")) {
|
||||
files.get(p.getValue()).CheckStateByMessageType(0);
|
||||
} else if (S.toLowerCase().startsWith("error"))
|
||||
files.get(p.getValue()).CheckStateByMessageType(1);
|
||||
}
|
||||
}
|
||||
public void ReadParseMessagesNoSave(LinkedHashMap<String, DBProjectFile> files) throws Exception {
|
||||
if (getParserOutFile().exists()) ReadMessagesNoSave(Utils.ReadAllText(getParserOutFile()), files);
|
||||
if (getParserErrFile().exists()) ReadMessagesNoSave(Utils.ReadAllText(getParserErrFile()), files);
|
||||
}
|
||||
public int FragmentArraysCount(Integer first, Integer second) {
|
||||
int res = 0;
|
||||
for (ArrayDecl ai : array_decls) {
|
||||
if ((ai.line >= first) && (ai.line <= second))
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
9
src/ProjectData/Files/FileState.java
Normal file
9
src/ProjectData/Files/FileState.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package ProjectData.Files;
|
||||
public enum FileState {
|
||||
Undefined, //состояние файла сброшено.
|
||||
OK, //никаких сообщений нет, зеленая галочка.
|
||||
HasNotes, //есть только note
|
||||
HasWarnings, //есть warning, нет error
|
||||
HasErrors, //есть error
|
||||
Excluded //исключен из рассмотрения
|
||||
}
|
||||
23
src/ProjectData/Files/FileType.java
Normal file
23
src/ProjectData/Files/FileType.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package ProjectData.Files;
|
||||
public enum FileType {
|
||||
none,
|
||||
program,
|
||||
header,
|
||||
forbidden,
|
||||
data;
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case program:
|
||||
return "Программа";
|
||||
case header:
|
||||
return "Заголовочный";
|
||||
case none:
|
||||
return "нет";
|
||||
case forbidden:
|
||||
return "не поддерживается";
|
||||
case data:
|
||||
return "Данные";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
11
src/ProjectData/Files/FilesDBTable.java
Normal file
11
src/ProjectData/Files/FilesDBTable.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files;
|
||||
import Common.Database.DBTable;
|
||||
public class FilesDBTable extends DBTable<String, DBProjectFile> {
|
||||
public FilesDBTable() {
|
||||
super(String.class, DBProjectFile.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "файл";
|
||||
}
|
||||
}
|
||||
32
src/ProjectData/Files/LanguageStyle.java
Normal file
32
src/ProjectData/Files/LanguageStyle.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package ProjectData.Files;
|
||||
public enum LanguageStyle {
|
||||
none,
|
||||
fixed,
|
||||
extended,
|
||||
free;
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case fixed:
|
||||
return "Фиксированный";
|
||||
case extended:
|
||||
return "Расширенный";
|
||||
case free:
|
||||
return "Свободный";
|
||||
case none:
|
||||
return "нет";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public int getMargin() {
|
||||
switch (this) {
|
||||
case fixed:
|
||||
return 72;
|
||||
case extended:
|
||||
return 132;
|
||||
case free:
|
||||
return 160;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import Common.UI.Editor.CaretInfo;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
import org.fife.ui.autocomplete.BasicCompletion;
|
||||
//определяет, должна ли отображаться в меню автозаполнения директива данного типа.
|
||||
public class BaseDirective extends BasicCompletion {
|
||||
public DirectiveName name;
|
||||
public boolean visible = false; //должна ли быть в меню.
|
||||
public BaseDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in.getText(), name_in.getDescription());
|
||||
name = name_in;
|
||||
}
|
||||
//есть ли совпадение с началом директивы в строке
|
||||
public boolean isMatch() {
|
||||
return
|
||||
getCaretInfo().suffix_word.isEmpty() &&
|
||||
name.getText().startsWith(getCaretInfo().prefix_word)
|
||||
&& (!name.getText().equals(getCaretInfo().prefix_word))
|
||||
&& !Utils.isBracketsBalanced(getCaretInfo().before);
|
||||
}
|
||||
//итоговая функция, определяющая наличие директивы в автозаполнении
|
||||
public boolean Check() {
|
||||
return visible = isMatch();
|
||||
}
|
||||
protected CaretInfo getCaretInfo() {
|
||||
// System.out.println(getOwner());
|
||||
// System.out.println(getOwner().getEditor());
|
||||
return getOwner().getEditor().getCaretInfo();
|
||||
}
|
||||
protected SapforAutoComplete getOwner() {
|
||||
return ((BaseProvider) getProvider()).getOwner();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class CheckPointTypeDirective extends BaseDirective {
|
||||
public CheckPointTypeDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 2) &&
|
||||
getOwner().flags.get(0).equals(DirectiveName.SPF) &&
|
||||
getOwner().flags.get(1).equals(DirectiveName.CHECKPOINT) &&
|
||||
getOwner().nearestGroup.equals(DirectiveName.TYPE)
|
||||
&& !getOwner().flags.contains(DirectiveName.ASYNC)
|
||||
&& !getOwner().flags.contains(DirectiveName.FLEXIBLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
public enum DirectiveName {
|
||||
UNDEFINED,
|
||||
//--------------
|
||||
START,
|
||||
SPF,
|
||||
ANALYSIS,
|
||||
PARALLEL,
|
||||
TRANSFORM,
|
||||
PARALLEL_REG,
|
||||
END_PARALLEL_REG,
|
||||
REDUCTION,
|
||||
MAX,
|
||||
MIN,
|
||||
SUM,
|
||||
PROD,
|
||||
AND,
|
||||
OR,
|
||||
EQV,
|
||||
NEQV,
|
||||
MAXLOC,
|
||||
MINLOC,
|
||||
PRIVATE,
|
||||
SHADOW,
|
||||
ACROSS,
|
||||
REMOTE_ACCESS,
|
||||
NOINLINE,
|
||||
FISSION,
|
||||
EXPAND,
|
||||
SHRINK,
|
||||
CHECKPOINT,
|
||||
INTERVAL,
|
||||
FILES_COUNT,
|
||||
TIME,
|
||||
ITER,
|
||||
VARLIST,
|
||||
EXCEPT,
|
||||
TYPE,
|
||||
ASYNC,
|
||||
FLEXIBLE,
|
||||
PARAMETER,
|
||||
UNROLL
|
||||
;
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case SPF:
|
||||
return "SPF директива";
|
||||
case ANALYSIS:
|
||||
return "Директива анализа";
|
||||
case PARAMETER:
|
||||
return "Директива параметра задачи";
|
||||
case PARALLEL:
|
||||
return "Директива распараллеливания";
|
||||
case TRANSFORM:
|
||||
return "Директива трансформации";
|
||||
case PARALLEL_REG:
|
||||
return "Директива начала области распараллеливания";
|
||||
case END_PARALLEL_REG:
|
||||
return "Директива конца области распараллеливания";
|
||||
case REDUCTION:
|
||||
return "Клауза редукции";
|
||||
case MAX:
|
||||
return "Операция MAX";
|
||||
case MIN:
|
||||
return "Операция MIN";
|
||||
case SUM:
|
||||
return "Операция SUM";
|
||||
case PROD:
|
||||
return "Операция PROD";
|
||||
case AND:
|
||||
return "Операция AND";
|
||||
case OR:
|
||||
return "Операция OR";
|
||||
case EQV:
|
||||
return "Операция EQV";
|
||||
case NEQV:
|
||||
return "Операция NEQV";
|
||||
case MAXLOC:
|
||||
return "Операция MAXLOC";
|
||||
case MINLOC:
|
||||
return "Операция MINLOC";
|
||||
case PRIVATE:
|
||||
return "Клауза приватных переменных";
|
||||
case SHADOW:
|
||||
return "Клауза теневых граней";
|
||||
case ACROSS:
|
||||
return "Клауза регулярных зависимостей";
|
||||
case REMOTE_ACCESS:
|
||||
return "Клауза удаленных ссылок";
|
||||
case NOINLINE:
|
||||
return "Клауза для отмены подстановки процедуры";
|
||||
case FISSION:
|
||||
return "Клауза для разделения циклов";
|
||||
case UNROLL:
|
||||
return "Клауза для разворачивания цикла";
|
||||
case EXPAND:
|
||||
return "Клауза для расширения приватных переменных";
|
||||
case SHRINK:
|
||||
return "Клауза для сужения приватных переменных";
|
||||
case CHECKPOINT:
|
||||
return "Директива контрольной точки";
|
||||
case INTERVAL:
|
||||
return "Клауза интервала";
|
||||
case FILES_COUNT:
|
||||
return "Клауза количества файлов";
|
||||
case VARLIST:
|
||||
return "Клауза переменных";
|
||||
case EXCEPT:
|
||||
return "Клауза исключённых переменных";
|
||||
case TYPE:
|
||||
return "Клауза типа";
|
||||
case ITER:
|
||||
return "По достижении итерации";
|
||||
case TIME:
|
||||
return "По истечении времени (сек)";
|
||||
case ASYNC:
|
||||
return "Асинхронная";
|
||||
case FLEXIBLE:
|
||||
return "Гибкая";
|
||||
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
public String getText() {
|
||||
switch (this) {
|
||||
case SPF:
|
||||
return "!$SPF ";
|
||||
case END_PARALLEL_REG:
|
||||
return "END PARALLEL_REG";
|
||||
default:
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class IntervalDirective extends BaseDirective {
|
||||
protected String prefix;
|
||||
protected String word;
|
||||
protected String suffix;
|
||||
public IntervalDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 2) &&
|
||||
getOwner().flags.get(0).equals(DirectiveName.SPF) &&
|
||||
getOwner().flags.get(1).equals(DirectiveName.CHECKPOINT) &&
|
||||
getOwner().nearestGroup.equals(DirectiveName.INTERVAL)
|
||||
&& !getOwner().flags.contains(DirectiveName.TIME)
|
||||
&& !getOwner().flags.contains(DirectiveName.ITER);
|
||||
}
|
||||
@Override
|
||||
public String getReplacementText() {
|
||||
prefix = Utils.pack(getCaretInfo().before.substring(0, getCaretInfo().before.length() - getCaretInfo().prefix_word.length()));
|
||||
word = name.getText();
|
||||
suffix = Utils.pack(getCaretInfo().after.substring(getCaretInfo().suffix_word.length()));
|
||||
String pp = prefix.replace(" ", "");
|
||||
String ps = suffix.replace(" ", "");
|
||||
if ((!ps.isEmpty()) && (ps.charAt(0) != ','))
|
||||
word = (word + ",");
|
||||
return word;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class RedListDirective extends SpecDirective {
|
||||
public RedListDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 2) &&
|
||||
getOwner().flags.get(0).equals(DirectiveName.SPF) &&
|
||||
getOwner().flags.get(1).equals(DirectiveName.ANALYSIS) &&
|
||||
getOwner().nearestGroup.equals(DirectiveName.REDUCTION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class RegionDirective extends BaseDirective {
|
||||
public RegionDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() == 1) && (getOwner().flags.get(0).equals(DirectiveName.SPF));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class Spec1Directive extends SpecDirective {
|
||||
public Spec1Directive(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 1)
|
||||
&& getOwner().flags.get(0).equals(DirectiveName.SPF)
|
||||
&& getOwner().flags.get(1).equals(DirectiveName.ANALYSIS)
|
||||
&& getOwner().nearestGroup.equals(DirectiveName.ANALYSIS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class Spec2Directive extends SpecDirective {
|
||||
public Spec2Directive(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 1)
|
||||
&& getOwner().flags.get(0).equals(DirectiveName.SPF)
|
||||
&& getOwner().flags.get(1).equals(DirectiveName.PARALLEL)
|
||||
&& getOwner().nearestGroup.equals(DirectiveName.PARALLEL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class Spec3Directive extends SpecDirective {
|
||||
public Spec3Directive(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 1)
|
||||
&& getOwner().flags.get(0).equals(DirectiveName.SPF)
|
||||
&& getOwner().flags.get(1).equals(DirectiveName.TRANSFORM)
|
||||
&& getOwner().nearestGroup.equals(DirectiveName.TRANSFORM)
|
||||
&& !getOwner().flags.contains(DirectiveName.NOINLINE)
|
||||
&& !getOwner().flags.contains(DirectiveName.FISSION)
|
||||
&& !getOwner().flags.contains(DirectiveName.SHRINK)
|
||||
&& !getOwner().flags.contains(DirectiveName.EXPAND)
|
||||
&& !getOwner().flags.contains(DirectiveName.UNROLL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class Spec4Directive extends SpecDirective {
|
||||
public Spec4Directive(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return (getOwner().flags.size() > 1)
|
||||
&& getOwner().flags.get(0).equals(DirectiveName.SPF)
|
||||
&& getOwner().flags.get(1).equals(DirectiveName.CHECKPOINT)
|
||||
&& getOwner().nearestGroup.equals(DirectiveName.CHECKPOINT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
//промежуточный тип. относится ко всем директивам со скобками и требующим запятых.
|
||||
public class SpecDirective extends BaseDirective {
|
||||
protected String prefix;
|
||||
protected String word;
|
||||
protected String suffix;
|
||||
public SpecDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
public String get_word() {
|
||||
boolean noBrackets = name.equals(DirectiveName.NOINLINE)||name.equals(DirectiveName.UNROLL);
|
||||
return name.getText() + (noBrackets ? "" : "()");
|
||||
}
|
||||
@Override
|
||||
public String getReplacementText() {
|
||||
prefix = Utils.pack(getCaretInfo().before.substring(0, getCaretInfo().before.length() - getCaretInfo().prefix_word.length()));
|
||||
word = get_word();
|
||||
suffix = Utils.pack(getCaretInfo().after.substring(getCaretInfo().suffix_word.length()));
|
||||
String pp = prefix.replace(" ", "");
|
||||
String ps = suffix.replace(" ", "");
|
||||
if (!pp.isEmpty() && (pp.charAt(pp.length() - 1) != ',') && (pp.charAt(pp.length() - 1) != '('))
|
||||
word = ("," + word);
|
||||
if ((!ps.isEmpty()) && (ps.charAt(0) != ',') && (ps.charAt(0) != ')'))
|
||||
word = (word + ",");
|
||||
if ((ps.isEmpty()) || ps.charAt(ps.length() - 1) != ')')
|
||||
word += ")";
|
||||
return word;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class StartDirective extends BaseDirective {
|
||||
public StartDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public boolean Check() {
|
||||
return getOwner().flags.contains(DirectiveName.START);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.BaseProvider;
|
||||
public class TypeDirective extends RegionDirective {
|
||||
public TypeDirective(BaseProvider provider_in, DirectiveName name_in) {
|
||||
super(provider_in, name_in);
|
||||
}
|
||||
@Override
|
||||
public String getReplacementText() {
|
||||
return super.getReplacementText() + "()";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.BaseDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
import org.fife.ui.autocomplete.DefaultCompletionProvider;
|
||||
public class BaseProvider extends DefaultCompletionProvider {
|
||||
protected static char[] separators = new char[]{'!', '$', '*', ' ', ',', '(', ')'};
|
||||
protected SapforAutoComplete owner;//владелец.
|
||||
public BaseProvider(SapforAutoComplete owner_in) {
|
||||
owner = owner_in;
|
||||
}
|
||||
public SapforAutoComplete getOwner() {
|
||||
return owner;
|
||||
}
|
||||
protected boolean isSeparator(char ch) {
|
||||
for (char s : separators)
|
||||
if (ch == s) return true;
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
protected boolean isValidChar(char ch) {
|
||||
return super.isValidChar(ch) || isSeparator(ch);
|
||||
}
|
||||
//получить текст от каретки и до разделителя
|
||||
public void addDirective(BaseDirective directive) {
|
||||
addCompletion(directive);
|
||||
owner.directives.put(directive.name, directive);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.CheckPointTypeDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class CheckPointTypeProvider extends PrefixWordProvider {
|
||||
public CheckPointTypeProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new CheckPointTypeDirective(this, DirectiveName.ASYNC));
|
||||
addDirective(new CheckPointTypeDirective(this, DirectiveName.FLEXIBLE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.IntervalDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class IntervalProvider extends PrefixWordProvider {
|
||||
public IntervalProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new IntervalDirective(this, DirectiveName.TIME));
|
||||
addDirective(new IntervalDirective(this, DirectiveName.ITER));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
import ProjectData.Files.UI.Editor.SPFEditor;
|
||||
|
||||
import javax.swing.text.JTextComponent;
|
||||
//https://github.com/bobbylight/AutoComplete/blob/master/AutoCompleteDemo/src/main/java/org/fife/ui/autocomplete/demo/DemoRootPane.java
|
||||
//ОБРАЗЕЦ
|
||||
//отличается тем, что принимает на вход дополнительные символы
|
||||
// и берет не всю строку перед кареткой а только последнее слово
|
||||
public class PrefixWordProvider extends BaseProvider {
|
||||
public PrefixWordProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
}
|
||||
@Override
|
||||
public String getAlreadyEnteredText(JTextComponent comp) {
|
||||
return ((SPFEditor) comp).getCaretInfo().prefix_word;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.RedListDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class ReductionProvider extends PrefixWordProvider {
|
||||
public ReductionProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new RedListDirective(this, DirectiveName.MAX));
|
||||
addDirective(new RedListDirective(this, DirectiveName.MIN));
|
||||
addDirective(new RedListDirective(this, DirectiveName.MAXLOC));
|
||||
addDirective(new RedListDirective(this, DirectiveName.MINLOC));
|
||||
addDirective(new RedListDirective(this, DirectiveName.AND));
|
||||
addDirective(new RedListDirective(this, DirectiveName.OR));
|
||||
addDirective(new RedListDirective(this, DirectiveName.EQV));
|
||||
addDirective(new RedListDirective(this, DirectiveName.NEQV));
|
||||
addDirective(new RedListDirective(this, DirectiveName.SUM));
|
||||
addDirective(new RedListDirective(this, DirectiveName.PROD));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.Spec1Directive;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class Spec1Provider extends PrefixWordProvider {
|
||||
public Spec1Provider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new Spec1Directive(this, DirectiveName.REDUCTION));
|
||||
addDirective(new Spec1Directive(this, DirectiveName.PRIVATE));
|
||||
addDirective(new Spec1Directive(this, DirectiveName.PARAMETER));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.Spec2Directive;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class Spec2Provider extends PrefixWordProvider {
|
||||
public Spec2Provider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new Spec2Directive(this, DirectiveName.SHADOW));
|
||||
addDirective(new Spec2Directive(this, DirectiveName.ACROSS));
|
||||
addDirective(new Spec2Directive(this, DirectiveName.REMOTE_ACCESS));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.Spec3Directive;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class Spec3Provider extends PrefixWordProvider {
|
||||
public Spec3Provider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new Spec3Directive(this, DirectiveName.NOINLINE));
|
||||
addDirective(new Spec3Directive(this, DirectiveName.FISSION));
|
||||
addDirective(new Spec3Directive(this, DirectiveName.SHRINK));
|
||||
addDirective(new Spec3Directive(this, DirectiveName.EXPAND));
|
||||
addDirective(new Spec3Directive(this, DirectiveName.UNROLL));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.Spec4Directive;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class Spec4Provider extends PrefixWordProvider {
|
||||
public Spec4Provider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new Spec4Directive(this, DirectiveName.INTERVAL));
|
||||
addDirective(new Spec4Directive(this, DirectiveName.FILES_COUNT));
|
||||
addDirective(new Spec4Directive(this, DirectiveName.VARLIST));
|
||||
addDirective(new Spec4Directive(this, DirectiveName.EXCEPT));
|
||||
addDirective(new Spec4Directive(this, DirectiveName.TYPE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.StartDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class StartProvider extends BaseProvider {
|
||||
public StartProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new StartDirective(this, DirectiveName.SPF));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.RegionDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.TypeDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
public class TypeProvider extends PrefixWordProvider {
|
||||
public TypeProvider(SapforAutoComplete owner_in) {
|
||||
super(owner_in);
|
||||
addDirective(new TypeDirective(this, DirectiveName.ANALYSIS));
|
||||
addDirective(new TypeDirective(this, DirectiveName.PARALLEL));
|
||||
addDirective(new TypeDirective(this, DirectiveName.TRANSFORM));
|
||||
addDirective(new TypeDirective(this, DirectiveName.CHECKPOINT));
|
||||
addDirective(new RegionDirective(this, DirectiveName.PARALLEL_REG));
|
||||
addDirective(new RegionDirective(this, DirectiveName.END_PARALLEL_REG));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.BaseDirective;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Directives.DirectiveName;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.Providers.*;
|
||||
import ProjectData.Files.UI.Editor.SPFEditor;
|
||||
import org.fife.ui.autocomplete.AutoCompletion;
|
||||
import org.fife.ui.autocomplete.DefaultCompletionProvider;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
public class SapforAutoComplete extends AutoCompletion {
|
||||
//---
|
||||
public Vector<BaseProvider> providers = new Vector<>();
|
||||
public LinkedHashMap<DirectiveName, BaseDirective> directives = new LinkedHashMap<>();
|
||||
public Vector<DirectiveName> flags = new Vector<>();
|
||||
public DirectiveName nearestGroup;
|
||||
private SPFEditor editor = null;
|
||||
public SapforAutoComplete(SPFEditor editor_in) {
|
||||
//заглушка.
|
||||
super(new DefaultCompletionProvider());
|
||||
editor = editor_in;
|
||||
providers.add(new StartProvider(this));
|
||||
providers.add(new TypeProvider(this));
|
||||
providers.add(new Spec1Provider(this));
|
||||
providers.add(new ReductionProvider(this));
|
||||
providers.add(new Spec2Provider(this));
|
||||
providers.add(new Spec3Provider(this));
|
||||
providers.add(new Spec4Provider(this));
|
||||
providers.add(new IntervalProvider(this));
|
||||
providers.add(new CheckPointTypeProvider(this));
|
||||
install(editor);
|
||||
setAutoActivationEnabled(false);
|
||||
setAutoCompleteEnabled(false);
|
||||
setAutoCompleteSingleChoices(false);
|
||||
}
|
||||
public SPFEditor getEditor() {
|
||||
return editor;
|
||||
}
|
||||
//---
|
||||
public void updateFlags() {
|
||||
flags.clear();
|
||||
//определить присутствие директив в строке.
|
||||
for (DirectiveName name : directives.keySet()) {
|
||||
if (name.equals(DirectiveName.SPF)) {
|
||||
String line = editor.getCaretInfo().current_line;
|
||||
if (line.startsWith("!$")) {
|
||||
boolean ok = true;
|
||||
for (int z = 2; z < line.length(); ++z)
|
||||
if (line.charAt(z) != ' ')
|
||||
ok = false;
|
||||
if (ok)
|
||||
flags.add(DirectiveName.START);
|
||||
else if (editor.getCaretInfo().current_line.contains(name.getText()))
|
||||
flags.add(name);
|
||||
}
|
||||
} else if (editor.getCaretInfo().current_line.contains(name.getText()))
|
||||
flags.add(name);
|
||||
}
|
||||
}
|
||||
public void findNearestGroup() {
|
||||
int indicator = 0;
|
||||
String word = "";
|
||||
SearchState s = SearchState.BracketSearch;
|
||||
nearestGroup = DirectiveName.UNDEFINED;
|
||||
for (int i = (editor.getCaretInfo().before.length() - 1); i >= 0; i--) {
|
||||
char c = editor.getCaretInfo().before.charAt(i);
|
||||
switch (s) {
|
||||
case BracketSearch:
|
||||
switch (c) {
|
||||
case '(':
|
||||
indicator++;
|
||||
if (indicator > 0)
|
||||
s = SearchState.DirectiveSearch;
|
||||
break;
|
||||
case ')':
|
||||
indicator--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DirectiveSearch:
|
||||
switch (c) {
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
s = SearchState.Directive;
|
||||
word = c + word;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Directive:
|
||||
word = c + word;
|
||||
for (DirectiveName directiveName : directives.keySet()) {
|
||||
if (directiveName.getText().equals(word)) {
|
||||
nearestGroup = directiveName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//вызывается при событиях каретки текстового редактора.
|
||||
//обновление меню которое вызовется при Ctrl+Space
|
||||
public void Parse() {
|
||||
updateFlags();
|
||||
findNearestGroup();
|
||||
for (BaseDirective directive : directives.values()) {
|
||||
//если директива видима, значит ее провайдер нам и нужен.
|
||||
if (directive.Check()) {
|
||||
if (!directive.getProvider().equals(this.getCompletionProvider()))
|
||||
setCompletionProvider(directive.getProvider());
|
||||
doCompletion();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//если ничего не нашли, ставим пустого
|
||||
//TODO - не такой уж он и пустой!
|
||||
setCompletionProvider(providers.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR;
|
||||
public enum SearchState {
|
||||
BracketSearch,
|
||||
DirectiveSearch,
|
||||
Directive
|
||||
}
|
||||
205
src/ProjectData/Files/UI/Editor/SPFEditor.java
Normal file
205
src/ProjectData/Files/UI/Editor/SPFEditor.java
Normal file
@@ -0,0 +1,205 @@
|
||||
package ProjectData.Files.UI.Editor;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.Editor.BaseEditor;
|
||||
import Common.UI.Editor.CaretInfo;
|
||||
import Common.UI.Menus.StyledPopupMenu;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import GlobalData.Settings.SettingName;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.Files.FileState;
|
||||
import ProjectData.Files.UI.Editor.AutoComplete.SAPFOR.SapforAutoComplete;
|
||||
import Common.UI.Menus.MainEditorMenu;
|
||||
import ProjectData.SapforData.Loops.Loop;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
import Visual_DVM_2021.UI.Interface.SPFEditorInterface;
|
||||
import javafx.util.Pair;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaHighlighter;
|
||||
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DefaultHighlighter;
|
||||
import javax.swing.text.Highlighter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Vector;
|
||||
public class SPFEditor extends BaseEditor implements SPFEditorInterface {
|
||||
public static final Color never = new Color(229, 228, 226, 90);
|
||||
public DBProjectFile file = null; //файл связанный с редактором
|
||||
//----
|
||||
public RSyntaxTextAreaHighlighter highlighter = null;
|
||||
//----
|
||||
public SapforAutoComplete autoComplete = null;
|
||||
public boolean switching_language = false;
|
||||
Vector<Object> loopsHighlights = new Vector<>();
|
||||
Vector<Object> gcovHighlights = new Vector<>();
|
||||
//-включение /отключение событий --
|
||||
private CaretInfo caretInfo = new CaretInfo();
|
||||
public SPFEditor(DBProjectFile file_in) {
|
||||
file = file_in;
|
||||
highlighter = (RSyntaxTextAreaHighlighter) getHighlighter();
|
||||
autoComplete = new SapforAutoComplete(this);
|
||||
//-------------------------
|
||||
float font_size = (float) Global.db.settings.get(SettingName.EditorFontSize).toInt32();
|
||||
setFont(getFont().deriveFont(font_size));
|
||||
//-------------------------
|
||||
setText(Utils.ReadAllText(file.file).replace("\r", " "));
|
||||
gotoLine(file.lastLine);
|
||||
//-------------------------
|
||||
addCaretListener(сe -> UpdateCaretInfo());
|
||||
getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent arg0) {
|
||||
if (!switching_language) {
|
||||
file.NeedsSave = true;
|
||||
if (Global.enable_text_changed && file.state != FileState.Excluded) {
|
||||
Current.getSapfor().ResetAllAnalyses();
|
||||
//текст изменился, значит M ка более не актуальна.
|
||||
file.father.dropLastModification();
|
||||
}
|
||||
Pass_2021.passes.get(PassCode_2021.Save).Reset();
|
||||
}
|
||||
}
|
||||
});
|
||||
//----
|
||||
addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.isControlDown()) {
|
||||
switch (e.getKeyCode()) {
|
||||
case KeyEvent.VK_F:
|
||||
UI.ShowSearchForm(false);
|
||||
break;
|
||||
case KeyEvent.VK_H:
|
||||
UI.ShowSearchForm(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//---------------------------------------------------->>
|
||||
public static String getLastWord(String text, char... separators) {
|
||||
Vector<Character> separators_ = new Vector<>();
|
||||
for (char s : separators)
|
||||
separators_.add(s);
|
||||
String res = "";
|
||||
char[] letters = text.toCharArray();
|
||||
for (int i = letters.length - 1; i >= 0; --i) {
|
||||
char c = letters[i];
|
||||
if (separators_.contains(c)) break;
|
||||
else res = c + res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public static String getFirstWord(String text, char... separators) {
|
||||
Vector<Character> separators_ = new Vector<>();
|
||||
for (char s : separators)
|
||||
separators_.add(s);
|
||||
String res = "";
|
||||
char[] letters = text.toCharArray();
|
||||
for (int i = 0; i < letters.length; ++i) {
|
||||
char c = letters[i];
|
||||
if (separators_.contains(c)) break;
|
||||
else res += c;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public CaretInfo getCaretInfo() {
|
||||
return caretInfo;
|
||||
}
|
||||
public void UpdateCaretInfo() {
|
||||
caretInfo = new CaretInfo(this);
|
||||
autoComplete.Parse();
|
||||
}
|
||||
@Override
|
||||
public void ClearHighlights() {
|
||||
highlighter.removeAllHighlights();
|
||||
}
|
||||
@Override
|
||||
public void ClearLoopsHighLights() {
|
||||
for (Object loop : loopsHighlights)
|
||||
highlighter.removeHighlight(loop);
|
||||
}
|
||||
@Override
|
||||
public void ClearGOCVHighlights() {
|
||||
for (Object line : gcovHighlights)
|
||||
highlighter.removeHighlight(line);
|
||||
}
|
||||
@Override
|
||||
public void HighlightLoops() {
|
||||
ClearLoopsHighLights();
|
||||
for (Loop loop : file.AllLoops.values()) {
|
||||
Highlighter.HighlightPainter painter = loop.loopState.getPainter();
|
||||
if (painter != null) {
|
||||
try {
|
||||
loopsHighlights.add(highlighter.addHighlight(
|
||||
getLineStartOffset(loop.line - 1),
|
||||
getLineEndOffset(loop.line - 1),
|
||||
painter
|
||||
));
|
||||
} catch (BadLocationException ex) {
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//нумерация с нуля!
|
||||
boolean lineNumberIsValid(int num) {
|
||||
return (num >= 0) && (num < this.getLineCount());
|
||||
}
|
||||
@Override
|
||||
public void HighlightGCOV() {
|
||||
ClearGOCVHighlights();
|
||||
for (int lineNum : file.gcov_info.line_info.keySet()) {
|
||||
Pair<Long, Integer> p = file.gcov_info.line_info.get(lineNum);
|
||||
//System.out.println((lineNum + 1) + ": " + p.getKey() + " " + p.getValue() + "%");
|
||||
Color color = never;
|
||||
if (p.getKey() > 0) {
|
||||
color = (p.getValue() >= Global.db.settings.get(SettingName.GCOVLimit).toInt32()) ?
|
||||
new Color(255, 255, (100 - p.getValue()), 90) : null;
|
||||
}
|
||||
if (color != null) {
|
||||
Highlighter.HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(color);
|
||||
try {
|
||||
gcovHighlights.add(highlighter.addHighlight(
|
||||
getLineStartOffset(lineNum),
|
||||
getLineEndOffset(lineNum),
|
||||
painter
|
||||
));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void saveFont() {
|
||||
Pass_2021.passes.get(PassCode_2021.UpdateSetting).Do(
|
||||
SettingName.EditorFontSize,
|
||||
getFont().getSize());
|
||||
}
|
||||
@Override
|
||||
protected void saveText() {
|
||||
Pass_2021.passes.get(PassCode_2021.Save).Do();
|
||||
}
|
||||
@Override
|
||||
protected StyledPopupMenu createMenu() {
|
||||
return new MainEditorMenu(this);
|
||||
}
|
||||
public int getCurrentLine() {
|
||||
return getCaretLineNumber() + 1;
|
||||
}
|
||||
public int getCurrentSymbol() {
|
||||
return getCaretOffsetFromLineStart() + 1;
|
||||
}
|
||||
}
|
||||
39
src/ProjectData/Files/UI/FileGraphTree.java
Normal file
39
src/ProjectData/Files/UI/FileGraphTree.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package ProjectData.Files.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Trees.DataTree;
|
||||
import Common.UI.Trees.TreeRenderers;
|
||||
import ProjectData.SapforData.FileObject;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
public class FileGraphTree extends DataTree {
|
||||
public FileGraphTree(DefaultMutableTreeNode root) {
|
||||
super(root);
|
||||
// ExpandAll();
|
||||
}
|
||||
@Override
|
||||
public TreeRenderers getRenderer() {
|
||||
return TreeRenderers.RendererGraph;
|
||||
}
|
||||
@Override
|
||||
public Current getCurrent() {
|
||||
return Current.FileGraphElement;
|
||||
}
|
||||
@Override
|
||||
public void ShowCurrentObject() throws Exception {
|
||||
Current.getFile().form.EventsOff();
|
||||
Object o = Current.get(getCurrent());
|
||||
Current.getFile().form.getEditor().gotoLine((o instanceof FileObjectWithMessages) ? (((FileObjectWithMessages) o).line) : 1);
|
||||
Current.getFile().form.ShowMessages();
|
||||
Current.getFile().form.EventsOn();
|
||||
}
|
||||
@Override
|
||||
protected boolean findNode(Object userObject, Object criteria) {
|
||||
return (userObject instanceof FileObject) && (
|
||||
((FileObject) (userObject)).line == (Integer) criteria);
|
||||
}
|
||||
@Override
|
||||
protected int getStartLine() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
51
src/ProjectData/Files/UI/FilesHyperlinksPanel.java
Normal file
51
src/ProjectData/Files/UI/FilesHyperlinksPanel.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package ProjectData.Files.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import Common.UI.UI;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Vector;
|
||||
//https://javaswing.wordpress.com/2009/10/10/jlist_using/
|
||||
//https://qarchive.ru/14623936_kak_poluchit__vydelennyi__tekst_elementa_iz_jlist_s_izobrazheniem_
|
||||
public class FilesHyperlinksPanel extends JPanel {
|
||||
public Vector<String> links = null;
|
||||
public JList<String> Hyperlinks = null;
|
||||
MouseAdapter adapter = null;
|
||||
public FilesHyperlinksPanel() {
|
||||
super(new BorderLayout());
|
||||
//о курсорах https://javaswing.wordpress.com/2010/07/13/cursor/
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
public void UpdateByCell(Vector<String> links_in) {
|
||||
links = links_in;
|
||||
removeAll();
|
||||
Hyperlinks = new JList<>(links);
|
||||
Hyperlinks.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
if (adapter != null) {
|
||||
removeMouseListener(adapter);
|
||||
adapter = null;
|
||||
}
|
||||
Hyperlinks.addMouseListener(adapter = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
int index = Hyperlinks.locationToIndex(e.getPoint());
|
||||
if (index >= 0) {
|
||||
String[] data = links.get(index).split(":");
|
||||
String file = data[0];
|
||||
int line = Integer.parseInt(data[1]);
|
||||
UI.getMainWindow().getProjectWindow().GotoFile(file, line, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
Hyperlinks.setLayoutOrientation(JList.VERTICAL);
|
||||
Hyperlinks.setFont(Current.getTheme().Fonts.get(VisualiserFonts.Hyperlink));
|
||||
add(Hyperlinks, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
108
src/ProjectData/Files/UI/FilesTree.java
Normal file
108
src/ProjectData/Files/UI/FilesTree.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package ProjectData.Files.UI;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.DragDrop.FileDrop;
|
||||
import Common.UI.Menus.GraphMenu;
|
||||
import Common.UI.Menus.ProjectFilesMenu;
|
||||
import Common.UI.UI;
|
||||
import Common.UI.Trees.StyledTree;
|
||||
import Common.UI.Trees.TreeRenderers;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
public class FilesTree extends StyledTree {
|
||||
public FilesTree() {
|
||||
super(Current.getProject().filesTreeRoot);
|
||||
this.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
switch (e.getKeyCode()) {
|
||||
case KeyEvent.VK_DELETE:
|
||||
forkFD(PassCode_2021.DeleteFile, PassCode_2021.DeleteDirectory);
|
||||
break;
|
||||
case KeyEvent.VK_ADD: //num lock +
|
||||
case KeyEvent.VK_EQUALS: //+
|
||||
Pass_2021.passes.get(PassCode_2021.IncludeFile).Do();
|
||||
break;
|
||||
case KeyEvent.VK_SUBTRACT: //num lock -
|
||||
case KeyEvent.VK_MINUS: //-
|
||||
Pass_2021.passes.get(PassCode_2021.ExcludeFile).Do();
|
||||
break;
|
||||
case KeyEvent.VK_F2:
|
||||
forkFD(PassCode_2021.RenameFile, PassCode_2021.RenameDirectory);
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
LeftMouseAction2();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
new FileDrop(System.out, this, files -> {
|
||||
Pass_2021.passes.get(PassCode_2021.ImportFiles).Do(files);
|
||||
});
|
||||
Current.set(Current.File, null);
|
||||
}
|
||||
private static void forkFD(PassCode_2021 file_pass, PassCode_2021 folder_pass) {
|
||||
DefaultMutableTreeNode node = Current.getProjectNode();
|
||||
if (node != null)
|
||||
Pass_2021.passes.get((node.getUserObject() instanceof DBProjectFile) ?
|
||||
file_pass : folder_pass).Do();
|
||||
}
|
||||
@Override
|
||||
public TreeRenderers getRenderer() {
|
||||
return TreeRenderers.RendererFile;
|
||||
}
|
||||
@Override
|
||||
protected GraphMenu createMenu() {
|
||||
return new ProjectFilesMenu(this);
|
||||
}
|
||||
@Override
|
||||
public void SelectionAction(TreePath e) {
|
||||
System.out.println("Select");
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getLastPathComponent();
|
||||
Current.set(Current.ProjectNode, node);
|
||||
Object o = node.getUserObject();
|
||||
if (o instanceof File) {
|
||||
Current.set(Current.SelectedDirectory, o);
|
||||
Current.set(Current.SelectedFile, null);
|
||||
UI.getMainWindow().getProjectWindow().ShowNoSelectedFile();
|
||||
} else if (o instanceof DBProjectFile) {
|
||||
Current.set(Current.SelectedFile, o);
|
||||
File file = ((DBProjectFile) o).file;
|
||||
Current.set(Current.SelectedDirectory, file.getParentFile());
|
||||
UI.getMainWindow().getProjectWindow().ShowSelectedFile();
|
||||
}
|
||||
UI.getMainWindow().getProjectWindow().ShowSelectedDirectory();
|
||||
}
|
||||
@Override
|
||||
public void LeftMouseAction2() {
|
||||
if (Current.getProjectNode() != null) {
|
||||
Object o = Current.getProjectNode().getUserObject();
|
||||
if (o instanceof DBProjectFile) {
|
||||
//очень важно. иначе по открытии файла дерево остается в фокусе.
|
||||
//и не происходит прокрутки скролла к строке!!
|
||||
UI.getMainWindow().getProjectWindow().FocusFileTabs();
|
||||
Pass_2021.passes.get(PassCode_2021.OpenCurrentFile).Do(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void LeftMouseAction1() {
|
||||
if (Global.files_multiselection && Current.getSelectedFile() != null) {
|
||||
Current.getSelectedFile().SwitchSelection();
|
||||
System.out.println("LMC "+Current.getSelectedFile().name+" : "+Current.getSelectedFile().isSelected());
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected int getStartLine() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
46
src/ProjectData/Files/UI/FilesTreeCellRenderer.java
Normal file
46
src/ProjectData/Files/UI/FilesTreeCellRenderer.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package ProjectData.Files.UI;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import Common.UI.Trees.StyledTreeCellRenderer;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.Files.FileState;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.awt.*;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
//https://kodejava.org/how-do-i-create-jtree-with-different-icons-for-each-node/
|
||||
//https://ru.coredump.biz/questions/14968005/dynamically-change-icon-of-specific-nodes-in-jtree
|
||||
public class FilesTreeCellRenderer extends StyledTreeCellRenderer {
|
||||
public java.awt.Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
Object o = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
if (o instanceof File) {
|
||||
//это папка.
|
||||
File dir = (File) o;
|
||||
setIcon(new ImageIcon(getClass().getResource("/icons/Folder.png")));
|
||||
setText(dir.getName());
|
||||
setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreePlain));
|
||||
} else if (o instanceof DBProjectFile) {
|
||||
DBProjectFile file = (DBProjectFile) o;
|
||||
if (Global.files_multiselection) {
|
||||
setIcon(file.GetSelectionIcon());
|
||||
} else {
|
||||
setIcon(file.GetIcon());
|
||||
}
|
||||
setText(file.file.getName());
|
||||
if (file.IsMain()) setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreeBold));
|
||||
else setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreePlain));
|
||||
if (file.state.equals(FileState.Excluded)) {
|
||||
Map attributes = getFont().getAttributes();
|
||||
attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
|
||||
setFont(new Font(attributes));
|
||||
}
|
||||
}
|
||||
setForeground(tree.getForeground());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
64
src/ProjectData/Files/UI/FortranFolder.java
Normal file
64
src/ProjectData/Files/UI/FortranFolder.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package ProjectData.Files.UI;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.Token;
|
||||
import org.fife.ui.rsyntaxtextarea.TokenTypes;
|
||||
import org.fife.ui.rsyntaxtextarea.folding.Fold;
|
||||
import org.fife.ui.rsyntaxtextarea.folding.FoldParser;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
public class FortranFolder implements FoldParser {
|
||||
protected static final char[] C_MLC_END = "*/".toCharArray();
|
||||
private static final char[] KEYWORD_IMPORT = "import".toCharArray();
|
||||
@Override
|
||||
public List<Fold> getFolds(RSyntaxTextArea textArea) {
|
||||
List<Fold> folds = new ArrayList();
|
||||
Fold currentFold = null;
|
||||
int lineCount = textArea.getLineCount();
|
||||
int lastRightCurlyLine = -1;
|
||||
Fold prevFold = null;
|
||||
try {
|
||||
for (int line = 0; line < lineCount; ++line) {
|
||||
for (Token t = textArea.getTokenListForLine(line); t != null && t.isPaintable(); t = t.getNextToken()) {
|
||||
Fold parentFold;
|
||||
if (this.isDo(t)) {
|
||||
if (prevFold != null && line == lastRightCurlyLine) {
|
||||
currentFold = prevFold;
|
||||
prevFold = null;
|
||||
lastRightCurlyLine = -1;
|
||||
} else if (currentFold == null) {
|
||||
currentFold = new Fold(0, textArea, t.getOffset());
|
||||
folds.add(currentFold);
|
||||
} else {
|
||||
currentFold = currentFold.createChild(0, t.getOffset());
|
||||
}
|
||||
} else if (this.isEndDo(t)) {
|
||||
if (currentFold != null) {
|
||||
currentFold.setEndOffset(t.getOffset());
|
||||
parentFold = currentFold.getParent();
|
||||
if (currentFold.isOnSingleLine()) {
|
||||
if (!currentFold.removeFromParent()) {
|
||||
folds.remove(folds.size() - 1);
|
||||
}
|
||||
} else {
|
||||
lastRightCurlyLine = line;
|
||||
prevFold = currentFold;
|
||||
}
|
||||
currentFold = parentFold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException var16) {
|
||||
var16.printStackTrace();
|
||||
}
|
||||
return folds;
|
||||
}
|
||||
public boolean isDo(Token t) {
|
||||
return t.getType() == TokenTypes.RESERVED_WORD && t.getLexeme().equalsIgnoreCase("DO");
|
||||
}
|
||||
public boolean isEndDo(Token t) {
|
||||
return t.getType() == TokenTypes.RESERVED_WORD && t.getLexeme().equalsIgnoreCase("ENDDO");
|
||||
}
|
||||
}
|
||||
28
src/ProjectData/GCOV/GCOV_info.java
Normal file
28
src/ProjectData/GCOV/GCOV_info.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package ProjectData.GCOV;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
public class GCOV_info {
|
||||
public long max;
|
||||
public LinkedHashMap<Integer, Pair<Long, Integer>> line_info = new LinkedHashMap<>();
|
||||
//номер строки / число ее выполнений / масштаб
|
||||
public void clear() {
|
||||
max = 0;
|
||||
line_info.clear();
|
||||
}
|
||||
public void add_line(int num, long count) {
|
||||
line_info.put(num, new Pair<>(count, 0));
|
||||
if (max < count) max = count;
|
||||
}
|
||||
//пределим минимум и максимум. оба должны быть >0. + определим интервал
|
||||
public void setup() {
|
||||
//определям процент по отношению к максимуму
|
||||
for (int i : line_info.keySet()) {
|
||||
Pair<Long, Integer> p = line_info.get(i);
|
||||
int proportion = (max > 0) ? ((int) (((double) p.getKey() / max) * 100)) : 0;
|
||||
if (proportion < 1) proportion = 1;
|
||||
line_info.replace(i, new Pair<>(p.getKey(), proportion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
src/ProjectData/LanguageName.java
Normal file
66
src/ProjectData/LanguageName.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package ProjectData;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
public enum LanguageName {
|
||||
n,
|
||||
fortran,
|
||||
c,
|
||||
cpp;
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case fortran:
|
||||
return "Fortran";
|
||||
case c:
|
||||
return "С";
|
||||
case cpp:
|
||||
return "С++";
|
||||
case n:
|
||||
return "нет";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public String getDVMLink() {
|
||||
switch (this) {
|
||||
case fortran:
|
||||
return "flink";
|
||||
case c:
|
||||
return "clink";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public String getDVMCompile() {
|
||||
switch (this) {
|
||||
case fortran:
|
||||
return "f";
|
||||
case c:
|
||||
return "c";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public String getStyleKey() {
|
||||
switch (this) {
|
||||
case fortran:
|
||||
return //SyntaxConstants.SYNTAX_STYLE_FORTRAN;
|
||||
"text/FortranSPF";
|
||||
case c:
|
||||
return SyntaxConstants.SYNTAX_STYLE_C;
|
||||
case cpp:
|
||||
return SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS;
|
||||
default:
|
||||
return SyntaxConstants.SYNTAX_STYLE_NONE;
|
||||
}
|
||||
}
|
||||
public String getIcon(){
|
||||
switch (this){
|
||||
case fortran:
|
||||
return "/icons/Languages/Fortran.png";
|
||||
case c:
|
||||
return "/icons/Languages/C.png";
|
||||
case cpp:
|
||||
return "/icons/Languages/Cpp.png";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/ProjectData/Messages/Errors/ErrorsDBTable.java
Normal file
25
src/ProjectData/Messages/Errors/ErrorsDBTable.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package ProjectData.Messages.Errors;
|
||||
import Common.Current;
|
||||
import ProjectData.Messages.MessagesDBTable;
|
||||
public class ErrorsDBTable extends MessagesDBTable<MessageError> {
|
||||
public ErrorsDBTable() {
|
||||
super(MessageError.class);
|
||||
// setUIContent(UI.getMainWindow().errorsPanel);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "сообщение об ошибке";
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.Errors;
|
||||
}
|
||||
public void changeColumnFilterValue(int columnIndex, String text) {
|
||||
if (columnIndex == 3)
|
||||
MessageError.filterValue = text;
|
||||
}
|
||||
public Object getColumnFilterValue(int columnIndex) {
|
||||
return MessageError.filterValue;
|
||||
}
|
||||
|
||||
}
|
||||
14
src/ProjectData/Messages/Errors/MessageError.java
Normal file
14
src/ProjectData/Messages/Errors/MessageError.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Messages.Errors;
|
||||
import ProjectData.Messages.Message;
|
||||
public class MessageError extends Message {
|
||||
public MessageError(String file_in, int line_in, String value_in, int group_in) throws Exception {
|
||||
super(file_in, line_in, value_in, group_in);
|
||||
}
|
||||
public MessageError() {
|
||||
}
|
||||
public static String filterValue = "";
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return super.isVisible()&&value.contains(filterValue);
|
||||
}
|
||||
}
|
||||
443
src/ProjectData/Messages/Message.java
Normal file
443
src/ProjectData/Messages/Message.java
Normal file
@@ -0,0 +1,443 @@
|
||||
package ProjectData.Messages;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import GlobalData.Settings.SettingName;
|
||||
import ProjectData.SapforData.FileObject;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
import Visual_DVM_2021.Passes.PassException;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
public class Message extends FileObject {
|
||||
@Description("IGNORE")
|
||||
public static final int parser_group = -1;
|
||||
private static HashMap<String, String> codedMessages;
|
||||
private static HashMap<String, String> codedMessages2;
|
||||
public int group;
|
||||
public String group_s = "#";
|
||||
public String value;
|
||||
public Message() {
|
||||
}
|
||||
public Message(String file_in, int line_in, String value_in, int group_in
|
||||
) throws Exception {
|
||||
file = file_in;
|
||||
line = line_in;
|
||||
setGroup(group_in);
|
||||
value = ((group == parser_group) ||
|
||||
!Global.getSetting(SettingName.TRANSLATE_MESSAGES).toBoolean() ?
|
||||
value_in : decodeRussianMessage(value_in));
|
||||
}
|
||||
|
||||
// last code - 183
|
||||
private static String decodeRussianMessage(String coded) throws Exception {
|
||||
if (codedMessages == null) {
|
||||
codedMessages = new HashMap<>();
|
||||
codedMessages2 = new HashMap<>();
|
||||
codedMessages2.put("RR1_1", "перед");
|
||||
codedMessages2.put("RR1_2", "объявлением переменных или");
|
||||
codedMessages2.put("RR1_3", "циклом");
|
||||
codedMessages2.put("RR1_4", "после");
|
||||
codedMessages2.put("RR1_5", "всех операторов объявления");
|
||||
codedMessages2.put("RR1_6", "заголовка процедуры");
|
||||
codedMessages2.put("RR1_7", "единожды");
|
||||
codedMessages2.put("RR1_8", "только");
|
||||
codedMessages2.put("RR158_1", "' для этого цикла.");
|
||||
codedMessages2.put("RR42_1", "как выходной аргумент");
|
||||
codedMessages2.put("RR42_2", "как массив в функции");
|
||||
//1001
|
||||
codedMessages.put("R1", "Неверное расположение директивы: можно располагать только %s %s %s.");
|
||||
codedMessages.put("R2", "Неверное выражение: слишком много переменных цикла.");
|
||||
codedMessages.put("R3", "Неверное выражение: возможно только вида a * i + b.");
|
||||
codedMessages.put("R4", "Неверное расположение директивы: для области '%s' ожидается 'SPF END PARALLEL_REG_DIR', а была получена 'SPF PARALLEL_REG_DIR'.");
|
||||
codedMessages.put("R5", "Неверное расположение директивы: для области '%s' ожидается 'SPF END PARALLEL_REG_DIR'.");
|
||||
codedMessages.put("R6", "Неверное расположение директивы: для области '%s' ожидается 'SPF END PARALLEL_REG_DIR'.");
|
||||
codedMessages.put("R7", "Неверное расположение директивы: ожидается 'SPF PARALLEL_REG_DIR', а была получена 'SPF END PARALLEL_REG_DIR'.");
|
||||
codedMessages.put("R8", "Неверное расположение директивы: ожидается 'SPF PARALLEL_REG_DIR' в той же области видимости.");
|
||||
codedMessages.put("R9", "Неверное расположение директивы: ожидается 'SPF PARALLEL_REG_DIR'.");
|
||||
codedMessages.put("R10", "Неправильная расстановка области распараллеливания: есть несколько входов во фрагмент '%s', вызванные оператором ENTRY.");
|
||||
codedMessages.put("R11", "Неправильная расстановка области распараллеливания: есть несколько входов во фрагмент '%s', вызванные оператором GOTO.");
|
||||
codedMessages.put("R12", "Неправильное расположение строк: можно выбирать строки только в исполняемой части кода.");
|
||||
codedMessages.put("R13", "Неправильное расположение строк: начало не может быть больше конца.");
|
||||
codedMessages.put("R14", "Неправильное расположение строк: начало и конец при расширении не могут лежать в разных областях.");
|
||||
codedMessages.put("R15", "Неправильное положение строки: начало и конец не могут быть в неявных фрагментах.");
|
||||
codedMessages.put("R16", "Неправильное положение строк: начало и конец не могут быть в разных процедурах.");
|
||||
codedMessages.put("R17", "Неправильное расположение строк: выделенный фрагмент при расширении не должен включать фрагменты разных областей.");
|
||||
codedMessages.put("R18", "Неправильное расположение строк: начало и конец должны быть в одной области видимости.");
|
||||
codedMessages.put("R19", "Неправильное расположение строк %d-%d: нельзя объединить фрагменты в разных областях видимости.");
|
||||
codedMessages.put("R20", "Неправильное расположение строк: начало и конец должны быть в одной области видимости.");
|
||||
//1002
|
||||
codedMessages.put("R21", "Переменная '%s' не используется в цикле.");
|
||||
codedMessages.put("R22", "Переменная '%s' не используется в цикле.");
|
||||
//1003
|
||||
codedMessages.put("R23", "Переменная '%s' не изменяется в цикле.");
|
||||
codedMessages.put("R24", "Переменная '%s' не изменяется в цикле.");
|
||||
//1004
|
||||
codedMessages.put("R25", "Размерность массива '%s' %d, а должна быть 1.");
|
||||
//1005
|
||||
codedMessages.put("R26", "Тип массива '%s' должен быть INTEGER.");
|
||||
//1006
|
||||
codedMessages.put("R27", "Типом переменной '%s' должен быть массив.");
|
||||
codedMessages.put("R28", "Переменная '%s' не является массивом.");
|
||||
codedMessages.put("R29", "Переменная '%s' не является массивом.");
|
||||
//1007
|
||||
codedMessages.put("R30", "Размер массива не может быть вычислен.");
|
||||
//1008
|
||||
codedMessages.put("R31", "Размер массива '%s' %d, а вы вводите %d.");
|
||||
codedMessages.put("R32", "Размерность массива '%s' %d, а вы вводите %d.");
|
||||
//1009
|
||||
codedMessages.put("R33", "Массив '%s' является приватным.");
|
||||
codedMessages.put("R34", "Массив '%s' является приватным.");
|
||||
//1010
|
||||
codedMessages.put("R35", "Разрешены только положительные числа.");
|
||||
//1011
|
||||
codedMessages.put("R36", "Нет такого выражения '%s' в цикле.");
|
||||
//1012
|
||||
codedMessages.put("R37", "Невозможно определить размеры массива '%s'.");
|
||||
codedMessages.put("R149", "Невозможно определить размеры цикла '%s'.");
|
||||
//1013
|
||||
codedMessages.put("R38", "Отличается количество формальных и фактических параметров для процедуры '%s'."); //Требуется выполнить подстановку процедуры '%s', так как
|
||||
codedMessages.put("R39", "Отличается тип фактического (%s : %s) и формального (%s : %s) %d-го параметра для процедуры '%s'."); //Требуется выполнить подстановку процедуры '%s', так как
|
||||
codedMessages.put("R40", "Требуется выполнить подстановку процедуры '%s', так как можно передавать массивы только целиком.");
|
||||
codedMessages.put("R41", "Требуется выполнить подстановку процедуры '%s' из-за обращения к неприватному массиву '%s' в цикле на строке %d %s.");
|
||||
codedMessages.put("R42", "Требуется выполнить подстановку процедуры '%s' из-за обращения к неприватному массиву '%s' %s.");
|
||||
codedMessages.put("R43", "Требуется подставить процедуру '%s' из-за разной размерности массива '%s', передаваемого в качестве параметра: размерность формального параметра = %d, а фактического параметра = %d.");
|
||||
codedMessages.put("R44", "Для процедуры '%s' обнаружено несоответствие типов формального и фактического параметра для массива '%s'.");
|
||||
codedMessages.put("R45", "Необходимо подставить процедуру '%s', так как через параметр %d передается итерационная переменная цикла на строке %d и она используется в индексном выражении в обращении к массиву в теле этой процедуры.");
|
||||
//1014
|
||||
codedMessages.put("R46", "Была найдена рекурсивная цепочка вызовов: '%s', данная процедура исключена из рассмотрения.");
|
||||
//1015
|
||||
codedMessages.put("R47", "Данная процедура не вызывается в данном проекте.");
|
||||
//1016
|
||||
codedMessages.put("R48", "Невозможно вычислить количество итераций данного цикла, информация о количестве итераций для всех остальных циклов в области распараллеливания '%s' будет проигнорирована.");
|
||||
//1017
|
||||
codedMessages.put("R49", "Невозможно найти определение для символа '%s' в данной области видимости.");
|
||||
//1018
|
||||
codedMessages.put("R50", "Данный цикл не в END DO формате.");
|
||||
codedMessages.put("R51", "Данный цикл не в END DO формате.");
|
||||
//1019
|
||||
codedMessages.put("R52", "Включаемый файл '%s' содержит исполняемые операторы, что запрещено к распараллеливанию в системе SAPFOR.");
|
||||
//1020
|
||||
codedMessages.put("R53", "Активные DVM-директивы не поддерживаются.");
|
||||
//1021
|
||||
codedMessages.put("R54", "Обращение к массиву '%s' содержит более одной индексной переменной циклов.");
|
||||
codedMessages.put("R55", "Обращение к массиву '%s' по измерению '%d' не содержит итерационных переменных циклов.");
|
||||
//1022
|
||||
codedMessages.put("R56", "Обращение к массиву '%s' имеет косвенную адресацию.");
|
||||
//1023
|
||||
codedMessages.put("R57", "Невозможно вычислить индексное выражение в обращении к массиву '%s'.");
|
||||
//1024
|
||||
codedMessages.put("R58", "Коэффициент A в линейном обращении A*x+B к массиву '%s' не может быть отрицательным, так как инверсное распределение не поддерживается.");
|
||||
//1025
|
||||
codedMessages.put("R59", "Невозможно сопоставить обращение к массиву на запись '%s' с данными циклом.");
|
||||
//1026
|
||||
codedMessages.put("R60", "Обнаружен оператор записи в нераспределенный массив '%s', связанный с данным циклом.");
|
||||
codedMessages.put("R61", "Обнаружен оператор записи в нераспределенный массив '%s', связанный с данным циклом.");
|
||||
//1027
|
||||
codedMessages.put("R179", "Обнаружен более, чем один оператор в одной и той же строке, попробуйте применить проход 'Коррекция стиля кода'.");
|
||||
//1028
|
||||
codedMessages.put("R62", "Описание модуля '%s' должно находиться в данном файле.");
|
||||
//1029 && 1030
|
||||
codedMessages.put("R158", "Рекурсия не анализируется для приватных переменных в common-блоке '%s'.");
|
||||
codedMessages.put("R159", "Анализ приватных переменных невозможен для данного цикла из-за: '%s'.");
|
||||
codedMessages.put("R160", "Переменная '%s' из списка приватных переменных не может быть классифицирована как приватная.");
|
||||
codedMessages.put("R161", "Массив '%s' из списка приватных переменных не может быть классифицирована как приватный.");
|
||||
codedMessages.put("R162", "Добавлена приватная переменная '%s");
|
||||
codedMessages.put("R163", "Добавлена приватная переменная по массиву '%s");
|
||||
//1031
|
||||
codedMessages.put("R63", "Неверное имя области: имя '%s' уже объявлено на строке %d.");
|
||||
//1032
|
||||
codedMessages.put("R64", "Неверное имя области: имя '%s' уже объявлено в common-блоке '%s'.");
|
||||
//1033
|
||||
codedMessages.put("R65", "Область распараллеливания '%s' включает саму себя в файле '%s'.");
|
||||
//1034
|
||||
codedMessages.put("R66", "Неверное расположение области: не существует common-блока в текущей функции '%s' со следующими массивами:%s.");
|
||||
//1035
|
||||
//--- TODO
|
||||
//1036
|
||||
codedMessages.put("R67", "Невозможно построить дерево выравнивания в данной области распараллеливания, используя пользовательские DVM-директивы.");
|
||||
//1037
|
||||
codedMessages.put("R68", "Массив '%s' не может быть распределен из-за ограничений ввода/вывода, накладываемых DVM системой.");
|
||||
//1038
|
||||
codedMessages.put("R69", "Оператор PAUSE является запрещенным в параллельной программе.");
|
||||
codedMessages.put("R70", "Оператор EQUIVALENCE не поддерживается на данный момент.");
|
||||
//1039
|
||||
codedMessages.put("R71", "Переменные '%s' и '%s' находятся в одной области ассоциации (common block '%s'), но имеют разные типы (файлы - %s:%d и %s:%d).");
|
||||
//1040
|
||||
codedMessages.put("R72", "Первые %d измерений массива '%s' запрещены к распределению из-за передачи к процедуру '%s'.");
|
||||
codedMessages.put("R73", "Первое измерение массива '%s' запрещено к распределению из-за передачи в процедуру '%s'.");
|
||||
//1041
|
||||
codedMessages.put("R74", "Область распараллеливания '%s'содержит строку, которая включена в другую область, необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//1042
|
||||
codedMessages.put("R75", "Распределенный массив '%s' состоящий в common блоке '%s' должен иметь описание в главной программной единице.");
|
||||
//1043
|
||||
codedMessages.put("R76", "Неверное выражение в директиве: ожидается список переменных.");
|
||||
codedMessages.put("R77", "Неверное выражение в директиве: ожидается %d тесно-вложенных циклов на строке %d, но их всего %d.");
|
||||
codedMessages.put("R78", "Неверное выражение в директиве: ожидается переменная '%s' на позиции %d.");
|
||||
//1044
|
||||
codedMessages.put("R79", "Поддерживаются процедуры только без побочных эффектов.");
|
||||
codedMessages.put("R80", "Поддерживаются процедуры только без побочных эффектов.");
|
||||
//1045
|
||||
codedMessages.put("R81", "Аргумент '%s' процедуры '%s' имеет неизвестные нижнюю и/или верхнюю границы.");
|
||||
//1046
|
||||
codedMessages.put("R82", "Количество формальных и фактических параметров не одинаково для вызова данной процедуры '%s'.");
|
||||
codedMessages.put("R83", "Количество формальных и фактических параметров не одинаково для вызова данной процедуры '%s'.");
|
||||
codedMessages.put("R84", "Количество формальных и фактических параметров не одинаково для вызова данной процедуры '%s'.");
|
||||
//1047
|
||||
codedMessages.put("R85", "%d измерение массива '%s' не может быть распределено из-за различных отображений на циклы в операциях присваиваний.");
|
||||
codedMessages.put("R86", "Массив '%s' не может быть распределен, так как все его измерения запрещены к распределению.");
|
||||
codedMessages.put("R87", "Массив '%s' не может быть распределен.");
|
||||
codedMessages.put("R88", "Массив '%s' не может быть распределен.");
|
||||
codedMessages.put("R89", "Массив '%s' не может быть распределен.");
|
||||
codedMessages.put("R90", "Массив '%s' не может быть распределен из-за использования RESHAPE.");
|
||||
codedMessages.put("R91", "Массив '%s' не может быть распределен.");
|
||||
codedMessages.put("R164", "Массив '%s' не может быть распределен из-за использования конструктора инициализации");
|
||||
//1048
|
||||
codedMessages.put("R92", "Процедура '%s' с одинаковым именем была объявлена в более, чем одном месте: в файле '%s':%d и '%s':%d.");
|
||||
//1049
|
||||
codedMessages.put("R93", "Процедура не является чистой (без побочных эффектов) из-за наличия данного оператора.");
|
||||
//1050
|
||||
codedMessages.put("R146", "Найдена более, чем одна главная программная единица (PROGRAM).");
|
||||
codedMessages.put("R147", "Не найдена ни одна главная программная единица (PROGRAM).");
|
||||
//1051
|
||||
codedMessages.put("R148", "Обнаружены вызовы MPI-процедур, включен режим специальный режим распараллеливания MPI-программ.");
|
||||
//1052
|
||||
codedMessages.put("R150", "Ошибка в расстановке пользовательских интервалов - не удалось найти конец интервала.");
|
||||
//1053
|
||||
codedMessages.put("R154", "Ошибка в выражении SHRINK клаузы: переменная должна быть массивом в файле '%s'.");
|
||||
//1054
|
||||
codedMessages.put("R155", "Длина маски для массива '%s' должна быть равна %d, но указано только %d измерений в файле '%s'.");
|
||||
//1055
|
||||
codedMessages.put("R156", "Ошибка в выражении маски на %d позиции массива '%s': в качестве значения могут быть только 0 и 1 в файле '%s'.");
|
||||
//1056
|
||||
codedMessages.put("R157", "Массив '%s' в клаузе SHRINK также должен быть объявлен в клаузе private в файле '%s'.");
|
||||
//1057
|
||||
codedMessages.put("R175", "Переменная '%s' должна использоваться в следующем операторе.");
|
||||
//1058
|
||||
codedMessages.put("R176", "В левой части клаузы PARAMETER должна быть переменная.");
|
||||
//1059
|
||||
codedMessages.put("R182", "Редукционная операция по элементу массива '%s' на данный момент не поддерживается.");
|
||||
//1060
|
||||
codedMessages.put("R183", "Расположение операторов FORMAT в области описания типов данных не поддерживается, попробуйте применить проход 'Коррекция стиля кода'.");
|
||||
//1061
|
||||
codedMessages.put("R184", "Область объявления массива '%s' конфликтует с предыдущей областью. Возможно, это вызвано использованием include-файлов. Попробуйте применить проход 'Подстановка заголовочных файлов'.");
|
||||
//2001
|
||||
codedMessages.put("R94", "Невозможно автоматически преобразовать данное присваивание к циклу.");
|
||||
codedMessages.put("R95", "Невозможно автоматически преобразовать данное присваивание к циклу.");
|
||||
//2002
|
||||
codedMessages.put("R96", "Арифметический IF был преобразован в IF-ENDIF.");
|
||||
codedMessages.put("R97", "Вычисляемый GOTO был преобразован в IF-ENDIF.");
|
||||
//2003
|
||||
codedMessages.put("R98", "Невозможно автоматически преобразовать цикл в END DO формат.");
|
||||
//2004
|
||||
codedMessages.put("R99", "Цикл был преобразован в END DO формат.");
|
||||
//2005
|
||||
codedMessages.put("R100", "Циклы в строке %d и в строке %d были объединены.");
|
||||
//2006
|
||||
codedMessages.put("R101", "Была выполнена подстановка макроса с именем '%s'.");
|
||||
//2007
|
||||
codedMessages.put("R102", "Возникла непредвиденная ситуация во время генерации выходного текста.");
|
||||
codedMessages.put("R103", "Возникла непредвиденная ситуация во время генерации выходного текста.");
|
||||
//2008
|
||||
// -- TODO
|
||||
//2009
|
||||
codedMessages.put("R104", "Невозможно разделить данный цикл из-за следующей зависимости: %s.");
|
||||
//2010
|
||||
codedMessages.put("R105", "Данный цикл содержит косвенные подциклы, поэтому не может быть разделен.");
|
||||
codedMessages.put("R106", "У данного цикла есть ограничение на разделение в строке %s (наличие операторов goto, print, stop или этот цикл не является DO-ENDDO).");
|
||||
codedMessages.put("R107", "У данного цикла есть зависимости, которые нельзя проанализировать, поэтому он не может быть разделен в строке %s.");
|
||||
//2011
|
||||
codedMessages.put("R177", "Подстановка процедур разрешена только в исполняемой части кода.");
|
||||
//2012
|
||||
codedMessages.put("R173", "Операторы SAVE и DATA запрещены в дублируемых процедурах");
|
||||
//2013
|
||||
codedMessages.put("R174", "Операторы SAVE и DATA запрещены в дублируемых процедурах: переменная '%s'");
|
||||
//2014
|
||||
codedMessages.put("R180", "Невозможно выполнить подстановку процедур '%s': разная размерность формального и фактического параметра '%s'");
|
||||
//2015
|
||||
codedMessages.put("R185", "Неправильный синтаксис директивы");
|
||||
codedMessages.put("R186", "Неправильный синтаксис директивы - выражения в заголовке цикла должны быть вычисляемыми");
|
||||
codedMessages.put("R187", "Выражения в заголовке цикла должны быть вычисляемыми");
|
||||
codedMessages.put("R195", "Нельзя выполнить преобразование из-за данного оператора, который имеет construct-name");
|
||||
//2016
|
||||
codedMessages.put("R188", "Нельзя удалить приватную переменную '%s' - для неё не найдена маска фиксированных измерений");
|
||||
//2017
|
||||
codedMessages.put("R189", "Нельзя удалить приватную переменную '%s' - она имеет рекурсивную зависимость");
|
||||
codedMessages.put("R190", "Нельзя удалить приватную переменную '%s' - она зависит от неинвариантной переменной цикла '%s'");
|
||||
//2018
|
||||
codedMessages.put("R191", "Приватная переменная '%s' была удалена");
|
||||
codedMessages.put("R201", "Приватная переменная '%s' была частично удалена");
|
||||
|
||||
//2019
|
||||
codedMessages.put("R192", "Нельзя удалить приватную переменную '%s' - она не имеет фиксированных измерений");
|
||||
//2020
|
||||
codedMessages.put("R193", "Нельзя удалить приватную переменную '%s' - более одного определения достигают оператора");
|
||||
codedMessages.put("R194", "Нельзя удалить приватную переменную '%s' - не удалось найти достигающее определение для оператора");
|
||||
//2022
|
||||
codedMessages.put("R196", "Невозможно выполнить преобразование циклов из-за зависимостей между операторами.");
|
||||
//2023
|
||||
codedMessages.put("R197", "Преобразование не может быть выполнено - не произошло никаких изменений в коде");
|
||||
codedMessages.put("R198", "Цикл на строке %d был удалён");
|
||||
codedMessages.put("R199", "Зависимость по скаляру с типом lastprivate препятствует распараллеливанию данного цикла");
|
||||
codedMessages.put("R200", "Добавлена lastprivate переменная '%s' к циклу на строке %d");
|
||||
//3002
|
||||
|
||||
//3001
|
||||
codedMessages.put("R108", "Добавлена across-зависимость к массиву '%s' в цикле.");
|
||||
//3002
|
||||
codedMessages.put("R109", "Добавлена приватная переменная '%s' к циклу на строке %d.");
|
||||
//3003
|
||||
codedMessages.put("R110", "Добавлена редукционная переменная '%s' с типом операции '%s' к циклу на строке %d.");
|
||||
//3004
|
||||
codedMessages.put("R111", "Неизвестный тип редукционной операции по скаляру '%s'.");
|
||||
//3005
|
||||
codedMessages.put("R112", "Неизвестная зависимость по скалярной переменной '%s' (попробуйте вручную специфицировать ее тип).");
|
||||
//3006
|
||||
codedMessages.put("R113", "Неизвестная зависимость по массиву препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R114", "Неизвестная зависимость по скаляру препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R115", "Внешние или внутренние операторы перехода (GOTO/EXIT) препятствуют распараллеливанию данного цикла.");
|
||||
codedMessages.put("R116", "Операторы ввода/вывода препятствуют распараллеливанию данного цикла.");
|
||||
codedMessages.put("R117", "Операторы STOP препятствуют распараллеливанию данного цикла.");
|
||||
codedMessages.put("R118", "Обнаружены конфликтные присваивания, которые препятствуют распараллеливанию данного цикла.");
|
||||
codedMessages.put("R119", "Невозможность сопоставить обращение к массиву на запись препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R120", "Косвенная адресация по распределяемому массиву препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R121", "Обращение к нераспределенному массиву на запись препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R122", "Найдены различные правила выравнивания массивов, используемых на запись в данном цикле, препятствует распараллеливанию.");
|
||||
codedMessages.put("R123", "Процедуры с побочным эффектом препятствуют распараллеливанию данного цикла.");
|
||||
codedMessages.put("R124", "%s зависимость между %s (строка %d) и %s (строка %d) с неизвестным расстоянием препятствует распараллеливанию цикла на строке %d.");
|
||||
codedMessages.put("R125", "%s зависимость между %s (строка %d) и %s (строка %d) с неизвестным расстоянием препятствует распараллеливанию.");
|
||||
codedMessages.put("R144", "Обнаружено непрямоугольное пространство итераций, что препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R145", "Обнаружены DVM интервалы внутри цикла, что препятствует распараллеливанию данного цикла.");
|
||||
codedMessages.put("R178", "Данный вид циклов не поддерживается системой.");
|
||||
//--TODO R124 R125 про неопределенную длину зависимости
|
||||
//3007
|
||||
codedMessages.put("R126", "Невозможно создать с шаблоном для массива '%s': размерность массива '%d' и это не соответствует '%d'.");
|
||||
codedMessages.put("R127", "Невозможно сопоставить выравнивания массивов, передаваемых в процедуру.");
|
||||
//3008
|
||||
codedMessages.put("R128", "Внутренняя ошибка анализа, распараллеливание не будет выполнено для данного файла.");
|
||||
//3009
|
||||
codedMessages.put("R129", "Добавленный REMOTE_ACCESS для обращения к массиву '%s' может привести к сильному замедлению.");
|
||||
//3010
|
||||
codedMessages.put("R130", "Не обнаружены массивы или свободные циклы для распределения в данном проекте.");
|
||||
codedMessages.put("R131", "Не обнаружены массивы или свободные циклы для распределения в данной области распараллеливания.");
|
||||
//3011
|
||||
codedMessages.put("R132", "У массивов '%s' и '%s' разные правила выравнивания согласно обращению на запись в данном цикле.");
|
||||
//3012
|
||||
codedMessages.put("R133", "Области распараллеливания %sимеют общую используемую процедуру '%s', необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3013
|
||||
codedMessages.put("R134", "Области распараллеливания %sимеют общий используемый локальный массив '%s', необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
codedMessages.put("R152", "Области распараллеливания %sимеют общий используемый массив из модуля '%s', необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3014
|
||||
codedMessages.put("R135", "Область распараллеливания '%s' содержит common-массив '%s', используемый в области и вне её, необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3015
|
||||
codedMessages.put("R136", "Область распараллеливания '%s' не имеет DVM-интервала для фрагмента, необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3016
|
||||
codedMessages.put("R137", "Невозможно считать DVM-статистику для получения времен.");
|
||||
//3017
|
||||
codedMessages.put("R138", "Область распараллеливания '%s' не содержит копирования массива '%s' в DVM-интервале, необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3018
|
||||
codedMessages.put("R139", "Область распараллеливания '%s' не содержит копирования массива '%s' в DVM-интервале, необходимо применить проход 'Разрешение конфликтов областей'.");
|
||||
//3019
|
||||
//--- TODO предиктор
|
||||
//3020
|
||||
codedMessages.put("R140", "Обнаружен массив '%s', являющийся параметром процедуры, в которую передаются как распределенные, так и нераспределенные массивы. Возможно, стоит запретить к распределению обнаруженные массивы, либо продублировать соответствующую процедуру.");
|
||||
codedMessages.put("R141", "Обнаружен распределяемый массив '%s', передаваемый в качестве параметра в процедуру.");
|
||||
codedMessages.put("R153", "Обнаружен не распределяемый массив '%s', передаваемый в качестве параметра в процедуру.");
|
||||
codedMessages.put("R142", "Для массива '%s' не удается найти единого распределения, внутренняя ошибка системы.");
|
||||
//3021
|
||||
codedMessages.put("R151", "Пустые области распараллеливания не допускаются.");
|
||||
//3022
|
||||
codedMessages.put("R171", "Невозможно определить правила выравнивания для массива '%s'.");
|
||||
//4001
|
||||
//---TODO ошибки из SAGE
|
||||
//4002
|
||||
codedMessages.put("R143", "Неверное объявление PURE процедуры - отсутствуют операторы INTENT.");
|
||||
//5001
|
||||
codedMessages.put("R165", "В клаузе 'INTERVAL' первый аргумент должен быть 'TIME' или 'ITER', а второй - типа integer.");
|
||||
//5002
|
||||
codedMessages.put("R166", "Директива %s с клаузой '%s' может располагаться только в исполняемой части кода.");
|
||||
//5003
|
||||
codedMessages.put("R167", "Директива CHECKPOINT с клаузой 'FILES' должна содержать одно значение типа integer.");
|
||||
//5004
|
||||
codedMessages.put("R168", "Переменная '%s' в клаузе '%s' должна быть объявлена в той же области видимости.");
|
||||
//5005
|
||||
codedMessages.put("R169", "Недопустимый параметр в клаузе TYPE директивы CHECKPOINT.");
|
||||
//5006
|
||||
codedMessages.put("R170", "Клауза '%s' может быть указана только один раз.");
|
||||
//5007
|
||||
codedMessages.put("R172", "Переменная '%s' не может быть указана одновременно в клаузах 'VARLIST' и 'EXCEPT'.");
|
||||
}
|
||||
int idxOfCode = coded.indexOf(':');
|
||||
if (idxOfCode == -1)
|
||||
return coded; // наверно не ошибка, если вдруг передано сообщение без кода
|
||||
else {
|
||||
String code = coded.substring(0, idxOfCode);
|
||||
String message = coded.substring(idxOfCode + 1);
|
||||
if (codedMessages.containsKey(code)) {
|
||||
String original = codedMessages.get(code);
|
||||
if (message == "")
|
||||
return original;
|
||||
else {
|
||||
String[] splited = message.split("#");
|
||||
int idx = 0;
|
||||
int sum = 0;
|
||||
do {
|
||||
idx = original.indexOf('%', idx);
|
||||
if (idx != -1) {
|
||||
sum++;
|
||||
idx += 2;
|
||||
}
|
||||
} while (idx != -1);
|
||||
if (sum != splited.length && !message.equals(""))
|
||||
throw new PassException("Ошибка при декодировании собщений на русском языке");
|
||||
idx = 0;
|
||||
String result = "";
|
||||
for (int z = 0; z < sum; ++z) {
|
||||
int newIdx = original.indexOf('%', idx);
|
||||
result += original.substring(idx, newIdx) + splited[z];
|
||||
idx = newIdx + 2;
|
||||
}
|
||||
result += original.substring(idx);
|
||||
for (Map.Entry<String, String> entry : codedMessages2.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
idx = 0;
|
||||
do {
|
||||
int newIdx = result.indexOf(key, idx);
|
||||
if (newIdx != -1)
|
||||
result = result.substring(idx, newIdx) + value + result.substring(newIdx + key.length() + 1);
|
||||
else
|
||||
idx = -1;
|
||||
} while (idx != -1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return "Ошибка при декодировании сообщений на русском языке - код <" + code +
|
||||
"> не найден. Попробуйте использовать английский язык."
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void setGroup(int group_in) {
|
||||
group = group_in;
|
||||
switch (group) {
|
||||
case 0:
|
||||
group_s += "m0000";
|
||||
break;
|
||||
case parser_group: //сообщения от парсера.
|
||||
group_s += "parser";
|
||||
break;
|
||||
default:
|
||||
group_s += group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
if (Current.HasFile() && Current.getFile().name.equals(file)) {
|
||||
Object o = Current.get(Current.FileGraphElement);
|
||||
return !(o instanceof FileObjectWithMessages) || ((FileObjectWithMessages) o).HasMessage(this);
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
80
src/ProjectData/Messages/MessagesDBTable.java
Normal file
80
src/ProjectData/Messages/MessagesDBTable.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package ProjectData.Messages;
|
||||
import Common.Current;
|
||||
import Common.Database.DataSet;
|
||||
import Common.Database.iDBTable;
|
||||
import Common.UI.DataSetControlForm;
|
||||
import Common.UI.Tables.ColumnFilter;
|
||||
import Common.UI.Tables.TableRenderers;
|
||||
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.table.TableRowSorter;
|
||||
import java.util.Comparator;
|
||||
//https://stackoverflow.com/questions/2026965/can-i-add-a-button-to-a-jtable-column-header
|
||||
//https://stackoverflow.com/questions/7137786/how-can-i-put-a-control-in-the-jtableheader-of-a-jtable/29963916#29963916
|
||||
//https://stackoverflow.com/questions/7137786/how-can-i-put-a-control-in-the-jtableheader-of-a-jtable ->>
|
||||
public class MessagesDBTable<M extends Message> extends iDBTable<M> {
|
||||
public MessagesDBTable(Class<M> d_in) {
|
||||
super(d_in);
|
||||
}
|
||||
@Override
|
||||
protected DataSetControlForm createUI() {
|
||||
DataSet dataset = this;
|
||||
return new DataSetControlForm(this) {
|
||||
@Override
|
||||
public void ShowCurrentObject() throws Exception {
|
||||
super.ShowCurrentObject();
|
||||
Current.getFile().form.getEditor().gotoLine(getCurrent().line);
|
||||
}
|
||||
@Override
|
||||
protected void AdditionalInitColumns() {
|
||||
columns.get(0).setVisible(false);
|
||||
columns.get(3).setMinWidth(700);
|
||||
columns.get(3).setRenderer(TableRenderers.RendererWrapText);
|
||||
}
|
||||
@Override
|
||||
public void MouseAction2() throws Exception {
|
||||
ShowCurrentObject();
|
||||
}
|
||||
@Override
|
||||
public void CreateControl() {
|
||||
super.CreateControl();
|
||||
columnsFilters.put(3, new ColumnFilter(dataset, 3));
|
||||
control.setRowSorter(null);
|
||||
TableRowSorter<TableModel> sorter = new TableRowSorter<>(control.getModel());
|
||||
sorter.setSortable(3, false);
|
||||
control.setRowSorter(sorter);
|
||||
/*
|
||||
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
|
||||
for (int i = 0; i < 6; ++i)
|
||||
sorter.setSortable(i, false);
|
||||
sortKeys.add(new RowSorter.SortKey(6, SortOrder.DESCENDING));
|
||||
sortKeys.add(new RowSorter.SortKey(7, SortOrder.DESCENDING));
|
||||
*/
|
||||
|
||||
// sorter.setSortKeys(sortKeys);
|
||||
// sorter.sort();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Object getFieldAt(M object, int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 1:
|
||||
return object.group_s;
|
||||
case 2:
|
||||
return object.line;
|
||||
case 3:
|
||||
return object.value;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String[] getUIColumnNames() {
|
||||
return new String[]{"группа", "строка", "текст"};
|
||||
}
|
||||
@Override
|
||||
public Comparator<M> getComparator() {
|
||||
return Comparator.comparingInt(o -> o.line);
|
||||
}
|
||||
}
|
||||
14
src/ProjectData/Messages/Notes/MessageNote.java
Normal file
14
src/ProjectData/Messages/Notes/MessageNote.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package ProjectData.Messages.Notes;
|
||||
import ProjectData.Messages.Message;
|
||||
public class MessageNote extends Message {
|
||||
public MessageNote(String file_in, int line_in, String value_in, int group_in) throws Exception {
|
||||
super(file_in, line_in, value_in, group_in);
|
||||
}
|
||||
public MessageNote() {
|
||||
}
|
||||
public static String filterValue = "";
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return super.isVisible()&&value.contains(filterValue);
|
||||
}
|
||||
}
|
||||
25
src/ProjectData/Messages/Notes/NotesDBTable.java
Normal file
25
src/ProjectData/Messages/Notes/NotesDBTable.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package ProjectData.Messages.Notes;
|
||||
import Common.Current;
|
||||
import ProjectData.Messages.MessagesDBTable;
|
||||
public class NotesDBTable extends MessagesDBTable<MessageNote> {
|
||||
public NotesDBTable() {
|
||||
super(MessageNote.class);
|
||||
// setUIContent(UI.getMainWindow().notesPanel);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "примечание";
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.Notes;
|
||||
}
|
||||
public void changeColumnFilterValue(int columnIndex, String text) {
|
||||
if (columnIndex == 3)
|
||||
MessageNote.filterValue = text;
|
||||
}
|
||||
public Object getColumnFilterValue(int columnIndex) {
|
||||
return MessageNote.filterValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package ProjectData.Messages.Recommendations;
|
||||
import Common.Database.iDBObject;
|
||||
import Common.Utils.Utils;
|
||||
import GlobalData.Settings.SettingName;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
public class MessageRecommendation extends iDBObject {
|
||||
//рекомендация может касаться, либо настройки либо прохода. так же может быть просто текстовой.
|
||||
@Description("DEFAULT 'Text'")
|
||||
public RecommendationType type = RecommendationType.Text;
|
||||
@Description("DEFAULT 'Undefined'")
|
||||
public String argName = "Undefined";//либо имя настройки либо имя прохода
|
||||
@Description("DEFAULT ''")
|
||||
public String argValue = ""; //Либо значение настройки либо аргумент для прохода
|
||||
@Description("DEFAULT ''")
|
||||
public String text = ""; //текст
|
||||
public MessageRecommendation() {
|
||||
}
|
||||
public MessageRecommendation(PassCode_2021 passCode_in) {
|
||||
type = RecommendationType.Transformation;
|
||||
argName = passCode_in.toString();
|
||||
text = "Выполните преобразование " + Utils.Quotes(passCode_in.getDescription());
|
||||
}
|
||||
public MessageRecommendation(SettingName settingName_in, String settingValue_in) {
|
||||
type = RecommendationType.Setting;
|
||||
argName = settingName_in.toString();
|
||||
argValue = settingValue_in;
|
||||
if (argValue.equals("1"))
|
||||
text = "Включите настройку SAPFOR " + Utils.Quotes(settingName_in.getDescription());
|
||||
else if (argValue.equals("0"))
|
||||
text = "Отключите настройку SAPFOR " + Utils.Quotes(settingName_in.getDescription());
|
||||
else
|
||||
text = "Задайте значение " + Utils.DQuotes(argValue) + " для настройки SAPFOR " + Utils.Quotes(settingName_in.getDescription());
|
||||
}
|
||||
public MessageRecommendation(String text_in) {
|
||||
type = RecommendationType.Text;
|
||||
text = text_in;
|
||||
}
|
||||
public boolean isMatch(MessageRecommendation recommendation_in) {
|
||||
return type.equals(recommendation_in.type) &&
|
||||
argName.equals(recommendation_in.argName) &&
|
||||
argValue.equals(recommendation_in.argValue);
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ProjectData.Messages.Recommendations;
|
||||
public enum RecommendationType {
|
||||
Setting,
|
||||
Analysis,
|
||||
Transformation,
|
||||
Text;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package ProjectData.Messages.Recommendations;
|
||||
import Common.Current;
|
||||
import Common.Database.iDBTable;
|
||||
import Common.UI.DataSetControlForm;
|
||||
import Common.UI.Tables.TableRenderers;
|
||||
import GlobalData.Settings.SettingName;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
public class RecommendationsDBTable extends iDBTable<MessageRecommendation> {
|
||||
//group=1 - настройка
|
||||
//group=2 - преобразование
|
||||
public RecommendationsDBTable() {
|
||||
super(MessageRecommendation.class);
|
||||
// setUIContent(UI.getMainWindow().errorsPanel);
|
||||
}
|
||||
@Override
|
||||
protected DataSetControlForm createUI() {
|
||||
return new DataSetControlForm(this){
|
||||
@Override
|
||||
protected void AdditionalInitColumns() {
|
||||
columns.get(0).setVisible(false);
|
||||
columns.get(1).setMinWidth(700);
|
||||
columns.get(1).setRenderer(TableRenderers.RendererWrapText);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@Override
|
||||
public String[] getUIColumnNames() {
|
||||
return new String[]{"текст"};
|
||||
}
|
||||
@Override
|
||||
public Object getFieldAt(MessageRecommendation object, int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 1:
|
||||
return object.text;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "рекомендация";
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.Recommendations;
|
||||
}
|
||||
public void addRecommendation(int group_in) {
|
||||
MessageRecommendation result = null;
|
||||
switch (group_in) {
|
||||
/*
|
||||
case 1013:
|
||||
//процедура. понять как извлекать ее из сообщения, и сунуть как аргумент преобразованию.
|
||||
break;
|
||||
*/
|
||||
case 1015:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_RemoveUnusedFunctions);
|
||||
break;
|
||||
case 1018:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_LoopEndDoConverterPass);
|
||||
break;
|
||||
case 1020:
|
||||
result = new MessageRecommendation(SettingName.KEEP_DVM_DIRECTIVES, "1");
|
||||
break;
|
||||
case 1027:
|
||||
case 1060:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_CorrectCodeStylePass);
|
||||
break;
|
||||
case 1041:
|
||||
case 3012:
|
||||
case 3013:
|
||||
case 3014:
|
||||
case 3015:
|
||||
case 3017:
|
||||
case 3018:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_ResolveParallelRegionConflicts);
|
||||
break;
|
||||
case 1061:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_InsertIncludesPass);
|
||||
break;
|
||||
case 3020:
|
||||
result = new MessageRecommendation(PassCode_2021.SPF_DuplicateFunctionChains);
|
||||
break;
|
||||
}
|
||||
MessageRecommendation finalResult = result;
|
||||
if ((result != null) && (Data.values().stream().noneMatch(recommendation -> recommendation.isMatch(finalResult)))) {
|
||||
try {
|
||||
getDb().Insert(result);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/ProjectData/Messages/Warnings/MessageWarning.java
Normal file
17
src/ProjectData/Messages/Warnings/MessageWarning.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package ProjectData.Messages.Warnings;
|
||||
import ProjectData.Messages.Message;
|
||||
public class MessageWarning extends Message {
|
||||
|
||||
|
||||
public MessageWarning(String file_in, int line_in, String value_in, int group_in) throws Exception {
|
||||
super(file_in, line_in, value_in, group_in);
|
||||
}
|
||||
public MessageWarning() {
|
||||
}
|
||||
public static String filterValue = "";
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return super.isVisible()&&value.contains(filterValue);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/ProjectData/Messages/Warnings/WarningsDBTable.java
Normal file
25
src/ProjectData/Messages/Warnings/WarningsDBTable.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package ProjectData.Messages.Warnings;
|
||||
import Common.Current;
|
||||
import ProjectData.Messages.MessagesDBTable;
|
||||
public class WarningsDBTable extends MessagesDBTable<MessageWarning> {
|
||||
//https://stackoverflow.com/questions/13079777/editable-jtableheader
|
||||
public WarningsDBTable() {
|
||||
super(MessageWarning.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "предупреждение";
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.Warnings;
|
||||
}
|
||||
// применить значение фильтра к фильру объекта напирмер Message.filterValue = text;
|
||||
public void changeColumnFilterValue(int columnIndex, String text) {
|
||||
if (columnIndex == 3)
|
||||
MessageWarning.filterValue = text;
|
||||
}
|
||||
public Object getColumnFilterValue(int columnIndex) {
|
||||
return MessageWarning.filterValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ProjectData.PredictorStatistic;
|
||||
import Common.Database.DBTable;
|
||||
public class PredictorStatisticsDBTable extends DBTable<String, PredictorStatistics_2021> {
|
||||
public PredictorStatisticsDBTable() {
|
||||
super(String.class, PredictorStatistics_2021.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "статистика варианта";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package ProjectData.PredictorStatistic;
|
||||
import Common.Database.DBObject;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static ProjectData.SapforData.Variants.ParallelVariant.rankNaN;
|
||||
import static ProjectData.SapforData.Variants.ParallelVariant.statNaN;
|
||||
public class PredictorStatistics_2021 extends DBObject {
|
||||
@Description("PRIMARY KEY, UNIQUE")
|
||||
public String key = "";
|
||||
public long PredictionTime = 0;
|
||||
//статистика -------------------------------
|
||||
public long ParallelCount = statNaN;
|
||||
public long RemoteCount = statNaN;
|
||||
public long RedistributeCount = statNaN;
|
||||
public long IntervalCount = statNaN;
|
||||
public long PS_RemoteCount = statNaN;
|
||||
public long PS_ShadowCount = statNaN;
|
||||
public long PS_ReductionCount = statNaN;
|
||||
public long PS_AcrossCount = statNaN;
|
||||
public long Rank = rankNaN;
|
||||
@Description("DEFAULT ''")
|
||||
public String last_version = "";
|
||||
//-------------------------------------------
|
||||
@Description("IGNORE")
|
||||
public boolean loaded = true;
|
||||
//этот конструктор только для пустой статистики.
|
||||
public PredictorStatistics_2021(String key_in) {
|
||||
key = key_in;
|
||||
loaded = false;
|
||||
}
|
||||
public PredictorStatistics_2021() {
|
||||
}
|
||||
public Date getPredictionDate() {
|
||||
return new Date(PredictionTime);
|
||||
}
|
||||
//распаковка инфы о варианте от сапфора.
|
||||
public void Unpack(String packed) {
|
||||
String[] splited = packed.split("\\|");
|
||||
ParallelCount = Integer.parseInt(splited[0]);
|
||||
RemoteCount = Integer.parseInt(splited[1]);
|
||||
RedistributeCount = Integer.parseInt(splited[2]);
|
||||
IntervalCount = Integer.parseInt(splited[3]);
|
||||
PS_RemoteCount = Integer.parseInt(splited[4]);
|
||||
PS_ShadowCount = Integer.parseInt(splited[5]);
|
||||
PS_ReductionCount = Integer.parseInt(splited[6]);
|
||||
PS_AcrossCount = Integer.parseInt(splited[7]);
|
||||
try {
|
||||
Rank = Integer.parseInt(splited[8]);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
PredictionTime = new Date().getTime();
|
||||
}
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
10
src/ProjectData/Project/ChangeSettingPass.java
Normal file
10
src/ProjectData/Project/ChangeSettingPass.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package ProjectData.Project;
|
||||
import GlobalData.Settings.DBSetting;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
public class ChangeSettingPass extends Pass_2021<DBSetting> {
|
||||
@Override
|
||||
protected boolean canStart(Object... args) throws Exception {
|
||||
target = (DBSetting) args[0];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
11
src/ProjectData/Project/ProjectInfoDBTable.java
Normal file
11
src/ProjectData/Project/ProjectInfoDBTable.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package ProjectData.Project;
|
||||
import Common.Database.DBTable;
|
||||
public class ProjectInfoDBTable extends DBTable<String, db_project_info> {
|
||||
public ProjectInfoDBTable() {
|
||||
super(String.class, db_project_info.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "проект";
|
||||
}
|
||||
}
|
||||
49
src/ProjectData/Project/UI/PackageVersionsTree.java
Normal file
49
src/ProjectData/Project/UI/PackageVersionsTree.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ProjectData.Project.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Trees.DataTree;
|
||||
import Common.UI.Trees.TreeRenderers;
|
||||
import Common.UI.UI;
|
||||
import ProjectData.Project.db_project_info;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
public class PackageVersionsTree extends DataTree {
|
||||
public PackageVersionsTree() {
|
||||
super(null);
|
||||
// Current.getSapforTasksPackage().root);
|
||||
// setRootVisible(false);
|
||||
ExpandAll();
|
||||
}
|
||||
@Override
|
||||
public TreeRenderers getRenderer() {
|
||||
return TreeRenderers.RendererPackageVersion;
|
||||
}
|
||||
@Override
|
||||
public Current getCurrent() {
|
||||
return Current.PackageVersion;
|
||||
}
|
||||
@Override
|
||||
protected int getStartLine() {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public void SelectionAction(TreePath path) {
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
|
||||
Object object = node.getUserObject();
|
||||
if (object instanceof db_project_info) {
|
||||
Current.set(getCurrent(), object);
|
||||
}else {
|
||||
Current.set(getCurrent(), null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void LeftMouseAction2() {
|
||||
if ((Current.HasPackageVersion())&&(UI.Question("Открыть версию пакета, как текущий проект"))){
|
||||
//Открываем как папку, чтобы было отдельное дерево версий, уже как для нормального проекта.
|
||||
//? Запретить удалять ее (?). копировать куда то как времянку мб.
|
||||
Pass_2021.passes.get(PassCode_2021.OpenCurrentProject).Do(Current.getPackageVersion().Home);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package ProjectData.Project.UI;
|
||||
import Common.UI.Trees.StyledTreeCellRenderer;
|
||||
import ProjectData.Project.db_project_info;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.net.URL;
|
||||
public class PackageVersionsTreeCellRenderer extends StyledTreeCellRenderer {
|
||||
public java.awt.Component getTreeCellRendererComponent(
|
||||
JTree tree, Object value,
|
||||
boolean selected, boolean expanded,
|
||||
boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
URL imageUrl = null;
|
||||
Object o = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
if (o instanceof db_project_info) {
|
||||
/*
|
||||
db_project_info version = (db_project_info) o;
|
||||
String type_image_key = "";
|
||||
if (version.Home.getParent().equals(Current.getSapforTasksPackage().getWorkspace().getAbsolutePath()))
|
||||
type_image_key = "Root";
|
||||
else if (version.IsMCopy())
|
||||
type_image_key = "M";
|
||||
else
|
||||
type_image_key = "Version";
|
||||
imageUrl = getClass().getResource("/icons/versions/" +
|
||||
type_image_key +
|
||||
".png");
|
||||
if (imageUrl != null) {
|
||||
setIcon(new ImageIcon(imageUrl));
|
||||
}
|
||||
setForeground(tree.getForeground());
|
||||
setFont(getFont().deriveFont((float) 14.0));
|
||||
setText(version.getTitle());
|
||||
|
||||
*/
|
||||
}else {
|
||||
setForeground(tree.getForeground());
|
||||
setFont(getFont().deriveFont((float) 14.0));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
68
src/ProjectData/Project/UI/VersionsTree.java
Normal file
68
src/ProjectData/Project/UI/VersionsTree.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package ProjectData.Project.UI;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.Menus.GraphMenu;
|
||||
import Common.UI.Menus.VersionsMenu;
|
||||
import Common.UI.Selectable;
|
||||
import Common.UI.Trees.DataTree;
|
||||
import Common.UI.Trees.TreeRenderers;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
public class VersionsTree extends DataTree {
|
||||
public VersionsTree() {
|
||||
super(Current.getRoot().node);
|
||||
SelectCurrentProject();
|
||||
this.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
switch (e.getKeyCode()) {
|
||||
case KeyEvent.VK_DELETE:
|
||||
Pass_2021.passes.get(PassCode_2021.DeleteVersion).Do();
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
if (Current.HasVersion())
|
||||
Pass_2021.passes.get(PassCode_2021.OpenCurrentProject).Do(Current.getVersion());
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public TreeRenderers getRenderer() {
|
||||
return TreeRenderers.RendererVersion;
|
||||
}
|
||||
@Override
|
||||
public Current getCurrent() {
|
||||
return Current.Version;
|
||||
}
|
||||
public void SelectCurrentProject() {
|
||||
setSelectionPath(new TreePath(Current.getProject().node.getPath()));
|
||||
}
|
||||
@Override
|
||||
protected GraphMenu createMenu() {
|
||||
return new VersionsMenu(this);
|
||||
}
|
||||
@Override
|
||||
public void LeftMouseAction1() {
|
||||
if (Global.versions_multiselection) {
|
||||
// только если есть режим выбора версий.
|
||||
Object element = Current.get(getCurrent());
|
||||
if ((element instanceof Selectable)) {
|
||||
((Selectable) element).SwitchSelection();
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void LeftMouseAction2() {
|
||||
Pass_2021.passes.get(PassCode_2021.OpenCurrentProject).Do(Current.getVersion());
|
||||
}
|
||||
@Override
|
||||
protected int getStartLine() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
74
src/ProjectData/Project/UI/VersionsTreeCellRenderer.java
Normal file
74
src/ProjectData/Project/UI/VersionsTreeCellRenderer.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package ProjectData.Project.UI;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.Selectable;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import Common.UI.Trees.StyledTreeCellRenderer;
|
||||
import ProjectData.Project.db_project_info;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.net.URL;
|
||||
//https://docs.oracle.com/javase/7/docs/api/javax/swing/tree/DefaultMutableTreeNode.html
|
||||
//https://java.hotexamples.com/ru/examples/java.awt/JTree/-/java-jtree-class-examples.html
|
||||
public class VersionsTreeCellRenderer extends StyledTreeCellRenderer {
|
||||
public java.awt.Component getTreeCellRendererComponent(
|
||||
JTree tree, Object value,
|
||||
boolean selected, boolean expanded,
|
||||
boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
Object o = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
db_project_info version = (db_project_info) o;
|
||||
if (Global.versions_multiselection) {
|
||||
setIcon(((Selectable) o).GetSelectionIcon());
|
||||
} else {
|
||||
URL imageUrl = null;
|
||||
boolean current = Current.HasProject() && version.Home.equals(Current.getProject().Home);
|
||||
String type_image_key = "";
|
||||
if (version.Home.equals(Current.getRoot().Home))
|
||||
type_image_key = "Root";
|
||||
else if (version.IsMCopy())
|
||||
type_image_key = "M";
|
||||
else
|
||||
type_image_key = "Version";
|
||||
if (current)
|
||||
type_image_key = "current" + type_image_key;
|
||||
imageUrl = getClass().getResource("/icons/versions/" +
|
||||
type_image_key +
|
||||
".png");
|
||||
if (imageUrl != null) {
|
||||
setIcon(new ImageIcon(imageUrl));
|
||||
}
|
||||
}
|
||||
setForeground(tree.getForeground());
|
||||
setFont(Current.getTheme().Fonts.get(
|
||||
version.isNew ? VisualiserFonts.NewVersion : VisualiserFonts.TreePlain));
|
||||
setText(version.getTitle());
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
Fonts.put(VisualiserFonts.Version, new Font(
|
||||
new HashMap<TextAttribute, Object>() {
|
||||
{
|
||||
put(TextAttribute.FAMILY, "Times New Roman");
|
||||
put(TextAttribute.FOREGROUND, Color.BLACK);
|
||||
put(TextAttribute.BACKGROUND, Color.WHITE);
|
||||
put(TextAttribute.SIZE, 14);
|
||||
}
|
||||
}
|
||||
|
||||
));
|
||||
Fonts.put(VisualiserFonts.NewVersion, new Font(
|
||||
new HashMap<TextAttribute, Object>() {
|
||||
{
|
||||
put(TextAttribute.FAMILY, "Times New Roman");
|
||||
put(TextAttribute.FOREGROUND, Color.BLACK);
|
||||
put(TextAttribute.BACKGROUND, Color.YELLOW);
|
||||
put(TextAttribute.SIZE, 14);
|
||||
}
|
||||
}
|
||||
|
||||
));
|
||||
*/
|
||||
}
|
||||
1569
src/ProjectData/Project/db_project_info.java
Normal file
1569
src/ProjectData/Project/db_project_info.java
Normal file
File diff suppressed because it is too large
Load Diff
92
src/ProjectData/ProjectDatabase.java
Normal file
92
src/ProjectData/ProjectDatabase.java
Normal file
@@ -0,0 +1,92 @@
|
||||
package ProjectData;
|
||||
import Common.Database.SQLITE.SQLiteDatabase;
|
||||
import ProjectData.DBArray.ArraysDBTable;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.Files.FileType;
|
||||
import ProjectData.Files.FilesDBTable;
|
||||
import ProjectData.Messages.Errors.ErrorsDBTable;
|
||||
import ProjectData.Messages.Notes.NotesDBTable;
|
||||
import ProjectData.Messages.Recommendations.RecommendationsDBTable;
|
||||
import ProjectData.Messages.Warnings.WarningsDBTable;
|
||||
import ProjectData.PredictorStatistic.PredictorStatisticsDBTable;
|
||||
import ProjectData.Project.ProjectInfoDBTable;
|
||||
import ProjectData.Project.db_project_info;
|
||||
import ProjectData.SapforData.Functions.FuncCoordinatesDBTable;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.io.File;
|
||||
import java.util.Vector;
|
||||
public class ProjectDatabase extends SQLiteDatabase {
|
||||
public db_project_info owner;
|
||||
public ProjectInfoDBTable projectInfo;
|
||||
public FilesDBTable files;
|
||||
public ArraysDBTable savedArrays; //мб в дальнейшем как то объединить эти объекты с сапфоровскими? хз.
|
||||
public PredictorStatisticsDBTable predictorStatistics;
|
||||
public NotesDBTable notes;
|
||||
public WarningsDBTable warnings;
|
||||
public ErrorsDBTable errors;
|
||||
public RecommendationsDBTable recommendations;
|
||||
public FuncCoordinatesDBTable funcCoordinates;
|
||||
public ProjectDatabase(db_project_info owner_in) {
|
||||
super(db_project_info.get_db_file((owner_in).Home));
|
||||
owner = owner_in;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
@Override
|
||||
protected void initAllTables() throws Exception {
|
||||
addTable(projectInfo = new ProjectInfoDBTable());
|
||||
addTable(files = new FilesDBTable());
|
||||
addTable(savedArrays = new ArraysDBTable());
|
||||
addTable(predictorStatistics = new PredictorStatisticsDBTable());
|
||||
addTable(notes = new NotesDBTable());
|
||||
addTable(warnings = new WarningsDBTable());
|
||||
addTable(errors = new ErrorsDBTable());
|
||||
addTable(recommendations = new RecommendationsDBTable());
|
||||
addTable(funcCoordinates = new FuncCoordinatesDBTable());
|
||||
}
|
||||
//Делать это только после пострения дерева версий. чтобы файлы версий не учитывались!!
|
||||
public DefaultMutableTreeNode get_files_r(File file) throws Exception {
|
||||
DefaultMutableTreeNode res = null;
|
||||
if (owner.isProjectDirectory(file)) {
|
||||
res = new DefaultMutableTreeNode(file);
|
||||
File[] files_ = file.listFiles();
|
||||
if (files_ != null) {
|
||||
for (File f : files_) {
|
||||
DefaultMutableTreeNode node = get_files_r(f);
|
||||
//Null может быть если подпапки оказались от версий
|
||||
if (node != null)
|
||||
res.add(node);
|
||||
}
|
||||
}
|
||||
} else if (file.isFile()) {
|
||||
DBProjectFile pf = null;
|
||||
String name = owner.getInnerName(file);
|
||||
if (files.Data.containsKey(name)) {
|
||||
pf = files.Data.get(name);
|
||||
pf.Init(file, owner);
|
||||
} else {
|
||||
pf = new DBProjectFile(file, owner);
|
||||
if (pf.fileType != FileType.forbidden)
|
||||
Insert(pf);
|
||||
else return null;
|
||||
}
|
||||
res = pf.node = new DefaultMutableTreeNode(pf); //узел файла тут же надо запомнить.
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@Override
|
||||
public void Init() throws Exception {
|
||||
owner.DeleteCrushedVersionIfNeed();
|
||||
owner.filesTreeRoot = get_files_r(owner.Home);
|
||||
Vector<DBProjectFile> inexisting_files = new Vector<>();
|
||||
for (DBProjectFile f : files.Data.values())
|
||||
if (f.father == null) inexisting_files.add(f);
|
||||
for (DBProjectFile f : inexisting_files)
|
||||
Delete(f);
|
||||
}
|
||||
//особый проход. нужен при первичной загрузке проекта.
|
||||
public db_project_info LoadOnlyProjectInfo() throws Exception {
|
||||
LoadAll(projectInfo);
|
||||
return projectInfo.getFirstRecord();
|
||||
}
|
||||
}
|
||||
35
src/ProjectData/ProjectView.java
Normal file
35
src/ProjectData/ProjectView.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package ProjectData;
|
||||
public enum ProjectView {
|
||||
Files,
|
||||
Includes,
|
||||
FunctionsCallsPoints,
|
||||
FunctionsHierarchy;
|
||||
public String getIcon(){
|
||||
switch (this){
|
||||
case Files:
|
||||
return "/icons/Editor/Paste.png";
|
||||
case Includes:
|
||||
return "/icons/Transformations/SPF_InsertIncludesPass.png";
|
||||
case FunctionsHierarchy:
|
||||
return "/icons/FunctionsH.png";
|
||||
case FunctionsCallsPoints:
|
||||
return "/icons/Function.png";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public String getDescription(){
|
||||
switch (this){
|
||||
case Files:
|
||||
return "Файлы";
|
||||
case Includes:
|
||||
return "Зависимости по включениям";
|
||||
case FunctionsHierarchy:
|
||||
return "Иерархия процедур";
|
||||
case FunctionsCallsPoints:
|
||||
return "Точки вызовов процедур";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/ProjectData/SapforData/Arrays/ArrayDecl.java
Normal file
18
src/ProjectData/SapforData/Arrays/ArrayDecl.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package ProjectData.SapforData.Arrays;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
// это то что отображается в боковом графе файла. не путать с сапфоровским ProjectArray
|
||||
public class ArrayDecl extends FileObjectWithMessages {
|
||||
public String array_name;
|
||||
public ArrayLocation array_loc;
|
||||
public ArrayDecl(String array_name_in, ArrayLocation array_loc_in, DBProjectFile father_in, int lineNum_in) {
|
||||
super(father_in, lineNum_in);
|
||||
array_name = array_name_in;
|
||||
array_loc = array_loc_in;
|
||||
}
|
||||
@Override
|
||||
public String Description() {
|
||||
return array_loc.getDescription() + " массив " + Utils.Brackets(array_name);
|
||||
}
|
||||
}
|
||||
40
src/ProjectData/SapforData/Arrays/ArrayLocation.java
Normal file
40
src/ProjectData/SapforData/Arrays/ArrayLocation.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package ProjectData.SapforData.Arrays;
|
||||
public enum ArrayLocation {
|
||||
local, common, module, parameter, structure, local_save, unknown;
|
||||
public static ArrayLocation fromInt(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return local;
|
||||
case 1:
|
||||
return common;
|
||||
case 2:
|
||||
return module;
|
||||
case 3:
|
||||
return parameter;
|
||||
case 4:
|
||||
return structure;
|
||||
case 5:
|
||||
return local_save;
|
||||
default:
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case local:
|
||||
return "локальный";
|
||||
case common:
|
||||
return "глобальный";
|
||||
case module:
|
||||
return "модульный";
|
||||
case parameter:
|
||||
return "параметр";
|
||||
case structure:
|
||||
return "структура";
|
||||
case local_save:
|
||||
return "локальный сохраняемый";
|
||||
default:
|
||||
return this.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/ProjectData/SapforData/Arrays/ArrayState.java
Normal file
24
src/ProjectData/SapforData/Arrays/ArrayState.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package ProjectData.SapforData.Arrays;
|
||||
import javax.swing.*;
|
||||
import java.net.URL;
|
||||
public enum ArrayState {
|
||||
Selected, None, SpfPrivate, IOPrivate, Unknown;
|
||||
public static ArrayState fromInt(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return Selected;
|
||||
case 1:
|
||||
return None;
|
||||
case 2:
|
||||
return SpfPrivate;
|
||||
case 3:
|
||||
return IOPrivate;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
}
|
||||
public ImageIcon GetIcon() {
|
||||
URL imageUrl = getClass().getResource("/icons/Arrays/" + this + ".png");
|
||||
return new ImageIcon(imageUrl);
|
||||
}
|
||||
}
|
||||
82
src/ProjectData/SapforData/Arrays/ArraysSet.java
Normal file
82
src/ProjectData/SapforData/Arrays/ArraysSet.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package ProjectData.SapforData.Arrays;
|
||||
import Common.Current;
|
||||
import Common.Database.DataSet;
|
||||
import Common.Global;
|
||||
import Common.UI.DataSetControlForm;
|
||||
import GlobalData.Settings.SettingName;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import static Common.UI.Tables.TableEditors.EditorHyperlinks;
|
||||
import static Common.UI.Tables.TableRenderers.RendererHiddenList;
|
||||
import static Common.UI.Tables.TableRenderers.RendererHyperlinks;
|
||||
public class ArraysSet extends DataSet<Long, ProjectArray> {
|
||||
public ArraysSet() {
|
||||
super(Long.class, ProjectArray.class);
|
||||
}
|
||||
@Override
|
||||
public String getSingleDescription() {
|
||||
return "массив";
|
||||
}
|
||||
@Override
|
||||
public String getPluralDescription() {
|
||||
return "объявленные массивы";
|
||||
}
|
||||
@Override
|
||||
public Current CurrentName() {
|
||||
return Current.ProjectArray;
|
||||
}
|
||||
@Override
|
||||
protected DataSetControlForm createUI() {
|
||||
return new DataSetControlForm(this) {
|
||||
@Override
|
||||
public boolean hasCheckBox() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
protected void AdditionalInitColumns() {
|
||||
columns.get(0).setVisible(false);
|
||||
if (Global.db.settings.get(SettingName.ShowFullArraysDeclarations).toBoolean()) {
|
||||
columns.get(4).setRenderer(RendererHyperlinks);
|
||||
columns.get(4).setEditor(EditorHyperlinks);
|
||||
} else {
|
||||
columns.get(4).setRenderer(RendererHiddenList);
|
||||
columns.get(4).setMaxWidth(200);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public String[] getUIColumnNames() {
|
||||
return new String[]{
|
||||
"Имя", "Область описания", "Файлы объявления", "Размерность", "Размер элемента(байт)", "Область распараллеливания"
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Object getFieldAt(ProjectArray object, int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 1:
|
||||
return object.State;
|
||||
case 2:
|
||||
return object.GetShortNameWithDim();
|
||||
case 3:
|
||||
return object.locName + " : " + object.location;
|
||||
case 4:
|
||||
return object.GetDeclPlacesList();
|
||||
case 5:
|
||||
return object.dimSize;
|
||||
case 6:
|
||||
return object.typeSize;
|
||||
case 7:
|
||||
return object.GetRegionsText();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void CheckAll(boolean flag) {
|
||||
Pass_2021.passes.get(PassCode_2021.MassSelectArrays).Do(flag,new Vector(Current.getProject().declaratedArrays.Data.values()));
|
||||
}
|
||||
}
|
||||
145
src/ProjectData/SapforData/Arrays/Distribution/AlignRule.java
Normal file
145
src/ProjectData/SapforData/Arrays/Distribution/AlignRule.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package ProjectData.SapforData.Arrays.Distribution;
|
||||
import Common.Utils.Index;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
import ProjectData.SapforData.Regions.ParallelRegion;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
public class AlignRule {
|
||||
public BigInteger alignArray_address;
|
||||
public BigInteger alignWith_address;
|
||||
public ParallelRegion parent_region = null;
|
||||
public Vector<Pair<Integer, Integer>> alignRule;
|
||||
public Vector<Pair<Integer, Pair<Integer, Integer>>> alignRuleWith = new Vector<>();
|
||||
public AlignRule(String[] splited, Index idx) {
|
||||
alignArray_address = new BigInteger((splited[idx.Inc()]));
|
||||
alignWith_address = new BigInteger(splited[idx.Inc()]);
|
||||
int alignRule_size = Integer.parseInt((splited[idx.Inc()]));
|
||||
alignRule = new Vector<>(alignRule_size);
|
||||
for (int i = 0; i < alignRule_size; ++i) {
|
||||
int first = Integer.parseInt(splited[idx.Inc()]);
|
||||
int second = Integer.parseInt(splited[idx.Inc()]);
|
||||
alignRule.add(new Pair<>(first, second));
|
||||
}
|
||||
int alignRuleWith_size = Integer.parseInt(splited[idx.Inc()]);
|
||||
alignRuleWith = new Vector<>(alignRuleWith_size);
|
||||
for (int i = 0; i < alignRuleWith_size; ++i) {
|
||||
int first = Integer.parseInt(splited[idx.Inc()]);
|
||||
int first_ = Integer.parseInt(splited[idx.Inc()]);
|
||||
int second_ = Integer.parseInt(splited[idx.Inc()]);
|
||||
alignRuleWith.add(new Pair<>(first, new Pair<>(first_, second_)));
|
||||
}
|
||||
}
|
||||
private static Pair<String, String> convertDigitToPositive(int digit) {
|
||||
String buf = "";
|
||||
String sign = " + ";
|
||||
if (digit < 0) {
|
||||
sign = " - ";
|
||||
int val = -digit;
|
||||
buf += String.valueOf(val);
|
||||
} else
|
||||
buf += String.valueOf(digit);
|
||||
return new Pair<>(sign, buf);
|
||||
}
|
||||
public ProjectArray getAlignArray() {
|
||||
return parent_region.arrays.get(alignArray_address);
|
||||
}
|
||||
public ProjectArray getAlignWith() {
|
||||
return parent_region.arrays.get(alignWith_address);
|
||||
}
|
||||
String genStringExpr(String letter, Pair<Integer, Integer> expr) {
|
||||
String retVal = "";
|
||||
if (expr.getKey() == 0 && expr.getValue() == 0)
|
||||
retVal = "*";
|
||||
else if (expr.getValue() == 0) {
|
||||
if (expr.getKey() == 1)
|
||||
retVal = letter;
|
||||
else {
|
||||
Pair<String, String> digit2 = convertDigitToPositive(expr.getKey());
|
||||
if (digit2.getKey() == " - ")
|
||||
retVal = "(-" + digit2.getValue() + ")" + " * " + letter;
|
||||
else retVal = digit2.getValue() + " * " + letter;
|
||||
}
|
||||
} else {
|
||||
Pair<String, String> digit1 = convertDigitToPositive(expr.getValue());
|
||||
if (expr.getKey() == 1)
|
||||
retVal = letter + digit1.getKey() + digit1.getValue();
|
||||
else {
|
||||
Pair<String, String> digit2 = convertDigitToPositive(expr.getKey());
|
||||
if (digit2.getKey() == " - ")
|
||||
retVal = "(-" + digit2.getValue() + ")" + " * " + letter + digit1.getKey() + digit1.getValue();
|
||||
else
|
||||
retVal = digit2.getValue() + " * " + letter + digit1.getKey() + digit1.getValue();
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
public int GetLenString() {
|
||||
String val = "";
|
||||
val += getAlignArray().shortName + "(";
|
||||
for (int i = 0; i < alignRule.size(); ++i) {
|
||||
val += genStringExpr(ProjectArray.alignNames[i], alignRule.get(i));
|
||||
if (i != alignRule.size() - 1)
|
||||
val += ",";
|
||||
}
|
||||
val += ") ";
|
||||
return val.length();
|
||||
}
|
||||
public Pair<String, String> GenRule(int maxArrayStringLen) {
|
||||
getAlignArray().ac_current.clear();
|
||||
getAlignArray().ac_new.clear();
|
||||
getAlignArray().spaces_shift = "";
|
||||
//------------------------------------------------------------>>>
|
||||
getAlignArray().align_template = getAlignWith();
|
||||
getAlignArray().parent_region = parent_region;
|
||||
//------------------------------------------------------------>>>
|
||||
String retVal = "";
|
||||
String arrayString = "";
|
||||
retVal += getAlignArray().TypeString() + " ";
|
||||
arrayString += getAlignArray().shortName + "(";
|
||||
for (int i = 0; i < alignRule.size(); ++i) {
|
||||
arrayString += genStringExpr(ProjectArray.alignNames[i], alignRule.get(i));
|
||||
if (i != alignRule.size() - 1)
|
||||
arrayString += ",";
|
||||
}
|
||||
arrayString += ") ";
|
||||
for (int i = 0; i < maxArrayStringLen - arrayString.length(); ++i) {
|
||||
getAlignArray().spaces_shift += " ";
|
||||
}
|
||||
retVal += getAlignArray().spaces_shift;
|
||||
retVal += arrayString;
|
||||
String bracket_open = "(";
|
||||
String bracket_close = ")";
|
||||
|
||||
/*
|
||||
if (getAlignWith().isTemplFlag > 0)
|
||||
{
|
||||
bracket_open = "[";
|
||||
bracket_close = "]";
|
||||
}
|
||||
*/
|
||||
retVal += "→ " + getAlignWith().shortName + bracket_open;
|
||||
Vector<String> alignEachDim = new Vector<>(getAlignWith().dimSize);
|
||||
for (int i = 0; i < alignEachDim.capacity(); ++i)
|
||||
alignEachDim.add("*");
|
||||
for (int i = 0; i < alignRuleWith.size(); ++i) {
|
||||
if (alignRuleWith.get(i).getKey() != -1) {
|
||||
alignEachDim.set(alignRuleWith.get(i).getKey(), genStringExpr(ProjectArray.alignNames[i], alignRuleWith.get(i).getValue()));
|
||||
//коэццициенты находятся здесь!!------------------------------------------------------------------->>
|
||||
getAlignArray().ac_current.put(i,
|
||||
new Dimension(i,
|
||||
alignRuleWith.get(i).getValue().getKey(),
|
||||
alignRuleWith.get(i).getValue().getValue()
|
||||
));
|
||||
} else getAlignArray().ac_current.put(i, new Dimension(i));
|
||||
}
|
||||
for (int i = 0; i < alignEachDim.size(); ++i) {
|
||||
retVal += alignEachDim.get(i);
|
||||
if (i != getAlignWith().dimSize - 1)
|
||||
retVal += ",";
|
||||
}
|
||||
retVal += bracket_close;// + String_.wands(alignArray.Id.ToString());
|
||||
return new Pair<>(getAlignWith().shortName, retVal);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package ProjectData.SapforData.Arrays.Distribution;
|
||||
import ProjectData.SapforData.Arrays.ArrayLocation;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
public class DataDirective extends Directive {
|
||||
public Vector<AlignRule> alignRules;
|
||||
public String rules_ = "";
|
||||
public Vector<String> rules = new Vector<>();
|
||||
public void genRules_(LinkedHashMap<Long, ProjectArray> Arrays) {
|
||||
rules_ = "";
|
||||
int maxLen = 0;
|
||||
for (AlignRule a : alignRules)
|
||||
maxLen = Math.max(maxLen, a.GetLenString());
|
||||
LinkedHashMap<String, Vector<String>> toPrint = new LinkedHashMap<>();
|
||||
for (AlignRule a : alignRules) {
|
||||
if (Arrays.get(a.alignArray_address).location != ArrayLocation.parameter) {
|
||||
Pair<String, String> result = a.GenRule(maxLen);
|
||||
if (!toPrint.containsKey(result.getKey()))
|
||||
toPrint.put(result.getKey(), new Vector<>());
|
||||
toPrint.get(result.getKey()).add(result.getValue());
|
||||
}
|
||||
}
|
||||
for (Vector<String> v : toPrint.values()) {
|
||||
rules_ += String.join("\n", v);
|
||||
}
|
||||
}
|
||||
public void genRules(LinkedHashMap<BigInteger, ProjectArray> Arrays) {
|
||||
rules.clear();
|
||||
int maxLen = 0;
|
||||
for (AlignRule a : alignRules)
|
||||
maxLen = Math.max(maxLen, a.GetLenString());
|
||||
LinkedHashMap<String, Vector<String>> toPrint = new LinkedHashMap<>();
|
||||
for (AlignRule a : alignRules) {
|
||||
if (Arrays.get(a.alignArray_address).location != ArrayLocation.parameter) {
|
||||
Pair<String, String> result = a.GenRule(maxLen);
|
||||
if (!toPrint.containsKey(result.getKey()))
|
||||
toPrint.put(result.getKey(), new Vector<>());
|
||||
toPrint.get(result.getKey()).add(result.getValue());
|
||||
}
|
||||
}
|
||||
for (Vector<String> v : toPrint.values())
|
||||
for (String r : v)
|
||||
rules.add(r);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package ProjectData.SapforData.Arrays.Distribution;
|
||||
import Common.Database.DBObject;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
public class Dimension extends DBObject {
|
||||
//--------------------------------------
|
||||
public int num; //номер измерения.
|
||||
public int K = 0;
|
||||
public int B = 0;
|
||||
public boolean active = false;
|
||||
//-------------------------------------
|
||||
public Dimension(int num_in) {
|
||||
num = num_in;
|
||||
}
|
||||
public Dimension(int num_in, int K_in, int B_in) {
|
||||
num = num_in;
|
||||
K = K_in;
|
||||
B = B_in;
|
||||
active = true;
|
||||
}
|
||||
public Dimension clone_() {
|
||||
Dimension res = new Dimension(num);
|
||||
res.active = active;
|
||||
res.K = K;
|
||||
res.B = B;
|
||||
return res;
|
||||
}
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return num;
|
||||
}
|
||||
public String getLetter() {
|
||||
return ProjectArray.alignNames[num];
|
||||
} //для отображения букв
|
||||
public int getS() {
|
||||
return active ? num : -1;
|
||||
} //для триплета. шифр.
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ProjectData.SapforData.Arrays.Distribution;
|
||||
import ProjectData.LanguageName;
|
||||
public class Directive {
|
||||
public LanguageName langType = LanguageName.fortran;
|
||||
public String file = "";
|
||||
public int line = -1;
|
||||
public int col = -1;
|
||||
}
|
||||
400
src/ProjectData/SapforData/Arrays/ProjectArray.java
Normal file
400
src/ProjectData/SapforData/Arrays/ProjectArray.java
Normal file
@@ -0,0 +1,400 @@
|
||||
package ProjectData.SapforData.Arrays;
|
||||
import Common.Current;
|
||||
import Common.Database.DBObject;
|
||||
import Common.Utils.Index;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.DBArray.DBArray;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.SapforData.Arrays.Distribution.Dimension;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateDimension;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateDimensionState;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateLink;
|
||||
import ProjectData.SapforData.Regions.ParallelRegion;
|
||||
import ProjectData.SapforData.Regions.UI.ArrayAlignmentBar;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
public class ProjectArray extends DBObject {
|
||||
//----------------------------------------------------------------------
|
||||
public static final String[] alignNames = {"i", "j", "k", "l", "m", "n", "q", "r", "s", "t", "u", "w", "x", "y", "z"};
|
||||
//-
|
||||
public static String filterName = "";
|
||||
public static String filterLocation = "";
|
||||
public static String filterLocationName = "";
|
||||
public static String filterFile = "";
|
||||
public static String filterRegion = "*";
|
||||
public String UniqKey;
|
||||
public ArrayState State;
|
||||
//-----------------------------
|
||||
public long id;
|
||||
public String name;
|
||||
public String shortName;
|
||||
public int dimSize;
|
||||
public int typeSize;
|
||||
public ArrayLocation location;
|
||||
public String locName;
|
||||
//только для шаблонов. для ФИЛЬТРА управления распределением измерений.
|
||||
public Vector<TemplateDimension> dimensions = new Vector<>();
|
||||
public int isTemplFlag;
|
||||
public int isLoopArrayFlag;
|
||||
//----------------------------
|
||||
public BigInteger address;
|
||||
//----------------------------
|
||||
public ParallelRegion parent_region = null; //родительяская область распараллеливания.
|
||||
//связи->
|
||||
public LinkedHashMap<Long, ProjectArray> links = new LinkedHashMap<>();
|
||||
//------>
|
||||
public ProjectArray align_template = null; //ссылка на шаблон на который идет выравнивание.
|
||||
public String spaces_shift = ""; //смещение из пробелов
|
||||
//ИЗМЕНЕНИЕ РАСПРЕДЕЛЕНИЯ
|
||||
//------------------------------------------------------------------------------------------------------>
|
||||
//текущие
|
||||
public LinkedHashMap<Integer, Dimension> ac_current = new LinkedHashMap<>();
|
||||
//кандидаты на замену.
|
||||
public LinkedHashMap<Integer, Dimension> ac_new = new LinkedHashMap<>();
|
||||
//https://stackoverflow.com/questions/4941372/how-to-insert-image-into-jtable-cell
|
||||
public ArrayAlignmentBar bar = null;
|
||||
//------------------------------------------------------------------------------------------------------>
|
||||
//<editor-fold desc="Функционал шаблона">
|
||||
public Vector<BigInteger> regIDs = new Vector<>();
|
||||
Vector<Pair<Integer, Integer>> sizes = new Vector<>();
|
||||
Vector<Integer> deprecateToDist = new Vector<>();
|
||||
Vector<Integer> mappedDims = new Vector<>();
|
||||
LinkedHashMap<BigInteger, TemplateLink> templateInfo = new LinkedHashMap<>();
|
||||
Vector<ArrayDecl> declPlaces = new Vector<>();
|
||||
Vector<String> regions = new Vector<>();
|
||||
public ProjectArray(String[] infoF, Index idx, BigInteger address_in) {
|
||||
id = Integer.parseInt(infoF[idx.Inc()]);
|
||||
name = infoF[idx.Inc()];
|
||||
shortName = infoF[idx.Inc()];
|
||||
dimSize = Integer.parseInt(infoF[idx.Inc()]);
|
||||
typeSize = Integer.parseInt(infoF[idx.Inc()]);
|
||||
address = address_in;
|
||||
State = ArrayState.fromInt(Integer.parseInt(infoF[idx.Inc()]));
|
||||
location = ArrayLocation.fromInt(Integer.parseInt(infoF[idx.Inc()]));
|
||||
locName = infoF[idx.Inc()];
|
||||
int sizes_size = Integer.parseInt(infoF[idx.Inc()]);
|
||||
for (int i = 0; i < sizes_size; ++i) {
|
||||
int first = Integer.parseInt(infoF[idx.Inc()]);
|
||||
int second = Integer.parseInt(infoF[idx.Inc()]);
|
||||
sizes.add(new Pair<>(first, second));
|
||||
}
|
||||
sizes_size = Integer.parseInt(infoF[idx.Inc()]);
|
||||
for (int i = 0; i < sizes_size; ++i)
|
||||
deprecateToDist.add(Integer.parseInt(infoF[idx.Inc()]));
|
||||
sizes_size = Integer.parseInt(infoF[idx.Inc()]);
|
||||
for (int i = 0; i < sizes_size; ++i)
|
||||
mappedDims.add(Integer.parseInt(infoF[idx.Inc()]));
|
||||
int templateInfo_size = Integer.parseInt(infoF[idx.Inc()]);
|
||||
for (int i = 0; i < templateInfo_size; ++i) {
|
||||
BigInteger key = new BigInteger(infoF[idx.Inc()]);
|
||||
TemplateLink templateLink = new TemplateLink(infoF, idx);
|
||||
templateInfo.put(key, templateLink);
|
||||
}
|
||||
String[] localSplited = infoF[idx.Inc()].split("\\|");
|
||||
isTemplFlag = Integer.parseInt(localSplited[0]);
|
||||
isLoopArrayFlag = Integer.parseInt(localSplited[1]);
|
||||
int numDeclPlaces = Integer.parseInt(localSplited[2]);
|
||||
int idxPl = 3;
|
||||
for (int i = 0; i < numDeclPlaces; ++i, idxPl += 2) {
|
||||
String declFile = Utils.toW(localSplited[idxPl]);
|
||||
DBProjectFile file = Current.getProject().db.files.Data.get(declFile);
|
||||
int declLine = Integer.parseInt(localSplited[idxPl + 1]);
|
||||
//declPlaces.add(new Pair<>(declFile, declLine));
|
||||
ArrayDecl decl = new ArrayDecl(shortName, location, file, declLine);
|
||||
declPlaces.add(decl);
|
||||
file.array_decls.add(decl); //--
|
||||
}
|
||||
int numRegs = Integer.parseInt(localSplited[idxPl++]);
|
||||
for (int i = 0; i < numRegs; ++i)
|
||||
regions.add(localSplited[idxPl++]);
|
||||
UniqKey = shortName + locName + dimSize;
|
||||
//короткое имя+ функция/модуль/комон+ размерность
|
||||
}
|
||||
public static String fill_binary(int d, String binary) {
|
||||
int delta = Math.abs(binary.length() - d);
|
||||
String res = binary;
|
||||
for (int i = 0; i < delta; ++i) {
|
||||
res = ("0" + res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//длина должна быть равной, ищем есть ли совпадающие позиции с единицами
|
||||
public static boolean mask(String banned, String variant) {
|
||||
for (int i = 0; i < variant.length(); ++i)
|
||||
if ((variant.toCharArray()[i] == '1') && (banned.toCharArray()[i] == '1')) //попался, масконосец!
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
public String printLinks() {
|
||||
Vector<String> res = links.keySet().stream().map(Object::toString).collect(Collectors.toCollection(Vector::new));
|
||||
return String.join(" ", res);
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return id;
|
||||
}
|
||||
public boolean has_decl_place(String bg_file) {
|
||||
for (ArrayDecl decl : declPlaces)
|
||||
if (decl.file.startsWith(bg_file)) return true;
|
||||
return false;
|
||||
}
|
||||
public boolean has_region(String bg_region) {
|
||||
if (bg_region.equals("*"))
|
||||
return true;
|
||||
for (String region : regions)
|
||||
if (region.startsWith(bg_region)) return true;
|
||||
return false;
|
||||
}
|
||||
public String TypeString() {
|
||||
return (isLoopArrayFlag == 0) ? ((isTemplFlag == 0) ? "МАССИВ" : "ШАБЛОН") : "ЦИКЛ";
|
||||
}
|
||||
public String state_symbol() {
|
||||
return State == ArrayState.Selected ? "☑" : "☐";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return id + " " + state_symbol() + " " +
|
||||
State + " " +
|
||||
shortName + " " +
|
||||
locName + " : " + location + " " + dimSize + " " + typeSize;
|
||||
}
|
||||
public String GetShortNameWithDim() {
|
||||
String res = shortName + "( ";
|
||||
if (sizes != null && sizes.size() != dimSize) {
|
||||
for (int i = 0; i < dimSize; ++i) {
|
||||
res += alignNames[i];
|
||||
if (i < dimSize - 1)
|
||||
res += ", ";
|
||||
else res += ")";
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < dimSize; ++i) {
|
||||
if (sizes.get(i).getKey() != sizes.get(i).getValue() && sizes.get(i).getKey() != -1)
|
||||
res += sizes.get(i).getKey() + ":" + sizes.get(i).getValue();
|
||||
else
|
||||
res += alignNames[i];
|
||||
if (i < dimSize - 1)
|
||||
res += ", ";
|
||||
else res += ")";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//-
|
||||
//для таблицы вариантов, измерения (i,j,k,..)
|
||||
public String GetShortNameWithDimLetters() {
|
||||
String res = shortName + "(";
|
||||
for (int i = 0; i < dimSize; ++i) {
|
||||
res += alignNames[i];
|
||||
if (i < dimSize - 1)
|
||||
res += ",";
|
||||
else res += ")";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//-
|
||||
public Vector<String> GetDeclPlacesList() {
|
||||
Vector<String> links = new Vector<>();
|
||||
for (ArrayDecl d : declPlaces)
|
||||
links.add(d.file + ":" + d.line);
|
||||
return links;
|
||||
}
|
||||
public String GetRegionsText() {
|
||||
String res = "";
|
||||
for (int i = 0; i < regions.size(); ++i)
|
||||
res += regions.get(i) + ((i != regions.size() - 1) ? "," : "");
|
||||
return res;
|
||||
}
|
||||
public boolean DimDisabled(int dim) {
|
||||
// не участвует в шаблонах. или явно запрещено
|
||||
return (mappedDims.get(dim) == 0) || (deprecateToDist.get(dim) == 1);
|
||||
}
|
||||
public void CreateDimensions() {
|
||||
for (BigInteger regID : regIDs) {
|
||||
ParallelRegion region = Current.getProject().parallelRegions.get(regID);
|
||||
for (int i = 0; i < Current.getProject().maxdim; ++i) {
|
||||
dimensions.add(new TemplateDimension(
|
||||
i, this, region
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
public Object[] CreateTemplateCells() {
|
||||
Vector<Object> res = new Vector<>();
|
||||
res.add(this.shortName);
|
||||
for (int i = 0; i < dimensions.size(); ++i) {
|
||||
res.add(dimensions.get(i));
|
||||
}
|
||||
return res.toArray();
|
||||
}
|
||||
//получить двоичное представление варианта распределения и дополнить его нулями.
|
||||
public String get_binary(long varID) {
|
||||
String binary = Long.toBinaryString(varID);
|
||||
return fill_binary(dimSize, binary);
|
||||
}
|
||||
public Vector<Long> get_varIDs(boolean filter) {
|
||||
long d = (long) Math.pow(2, dimSize);
|
||||
Vector<Long> varIDs = new Vector<>();
|
||||
Vector<String> DimsDep = new Vector<>();
|
||||
for (int z = 0; z < mappedDims.size(); ++z)
|
||||
DimsDep.add(
|
||||
String.valueOf((DimDisabled(z) ? 1 : 0)));
|
||||
String banned_dimensions = String.join("", DimsDep);
|
||||
//------ Дляполностью размноженного нужен d-1 ?
|
||||
for (long i = 0; i < d; ++i) {
|
||||
String binary = get_binary(i);
|
||||
if (!mask(banned_dimensions, binary)) {
|
||||
if (filter) {
|
||||
boolean valid = true;
|
||||
if (Current.getProject().f_distributed())
|
||||
valid = CheckFilterMask(i, true, binary);
|
||||
if (valid && Current.getProject().f_multiplied())
|
||||
valid = CheckFilterMask(i, false, binary);
|
||||
if (valid)
|
||||
varIDs.add(i);
|
||||
} else varIDs.add(i);
|
||||
}
|
||||
}
|
||||
return varIDs;
|
||||
}
|
||||
//проверка одиночного вар ида. нужна для минимального покрытия.
|
||||
public boolean checkVarID(long i, boolean filter) {
|
||||
Vector<String> DimsDep = new Vector<>();
|
||||
for (int z = 0; z < mappedDims.size(); ++z)
|
||||
DimsDep.add(String.valueOf((DimDisabled(z) ? 1 : 0)));
|
||||
String banned_dimensions = String.join("", DimsDep);
|
||||
String binary = get_binary(i);
|
||||
if (!mask(banned_dimensions, binary)) {
|
||||
if (filter) {
|
||||
boolean valid = true;
|
||||
if (Current.getProject().f_distributed())
|
||||
valid = CheckFilterMask(i, true, binary);
|
||||
if (valid && Current.getProject().f_multiplied())
|
||||
valid = CheckFilterMask(i, false, binary);
|
||||
return valid;
|
||||
} else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public Vector<Long> get_varIDs() {
|
||||
return get_varIDs(true);
|
||||
}
|
||||
//для первичного заполнения рекурсии
|
||||
public Vector<Vector<BigInteger>> get_triples(boolean filter) {
|
||||
Vector<Vector<BigInteger>> res = new Vector<>();
|
||||
Vector<Long> varIDs = get_varIDs(filter);
|
||||
for (long varID : varIDs) {
|
||||
for (BigInteger regID : regIDs) //для всех областей
|
||||
{
|
||||
Vector<BigInteger> tripple = new Vector<>();
|
||||
tripple.add(address);
|
||||
tripple.add(BigInteger.valueOf(varID));
|
||||
tripple.add(regID);
|
||||
res.add(tripple);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public String GetShortNameForVariant(long varID) {
|
||||
String binary = get_binary(varID);
|
||||
String res = shortName + "(";
|
||||
for (int i = 0; i < dimSize; ++i) {
|
||||
if (i < binary.length()) {
|
||||
switch (binary.toCharArray()[i]) {
|
||||
case '0':
|
||||
res += TemplateDimensionState.multiplied.getDescription();
|
||||
break;
|
||||
case '1':
|
||||
res += TemplateDimensionState.distributed.getDescription();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
res += Utils.ending(i == binary.length() - 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//</editor-fold>
|
||||
public String getFilterMask() {
|
||||
String res = "";
|
||||
for (int i = 0; i < dimensions.size(); ++i) {
|
||||
res += (dimensions.get(i).state.ordinal());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public boolean CheckFilterMask(long varID, boolean distributed, String binary_in) {
|
||||
char s = distributed ? '1' : '0';
|
||||
String filterMask = getFilterMask();
|
||||
String variant = binary_in.isEmpty() ? get_binary(varID) : binary_in;
|
||||
// System.out.println(shortName+"|mask="+filterMask+"|varId="+variant+"|"+s);
|
||||
for (int i = 0; i < variant.length(); ++i) {
|
||||
if ((filterMask.toCharArray()[i] == s) && (variant.toCharArray()[i] != s)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean CheckFilterMask(long varID, boolean distributed) {
|
||||
return CheckFilterMask(varID, distributed, "");
|
||||
}
|
||||
public void SaveUserState() throws Exception {
|
||||
if (Current.getProject().db.savedArrays.Data.containsKey(UniqKey)) {
|
||||
DBArray sa = Current.getProject().db.savedArrays.Data.get(UniqKey);
|
||||
sa.State = State;
|
||||
Current.getProject().db.Update(sa);
|
||||
} else
|
||||
Current.getProject().db.Insert(new DBArray(this));
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
@Override
|
||||
public boolean isSelectionEnabled() {
|
||||
return (State == ArrayState.Selected) || (State == ArrayState.None);
|
||||
}
|
||||
@Override
|
||||
public ImageIcon GetDisabledIcon() {
|
||||
return Utils.getIcon("/icons/Arrays/" + State.toString() + ".png");
|
||||
}
|
||||
@Override
|
||||
public void select(boolean flag) {
|
||||
Pass_2021.passes.get(PassCode_2021.MassSelectArrays).Do(flag, this);
|
||||
}
|
||||
@Override
|
||||
public boolean isSelected() {
|
||||
return (State == ArrayState.Selected);
|
||||
}
|
||||
//-
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
if (isTemplFlag > 0) return true;
|
||||
return shortName.startsWith(filterName) &&
|
||||
location.toString().startsWith(filterLocation) &&
|
||||
locName.startsWith(filterLocationName) &&
|
||||
has_decl_place(filterFile) &&
|
||||
has_region(filterRegion);
|
||||
}
|
||||
public void init_new_ac() {
|
||||
ac_new.clear();
|
||||
for (int dim : ac_current.keySet())
|
||||
ac_new.put(dim, ac_current.get(dim).clone_());
|
||||
}
|
||||
public boolean ac_need_change() {
|
||||
for (int dim : ac_current.keySet()) {
|
||||
Dimension old_ = ac_current.get(dim);
|
||||
Dimension new_ = ac_new.get(dim);
|
||||
if ((old_.K != new_.K) || (old_.B != new_.B))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean canBeDistributed() {
|
||||
return (isLoopArrayFlag == 0) && (isTemplFlag == 0);
|
||||
}
|
||||
//----
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package ProjectData.SapforData.Arrays.Templates;
|
||||
import Common.Database.DBObject;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
import ProjectData.SapforData.Regions.ParallelRegion;
|
||||
//для генерации вариантов и для управления распределением измерений.
|
||||
public class TemplateDimension extends DBObject {
|
||||
public int num = -1;
|
||||
public ProjectArray template = null;
|
||||
public ParallelRegion region = null;
|
||||
public TemplateDimensionState state;
|
||||
public TemplateDimension(int num_in, ProjectArray template_in, ParallelRegion region_in) {
|
||||
num = num_in;
|
||||
template = template_in;
|
||||
region = region_in;
|
||||
state = isBlocked() ? TemplateDimensionState.multiplied : TemplateDimensionState.distributed;
|
||||
}
|
||||
public boolean isBlocked() {
|
||||
return (num >= template.dimSize) || template.DimDisabled(num);
|
||||
}
|
||||
public void SwitchState() {
|
||||
switch (state) {
|
||||
case distributed:
|
||||
state = TemplateDimensionState.multiplied;
|
||||
break;
|
||||
case multiplied:
|
||||
state = TemplateDimensionState.distributed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return num;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package ProjectData.SapforData.Arrays.Templates;
|
||||
import Common.Current;
|
||||
public enum TemplateDimensionState {
|
||||
multiplied, //0
|
||||
distributed; //1
|
||||
public String getMaskDescription() {
|
||||
switch (this) {
|
||||
case distributed:
|
||||
if (Current.getProject().f_distributed()) {
|
||||
return "BLOCK";
|
||||
} else {
|
||||
if (Current.getProject().f_multiplied())
|
||||
return " X ";
|
||||
else return "BLOCK";
|
||||
}
|
||||
case multiplied:
|
||||
if (Current.getProject().f_multiplied()) {
|
||||
return " * ";
|
||||
} else {
|
||||
if (Current.getProject().f_distributed())
|
||||
return " X ";
|
||||
else return " * ";
|
||||
}
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case distributed:
|
||||
return "BLOCK";
|
||||
case multiplied:
|
||||
return " * ";
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ProjectData.SapforData.Arrays.Templates;
|
||||
import Common.Utils.Index;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.util.Vector;
|
||||
public class TemplateLink {
|
||||
Vector<Integer> linkWithTemplate = new Vector<>();
|
||||
Vector<Pair<Integer, Integer>> alignRuleWithTemplate = new Vector<>();
|
||||
long templateArray;
|
||||
public TemplateLink(String[] splited, Index idx) {
|
||||
int linkWithTemplate_size = Integer.parseInt(splited[idx.Inc()]);
|
||||
for (int i = 0; i < linkWithTemplate_size; ++i) {
|
||||
int link_ = Integer.parseInt(splited[idx.Inc()]);
|
||||
linkWithTemplate.add(link_);
|
||||
}
|
||||
int alignRuleWithTemplate_size = Integer.parseInt(splited[idx.Inc()]);
|
||||
for (int i = 0; i < alignRuleWithTemplate_size; ++i) {
|
||||
int f = Integer.parseInt(splited[idx.Inc()]);
|
||||
int s = Integer.parseInt(splited[idx.Inc()]);
|
||||
alignRuleWithTemplate.add(new Pair<>(f, s));
|
||||
}
|
||||
templateArray = Long.parseLong(splited[idx.Inc()]);
|
||||
}
|
||||
}
|
||||
20
src/ProjectData/SapforData/Arrays/UI/DimensionRenderer.java
Normal file
20
src/ProjectData/SapforData/Arrays/UI/DimensionRenderer.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Tables.RendererCell;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateDimension;
|
||||
|
||||
import javax.swing.*;
|
||||
public class DimensionRenderer extends RendererCell<TemplateDimension> {
|
||||
@Override
|
||||
public TemplateDimension Init(JTable table, Object value_in, int row, int column) {
|
||||
return (TemplateDimension) value_in;
|
||||
}
|
||||
@Override
|
||||
public void Display() {
|
||||
if (value != null) {
|
||||
setText(value.state.getMaskDescription());
|
||||
setFont(value.isBlocked() ? Current.getTheme().Fonts.get(VisualiserFonts.Disabled) : Current.getTheme().Fonts.get(VisualiserFonts.Hyperlink));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Tables.DBObjectEditor;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import Common.UI.UI;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateDimension;
|
||||
|
||||
import javax.swing.*;
|
||||
public class DimensionStateChanger extends DBObjectEditor<TemplateDimension> {
|
||||
@Override
|
||||
public Object getCellEditorValue() {
|
||||
return value;
|
||||
}
|
||||
@Override
|
||||
public void InitValue(JTable table, Object value_in, int row, int column) {
|
||||
value = (TemplateDimension) value_in;
|
||||
}
|
||||
@Override
|
||||
public void Action() {
|
||||
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Hyperlink));
|
||||
value.SwitchState();
|
||||
setText(value.state.getMaskDescription());
|
||||
UI.getVersionsWindow().getVariantsWindow().ShowFilteredVariantsCount();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.ControlForm;
|
||||
import Common.UI.Tables.Grid.GridAnchestor;
|
||||
import Common.UI.Tables.StyledTable;
|
||||
import Common.UI.UI;
|
||||
import ProjectData.SapforData.Arrays.ProjectArray;
|
||||
import ProjectData.SapforData.Arrays.Templates.TemplateDimension;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Vector;
|
||||
|
||||
import static Common.UI.Tables.TableEditors.EditorDimension;
|
||||
import static Common.UI.Tables.TableRenderers.RendererDimension;
|
||||
public class DimensionsTableForm extends ControlForm<StyledTable> {
|
||||
public DimensionsTableForm() {
|
||||
super(StyledTable.class);
|
||||
}
|
||||
@Override
|
||||
public void Show() {
|
||||
super.Show();
|
||||
content.add(scroll, BorderLayout.CENTER);
|
||||
content.updateUI();
|
||||
}
|
||||
@Override
|
||||
public void Clear() {
|
||||
super.Clear();
|
||||
UI.Clear(content);
|
||||
}
|
||||
@Override
|
||||
public void CreateControl() {
|
||||
Vector<String> columns = new Vector<>();
|
||||
columns.add("шаблон");
|
||||
for (int i = 0; i < Current.getProject().maxdim; ++i)
|
||||
columns.add(ProjectArray.alignNames[i]);
|
||||
Vector<Object> dimensions = new Vector<>();
|
||||
Current.getProject().templates.forEach(t -> dimensions.add(t.CreateTemplateCells()));
|
||||
control = new StyledTable(new GridAnchestor(columns, dimensions) {
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return ((Object[]) data.get(rowIndex))[columnIndex];
|
||||
}
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int col) {
|
||||
return (col > 0) && !((TemplateDimension) getValueAt(row, col)).isBlocked();
|
||||
}
|
||||
}) {
|
||||
@Override
|
||||
public void Init() {
|
||||
setDefaultRenderer(TemplateDimension.class, UI.TableRenderers.get(RendererDimension));
|
||||
setDefaultEditor(TemplateDimension.class, UI.TableEditors.get(EditorDimension));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/ProjectData/SapforData/Arrays/UI/DistributionMenu.java
Normal file
20
src/ProjectData/SapforData/Arrays/UI/DistributionMenu.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.UI.Menus.GraphMenu;
|
||||
import Common.UI.Trees.StyledTree;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import javax.swing.*;
|
||||
public class DistributionMenu extends GraphMenu {
|
||||
JMenuItem mChangeDistribution;
|
||||
public DistributionMenu(StyledTree tree) {
|
||||
super(tree, "области распараллеливания");
|
||||
mChangeDistribution = Pass_2021.passes.get(PassCode_2021.SPF_ModifyArrayDistribution).createMenuItem();
|
||||
add(mChangeDistribution);
|
||||
}
|
||||
@Override
|
||||
public void CheckElementsVisibility() {
|
||||
super.CheckElementsVisibility();
|
||||
mChangeDistribution.setVisible(Pass_2021.passes.get(PassCode_2021.SPF_GetArrayDistribution).isDone());
|
||||
}
|
||||
}
|
||||
12
src/ProjectData/SapforData/Arrays/UI/FileArraysTree.java
Normal file
12
src/ProjectData/SapforData/Arrays/UI/FileArraysTree.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import ProjectData.Files.UI.FileGraphTree;
|
||||
public class FileArraysTree extends FileGraphTree {
|
||||
public FileArraysTree() {
|
||||
super(Current.getFile().getArraysTree());
|
||||
}
|
||||
@Override
|
||||
public String getBranchesName() {
|
||||
return "объявления массивов";
|
||||
}
|
||||
}
|
||||
43
src/ProjectData/SapforData/Arrays/UI/RulesTree.java
Normal file
43
src/ProjectData/SapforData/Arrays/UI/RulesTree.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Menus.GraphMenu;
|
||||
import Common.UI.Trees.StyledTree;
|
||||
import Common.UI.Trees.TreeRenderers;
|
||||
import ProjectData.SapforData.Regions.ParallelRegion;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import static Common.UI.Trees.TreeRenderers.RendererRule;
|
||||
public class RulesTree extends StyledTree {
|
||||
public RulesTree() {
|
||||
super(Current.getProject().align_rules_root);
|
||||
setRootVisible(false);
|
||||
expandRow(0);
|
||||
ExpandAll();
|
||||
Current.set(Current.ParallelRegion, null);
|
||||
}
|
||||
@Override
|
||||
protected GraphMenu createMenu() {
|
||||
return new DistributionMenu(this);
|
||||
}
|
||||
@Override
|
||||
public TreeRenderers getRenderer() {
|
||||
return RendererRule;
|
||||
}
|
||||
@Override
|
||||
public void SelectionAction(TreePath e) {
|
||||
ParallelRegion region = null;
|
||||
if (e != null) {
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getLastPathComponent();
|
||||
Object o = node.getUserObject();
|
||||
if (o instanceof String) {
|
||||
region = (ParallelRegion) ((DefaultMutableTreeNode) node.getParent()).getUserObject();
|
||||
}
|
||||
if (o instanceof ParallelRegion) {
|
||||
region = (ParallelRegion) o;
|
||||
}
|
||||
}
|
||||
Current.set(Current.ParallelRegion, region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package ProjectData.SapforData.Arrays.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import Common.UI.Trees.StyledTreeCellRenderer;
|
||||
import ProjectData.SapforData.Regions.ParallelRegion;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
public class RulesTreeCellRenderer extends StyledTreeCellRenderer {
|
||||
public java.awt.Component getTreeCellRendererComponent(
|
||||
JTree tree, Object value,
|
||||
boolean selected, boolean expanded,
|
||||
boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
Object o = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
if (o instanceof String) {
|
||||
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Distribution));
|
||||
} else if (o instanceof ParallelRegion)
|
||||
setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreeItalic));
|
||||
setForeground(tree.getForeground());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
29
src/ProjectData/SapforData/FileObject.java
Normal file
29
src/ProjectData/SapforData/FileObject.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package ProjectData.SapforData;
|
||||
import Common.Current;
|
||||
import Common.Database.iDBObject;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
//объект принадлежащий файлу и относящийся к его строке.
|
||||
public abstract class FileObject extends iDBObject {
|
||||
@Description("DEFAULT ''")
|
||||
public String file = "";
|
||||
@Description("DEFAULT 1")
|
||||
public int line = 1;
|
||||
public FileObject() {
|
||||
}
|
||||
public FileObject(String file_in) {
|
||||
file = file_in;
|
||||
}
|
||||
@Override
|
||||
public String getSelectionText() {
|
||||
return "файл " + Utils.Brackets(file) + " строка: " + line;
|
||||
}
|
||||
public DBProjectFile getFather() {
|
||||
return Current.getProject().db.files.Data.get(file);
|
||||
}
|
||||
public void Show(boolean focus) {
|
||||
UI.getMainWindow().getProjectWindow().GotoFile(file, line, focus);
|
||||
}
|
||||
}
|
||||
58
src/ProjectData/SapforData/FileObjectWithMessages.java
Normal file
58
src/ProjectData/SapforData/FileObjectWithMessages.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package ProjectData.SapforData;
|
||||
import Common.UI.Themes.VisualiserFonts;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.Messages.Errors.MessageError;
|
||||
import ProjectData.Messages.Message;
|
||||
import ProjectData.Messages.Notes.MessageNote;
|
||||
import ProjectData.Messages.Warnings.MessageWarning;
|
||||
public abstract class FileObjectWithMessages extends FileObject {
|
||||
public String messages_presence = "OK";
|
||||
public FileObjectWithMessages() {
|
||||
}
|
||||
//использовать только если хотим проверять сообщения.
|
||||
public FileObjectWithMessages(DBProjectFile father_in, int line_in) {
|
||||
file = father_in.name;
|
||||
line = line_in;
|
||||
CheckMessagesPresence();
|
||||
}
|
||||
public boolean HasMessage(Message message) {
|
||||
return message.line == line;
|
||||
}
|
||||
public void CheckMessagesPresence() {
|
||||
messages_presence = "OK";
|
||||
DBProjectFile father = getFather();
|
||||
for (MessageError message : father.father.db.errors.Data.values()) {
|
||||
if (message.file.equals(father.name) && message.line == line) {
|
||||
messages_presence = "HasErrors";
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (MessageWarning message : father.father.db.warnings.Data.values()) {
|
||||
if (message.file.equals(father.name) && message.line == line) {
|
||||
messages_presence = "HasWarnings";
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (MessageNote message : father.father.db.notes.Data.values()) {
|
||||
if (message.file.equals(father.name) && message.line == line) {
|
||||
messages_presence = "HasNotes";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
public String TypeKey() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
public String ImageKey() {
|
||||
return "/icons/loops/" + messages_presence + TypeKey() + ".png";
|
||||
}
|
||||
public VisualiserFonts getFont() {
|
||||
return VisualiserFonts.TreePlain;
|
||||
}
|
||||
//-
|
||||
public abstract String Description();
|
||||
@Override
|
||||
public String toString() {
|
||||
return Description() + " в строке " + line;
|
||||
}
|
||||
}
|
||||
37
src/ProjectData/SapforData/Functions/FuncCall.java
Normal file
37
src/ProjectData/SapforData/Functions/FuncCall.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
public class FuncCall extends FileObjectWithMessages {
|
||||
public String funcName = ""; //не нужны дополнительные поля.имя функции это уже ключ.
|
||||
public boolean canBeInlined = false;
|
||||
public FuncCall(DBProjectFile father_in, String funcName_in, int line_in) {
|
||||
super(father_in, line_in);
|
||||
funcName = funcName_in;
|
||||
}
|
||||
public FuncCall() {
|
||||
}
|
||||
@Override
|
||||
public String getSelectionText() {
|
||||
return "вызов в строке " + line;
|
||||
}
|
||||
@Override
|
||||
public boolean isSelectionEnabled() {
|
||||
return canBeInlined;
|
||||
}
|
||||
@Override
|
||||
public String Description() {
|
||||
return "вызов " + Utils.Brackets(funcName);
|
||||
}
|
||||
@Override
|
||||
public void Select(boolean flag) {
|
||||
if (Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctions).isDone()) {
|
||||
super.Select(flag);
|
||||
} else {
|
||||
UI.Info("Для подстановки функций требуется выполнить проход " + Utils.DQuotes(PassCode_2021.SPF_GetGraphFunctions.getDescription()));
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/ProjectData/SapforData/Functions/FuncCallH.java
Normal file
45
src/ProjectData/SapforData/Functions/FuncCallH.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import java.util.Vector;
|
||||
public class FuncCallH extends FuncCall {
|
||||
//--
|
||||
public Vector<FuncCallH> calls = new Vector<>();
|
||||
//--
|
||||
//сообщения не проверяем.
|
||||
public FuncCallH(FuncCall funcCall_in) {
|
||||
file = funcCall_in.file;
|
||||
line = funcCall_in.line;
|
||||
funcName = funcCall_in.funcName;
|
||||
canBeInlined = funcCall_in.canBeInlined;
|
||||
}
|
||||
//особый случай. только для мейна
|
||||
//его объявление - его же и вызов.
|
||||
//сообщения не проверяем.
|
||||
public FuncCallH(FuncInfo funcInfo) {
|
||||
file = funcInfo.file;
|
||||
line = funcInfo.line;
|
||||
funcName = funcInfo.funcName;
|
||||
canBeInlined = true;
|
||||
}
|
||||
@Override
|
||||
public String getSelectionText() {
|
||||
return "вызов " + Utils.Brackets(funcName) + " в строке " + line;
|
||||
}
|
||||
@Override
|
||||
public void SelectAllChildren(boolean select) {
|
||||
for (FuncCallH callH : calls)
|
||||
callH.Select(select);
|
||||
}
|
||||
@Override
|
||||
public void Select(boolean flag) {
|
||||
if (Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctions).isDone()) {
|
||||
super.Select(flag);
|
||||
} else {
|
||||
UI.Info("Для подстановки функций требуется выполнить проход " + Utils.DQuotes(PassCode_2021.SPF_GetGraphFunctions.getDescription()));
|
||||
}
|
||||
}
|
||||
}
|
||||
4
src/ProjectData/SapforData/Functions/FuncCallState.java
Normal file
4
src/ProjectData/SapforData/Functions/FuncCallState.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
public enum FuncCallState {
|
||||
Normal, Standard, NotFound
|
||||
}
|
||||
15
src/ProjectData/SapforData/Functions/FuncCoordinates.java
Normal file
15
src/ProjectData/SapforData/Functions/FuncCoordinates.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import Common.Database.DBObject;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
public class FuncCoordinates extends DBObject {
|
||||
@Description("PRIMARY KEY, UNIQUE")
|
||||
public String name = "";
|
||||
@Description("DEFAULT 0.0")
|
||||
public Double X = 0.0;
|
||||
@Description("DEFAULT 0.0")
|
||||
public Double Y = 0.0;
|
||||
@Override
|
||||
public Object getPK() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import Common.Database.DBTable;
|
||||
public class FuncCoordinatesDBTable extends DBTable<String, FuncCoordinates> {
|
||||
public FuncCoordinatesDBTable() {
|
||||
super(String.class, FuncCoordinates.class);
|
||||
}
|
||||
}
|
||||
82
src/ProjectData/SapforData/Functions/FuncInfo.java
Normal file
82
src/ProjectData/SapforData/Functions/FuncInfo.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import Common.Utils.Index;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.Files.DBProjectFile;
|
||||
import ProjectData.SapforData.FileObjectWithMessages;
|
||||
import com.mxgraph.model.mxCell;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
public class FuncInfo extends FileObjectWithMessages {
|
||||
//----------------------------------------------------------
|
||||
public int lineEnd;
|
||||
public String funcName;
|
||||
public FunctionType type;
|
||||
public boolean doNotInline;
|
||||
public boolean doNotAnalyze;
|
||||
public boolean needToInline;
|
||||
public FuncParam parameters;
|
||||
//вызовы функций в теле этой функции
|
||||
public Vector<FuncCall> calls = new Vector<>();
|
||||
//вызовы этой самой функции, рассортированные по файлам.
|
||||
public LinkedHashMap<String, Vector<FuncCall>> own_calls = new LinkedHashMap<>();
|
||||
//Узел фуннкции при отрисовке графа процедур.
|
||||
//Нужен для сохранения всех позиций графа.
|
||||
public mxCell functionsGraphCell = null;
|
||||
//это конструктор при пофайловой распаковке. в него попадают только объявленные в проекте функции.
|
||||
public FuncInfo(String f_name, DBProjectFile father_in, String[] splited, Index calls_number) {
|
||||
super(father_in, Integer.parseInt(splited[0]));
|
||||
funcName = f_name;
|
||||
lineEnd = Integer.parseInt(splited[1]);
|
||||
calls_number.Set(Integer.parseInt(splited[2]));
|
||||
needToInline = (Integer.parseInt(splited[3])) != 0;
|
||||
doNotInline = (Integer.parseInt(splited[4])) != 0;
|
||||
doNotAnalyze = (Integer.parseInt(splited[5])) != 0;
|
||||
//в си это поле isMain
|
||||
type = ((Integer.parseInt(splited[6])) != 0) ? FunctionType.Main : FunctionType.Default;
|
||||
parameters = new FuncParam();
|
||||
if (splited.length > 6) {
|
||||
int countP = Integer.parseInt(splited[7]);
|
||||
parameters.Init(countP);
|
||||
for (int z = 0; z < countP * 3; z += 3)
|
||||
parameters.FillParam(z / 3, splited[8 + z + 2], splited[8 + z], Integer.parseInt(splited[8 + z + 1]));
|
||||
}
|
||||
}
|
||||
//функция без объявления. у нее есть только имя и тип.
|
||||
public FuncInfo(String f_name, FunctionType type_in) {
|
||||
funcName = f_name;
|
||||
type = type_in;
|
||||
doNotInline = true;
|
||||
}
|
||||
//--
|
||||
@Override
|
||||
public String getSelectionText() {
|
||||
return type.getDescription() + " " + Utils.Brackets(funcName);
|
||||
}
|
||||
public boolean isMain() {
|
||||
return type.equals(FunctionType.Main);
|
||||
}
|
||||
//------------------------------------------------
|
||||
@Override
|
||||
public boolean isSelectionEnabled() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public ImageIcon GetDisabledIcon() {
|
||||
return Utils.getIcon("/icons/Function.png");
|
||||
}
|
||||
@Override
|
||||
public void SelectAllChildren(boolean select) {
|
||||
for (String file_name : own_calls.keySet())
|
||||
for (FuncCall fc : own_calls.get(file_name))
|
||||
fc.Select(select);
|
||||
}
|
||||
public boolean isDeclared() {
|
||||
return type.equals(FunctionType.Main) || type.equals(FunctionType.Default);
|
||||
}
|
||||
@Override
|
||||
public String Description() {
|
||||
return type.getDescription() + " " + Utils.Brackets(funcName);
|
||||
}
|
||||
}
|
||||
60
src/ProjectData/SapforData/Functions/FuncParam.java
Normal file
60
src/ProjectData/SapforData/Functions/FuncParam.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
import java.util.Vector;
|
||||
public class FuncParam {
|
||||
static final int IN_BIT = 16;
|
||||
static final int OUT_BIT = 256;
|
||||
Vector<Integer> inout_types;
|
||||
Vector<String> identificators;
|
||||
Vector<String> parametersT;
|
||||
int countOfPars;
|
||||
public FuncParam() {
|
||||
countOfPars = 0;
|
||||
}
|
||||
public void Init(int numPar) {
|
||||
countOfPars = numPar;
|
||||
if (numPar != 0) {
|
||||
parametersT = new Vector<>(numPar);
|
||||
inout_types = new Vector<>(numPar);
|
||||
identificators = new Vector<>(numPar);
|
||||
for (int z = 0; z < numPar; ++z) {
|
||||
parametersT.add("NONE_T");
|
||||
inout_types.add(0);
|
||||
identificators.add("");
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean IsArgIn(int num) {
|
||||
if (num >= countOfPars)
|
||||
return false;
|
||||
else
|
||||
return (inout_types.get(num) & IN_BIT) != 0;
|
||||
}
|
||||
boolean IsArgOut(int num) {
|
||||
if (num >= countOfPars)
|
||||
return false;
|
||||
else
|
||||
return (inout_types.get(num) & OUT_BIT) != 0;
|
||||
}
|
||||
boolean IsArgInOut(int num) {
|
||||
if (num >= countOfPars)
|
||||
return false;
|
||||
else
|
||||
return IsArgIn(num) && IsArgOut(num);
|
||||
}
|
||||
public void FillParam(int num, String type, String ident, int inout) {
|
||||
parametersT.set(num, type);
|
||||
inout_types.set(num, inout);
|
||||
identificators.set(num, ident);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
Vector<String> res = new Vector<>();
|
||||
for (int i = 0; i < countOfPars; ++i) {
|
||||
String ps = IsArgInOut(i) ? "inout" :
|
||||
(IsArgOut(i) ? "out" : (IsArgIn(i) ? "in" : "?!"));
|
||||
ps += " " + inout_types.get(i) + " " + identificators.get(i) + " " + parametersT.get(i);
|
||||
res.add(ps);
|
||||
}
|
||||
return String.join(",", res);
|
||||
}
|
||||
}
|
||||
23
src/ProjectData/SapforData/Functions/FunctionType.java
Normal file
23
src/ProjectData/SapforData/Functions/FunctionType.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package ProjectData.SapforData.Functions;
|
||||
public enum FunctionType {
|
||||
Default, //обычное объявление
|
||||
Main, //ГПЕ
|
||||
//для графа функций
|
||||
Standard, //стандартная функция
|
||||
NotFound; //функция не найдена в проекте
|
||||
//-
|
||||
public String getDescription() {
|
||||
switch (this) {
|
||||
case Default:
|
||||
return "объявление";
|
||||
case Main:
|
||||
return "главная программная единица";
|
||||
case NotFound:
|
||||
return "не найдена";
|
||||
case Standard:
|
||||
return "стандартная";
|
||||
default:
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ProjectData.SapforData.Functions.UI;
|
||||
import Common.Current;
|
||||
import ProjectData.Files.UI.FileGraphTree;
|
||||
public class FileFunctionsTree extends FileGraphTree {
|
||||
public FileFunctionsTree() {
|
||||
super(Current.getFile().getFunctionsTree());
|
||||
}
|
||||
@Override
|
||||
public String getBranchesName() {
|
||||
return "объявления процедур";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package ProjectData.SapforData.Functions.UI.Graph;
|
||||
import Common.Current;
|
||||
import Common.UI.ControlForm;
|
||||
import Common.UI.UI;
|
||||
import com.mxgraph.swing.mxGraphComponent;
|
||||
|
||||
import java.awt.*;
|
||||
public class FunctionsGraphForm extends ControlForm<mxGraphComponent> {
|
||||
public FunctionsGraphForm() {
|
||||
super(mxGraphComponent.class);
|
||||
}
|
||||
@Override
|
||||
public void CreateControl() {
|
||||
control = Current.getProject().DrawFunctionsGraph();
|
||||
}
|
||||
@Override
|
||||
public void Show() {
|
||||
super.Show();
|
||||
content.add(scroll, BorderLayout.CENTER);
|
||||
content.updateUI();
|
||||
}
|
||||
@Override
|
||||
public void Clear() {
|
||||
super.Clear();
|
||||
UI.Clear(content);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package ProjectData.SapforData.Functions.UI.Graph;
|
||||
import Common.Current;
|
||||
import Common.UI.Menus.VisualiserMenuItem;
|
||||
import Common.UI.Menus.StyledPopupMenu;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import Visual_DVM_2021.Passes.All.SPF_GetGraphFunctionPositions;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
public class FunctionsGraphMenu extends StyledPopupMenu {
|
||||
JMenuItem changeCurrent;
|
||||
public FunctionsGraphMenu() {
|
||||
changeCurrent = new VisualiserMenuItem("Назначить выбранный узел текущей функцией");
|
||||
changeCurrent.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (Current.HasSelectedFunction()) {
|
||||
Current.set(Current.Function, Current.getSelectionFunction());
|
||||
UI.getMainWindow().getProjectWindow().getFunctionsWindow().ShowCurrentFunction();
|
||||
if (SPF_GetGraphFunctionPositions.showByCurrentFunction) {
|
||||
Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctionPositions).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
add(changeCurrent);
|
||||
}
|
||||
@Override
|
||||
public void CheckElementsVisibility() {
|
||||
if (Current.HasSelectedFunction()) {
|
||||
changeCurrent.setText("Назначить процедуру " + Utils.DQuotes(Current.getSelectionFunction().funcName) + " текущей.");
|
||||
changeCurrent.setEnabled(true);
|
||||
} else {
|
||||
changeCurrent.setText("Невозможно назначить текущую процедуру: узел графа не выбран");
|
||||
changeCurrent.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
package ProjectData.SapforData.Functions.UI.Graph;
|
||||
import Common.Current;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import ProjectData.SapforData.Functions.FuncCoordinates;
|
||||
import ProjectData.SapforData.Functions.FuncInfo;
|
||||
import ProjectData.SapforData.Functions.FunctionType;
|
||||
import Visual_DVM_2021.Passes.All.SPF_GetGraphFunctionPositions;
|
||||
import Visual_DVM_2021.Passes.PassCode_2021;
|
||||
import Visual_DVM_2021.Passes.Pass_2021;
|
||||
import com.mxgraph.model.mxCell;
|
||||
import com.mxgraph.model.mxGeometry;
|
||||
import com.mxgraph.swing.mxGraphComponent;
|
||||
import com.mxgraph.util.mxConstants;
|
||||
import com.mxgraph.util.mxEvent;
|
||||
import com.mxgraph.util.mxEventObject;
|
||||
import com.mxgraph.util.mxRectangle;
|
||||
import com.mxgraph.view.mxGraph;
|
||||
import com.mxgraph.view.mxStylesheet;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static com.mxgraph.util.mxConstants.SHAPE_DOUBLE_ELLIPSE;
|
||||
import static com.mxgraph.util.mxConstants.SHAPE_ELLIPSE;
|
||||
public class FunctionsGraphUI extends mxGraph {
|
||||
//--
|
||||
public final static Timer ffTimer = new Timer(1000, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println("Time to Redraw Functions Graph");
|
||||
Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctionPositions).Do();
|
||||
System.out.println("DONE");
|
||||
}
|
||||
});
|
||||
//---
|
||||
private static final int default_width = 80;
|
||||
private static final int default_height = 30;
|
||||
//форма узлов?
|
||||
// https://progi.pro/kak-sdelat-parallelogrammnuyu-vershinu-v-jgraphx-13032580
|
||||
//мануал
|
||||
//https://jgraph.github.io/mxgraph/docs/manual_javavis.html
|
||||
//https://jgraph.github.io/mxgraph/java/docs/com/mxgraph/swing/mxGraphComponent.html
|
||||
//общий манул
|
||||
//https://jgraph.github.io/mxgraph/docs/manual_javavis.html#1.3
|
||||
//манул п кликам?
|
||||
//https://github.com/jgraph/mxgraph/blob/master/java/examples/com/mxgraph/examples/swing/ClickHandler.java
|
||||
//все образцы
|
||||
//https://github.com/jgraph/mxgraph/tree/master/java/examples/com/mxgraph/examples/swing
|
||||
//https://github.com/jgraph/jgraphx/blob/master/src/com/mxgraph/util/mxConstants.java
|
||||
//про размеры
|
||||
//https://stackoverflow.com/questions/51619879/mxgraph-how-to-automatically-resize-mxcell-to-content-width-if-it-exceeds-the
|
||||
//---------------------
|
||||
//координаты вершин графа
|
||||
// public LinkedHashMap<String, Pair<Double, Double>> vertexCoordinates = new LinkedHashMap<>();
|
||||
protected GraphInfo graph = null; //инфа о вершинах и ребрах.
|
||||
public FunctionsGraphUI(GraphInfo graph_in) {
|
||||
graph = graph_in;
|
||||
//настройки графа
|
||||
setGridEnabled(true);
|
||||
//setAllowNegativeCoordinates(false);
|
||||
setAllowDanglingEdges(false); //запрет на висячие ребра.
|
||||
setCellsEditable(false); //запрет на редактирование клеток
|
||||
setCellsResizable(false); //запрет изменения размера клеток
|
||||
setKeepEdgesInBackground(true); // ребра на задний план. очень важно.
|
||||
setDropEnabled(false);
|
||||
setAutoSizeCells(true);
|
||||
setConnectableEdges(false);
|
||||
setCellsCloneable(false);
|
||||
//--------------------
|
||||
mxStylesheet stylesheet = getStylesheet();
|
||||
Hashtable<String, Object> style = new Hashtable<String, Object>();
|
||||
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
|
||||
style.put(mxConstants.STYLE_FONTCOLOR, "black");
|
||||
style.put(mxConstants.STYLE_FILLCOLOR, "yellow");
|
||||
style.put(mxConstants.STYLE_FONTSIZE, "16");
|
||||
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
|
||||
stylesheet.putCellStyle(FunctionType.Default.toString(), style);
|
||||
//------------------------------------------
|
||||
style = new Hashtable<String, Object>();
|
||||
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
|
||||
style.put(mxConstants.STYLE_FONTCOLOR, "black");
|
||||
style.put(mxConstants.STYLE_FILLCOLOR, "lightgreen");
|
||||
style.put(mxConstants.STYLE_FONTSIZE, "16");
|
||||
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
|
||||
stylesheet.putCellStyle(FunctionType.Main.toString(), style);
|
||||
//------------------------------------------
|
||||
style = new Hashtable<String, Object>();
|
||||
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
|
||||
style.put(mxConstants.STYLE_FONTCOLOR, "black");
|
||||
style.put(mxConstants.STYLE_FILLCOLOR, "lightgray");
|
||||
style.put(mxConstants.STYLE_FONTSIZE, "16");
|
||||
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
|
||||
// style.put(mxConstants.STYLE_STROKECOLOR, "lawngreen"); это и есть границы.
|
||||
// style.put(mxConstants.STYLE_STROKEWIDTH, 5);
|
||||
stylesheet.putCellStyle(FunctionType.Standard.toString(), style);
|
||||
//------------------------------------------
|
||||
style = new Hashtable<String, Object>();
|
||||
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
|
||||
style.put(mxConstants.STYLE_FONTCOLOR, "white");
|
||||
style.put(mxConstants.STYLE_FILLCOLOR, "darkred");
|
||||
style.put(mxConstants.STYLE_FONTSIZE, "16");
|
||||
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
|
||||
stylesheet.putCellStyle(FunctionType.NotFound.toString(), style);
|
||||
//------------------------------------------
|
||||
style = new Hashtable<String, Object>();
|
||||
style.put(mxConstants.STYLE_SHAPE, SHAPE_DOUBLE_ELLIPSE);
|
||||
style.put(mxConstants.STYLE_FONTCOLOR, "black");
|
||||
style.put(mxConstants.STYLE_FILLCOLOR, "lightblue");
|
||||
style.put(mxConstants.STYLE_FONTSIZE, "16");
|
||||
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
|
||||
// style.put(mxConstants.STYLE_STROKECOLOR, "lawngreen"); это и есть границы.
|
||||
// style.put(mxConstants.STYLE_STROKEWIDTH, 5);
|
||||
stylesheet.putCellStyle("current", style);
|
||||
}
|
||||
//---
|
||||
// еще один туториал?
|
||||
// https://www.47.gbmse.ru/resources/utility/mxgraph/docs/tutorial.html
|
||||
//
|
||||
//https://github.com/jgraph/mxgraph/tree/master/java/examples/com/mxgraph/examples/swing
|
||||
//https://jgraph.github.io/mxgraph/java/docs/com/mxgraph/swing/mxGraphComponent.html
|
||||
//https://www.47.gbmse.ru/resources/utility/mxgraph/docs/tutorial.html#3.2
|
||||
public mxGraphComponent Draw() {
|
||||
FuncInfo funcInfo = null;
|
||||
//установить координаты вершин.
|
||||
SetCoordinates(); //пустышка.
|
||||
Object parent = getDefaultParent();
|
||||
getModel().beginUpdate();
|
||||
//непосредственное добавление графики
|
||||
//------------------------------------
|
||||
//размеры
|
||||
//https://stackoverflow.com/questions/51619879/mxgraph-how-to-automatically-resize-mxcell-to-content-width-if-it-exceeds-the
|
||||
// UI.Info("++");
|
||||
LinkedHashMap<String, Object> mxVertexes = new LinkedHashMap<>();
|
||||
for (String name : graph.vertexCoordinates.keySet()) {
|
||||
funcInfo = Current.getProject().allFunctions.get(name);
|
||||
String vertexType = funcInfo.type.toString();
|
||||
if (SPF_GetGraphFunctionPositions.showByCurrentFunction) {
|
||||
FuncInfo current_fi = (FuncInfo) Current.get(Current.Function);
|
||||
if ((current_fi != null) && (funcInfo.funcName.equals(current_fi.funcName))) {
|
||||
vertexType = "current";
|
||||
}
|
||||
}
|
||||
mxVertexes.put(name,
|
||||
insertVertex(parent,
|
||||
name, //идентификатор вершины. должен быть уникальным.
|
||||
name, //объект не стоит делать. какие то мутки при перетаскивании объектов.
|
||||
//строки-ключа уже достаточно
|
||||
//координаты вершины
|
||||
graph.vertexCoordinates.get(name).getKey(),
|
||||
graph.vertexCoordinates.get(name).getValue(),
|
||||
default_width, default_height,
|
||||
vertexType
|
||||
));
|
||||
}
|
||||
for (String name : graph.vertexMap.keySet()) {
|
||||
mxCell cell = (mxCell) mxVertexes.get(name);
|
||||
mxRectangle preferred = getPreferredSizeForCell(cell);
|
||||
mxGeometry current = cell.getGeometry();
|
||||
current.setWidth((preferred.getWidth() > default_width) ? preferred.getWidth() : default_width);
|
||||
//updateCellSize(cell, true); это если просто везде выставить авторазмер.
|
||||
//тут же нам нужно применить его только в случае если ширина меньше чем надо.
|
||||
for (String neigbor : graph.vertexMap.get(name)) {
|
||||
insertEdge(parent, null,
|
||||
//надпись над ребром.
|
||||
"",
|
||||
//вершина 1
|
||||
mxVertexes.get(name),
|
||||
//вершина 2
|
||||
mxVertexes.get(neigbor));
|
||||
}
|
||||
}
|
||||
//------------------------------------
|
||||
//https://java.hotexamples.com/examples/com.mxgraph.view/mxGraph/setAutoSizeCells/java-mxgraph-setautosizecells-method-examples.html
|
||||
groupCells();
|
||||
getModel().endUpdate();
|
||||
//------------------------------------
|
||||
//обертка графа контролом
|
||||
mxGraphComponent graphComponent = new mxGraphComponent(this);
|
||||
graphComponent.setZoomFactor(1.10);
|
||||
//--
|
||||
// https://programtalk.com/java-more-examples/com.mxgraph.util.mxEvent.UP/
|
||||
addListener(mxEvent.CELLS_MOVED, new mxIEventListener() {
|
||||
@Override
|
||||
public void invoke(Object o, mxEventObject mxEventObject) {
|
||||
//Сохранение координат графа при сдвиге узла
|
||||
if (mxEventObject.getProperties().containsKey("cells")) {
|
||||
Object[] cells = (Object[]) mxEventObject.getProperties().get("cells");
|
||||
for (Object cell_ : cells) {
|
||||
if (cell_ instanceof mxCell) {
|
||||
mxCell cell = (mxCell) cell_;
|
||||
if (cell.isVertex()) {
|
||||
String funcName = (String) cell.getValue();
|
||||
FuncCoordinates coords = null;
|
||||
// UI.Info(cell.getGeometry().getPoint().toString());
|
||||
Point point = cell.getGeometry().getPoint();
|
||||
try {
|
||||
if (Current.getProject().db.funcCoordinates.containsKey(funcName)) {
|
||||
coords = Current.getProject().db.funcCoordinates.get(funcName);
|
||||
coords.name = funcName;
|
||||
coords.X = point.getX();
|
||||
coords.Y = point.getY();
|
||||
Current.getProject().db.Update(coords);
|
||||
} else {
|
||||
coords = new FuncCoordinates();
|
||||
coords.name = funcName;
|
||||
coords.X = point.getX();
|
||||
coords.Y = point.getY();
|
||||
Current.getProject().db.Insert(coords);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
System.out.println("------");
|
||||
for (String key: mxEventObject.getProperties().keySet()){
|
||||
System.out.println(key+" : "+ mxEventObject.getProperties().get(key));
|
||||
}
|
||||
System.out.println("------");
|
||||
|
||||
*/
|
||||
});
|
||||
graphComponent.getGraphControl().setComponentPopupMenu(new FunctionsGraphMenu());
|
||||
|
||||
//обработка клика мышом.
|
||||
graphComponent.getGraphControl().addMouseListener(new MouseAdapter() {
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
System.out.println("Released");
|
||||
Object cell = graphComponent.getCellAt(e.getX(), e.getY());
|
||||
if (cell != null) {
|
||||
mxCell mx_cell = (mxCell) cell;
|
||||
if (mx_cell.isVertex()) {
|
||||
String func_name = (String) mx_cell.getValue();
|
||||
FuncInfo fi = Current.getProject().allFunctions.get(func_name);
|
||||
switch (e.getClickCount()) {
|
||||
case 1:
|
||||
Current.set(Current.SelectedFunction, fi);
|
||||
break;
|
||||
case 2:
|
||||
switch (fi.type) {
|
||||
case Default:
|
||||
case Main:
|
||||
fi.Show(true);
|
||||
break;
|
||||
case Standard:
|
||||
case NotFound:
|
||||
UI.Info("процедура " + Utils.Brackets(func_name) + " " + fi.type.getDescription());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
graphComponent.getViewport().setBackground(Color.WHITE);
|
||||
return graphComponent;
|
||||
}
|
||||
//по умолчанию ничего не меняем.
|
||||
public void SetCoordinates() {
|
||||
}
|
||||
public void SaveCoords() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package ProjectData.SapforData.Functions.UI.Graph;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
public class FunctionsGraphUIGreed extends FunctionsGraphUI {
|
||||
//веса вершин.
|
||||
protected LinkedHashMap<String, Integer> weights = new LinkedHashMap<>();
|
||||
//группы вершин по весам.в порядке убывания весов.
|
||||
protected LinkedHashMap<Integer, Vector<String>> groups = new LinkedHashMap<>();
|
||||
public FunctionsGraphUIGreed(GraphInfo graph_in) {
|
||||
super(graph_in);
|
||||
}
|
||||
@Override
|
||||
public void SetCoordinates() {
|
||||
//получить веса вершин.
|
||||
for (String name : graph.vertexMap.keySet()) {
|
||||
Vector<String> edges = graph.vertexMap.get(name);
|
||||
//как минимум, вес вершины - это все исходящие из нее ребра.
|
||||
if (!weights.containsKey(name)) weights.put(name, edges.size());
|
||||
else weights.replace(name, weights.get(name) + edges.size());
|
||||
for (String dst : edges) {
|
||||
//есть ребро, значит уже вес 1
|
||||
if (!weights.containsKey(dst)) weights.put(dst, 1);
|
||||
else weights.replace(dst, weights.get(dst) + 1);
|
||||
}
|
||||
}
|
||||
//сортировка по весу вершин.
|
||||
//1 определить максимальный вес.
|
||||
int max = 0;
|
||||
for (String name : weights.keySet())
|
||||
if (weights.get(name) > max) max = weights.get(name);
|
||||
for (int i = max; i >= 0; --i) {
|
||||
Vector<String> current_group = new Vector<>();
|
||||
for (String name : weights.keySet()) {
|
||||
if (weights.get(name) == i) current_group.add(name);
|
||||
}
|
||||
if (current_group.size() > 0) {
|
||||
groups.put(i, current_group);
|
||||
}
|
||||
}
|
||||
//linked hash map - сохраняет порядок. поэтому они уже по убыванию.
|
||||
//теперь координаты. берем самую тыжелую группу, правильный многоугольник по центру
|
||||
//поток следующая, вокруг первого, и т д.
|
||||
int R = 150;
|
||||
int i = 0;
|
||||
double x_offet = 0;
|
||||
double y_ofset = 0;
|
||||
double rot = 0.0; //чтобы не было линеечки с каждой группой вращаем многоугольники.
|
||||
for (int w : groups.keySet()) {
|
||||
//первая вершина - особый случай. если она одна - ее в центр и надо
|
||||
if ((i == 0) && (groups.get(w).size() == 1)) {
|
||||
graph.vertexCoordinates.put(groups.get(w).get(0), new Pair<>(0.0, 0.0));
|
||||
} else {
|
||||
double phi0 = rot;
|
||||
double phi = 2 * Math.PI / groups.get(w).size();
|
||||
for (String name : groups.get(w)) {
|
||||
double x = R * Math.cos(phi0);
|
||||
double y = R * Math.sin(phi0);
|
||||
if (x < x_offet) x_offet = x;
|
||||
if (y < y_ofset) y_ofset = y;
|
||||
//todo добавить в рассчет прямоугольник и самой вершины.
|
||||
graph.vertexCoordinates.put(name, new Pair<>(x, y));
|
||||
phi0 += phi;
|
||||
}
|
||||
R += 100;
|
||||
}
|
||||
++i;
|
||||
rot += 10;
|
||||
if (rot > 360.0) rot = 0.0;
|
||||
}
|
||||
x_offet *= -1;
|
||||
y_ofset *= -1;
|
||||
//теперь надо применить смещение. смещение. чтобы не было отрицательных координат.
|
||||
for (String name : graph.vertexCoordinates.keySet()) {
|
||||
Pair<Double, Double> old = graph.vertexCoordinates.get(name);
|
||||
graph.vertexCoordinates.replace(name, new Pair<>(old.getKey() + x_offet + 50, old.getValue() + y_ofset + 50));
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/ProjectData/SapforData/Functions/UI/Graph/GraphInfo.java
Normal file
68
src/ProjectData/SapforData/Functions/UI/Graph/GraphInfo.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package ProjectData.SapforData.Functions.UI.Graph;
|
||||
import Common.Utils.Utils;
|
||||
import com.mxgraph.swing.mxGraphComponent;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
//только инфа о вершинах и ребрах. без отрисовки.
|
||||
public class GraphInfo {
|
||||
//вершины графа и ребра
|
||||
public LinkedHashMap<String, Vector<String>> vertexMap = new LinkedHashMap<>();
|
||||
//координаты для отрисовки. раз это теперь полноценная инфа, которая передается извне.
|
||||
public LinkedHashMap<String, Pair<Double, Double>> vertexCoordinates = new LinkedHashMap<>();
|
||||
//----------------
|
||||
public void addVertex(String vertexName) {
|
||||
if (!hasVertex(vertexName)) {
|
||||
vertexMap.put(vertexName, new Vector<>());
|
||||
}
|
||||
}
|
||||
public boolean hasVertex(String vertexName) {
|
||||
return vertexMap.containsKey(vertexName);
|
||||
}
|
||||
//-----------------
|
||||
public boolean hasEdge(String vertexName1, String vertexName2) {
|
||||
if (!hasVertex(vertexName1)) return false;
|
||||
Vector<String> edges = vertexMap.get(vertexName1);
|
||||
for (String end : edges)
|
||||
if (end.equals(vertexName2)) return true;
|
||||
return false;
|
||||
}
|
||||
public void addEdge(String vertexName1, String vertexName2) {
|
||||
if (!hasVertex(vertexName1)) addVertex(vertexName1);
|
||||
if (!hasVertex(vertexName2)) addVertex(vertexName2);
|
||||
if (!hasEdge(vertexName1, vertexName2)) {
|
||||
//находим список смежности, и добавляем новую вершину.
|
||||
Vector<String> edges1 = vertexMap.get(vertexName1);
|
||||
edges1.add(vertexName2);
|
||||
Collections.sort(edges1);
|
||||
}
|
||||
}
|
||||
//-
|
||||
public void Print() {
|
||||
Vector<String> edges = new Vector<>();
|
||||
for (String name : vertexMap.keySet()) {
|
||||
for (String neighbor : vertexMap.get(name)) {
|
||||
edges.add(Utils.Brackets(name + "," + neighbor));
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return vertexMap.isEmpty();
|
||||
}
|
||||
public void Clear() {
|
||||
vertexMap.clear();
|
||||
vertexCoordinates.clear();
|
||||
}
|
||||
/*
|
||||
public void ClearCoords() {
|
||||
vertexCoordinates.clear();
|
||||
}
|
||||
*/
|
||||
public mxGraphComponent Draw() {
|
||||
// return new FunctionsGraphUIGreed(this).Draw();
|
||||
return new FunctionsGraphUI(this).Draw();
|
||||
}
|
||||
|
||||
}
|
||||
19
src/ProjectData/SapforData/Functions/UI/InlineMenu.java
Normal file
19
src/ProjectData/SapforData/Functions/UI/InlineMenu.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package ProjectData.SapforData.Functions.UI;
|
||||
import Common.Current;
|
||||
import Common.UI.Menus.SelectionTreeMenu;
|
||||
import Common.UI.Trees.SelectableTree;
|
||||
import ProjectData.SapforData.Functions.FuncInfo;
|
||||
public class InlineMenu extends SelectionTreeMenu {
|
||||
public InlineMenu(SelectableTree tree_in) {
|
||||
super(tree_in);
|
||||
}
|
||||
@Override
|
||||
public Class getTargetClass() {
|
||||
return FuncInfo.class;
|
||||
}
|
||||
@Override
|
||||
public void SelectAll(boolean select) {
|
||||
for (FuncInfo fi : Current.getProject().allFunctions.values())
|
||||
fi.SelectAllChildren(select);
|
||||
}
|
||||
}
|
||||
27
src/ProjectData/SapforData/Functions/UI/InlineMenu2.java
Normal file
27
src/ProjectData/SapforData/Functions/UI/InlineMenu2.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package ProjectData.SapforData.Functions.UI;
|
||||
import Common.UI.Menus.SelectionTreeMenu;
|
||||
import Common.UI.Trees.SelectableTree;
|
||||
import ProjectData.SapforData.Functions.FuncCallH;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
public class InlineMenu2 extends SelectionTreeMenu {
|
||||
public InlineMenu2(SelectableTree tree_in) {
|
||||
super(tree_in);
|
||||
}
|
||||
@Override
|
||||
public Class getTargetClass() {
|
||||
return FuncCallH.class;
|
||||
}
|
||||
@Override
|
||||
public void SelectAll(boolean select) {
|
||||
if (tree.root.getChildCount() == 1)
|
||||
SelectR(
|
||||
(FuncCallH) ((DefaultMutableTreeNode) (tree.root.getChildAt(0))).getUserObject(),
|
||||
select);
|
||||
}
|
||||
public void SelectR(FuncCallH callH, boolean select) {
|
||||
callH.Select(select);
|
||||
for (FuncCallH child : callH.calls)
|
||||
SelectR(child, select);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user