Перенос.

This commit is contained in:
2023-09-17 22:13:42 +03:00
parent dd2e0ca7e0
commit 629d8b8477
1239 changed files with 61161 additions and 1 deletions

View 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;
}
}

View File

@@ -0,0 +1,9 @@
package ProjectData.Files;
public enum FileState {
Undefined, //состояние файла сброшено.
OK, //никаких сообщений нет, зеленая галочка.
HasNotes, //есть только note
HasWarnings, //есть warning, нет error
HasErrors, //есть error
Excluded //исключен из рассмотрения
}

View 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 "";
}
}

View 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 "файл";
}
}

View 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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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() + "()";
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -0,0 +1,6 @@
package ProjectData.Files.UI.Editor.AutoComplete.SAPFOR;
public enum SearchState {
BracketSearch,
DirectiveSearch,
Directive
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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");
}
}