Исправление перекомпиляции в Intellisense, если транзитивные зависимости были перекомпилированы (#3414)
* 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
This commit is contained in:
parent
97eb1132bb
commit
67060ad9ea
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -536,6 +536,55 @@ namespace CodeCompletion
|
|||
used_units.Add(unit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить массив всех транзитивно используемых модулей (ислючая пр-ва имен).
|
||||
/// По умолчанию для InterfaceUnitScope ищутся и зависимости реализации тоже.
|
||||
/// </summary>
|
||||
public SymScope[] GetRealUsedUnitsTransitive(bool includeImplementationDependenciesForUnit = true)
|
||||
{
|
||||
var usedUnits = new List<SymScope>();
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -143,94 +143,58 @@ namespace VisualPascalABC
|
|||
{
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> recomp_files = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
HashSet<string> recomp_files = new HashSet<string>(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
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вызов компиляции (интеллисенсом) файла с именем fileName и содержимым fileText.
|
||||
/// Возвращает true, если компиляция была успешна, false в противном случае.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Помечает модули из candidateModulesToCheck и watchedFiles для будущей перекомпиляции, если они завивисимы от модуля с именем recompiledDependencyName
|
||||
/// </summary>
|
||||
private void InvalidateDependentModules(CodeCompletion.SymScope[] candidateModulesToCheck, string recompiledDependencyName, Dictionary<string, bool> 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<CodeCompletion.SymScope>())
|
||||
.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;
|
||||
|
|
|
|||
|
|
@ -148,94 +148,58 @@ namespace VisualPascalABC
|
|||
{
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> recomp_files = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
HashSet<string> recomp_files = new HashSet<string>(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
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вызов компиляции (интеллисенсом) файла с именем fileName и содержимым fileText.
|
||||
/// Возвращает true, если компиляция была успешна, false в противном случае.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Помечает модули из candidateModulesToCheck и watchedFiles для будущей перекомпиляции, если они завивисимы от модуля с именем recompiledDependencyName
|
||||
/// </summary>
|
||||
private void InvalidateDependentModules(CodeCompletion.SymScope[] candidateModulesToCheck, string recompiledDependencyName, Dictionary<string, bool> 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<CodeCompletion.SymScope>())
|
||||
.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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue