доделал явную реализацию generic-интерфейсов
This commit is contained in:
parent
893e4d9d16
commit
7a5d113c77
14
TestSuite/interface3.pas
Normal file
14
TestSuite/interface3.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
type TClass<T> = class(IEnumerable<T>)
|
||||
public function System.Collections.Generic.IEnumerable<T>.GetEnumerator: IEnumerator<T>;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
public function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator;
|
||||
begin
|
||||
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
|
||||
end.
|
||||
30
TestSuite/interface4.pas
Normal file
30
TestSuite/interface4.pas
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
type
|
||||
IEnr = System.Collections.IEnumerator;
|
||||
IEnb = System.Collections.IEnumerable;
|
||||
|
||||
var a : integer;
|
||||
type My = class(IEnumerable<integer>)
|
||||
public
|
||||
function IEnb.GetEnumerator(): IEnr;
|
||||
begin
|
||||
a := 1;
|
||||
end;
|
||||
function System.Collections.Generic.IEnumerable<integer>.GetEnumerator(): IEnumerator<integer>;
|
||||
begin
|
||||
a := 2;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
var ien: IEnb := new My;
|
||||
ien.GetEnumerator;
|
||||
assert(a=1);
|
||||
var ien2: IEnumerable<integer> := new My;
|
||||
ien2.GetEnumerator;
|
||||
assert(a=2);
|
||||
a := 0;
|
||||
var mc := new My;
|
||||
mc.GetEnumerator();
|
||||
assert(a=2);
|
||||
end.
|
||||
|
|
@ -917,7 +917,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
while (si != null)
|
||||
{
|
||||
compar = si.sym_info as function_node;
|
||||
if (fn != compar && convertion_data_and_alghoritms.function_eq_params(fn, compar, false))
|
||||
if (fn != compar && convertion_data_and_alghoritms.function_eq_params(fn, compar))
|
||||
//if (fn is common_namespace_function_node && compar is common_namespace_function_node && (fn as common_namespace_function_node).comprehensive_namespace == (compar as common_namespace_function_node).comprehensive_namespace)
|
||||
|
||||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
|
|
@ -2760,7 +2760,7 @@ _cmn.types.AddElement(tctn);*/
|
|||
{
|
||||
fn = si.sym_info as function_node;
|
||||
//Сверяем параметры и тип возвращаемого значения
|
||||
if (convertion_data_and_alghoritms.function_eq_params_and_result(meth, fn) && fn.polymorphic_state != SemanticTree.polymorphic_state.ps_virtual_abstract)
|
||||
if (convertion_data_and_alghoritms.function_eq_params_and_result(meth, fn, true) && fn.polymorphic_state != SemanticTree.polymorphic_state.ps_virtual_abstract)
|
||||
{
|
||||
//Нашли нужную функцию
|
||||
common_method_node fn_common = fn as common_method_node;
|
||||
|
|
|
|||
|
|
@ -1467,9 +1467,9 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
|
||||
//Этот метод сверяет не только параметры, но и возвращаемое значение
|
||||
public static bool function_eq_params_and_result(function_node left, function_node right)
|
||||
public static bool function_eq_params_and_result(function_node left, function_node right, bool weak=false)
|
||||
{
|
||||
if (!function_eq_params(left, right))
|
||||
if (!function_eq_params(left, right, weak))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1482,18 +1482,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
//Сравниваем типы-параметры generic-функций
|
||||
public static bool function_eq_generic_params(function_node left, function_node right)
|
||||
{
|
||||
common_function_node cleft = left as common_function_node;
|
||||
common_function_node cright = right as common_function_node;
|
||||
List<ICommonTypeNode> left_type_params = null;
|
||||
List<ICommonTypeNode> right_type_params = null;
|
||||
if (cleft != null)
|
||||
{
|
||||
left_type_params = cleft.generic_params;
|
||||
}
|
||||
if (cright != null)
|
||||
{
|
||||
right_type_params = cright.generic_params;
|
||||
}
|
||||
List<type_node> left_type_params = left.get_generic_params_list();
|
||||
List<type_node> right_type_params = right.get_generic_params_list();
|
||||
if (left_type_params == null && right_type_params == null)
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -9100,12 +9100,6 @@ namespace PascalABCCompiler.TreeConverter
|
|||
common_type_node tp = null;
|
||||
definition_node def_temp = null;
|
||||
SyntaxTree.template_type_name ttn = null;
|
||||
/*SyntaxTree.operator_name_ident on = _method_name as SyntaxTree.operator_name;
|
||||
if (on != null)
|
||||
{
|
||||
_method_name.meth_name = new SyntaxTree.ident(name_reflector.get_name(on.operator_type.type));
|
||||
}
|
||||
*/
|
||||
bool is_operator = _method_name.meth_name is SyntaxTree.operator_name_ident;
|
||||
SyntaxTree.Operators op = PascalABCCompiler.SyntaxTree.Operators.Undefined;
|
||||
if(is_operator)
|
||||
|
|
@ -9114,8 +9108,6 @@ namespace PascalABCCompiler.TreeConverter
|
|||
bool explicit_impl = false;
|
||||
if ((context.converting_block() != block_type.namespace_block) && (_method_name.class_name != null))
|
||||
{
|
||||
/*AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name,
|
||||
get_location(_method_name.class_name)));*/
|
||||
explicit_impl = true;
|
||||
}
|
||||
if (is_operator && op==SyntaxTree.Operators.AddressOf && SemanticRules.AddressOfOperatorNonOverloaded)
|
||||
|
|
@ -9245,12 +9237,6 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
else if (def_temp as compiled_type_node == SystemLibrary.SystemLibrary.void_type)
|
||||
AddError(get_location(_method_name.class_name), "VOID_NOT_VALID");
|
||||
//else if ((def_temp as compiled_type_node).IsInterface)
|
||||
// AddError(new ExtensionMethodForInterfaceNotAllowed(get_location(_method_name.class_name)));
|
||||
//else
|
||||
//{
|
||||
// throw new CanNotDefineMethodOfCompiledType(get_location(_method_name));
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -9292,7 +9278,38 @@ namespace PascalABCCompiler.TreeConverter
|
|||
context.top_function.IsOperator = is_operator;
|
||||
if (ttn != null && def_temp is compiled_type_node)
|
||||
{
|
||||
visit_generic_params(context.top_function, ttn.template_args.idents);
|
||||
if (!explicit_impl)
|
||||
visit_generic_params(context.top_function, ttn.template_args.idents);
|
||||
else
|
||||
{
|
||||
List<type_node> instance_params = new List<type_node>();
|
||||
foreach (ident id in ttn.template_args.idents)
|
||||
{
|
||||
SymbolInfo si = context.find(id.name);
|
||||
if (si == null)
|
||||
AddError(new UndefinedNameReference(id.name, get_location(id)));
|
||||
if (!(si.sym_info is type_node))
|
||||
AddError(new ExpectedType(get_location(id)));
|
||||
instance_params.Add(si.sym_info as type_node);
|
||||
}
|
||||
if (!context.converted_explicit_interface_type.IsInterface)
|
||||
AddError(get_location(ttn), "INTERFACE_EXPECTED");
|
||||
type_node inst_tn = context.converted_explicit_interface_type.get_instance(instance_params);
|
||||
bool found = false;
|
||||
if (context.converted_type.ImplementingInterfaces.Count > 0)
|
||||
{
|
||||
foreach (type_node interf in context.converted_type.ImplementingInterfaces)
|
||||
{
|
||||
if (interf == inst_tn)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
AddError(get_location(ttn),"CLASS_NOT_IMPLEMENT_THIS_INTERFACE");
|
||||
}
|
||||
}
|
||||
//context.top_function.IsOperator = _method_name.meth_name is SyntaxTree.operator_name_ident;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ CANNOT_EVALUATE_FUNCTION_TYPE=Cannot infer the return type of function
|
|||
TYPE_NAME_EXPECTED=Type name expected
|
||||
EXPLICIT_IMPLEMENTATION_EXPECTED=Method implementation expected
|
||||
ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS=Anonymous delegates can not use generic parameters
|
||||
CLASS_NOT_IMPLEMENT_THIS_INTERFACE=Class doesn't implement this interface
|
||||
INTERFACE_EXPECTED=Interface expected
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
|
||||
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ CANNOT_EVALUATE_FUNCTION_TYPE=Невозможно вывести тип фун
|
|||
TYPE_NAME_EXPECTED=Ожидался тип
|
||||
EXPLICIT_IMPLEMENTATION_EXPECTED=Метод, явно реализующий интерфейс, должен быть реализован в определении класса
|
||||
ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS=Недопустимо описание анонимных делегатов, использующих generic-параметры
|
||||
CLASS_NOT_IMPLEMENT_THIS_INTERFACE=Класс не реализует данный интерфейс
|
||||
INTERFACE_EXPECTED=Ожидался интерфейс
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
|
||||
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue