diff --git a/Compiler/Compiler.cs b/Compiler/Compiler.cs index a8401cc5b..753b57739 100644 --- a/Compiler/Compiler.cs +++ b/Compiler/Compiler.cs @@ -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 namespaceModules) + private void AddNamespacesToMainDefinitions(SyntaxTree.unit_module mainLibrary, SyntaxTree.program_module main_program, Dictionary 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 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 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;