Refactoring of preparing user namespaces and checking for RTL errors methods (#2993)

* Refactor PrepareUserNamespaces method

* Rename CheckForRTLErrors method

* Delete outdated TODO's
This commit is contained in:
AlexanderZemlyak 2024-02-16 23:15:00 +03:00 committed by GitHub
parent eace530ed4
commit 6027083bcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -795,8 +795,7 @@ namespace PascalABCCompiler
{
if (RevisionClass.Build == "0")
return RevisionClass.MainVersion;
else
// TODO: Недостижимый код | EVA
else
return RevisionClass.MainVersion + "." + RevisionClass.Build;
}
}
@ -2229,7 +2228,7 @@ namespace PascalABCCompiler
if (ErrorsList.Count == 0)
{
//TODO: Разобратся c location для program_node и правильно передавать main_function. Добавить генератор main_function в SyntaxTreeToSemanticTreeConverter. | Думать позже EVA
//TODO: Разобратся c location для program_node и правильно передавать main_function. Добавить генератор main_function в SyntaxTreeToSemanticTreeConverter. | Отложено на потом EVA
// получние полного семантического дерева, включающего все зависимости
program_node semanticTree = ConstructMainSemanticTree(compilerOptions);
@ -2280,10 +2279,10 @@ namespace PascalABCCompiler
ErrorsList.Add(new CompilerInternalError("Compiler.ClosePCUReadersAndWriters", e));
}
// на случай ошибки в самом .pcu формате (имеются в виду ошибки, связанные с невозможностью использования RTL)
bool recompilationNeeded = CheckForRTLErrors();
// если есть семантические ошибки в RTL, то очистить ошибки и повторно перекомпилировать без RTL
bool recompilationNeeded = CheckForRTLErrorsAndClearAllErrorsIfFound();
OnChangeCompilerState(this, CompilerState.CompilationFinished, CompilerOptions.SourceFileName); // compilation finished state
OnChangeCompilerState(this, CompilerState.CompilationFinished, CompilerOptions.SourceFileName); // compilation finished state
if (ClearAfterCompilation)
ClearAll();
@ -2465,7 +2464,7 @@ namespace PascalABCCompiler
}
private bool CheckForRTLErrors()
private bool CheckForRTLErrorsAndClearAllErrorsIfFound()
{
bool anyRTLErrors = false;
@ -3061,7 +3060,7 @@ namespace PascalABCCompiler
unitToAdd = new SyntaxTree.uses_unit_in(
new SyntaxTree.ident_list(new SyntaxTree.ident(moduleName)),
new SyntaxTree.string_const(module.Name));
//uses_unit_in.source_context = uses_unit_in.in_file.source_context = uses_unit_in.name.source_context = new SyntaxTree.SourceContext(1, 1, 1, 1); Вопрос EVA
//uses_unit_in.source_context = uses_unit_in.in_file.source_context = uses_unit_in.name.source_context = new SyntaxTree.SourceContext(1, 1, 1, 1);
}
else
{
@ -3169,38 +3168,38 @@ namespace PascalABCCompiler
AddDeclarationsAndReferencedUnitsToNamespaces(namespaceModules, file, unitModule, namespaceNode);
}
// TODO: выделить в другой метод
// корневой модуль является чем-то одним из этого
SyntaxTree.unit_module mainLibrary = compilationUnit.SyntaxTree as SyntaxTree.unit_module;
SyntaxTree.program_module main_program = compilationUnit.SyntaxTree as SyntaxTree.program_module;
SyntaxTree.program_module mainProgram = compilationUnit.SyntaxTree as SyntaxTree.program_module;
foreach (string s in namespaces.Keys)
{
if (mainLibrary != null)
mainLibrary.interface_part.interface_definitions.Insert(0, namespaces[s]);
else
main_program.program_block.defs.Insert(0, namespaces[s]);
}
AddNamespacesToMainDefinitions(mainLibrary, mainProgram, namespaces);
SyntaxTree.uses_list mainUsesList = GetMainUsesList(mainLibrary, main_program, namespaceModules);
AddNamespacesToMainUsesList(mainLibrary, mainProgram, namespaceModules);
if (mainLibrary != null)
mainLibrary.interface_part.uses_modules = mainUsesList;
else
main_program.used_units = mainUsesList;
return namespaces;
}
private static SyntaxTree.uses_list GetMainUsesList(SyntaxTree.unit_module mainLibrary, SyntaxTree.program_module main_program, List<SyntaxTree.unit_or_namespace> namespaceModules)
private void AddNamespacesToMainDefinitions(SyntaxTree.unit_module mainLibrary, SyntaxTree.program_module main_program, Dictionary<string, SyntaxTree.syntax_namespace_node> namespaces)
{
SyntaxTree.uses_list mainUsesList = null;
if (mainLibrary != null)
foreach (string moduleName in namespaces.Keys)
{
if (mainLibrary.interface_part.uses_modules != null)
mainUsesList = mainLibrary.interface_part.uses_modules;
if (mainLibrary != null)
mainLibrary.interface_part.interface_definitions.Insert(0, namespaces[moduleName]);
else
main_program.program_block.defs.Insert(0, namespaces[moduleName]);
}
else if (main_program.used_units != null)
}
private void AddNamespacesToMainUsesList(SyntaxTree.unit_module mainLibrary, SyntaxTree.program_module main_program, List<SyntaxTree.unit_or_namespace> namespaceModules)
{
SyntaxTree.uses_list mainUsesList;
if (mainLibrary != null)
mainUsesList = mainLibrary.interface_part.uses_modules;
else
mainUsesList = main_program.used_units;
if (mainUsesList == null)
mainUsesList = new SyntaxTree.uses_list();
@ -3215,7 +3214,10 @@ namespace PascalABCCompiler
}
}
return mainUsesList;
if (mainLibrary != null)
mainLibrary.interface_part.uses_modules = mainUsesList;
else
main_program.used_units = mainUsesList;
}
private void AddDeclarationsAndReferencedUnitsToNamespaces(List<SyntaxTree.unit_or_namespace> namespace_modules, string file,
@ -3439,12 +3441,12 @@ namespace PascalABCCompiler
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
// оставить только PT4 и протестировать
// если в программе используются эти модули, то RTL не используется
string[] standardFilesExcludedFromRTL = new string[] { "PT4", "School", "CRT", "Arrays", "MPI", "Collections", "Core"};
bool includeInRTL = standardFilesExcludedFromRTL.All(file => !file.Equals(fileNameWithoutExtension, StringComparison.CurrentCultureIgnoreCase));
// если это исходный файл из папки Lib (стандартные паскалевские библиотеки)
// если это исходный файл из папки Lib (стандартные паскалевские модули)
if (CompilerOptions.UseDllForSystemUnits
&& Path.GetDirectoryName(fileName).Equals(Path.Combine(CompilerOptions.SystemDirectory, "Lib"), StringComparison.CurrentCultureIgnoreCase)
&& includeInRTL)
@ -3750,7 +3752,7 @@ namespace PascalABCCompiler
references = GetReferences(currentUnit);
// TODO: закончить рефакторинг | Вопрос, как мы будем подключать про-ва имен из других языков EVA
// Надо подумать, как мы будем подключать про-ва имен из других языков EVA
namespaces = PrepareUserNamespacesUsedInTheCurrentUnit(currentUnit);
}
@ -3951,7 +3953,8 @@ namespace PascalABCCompiler
{
// если сначала взяли pcu а потом решили его перекомпилировать, поэтому в таблице его нет
if (UnitTable[transitivelyUsedUnit] == null)
UnitTable[usedUnitId].currentUsedUnitId = transitivelyUsedUnit; // Вопрос EVA
UnitTable[usedUnitId].currentUsedUnitId = transitivelyUsedUnit;
// если "используемый используемого" (транзитивно зависимый) модуль находится в том же состоянии, что и просто используемый, то это означает циклическую зависимость
if (UnitTable[usedUnitId].currentUsedUnitId != null && UnitTable[UnitTable[usedUnitId].currentUsedUnitId].State == UnitState.BeginCompilation)
throw new CycleUnitReference(unitFileName, usedUnitNode);
@ -4021,9 +4024,8 @@ namespace PascalABCCompiler
SemanticCheckNoIncludeDirectivesInPascalUnit(currentUnit);
#endregion
// Set output file type for dll
if (isDll)
CompilerOptions.OutputFileType = CompilerOptions.OutputType.ClassLibrary; // Вопрос, нужно ли это здесь, если это есть в Compile в конце EVA
CompilerOptions.OutputFileType = CompilerOptions.OutputType.ClassLibrary; // есть также в конце Compile
if (ParsersController.LastParser != null)
currentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive;