This commit is contained in:
parent
debd0ddee6
commit
c3da960cbf
11
TestSuite/errors/err0394.pas
Normal file
11
TestSuite/errors/err0394.pas
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
type
|
||||
t1 = class
|
||||
|
||||
static procedure operator+=(a: t1; d: System.Action<integer>) := exit;
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
var a := new t1;
|
||||
a += ()->Writeln(1);
|
||||
end.
|
||||
18
TestSuite/lambdas11.pas
Normal file
18
TestSuite/lambdas11.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
type
|
||||
t1 = class
|
||||
l: List<Action0> := new List<Action0>;
|
||||
static procedure operator+=(a: t1; d: Action0);
|
||||
begin
|
||||
a.l.Add(d);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
var i: integer;
|
||||
|
||||
begin
|
||||
var a := new t1;
|
||||
a += ()->Inc(i);
|
||||
a.l[0]();
|
||||
assert(i = 1);
|
||||
end.
|
||||
8
TestSuite/lambdas12.pas
Normal file
8
TestSuite/lambdas12.pas
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
var i: integer;
|
||||
|
||||
begin
|
||||
var l := new List<Action0>;
|
||||
l += ()->Inc(i);
|
||||
l[0]();
|
||||
assert(i = 1);
|
||||
end.
|
||||
10
TestSuite/lambdas13.pas
Normal file
10
TestSuite/lambdas13.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
type TProc = procedure;
|
||||
|
||||
var i: integer;
|
||||
|
||||
begin
|
||||
var l := new List<TProc>;
|
||||
l += ()->Inc(i);
|
||||
l[0];
|
||||
assert(i = 1);
|
||||
end.
|
||||
21
TestSuite/lambdas14.pas
Normal file
21
TestSuite/lambdas14.pas
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
var i: integer;
|
||||
type
|
||||
t1 = class
|
||||
|
||||
static procedure operator+=(a: t1; d: System.Action<integer>);
|
||||
begin
|
||||
i := 1;
|
||||
end;
|
||||
static procedure operator+=(a: t1; d: Action0);
|
||||
begin
|
||||
i := 2;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
var a := new t1;
|
||||
a += ()->Writeln(1);
|
||||
assert(i = 2);
|
||||
a += (x: integer)->Writeln(1);
|
||||
assert(i = 1);
|
||||
end.
|
||||
|
|
@ -260,7 +260,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
/// <summary>
|
||||
/// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
|
||||
/// </summary>
|
||||
public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor)
|
||||
public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined)
|
||||
{
|
||||
if (lambdaDef == null)
|
||||
return;
|
||||
|
|
@ -271,7 +271,47 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (dii_left == null)
|
||||
{
|
||||
if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
|
||||
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
|
||||
{
|
||||
if (op != Operators.Undefined)
|
||||
{
|
||||
var sil = leftType.find_in_type(name_reflector.get_name(op));
|
||||
if (sil.Count > 0)
|
||||
{
|
||||
foreach (SymbolInfo si in sil)
|
||||
{
|
||||
if (si.sym_info is function_node)
|
||||
{
|
||||
function_node fn = si.sym_info as function_node;
|
||||
if (fn.parameters.Count == 2)
|
||||
{
|
||||
dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface);
|
||||
if (dii_left != null)
|
||||
break;
|
||||
if (fn.parameters[1].type.is_generic_parameter)
|
||||
{
|
||||
compiled_type_node ctn = leftType as compiled_type_node;
|
||||
common_type_node ctn2 = leftType as common_type_node;
|
||||
if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic)
|
||||
{
|
||||
dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
|
||||
if (dii_left != null)
|
||||
break;
|
||||
}
|
||||
if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic)
|
||||
{
|
||||
dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
|
||||
if (dii_left != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dii_left == null)
|
||||
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
#region Вывод параметров лямбда-выражения
|
||||
|
||||
LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this); //lroman//
|
||||
LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this, _assign.operator_type); //lroman//
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue