доделал явную реализацию 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)
|
while (si != null)
|
||||||
{
|
{
|
||||||
compar = si.sym_info as function_node;
|
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)
|
//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));
|
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||||
|
|
@ -2760,7 +2760,7 @@ _cmn.types.AddElement(tctn);*/
|
||||||
{
|
{
|
||||||
fn = si.sym_info as function_node;
|
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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1482,18 +1482,8 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
//Сравниваем типы-параметры generic-функций
|
//Сравниваем типы-параметры generic-функций
|
||||||
public static bool function_eq_generic_params(function_node left, function_node right)
|
public static bool function_eq_generic_params(function_node left, function_node right)
|
||||||
{
|
{
|
||||||
common_function_node cleft = left as common_function_node;
|
List<type_node> left_type_params = left.get_generic_params_list();
|
||||||
common_function_node cright = right as common_function_node;
|
List<type_node> right_type_params = right.get_generic_params_list();
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (left_type_params == null && right_type_params == null)
|
if (left_type_params == null && right_type_params == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -9100,12 +9100,6 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
common_type_node tp = null;
|
common_type_node tp = null;
|
||||||
definition_node def_temp = null;
|
definition_node def_temp = null;
|
||||||
SyntaxTree.template_type_name ttn = 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;
|
bool is_operator = _method_name.meth_name is SyntaxTree.operator_name_ident;
|
||||||
SyntaxTree.Operators op = PascalABCCompiler.SyntaxTree.Operators.Undefined;
|
SyntaxTree.Operators op = PascalABCCompiler.SyntaxTree.Operators.Undefined;
|
||||||
if(is_operator)
|
if(is_operator)
|
||||||
|
|
@ -9114,8 +9108,6 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
bool explicit_impl = false;
|
bool explicit_impl = false;
|
||||||
if ((context.converting_block() != block_type.namespace_block) && (_method_name.class_name != null))
|
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;
|
explicit_impl = true;
|
||||||
}
|
}
|
||||||
if (is_operator && op==SyntaxTree.Operators.AddressOf && SemanticRules.AddressOfOperatorNonOverloaded)
|
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)
|
else if (def_temp as compiled_type_node == SystemLibrary.SystemLibrary.void_type)
|
||||||
AddError(get_location(_method_name.class_name), "VOID_NOT_VALID");
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -9292,7 +9278,38 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
context.top_function.IsOperator = is_operator;
|
context.top_function.IsOperator = is_operator;
|
||||||
if (ttn != null && def_temp is compiled_type_node)
|
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;
|
//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
|
TYPE_NAME_EXPECTED=Type name expected
|
||||||
EXPLICIT_IMPLEMENTATION_EXPECTED=Method implementation expected
|
EXPLICIT_IMPLEMENTATION_EXPECTED=Method implementation expected
|
||||||
ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS=Anonymous delegates can not use generic parameters
|
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_
|
%PREFIX%=COMPILATIONERROR_
|
||||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
|
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
|
||||||
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'
|
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,8 @@ CANNOT_EVALUATE_FUNCTION_TYPE=Невозможно вывести тип фун
|
||||||
TYPE_NAME_EXPECTED=Ожидался тип
|
TYPE_NAME_EXPECTED=Ожидался тип
|
||||||
EXPLICIT_IMPLEMENTATION_EXPECTED=Метод, явно реализующий интерфейс, должен быть реализован в определении класса
|
EXPLICIT_IMPLEMENTATION_EXPECTED=Метод, явно реализующий интерфейс, должен быть реализован в определении класса
|
||||||
ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS=Недопустимо описание анонимных делегатов, использующих generic-параметры
|
ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS=Недопустимо описание анонимных делегатов, использующих generic-параметры
|
||||||
|
CLASS_NOT_IMPLEMENT_THIS_INTERFACE=Класс не реализует данный интерфейс
|
||||||
|
INTERFACE_EXPECTED=Ожидался интерфейс
|
||||||
%PREFIX%=COMPILATIONERROR_
|
%PREFIX%=COMPILATIONERROR_
|
||||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
|
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
|
||||||
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'
|
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue