From e0d6e0c1bfcfa26e4cf7d61cf1851daa1d6ce9d3 Mon Sep 17 00:00:00 2001 From: samuraiGH <87191377+samuraiGH@users.noreply.github.com> Date: Fri, 12 Jun 2026 20:18:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A7=D0=B0=D1=81=D1=82=D0=B8=D1=87=D0=BD?= =?UTF-8?q?=D0=BE=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=80=D0=B0=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BA=20=D1=87=D0=BB=D0=B5=D0=BD=D0=B0=D0=BC=20?= =?UTF-8?q?generic=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=B0=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BD=D1=83=D1=82=D1=80=D0=B8=20=D1=8D=D1=82=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=B0=20(#3430)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * partial fix for accessing generic members * more comments --- .../SyntaxTreeVisitorNodes/Assign.cs | 20 ++++++++++++++++-- .../TreeConversion/compilation_context.cs | 21 ++++++++++++++----- .../TreeConversion/syntax_tree_visitor.cs | 13 +++++++++++- TreeConverter/TreeRealization/generics.cs | 6 ++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs index 7d78df00d..daf823ef5 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs @@ -2,7 +2,6 @@ using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SystemLibrary; using PascalABCCompiler.TreeRealization; -using SymTable = SymbolTable; namespace PascalABCCompiler.TreeConverter { @@ -264,7 +263,15 @@ namespace PascalABCCompiler.TreeConverter // SSM 1.11.18 попытка правки возвращения процедуры в yield //if (from.type.semantic_node_type == semantic_node_type.delegated_method) //cfr.type.semantic_node_type = semantic_node_type.delegated_method; + + // восстанавливаем тип и в generic definition тоже + if (cfr.field.cont_type.is_generic_type_instance) + { + var genericInstance = (generic_instance_type_node)cfr.field.cont_type; + var fieldDefinition = (class_field)genericInstance.get_member_definition(cfr.field); + fieldDefinition.type = from.type; + } cfr.field.inital_value = context.GetInitalValueForVariable(cfr.field, cfr.field.inital_value); } @@ -273,7 +280,7 @@ namespace PascalABCCompiler.TreeConverter var lvr = to as local_block_variable_reference; lvr.var.type = from.type; lvr.type = from.type; - lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value); + lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value); } else AddError(to.location, "Не могу вывести тип при наличии yield: " + to.type.full_name); //to.type = from.type; // и без всякого real_type! @@ -295,6 +302,15 @@ namespace PascalABCCompiler.TreeConverter cfr.field.type = convert_strong(IEnumType); cfr.type = cfr.field.type; + + // восстанавливаем тип и в generic definition тоже + if (cfr.field.cont_type.is_generic_type_instance) + { + var genericInstance = (generic_instance_type_node)cfr.field.cont_type; + var fieldDefinition = (class_field)genericInstance.get_member_definition(cfr.field); + + fieldDefinition.type = cfr.field.type; + } } else if (to is local_block_variable_reference) { diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index 6d6f72782..ce8ae0663 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -1,12 +1,12 @@ // Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) //Класс, хранящий текущий контекст. Где находится компилятор (в какой функции, типе, пространстве имен). -using System; -using System.Linq; -using PascalABCCompiler.TreeRealization; -using System.Collections.Generic; -using System.Collections; using PascalABCCompiler.CoreUtils; +using PascalABCCompiler.TreeRealization; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; namespace PascalABCCompiler.TreeConverter { @@ -2314,6 +2314,17 @@ namespace PascalABCCompiler.TreeConverter { return _ctn.base_generic_instance.ConvertSymbolInfo(sil); } + + // необходимо для создания корректных обращений к членам generic типа изнутри этого типа + // подробнее #3430 + if (_ctn != null && _ctn.is_generic_type_definition && top_function != null) + { + var selfType = (generic_instance_type_node)_ctn + .get_instance( _ctn.generic_params.Cast().ToList() ); + + return selfType.ConvertSymbolInfo(sil); + } + return sil; } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 3c8d1009c..a3fe1ca69 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -18418,7 +18418,18 @@ namespace PascalABCCompiler.TreeConverter { if ((left as static_event_reference).en is compiled_event) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); - if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type && !context.converted_type.name.Contains("<>local_variables_class")) + + type_node eventContainingType = ((left as static_event_reference).en as common_event).cont_type; + + // context.converted_type содержит generic definition, если это generic тип + // поэтому берём original_generic при необходимости + if (eventContainingType.is_generic_type_instance) + eventContainingType = eventContainingType.original_generic; + + if (context.converted_type != null + && context.converted_type != eventContainingType + && !context.converted_type.name.Contains("<>local_variables_class") + ) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); } else if (right is static_event_reference) diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 3bfef5fbd..29ad1b4e2 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -1901,6 +1901,12 @@ namespace PascalABCCompiler.TreeRealization orig_event.is_static ? SemanticTree.polymorphic_state.ps_static : SemanticTree.polymorphic_state.ps_common, loc ); + + if (orig_event is common_event commonEvent) + { + evnt.field = (class_field)ConvertMember(commonEvent.field); + } + return evnt; }