From 67060ad9eac3d164c039ec7a91ade12eb1d9ea0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?=
=?UTF-8?q?=D0=97=D0=B5=D0=BC=D0=BB=D1=8F=D0=BA?=
<92867056+AlexanderZemlyak@users.noreply.github.com>
Date: Fri, 3 Apr 2026 23:08:57 +0300
Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA=D0=BE?=
=?UTF-8?q?=D0=BC=D0=BF=D0=B8=D0=BB=D1=8F=D1=86=D0=B8=D0=B8=20=D0=B2=20Int?=
=?UTF-8?q?ellisense,=20=D0=B5=D1=81=D0=BB=D0=B8=20=D1=82=D1=80=D0=B0?=
=?UTF-8?q?=D0=BD=D0=B7=D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5=20=D0=B7?=
=?UTF-8?q?=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20?=
=?UTF-8?q?=D0=B1=D1=8B=D0=BB=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA=D0=BE?=
=?UTF-8?q?=D0=BC=D0=BF=D0=B8=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?=
=?UTF-8?q?=D1=8B=20(#3414)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Add invalidating dependent modules in code completion parser controller
* Copy fields of importedModuleScope into fictive modules for SPython
* Copy changes in code completion parser controller to linux version
* Refactor CodeCompletionParserController
* Delete cache clearing in CodeCompletionParserController when invalidating dependent modules
---
CodeCompletion/DomSyntaxTreeVisitor.cs | 10 +-
CodeCompletion/SymTable.cs | 49 +++++
.../CodeCompletionParserController.cs | 174 ++++++++++-------
.../CodeCompletionParserController.cs | 176 +++++++++++-------
4 files changed, 277 insertions(+), 132 deletions(-)
diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs
index 5fc637182..0c498dccc 100644
--- a/CodeCompletion/DomSyntaxTreeVisitor.cs
+++ b/CodeCompletion/DomSyntaxTreeVisitor.cs
@@ -3107,7 +3107,11 @@ namespace CodeCompletion
if (fictiveUnit == null)
{
- fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName + "?ModuleName", SymbolKind.Namespace, ""), null);
+ fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName + "?ModuleName", SymbolKind.Namespace, ""), null);
+ // TODO: настроить копирование EVA
+ fictiveUnit.file_name = importedModuleScope.file_name;
+ fictiveUnit.used_units = importedModuleScope.used_units;
+ ((InterfaceUnitScope)fictiveUnit).impl_scope = ((InterfaceUnitScope)importedModuleScope).impl_scope;
currentScope.AddUsedUnit(fictiveUnit);
}
@@ -3139,6 +3143,10 @@ namespace CodeCompletion
if (fictiveUnit == null)
{
fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName, SymbolKind.Namespace, ""), null);
+ // TODO: настроить копирование EVA
+ fictiveUnit.file_name = importedModuleScope.file_name;
+ fictiveUnit.used_units = importedModuleScope.used_units;
+ ((InterfaceUnitScope)fictiveUnit).impl_scope = ((InterfaceUnitScope)importedModuleScope).impl_scope;
currentScope.AddUsedUnit(fictiveUnit);
}
diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs
index 090b959e0..1670bca0c 100644
--- a/CodeCompletion/SymTable.cs
+++ b/CodeCompletion/SymTable.cs
@@ -536,6 +536,55 @@ namespace CodeCompletion
used_units.Add(unit);
}
+ ///
+ /// Получить массив всех транзитивно используемых модулей (ислючая пр-ва имен).
+ /// По умолчанию для InterfaceUnitScope ищутся и зависимости реализации тоже.
+ ///
+ public SymScope[] GetRealUsedUnitsTransitive(bool includeImplementationDependenciesForUnit = true)
+ {
+ var usedUnits = new List();
+
+ if (used_units != null)
+ {
+ usedUnits.AddRange(used_units.Where(unit => unit.file_name != null));
+ }
+
+ if (this is InterfaceUnitScope interfaceScope && includeImplementationDependenciesForUnit && interfaceScope.impl_scope != null)
+ {
+ foreach (var recursiveUsedUnit in interfaceScope.impl_scope.GetRealUsedUnitsTransitive(true))
+ {
+ if (recursiveUsedUnit == this)
+ continue;
+
+ if (usedUnits.FirstOrDefault(unit => unit.file_name == recursiveUsedUnit.file_name) == null)
+ {
+ usedUnits.Add(recursiveUsedUnit);
+ }
+ }
+ }
+
+ if (used_units != null)
+ {
+ foreach (var usedUnit in used_units)
+ {
+ var recursiveUsedUnits = usedUnit.GetRealUsedUnitsTransitive(includeImplementationDependenciesForUnit);
+
+ foreach (var recursiveUsedUnit in recursiveUsedUnits)
+ {
+ if (recursiveUsedUnit == this)
+ continue;
+
+ if (usedUnits.FirstOrDefault(unit => unit.file_name == recursiveUsedUnit.file_name) == null)
+ {
+ usedUnits.Add(recursiveUsedUnit);
+ }
+ }
+ }
+ }
+
+ return usedUnits.ToArray();
+ }
+
public virtual string GetFullName()
{
return si.name;
diff --git a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs
index bc18190da..48d1a3b2b 100644
--- a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs
+++ b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs
@@ -143,94 +143,58 @@ namespace VisualPascalABC
{
try
{
- Dictionary recomp_files = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ HashSet recomp_files = new HashSet(StringComparer.OrdinalIgnoreCase);
bool is_comp = false;
foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
{
if (filesToParse[FileName])
{
+ // Попытка компиляции была
+ filesToParse[FileName] = false;
+
is_comp = true;
- CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string;
if (string.IsNullOrEmpty(text))
text = "begin end.";
- 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;
- filesToParse[FileName] = false;
- if (dc.is_compiled)
+
+ if (CompileWatchedFile(FileName, text, true))
{
- //CodeCompletion.CodeCompletionController.comp_modules.Remove(file_name);
- if (tmp != null && tmp.visitor.entry_scope != null)
- {
- tmp.visitor.entry_scope.Clear();
- if (tmp.visitor.cur_scope != null)
- tmp.visitor.cur_scope.Clear();
- }
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
- recomp_files[FileName] = FileName;
- filesToParse[FileName] = false;
- if (ParseInformationUpdated != null)
- ParseInformationUpdated(dc.visitor.entry_scope, FileName);
+ // успешная компиляция
+ recomp_files.Add(FileName);
}
- else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
}
}
foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
{
CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
- CodeCompletion.SymScope ss = null;
+
if (dc != null)
{
- if (dc.visitor.entry_scope != null) ss = dc.visitor.entry_scope;
- else if (dc.visitor.impl_scope != null) ss = dc.visitor.impl_scope;
- int j = 0;
- while (j < 2)
+ CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope;
+ if (watchedUnitScope != null)
{
- if (j == 0)
+ var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive();
+
+ for (int i = 0; i < usedUnitsTransitive.Length; i++)
{
- ss = dc.visitor.entry_scope;
- j++;
- }
- else
- {
- ss = dc.visitor.impl_scope;
- j++;
- }
- if (ss != null)
- {
- for (int i = 0; i < ss.used_units.Count; i++)
+ string usedUnitFileName = usedUnitsTransitive[i].file_name;
+
+ // Если какая-то из зависимостей была перекомпилирована
+ if (recomp_files.Contains(usedUnitFileName))
{
- string s = ss.used_units[i].file_name;
- if (s != null && filesToParse.ContainsKey(s) && recomp_files.ContainsKey(s))
+ // Помечаем нужные модули для будущей перекомпиляции
+ InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName);
+
+ // Перекомпилируем текущий модуль
+ is_comp = true;
+ string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string;
+
+ // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA
+ if (CompileWatchedFile(FileName, text, false))
{
- is_comp = true;
- CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
- string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, 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;
- filesToParse[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;
- ss.used_units[i] = dc.visitor.entry_scope;
- if (ParseInformationUpdated != null)
- ParseInformationUpdated(dc.visitor.entry_scope, FileName);
- }
- else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
+ // успешная компиляция
+ recomp_files.Add(FileName);
}
}
}
@@ -248,6 +212,86 @@ namespace VisualPascalABC
}
+ ///
+ /// Вызов компиляции (интеллисенсом) файла с именем fileName и содержимым fileText.
+ /// Возвращает true, если компиляция была успешна, false в противном случае.
+ ///
+ private bool CompileWatchedFile(string fileName, string fileText, bool clearOldScope)
+ {
+ bool success = false;
+
+ CodeCompletion.DomConverter tmp = CodeCompletion.CodeCompletionController.comp_modules[fileName] as CodeCompletion.DomConverter;
+ long cur_mem = Environment.WorkingSet;
+ CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
+ CodeCompletion.DomConverter dc = controller.Compile(fileName, fileText);
+ mem_delta += Environment.WorkingSet - cur_mem;
+
+ if (dc.is_compiled)
+ {
+ if (clearOldScope && tmp != null)
+ {
+ tmp.visitor.entry_scope?.Clear();
+ tmp.visitor.cur_scope?.Clear();
+ }
+ CodeCompletion.CodeCompletionController.comp_modules[fileName] = dc;
+
+ success = true;
+ ParseInformationUpdated?.Invoke(dc.visitor.entry_scope, fileName);
+ }
+ else if (tmp == null)
+ CodeCompletion.CodeCompletionController.comp_modules[fileName] = dc;
+
+ return success;
+ }
+
+ ///
+ /// Помечает модули из candidateModulesToCheck и watchedFiles для будущей перекомпиляции, если они завивисимы от модуля с именем recompiledDependencyName
+ ///
+ private void InvalidateDependentModules(CodeCompletion.SymScope[] candidateModulesToCheck, string recompiledDependencyName, Dictionary watchedFiles, string currentFileForRecompiling)
+ {
+ // Скоупы модулей, соответствующих watchedFiles
+ var compiledWatchedScopes = watchedFiles.Where(watchedFile => watchedFile.Key != currentFileForRecompiling)
+ .Select(watchedFile => CodeCompletion.CodeCompletionController.comp_modules[watchedFile.Key])
+ .SelectMany(converter => converter is CodeCompletion.DomConverter dc ?
+ new CodeCompletion.SymScope[] { dc.visitor.entry_scope, dc.visitor.impl_scope }
+ : Enumerable.Empty())
+ .Where(sc => sc != null);
+
+ var scopesToCheck = compiledWatchedScopes.Concat(candidateModulesToCheck).Distinct();
+
+ foreach (var scope in scopesToCheck)
+ {
+ string scopeFileName = scope.file_name;
+
+ if (scope is CodeCompletion.ImplementationUnitScope)
+ scopeFileName = ((CodeCompletion.SymScope)scope.TopScope).file_name;
+
+ if (scopeFileName == recompiledDependencyName)
+ continue;
+
+ var usedUnitsForUnit = scope.GetRealUsedUnitsTransitive();
+
+ // Если в зависимостях скоупа есть recompiledDependency
+ if (usedUnitsForUnit.FirstOrDefault(u => u.file_name == recompiledDependencyName) != null)
+ {
+ var unitOldConverter = CodeCompletion.CodeCompletionController.comp_modules[scopeFileName];
+
+ if (unitOldConverter != null)
+ {
+ // Помечаем для перекомпиляции
+ if (watchedFiles.ContainsKey(scopeFileName))
+ {
+ watchedFiles[scopeFileName] = true;
+ }
+ else
+ {
+ CodeCompletion.CodeCompletionController.comp_modules.Remove(scopeFileName);
+ }
+ }
+ }
+ }
+ }
+
public bool IsParsing()
{
return th != null && th.ThreadState == System.Threading.ThreadState.Running;
diff --git a/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs b/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs
index d2961ebe1..5e850f3a7 100644
--- a/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs
+++ b/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs
@@ -148,94 +148,58 @@ namespace VisualPascalABC
{
try
{
- Dictionary recomp_files = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ HashSet recomp_files = new HashSet(StringComparer.OrdinalIgnoreCase);
bool is_comp = false;
foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
{
-
+
if (filesToParse[FileName])
{
+ // Попытка компиляции была
+ filesToParse[FileName] = false;
+
is_comp = true;
- CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string;
if (string.IsNullOrEmpty(text))
text = "begin end.";
- 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;
- filesToParse[FileName] = false;
- if (dc.is_compiled)
+
+ if (CompileWatchedFile(FileName, text, true))
{
- //CodeCompletion.CodeCompletionController.comp_modules.Remove(file_name);
- if (tmp != null && tmp.visitor.entry_scope != null)
- {
- tmp.visitor.entry_scope.Clear();
- if (tmp.visitor.cur_scope != null)
- tmp.visitor.cur_scope.Clear();
- }
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
- recomp_files[FileName] = FileName;
- filesToParse[FileName] = false;
- if (ParseInformationUpdated != null)
- ParseInformationUpdated(dc.visitor.entry_scope, FileName);
+ // успешная компиляция
+ recomp_files.Add(FileName);
}
- else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
}
}
foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
{
CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
- CodeCompletion.SymScope ss = null;
+
if (dc != null)
{
- if (dc.visitor.entry_scope != null) ss = dc.visitor.entry_scope;
- else if (dc.visitor.impl_scope != null) ss = dc.visitor.impl_scope;
- int j = 0;
- while (j < 2)
+ CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope;
+ if (watchedUnitScope != null)
{
- if (j == 0)
+ var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive();
+
+ for (int i = 0; i < usedUnitsTransitive.Length; i++)
{
- ss = dc.visitor.entry_scope;
- j++;
- }
- else
- {
- ss = dc.visitor.impl_scope;
- j++;
- }
- if (ss != null)
- {
- for (int i = 0; i < ss.used_units.Count; i++)
+ string usedUnitFileName = usedUnitsTransitive[i].file_name;
+
+ // Если какая-то из зависимостей была перекомпилирована
+ if (recomp_files.Contains(usedUnitFileName))
{
- string s = ss.used_units[i].file_name;
- if (s != null && filesToParse.ContainsKey(s) && recomp_files.ContainsKey(s))
+ // Помечаем нужные модули для будущей перекомпиляции
+ InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName);
+
+ // Перекомпилируем текущий модуль
+ is_comp = true;
+ string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string;
+
+ // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA
+ if (CompileWatchedFile(FileName, text, false))
{
- is_comp = true;
- CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
- string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, 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;
- filesToParse[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;
- ss.used_units[i] = dc.visitor.entry_scope;
- if (ParseInformationUpdated != null)
- ParseInformationUpdated(dc.visitor.entry_scope, FileName);
- }
- else if (CodeCompletion.CodeCompletionController.comp_modules[FileName] == null)
- CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
+ // успешная компиляция
+ recomp_files.Add(FileName);
}
}
}
@@ -253,6 +217,86 @@ namespace VisualPascalABC
}
+ ///
+ /// Вызов компиляции (интеллисенсом) файла с именем fileName и содержимым fileText.
+ /// Возвращает true, если компиляция была успешна, false в противном случае.
+ ///
+ private bool CompileWatchedFile(string fileName, string fileText, bool clearOldScope)
+ {
+ bool success = false;
+
+ CodeCompletion.DomConverter tmp = CodeCompletion.CodeCompletionController.comp_modules[fileName] as CodeCompletion.DomConverter;
+ long cur_mem = Environment.WorkingSet;
+ CodeCompletion.CodeCompletionController controller = new CodeCompletion.CodeCompletionController();
+ CodeCompletion.DomConverter dc = controller.Compile(fileName, fileText);
+ mem_delta += Environment.WorkingSet - cur_mem;
+
+ if (dc.is_compiled)
+ {
+ if (clearOldScope && tmp != null)
+ {
+ tmp.visitor.entry_scope?.Clear();
+ tmp.visitor.cur_scope?.Clear();
+ }
+ CodeCompletion.CodeCompletionController.comp_modules[fileName] = dc;
+
+ success = true;
+ ParseInformationUpdated?.Invoke(dc.visitor.entry_scope, fileName);
+ }
+ else if (tmp == null)
+ CodeCompletion.CodeCompletionController.comp_modules[fileName] = dc;
+
+ return success;
+ }
+
+ ///
+ /// Помечает модули из candidateModulesToCheck и watchedFiles для будущей перекомпиляции, если они завивисимы от модуля с именем recompiledDependencyName
+ ///
+ private void InvalidateDependentModules(CodeCompletion.SymScope[] candidateModulesToCheck, string recompiledDependencyName, Dictionary watchedFiles, string currentFileForRecompiling)
+ {
+ // Скоупы модулей, соответствующих watchedFiles
+ var compiledWatchedScopes = watchedFiles.Where(watchedFile => watchedFile.Key != currentFileForRecompiling)
+ .Select(watchedFile => CodeCompletion.CodeCompletionController.comp_modules[watchedFile.Key])
+ .SelectMany(converter => converter is CodeCompletion.DomConverter dc ?
+ new CodeCompletion.SymScope[] { dc.visitor.entry_scope, dc.visitor.impl_scope }
+ : Enumerable.Empty())
+ .Where(sc => sc != null);
+
+ var scopesToCheck = compiledWatchedScopes.Concat(candidateModulesToCheck).Distinct();
+
+ foreach (var scope in scopesToCheck)
+ {
+ string scopeFileName = scope.file_name;
+
+ if (scope is CodeCompletion.ImplementationUnitScope)
+ scopeFileName = ((CodeCompletion.SymScope)scope.TopScope).file_name;
+
+ if (scopeFileName == recompiledDependencyName)
+ continue;
+
+ var usedUnitsForUnit = scope.GetRealUsedUnitsTransitive();
+
+ // Если в зависимостях скоупа есть recompiledDependency
+ if (usedUnitsForUnit.FirstOrDefault(u => u.file_name == recompiledDependencyName) != null)
+ {
+ var unitOldConverter = CodeCompletion.CodeCompletionController.comp_modules[scopeFileName];
+
+ if (unitOldConverter != null)
+ {
+ // Помечаем для перекомпиляции
+ if (watchedFiles.ContainsKey(scopeFileName))
+ {
+ watchedFiles[scopeFileName] = true;
+ }
+ else
+ {
+ CodeCompletion.CodeCompletionController.comp_modules.Remove(scopeFileName);
+ }
+ }
+ }
+ }
+ }
+
public bool IsParsing()
{
return th != null && th.ThreadState == System.Threading.ThreadState.Running;