diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index 1670bca0c..e6577ccd1 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -542,47 +542,41 @@ namespace CodeCompletion /// public SymScope[] GetRealUsedUnitsTransitive(bool includeImplementationDependenciesForUnit = true) { - var usedUnits = new List(); + var unitsList = new List(); - if (used_units != null) - { - usedUnits.AddRange(used_units.Where(unit => unit.file_name != null)); - } + HashSet visited = new HashSet(); - if (this is InterfaceUnitScope interfaceScope && includeImplementationDependenciesForUnit && interfaceScope.impl_scope != null) + void CollectUnitsHelper(SymScope currentScope) { - foreach (var recursiveUsedUnit in interfaceScope.impl_scope.GetRealUsedUnitsTransitive(true)) + IEnumerable usedUnitsLocal = currentScope.used_units?.Where(unit => unit.file_name != null); + + foreach (var unit in usedUnitsLocal) { - if (recursiveUsedUnit == this) - continue; + if (unitsList.Find(u => u.file_name == unit.file_name) == null) + unitsList.Add(unit); + } - if (usedUnits.FirstOrDefault(unit => unit.file_name == recursiveUsedUnit.file_name) == null) + if (currentScope is InterfaceUnitScope interfaceScope && includeImplementationDependenciesForUnit && interfaceScope.impl_scope != null) + { + CollectUnitsHelper(interfaceScope.impl_scope); + } + + foreach (var unit in usedUnitsLocal) + { + if (!visited.Contains(unit)) { - usedUnits.Add(recursiveUsedUnit); + visited.Add(unit); + CollectUnitsHelper(unit); } } } - if (used_units != null) - { - foreach (var usedUnit in used_units) - { - var recursiveUsedUnits = usedUnit.GetRealUsedUnitsTransitive(includeImplementationDependenciesForUnit); + visited.Add(this); + CollectUnitsHelper(this); - foreach (var recursiveUsedUnit in recursiveUsedUnits) - { - if (recursiveUsedUnit == this) - continue; + unitsList.Remove(this); - if (usedUnits.FirstOrDefault(unit => unit.file_name == recursiveUsedUnit.file_name) == null) - { - usedUnits.Add(recursiveUsedUnit); - } - } - } - } - - return usedUnits.ToArray(); + return unitsList.ToArray(); } public virtual string GetFullName() diff --git a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs index 48d1a3b2b..31fb69047 100644 --- a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs +++ b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionParserController.cs @@ -165,42 +165,46 @@ namespace VisualPascalABC } } } - foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA + if (recomp_files.Count > 0) { - CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter; - - if (dc != null) + foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA { - CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope; - if (watchedUnitScope != null) + CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter; + + if (dc != null) { - var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive(); - - for (int i = 0; i < usedUnitsTransitive.Length; i++) + CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope; + if (watchedUnitScope != null) { - string usedUnitFileName = usedUnitsTransitive[i].file_name; - - // Если какая-то из зависимостей была перекомпилирована - if (recomp_files.Contains(usedUnitFileName)) + var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive(); + + for (int i = 0; i < usedUnitsTransitive.Length; i++) { - // Помечаем нужные модули для будущей перекомпиляции - InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName); + string usedUnitFileName = usedUnitsTransitive[i].file_name; - // Перекомпилируем текущий модуль - is_comp = true; - string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string; - - // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA - if (CompileWatchedFile(FileName, text, false)) + // Если какая-то из зависимостей была перекомпилирована + if (recomp_files.Contains(usedUnitFileName)) { - // успешная компиляция - recomp_files.Add(FileName); + // Помечаем нужные модули для будущей перекомпиляции + InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName); + + // Перекомпилируем текущий модуль + is_comp = true; + string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string; + + // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA + if (CompileWatchedFile(FileName, text, false)) + { + // успешная компиляция + recomp_files.Add(FileName); + } } } } } } } + if (is_comp && mem_delta > 20000000 /*&& mem_delta > 10000000*/) //postavil delta dlja pamjati, posle kototoj delaetsja sborka musora { diff --git a/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs b/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs index 5e850f3a7..631eadfd8 100644 --- a/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs +++ b/VisualPascalABCNETLinux/IB/CodeCompletion/CodeCompletionParserController.cs @@ -170,36 +170,39 @@ namespace VisualPascalABC } } } - foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA + if (recomp_files.Count > 0) { - CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter; - - if (dc != null) + foreach (string FileName in filesToParse.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA { - CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope; - if (watchedUnitScope != null) + CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter; + + if (dc != null) { - var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive(); - - for (int i = 0; i < usedUnitsTransitive.Length; i++) + CodeCompletion.SymScope watchedUnitScope = dc.visitor.entry_scope; + if (watchedUnitScope != null) { - string usedUnitFileName = usedUnitsTransitive[i].file_name; + var usedUnitsTransitive = watchedUnitScope.GetRealUsedUnitsTransitive(); - // Если какая-то из зависимостей была перекомпилирована - if (recomp_files.Contains(usedUnitFileName)) + for (int i = 0; i < usedUnitsTransitive.Length; i++) { - // Помечаем нужные модули для будущей перекомпиляции - InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName); + string usedUnitFileName = usedUnitsTransitive[i].file_name; - // Перекомпилируем текущий модуль - is_comp = true; - string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string; - - // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA - if (CompileWatchedFile(FileName, text, false)) + // Если какая-то из зависимостей была перекомпилирована + if (recomp_files.Contains(usedUnitFileName)) { - // успешная компиляция - recomp_files.Add(FileName); + // Помечаем нужные модули для будущей перекомпиляции + InvalidateDependentModules(usedUnitsTransitive, usedUnitFileName, filesToParse, FileName); + + // Перекомпилируем текущий модуль + is_comp = true; + string text = visualEnvironmentCompiler.SourceFilesProvider(FileName, SourceFileOperation.GetText) as string; + + // Здесь третий параметр false, потому что старые данные компиляции еще могут пригодиться до новой перекомпиляции EVA + if (CompileWatchedFile(FileName, text, false)) + { + // успешная компиляция + recomp_files.Add(FileName); + } } } }