Частичное исправление обращения к членам generic класса изнутри этого класса (#3430)

* partial fix for accessing generic members

* more comments
This commit is contained in:
samuraiGH 2026-06-12 20:18:22 +03:00 committed by GitHub
parent 9b9f0fde5a
commit e0d6e0c1bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 8 deletions

View file

@ -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)
{

View file

@ -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<type_node>().ToList() );
return selfType.ConvertSymbolInfo(sil);
}
return sil;
}

View file

@ -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)

View file

@ -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;
}