2015-06-02 22:52:35 +03:00
|
|
|
|
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
|
|
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
|
|
using System;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
using ICSharpCode.TextEditor;
|
|
|
|
|
|
using ICSharpCode.TextEditor.Gui.CompletionWindow;
|
|
|
|
|
|
using ICSharpCode.TextEditor.Document;
|
|
|
|
|
|
|
|
|
|
|
|
namespace VisualPascalABC
|
|
|
|
|
|
{
|
|
|
|
|
|
public delegate void ParseInformationUpdatedDelegate(object obj, string fileName);
|
|
|
|
|
|
|
2017-05-26 13:29:21 +03:00
|
|
|
|
public class CodeCompletionParserController : VisualPascalABCPlugins.ICodeCompletionService
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
public static Hashtable open_files = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
public VisualEnvironmentCompiler visualEnvironmentCompiler;
|
|
|
|
|
|
private System.Threading.Thread th = null;
|
|
|
|
|
|
private CodeCompletionProvider ccp;
|
|
|
|
|
|
public event ParseInformationUpdatedDelegate ParseInformationUpdated;
|
|
|
|
|
|
|
|
|
|
|
|
public void StopParseThread()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th != null)
|
|
|
|
|
|
th.Abort();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CodeCompletionParserController()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.th = new System.Threading.Thread(new System.Threading.ThreadStart(ParseInThread));
|
|
|
|
|
|
ccp = new CodeCompletionProvider();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-19 12:58:42 +03:00
|
|
|
|
public PascalABCCompiler.Parsers.ICodeCompletionDomConverter GetConverter(string fileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
return CodeCompletion.CodeCompletionController.comp_modules[fileName] as PascalABCCompiler.Parsers.ICodeCompletionDomConverter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-05-14 22:35:07 +03:00
|
|
|
|
public static string CurrentTwoLetterISO
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return CodeCompletion.CodeCompletionController.currentLanguageISO;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.currentLanguageISO = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.ParsersController.SourceFilesProvider = visualEnvironmentCompiler.SourceFilesProvider;
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.currentLanguageISO = PascalABCCompiler.StringResourcesLanguage.CurrentTwoLetterISO;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RenameFile(string OldFileName, string NewFileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.Compare(OldFileName, NewFileName, true) != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[NewFileName] = CodeCompletion.CodeCompletionController.comp_modules[OldFileName];
|
|
|
|
|
|
if (CodeCompletion.CodeCompletionController.comp_modules.ContainsKey(OldFileName))
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules.Remove(OldFileName);
|
|
|
|
|
|
open_files[NewFileName] = open_files[OldFileName];
|
|
|
|
|
|
if (open_files.ContainsKey(OldFileName))
|
|
|
|
|
|
open_files.Remove(OldFileName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RegisterFileForParsing(string FileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
open_files[FileName] = true;
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.SetParser(System.IO.Path.GetExtension(FileName));
|
|
|
|
|
|
//ParseAllFiles();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void CloseFile(string FileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (CodeCompletion.CodeCompletionController.comp_modules[FileName] != null)
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules.Remove(FileName);
|
|
|
|
|
|
if (open_files[FileName] != null)
|
|
|
|
|
|
open_files.Remove(FileName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetAsChanged(string FileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (FileName != null)
|
|
|
|
|
|
open_files[FileName] = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetAllInProjectChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Hashtable open_files2 = open_files.Clone() as Hashtable;
|
|
|
|
|
|
foreach (string s in open_files2.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ProjectFactory.Instance.CurrentProject.ContainsSourceFile(s))
|
|
|
|
|
|
open_files[s] = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RunParseThread()
|
|
|
|
|
|
{
|
|
|
|
|
|
th = new System.Threading.Thread(InternalParsing);
|
|
|
|
|
|
th.Priority = System.Threading.ThreadPriority.BelowNormal;
|
|
|
|
|
|
th.IsBackground = true;
|
|
|
|
|
|
th.Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void StopParsing()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
VisualPABCSingleton.MainForm.StopTimer();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InternalParsing()
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
ParseInThread();
|
|
|
|
|
|
System.Threading.Thread.Sleep(2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private long mem_delta = 0;
|
|
|
|
|
|
|
|
|
|
|
|
internal void ParseInThread()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Hashtable open_files2 = (Hashtable)open_files.Clone();
|
|
|
|
|
|
Hashtable recomp_files = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
bool is_comp = false;
|
|
|
|
|
|
foreach (string FileName in open_files2.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
//(ssyy) 18.05.08 Вставил проверку на null
|
|
|
|
|
|
object o = open_files[FileName];
|
|
|
|
|
|
if (o != null && (bool)o == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
is_comp = true;
|
|
|
|
|
|
CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
|
|
|
|
|
|
string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, PascalABCCompiler.SourceFileOperation.GetText) as string;
|
2017-08-31 22:41:26 +03:00
|
|
|
|
if (string.IsNullOrEmpty(text))
|
|
|
|
|
|
text = "begin end.";
|
2015-05-14 22:35:07 +03:00
|
|
|
|
CodeCompletion.DomConverter tmp = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
|
|
|
|
|
|
long cur_mem = Environment.WorkingSet;
|
|
|
|
|
|
CodeCompletion.DomConverter dc = controller.Compile(FileName, text);
|
|
|
|
|
|
mem_delta += Environment.WorkingSet - cur_mem;
|
|
|
|
|
|
open_files[FileName] = false;
|
|
|
|
|
|
if (dc.is_compiled)
|
|
|
|
|
|
{
|
|
|
|
|
|
//CodeCompletion.CodeCompletionController.comp_modules.Remove(FileName);
|
2016-05-06 14:56:19 +03:00
|
|
|
|
if (tmp != null && tmp.visitor.entry_scope != null)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
2016-05-06 14:56:19 +03:00
|
|
|
|
tmp.visitor.entry_scope.Clear();
|
|
|
|
|
|
if (tmp.visitor.cur_scope != null)
|
|
|
|
|
|
tmp.visitor.cur_scope.Clear();
|
2015-05-14 22:35:07 +03:00
|
|
|
|
}
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
|
|
|
|
|
recomp_files[FileName] = FileName;
|
|
|
|
|
|
open_files[FileName] = false;
|
|
|
|
|
|
if (ParseInformationUpdated != null)
|
2016-05-06 14:56:19 +03:00
|
|
|
|
ParseInformationUpdated(dc.visitor.entry_scope, FileName);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
}
|
|
|
|
|
|
else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (string FileName in open_files2.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
|
|
|
|
|
|
CodeCompletion.SymScope ss = null;
|
|
|
|
|
|
if (dc != null)
|
|
|
|
|
|
{
|
2016-05-06 14:56:19 +03:00
|
|
|
|
if (dc.visitor.entry_scope != null) ss = dc.visitor.entry_scope;
|
|
|
|
|
|
else if (dc.visitor.impl_scope != null) ss = dc.visitor.impl_scope;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
int j = 0;
|
|
|
|
|
|
while (j < 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (j == 0)
|
|
|
|
|
|
{
|
2016-05-06 14:56:19 +03:00
|
|
|
|
ss = dc.visitor.entry_scope;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
j++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2016-05-06 14:56:19 +03:00
|
|
|
|
ss = dc.visitor.impl_scope;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
j++;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (ss != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < ss.used_units.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
string s = ss.used_units[i].file_name;
|
|
|
|
|
|
if (s != null && open_files2.ContainsKey(s) && recomp_files.ContainsKey(s))
|
|
|
|
|
|
{
|
|
|
|
|
|
is_comp = true;
|
|
|
|
|
|
CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
|
|
|
|
|
|
string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, PascalABCCompiler.SourceFileOperation.GetText) as string;
|
|
|
|
|
|
CodeCompletion.DomConverter tmp = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
|
|
|
|
|
|
long cur_mem = Environment.WorkingSet;
|
|
|
|
|
|
dc = controller.Compile(FileName, text);
|
|
|
|
|
|
mem_delta += Environment.WorkingSet - cur_mem;
|
|
|
|
|
|
open_files[FileName] = false;
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
|
|
|
|
|
if (dc.is_compiled)
|
|
|
|
|
|
{
|
|
|
|
|
|
/*if (tmp != null && tmp.stv.entry_scope != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
tmp.stv.entry_scope.Clear();
|
|
|
|
|
|
if (tmp.stv.cur_scope != null) tmp.stv.cur_scope.Clear();
|
|
|
|
|
|
}*/
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
|
|
|
|
|
recomp_files[FileName] = FileName;
|
2016-05-06 14:56:19 +03:00
|
|
|
|
ss.used_units[i] = dc.visitor.entry_scope;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
if (ParseInformationUpdated != null)
|
2016-05-06 14:56:19 +03:00
|
|
|
|
ParseInformationUpdated(dc.visitor.entry_scope, FileName);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
}
|
|
|
|
|
|
else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
|
|
|
|
|
|
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (is_comp && Environment.WorkingSet > 60000000 /*&& mem_delta > 10000000*/)
|
|
|
|
|
|
//postavil delta dlja pamjati, posle kototoj delaetsja sborka musora
|
|
|
|
|
|
{
|
|
|
|
|
|
mem_delta = 0;
|
|
|
|
|
|
GC.Collect();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsParsing()
|
|
|
|
|
|
{
|
|
|
|
|
|
return th != null && th.ThreadState == System.Threading.ThreadState.Running;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ParseAllFiles()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (visualEnvironmentCompiler.UserOptions.AllowCodeCompletion)// && visualEnvironmentCompiler.compilerLoaded)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th.ThreadState != System.Threading.ThreadState.Running)
|
|
|
|
|
|
{
|
|
|
|
|
|
th = new System.Threading.Thread(new System.Threading.ThreadStart(this.ParseInThread));
|
|
|
|
|
|
th.Priority = System.Threading.ThreadPriority.BelowNormal;
|
|
|
|
|
|
//th.IsBackground = true;
|
|
|
|
|
|
th.Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
//if (th == null)
|
|
|
|
|
|
// RunParseThread();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|