Частичное исправление обращения к членам generic класса изнутри этого класса (#3430)
* partial fix for accessing generic members * more comments
This commit is contained in:
parent
9b9f0fde5a
commit
e0d6e0c1bf
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue