# Conflicts:
#	TestSuite/CompilationSamples/PABCSystem.pas
This commit is contained in:
Mikhalkovich Stanislav 2023-04-09 19:10:55 +03:00
commit 94f3964dee
10 changed files with 119 additions and 4 deletions

View file

@ -7612,7 +7612,7 @@ namespace PascalABCCompiler.NETGenerator
{
if (value.obj.type.is_generic_parameter)
il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.type).tp);
else if (value.obj.conversion_type != null && value.obj.conversion_type.is_generic_parameter)
else if (value.obj.conversion_type != null && value.obj.conversion_type.is_generic_parameter && (!value.obj.type.IsInterface || value.obj.conversion_type.ImplementingInterfaces.Count > 0))
il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.conversion_type).tp);
il.EmitCall(OpCodes.Callvirt, mi, null);
}

View file

@ -0,0 +1,18 @@
var i: integer;
type
t1 = class
procedure Deconstruct;
begin
i := 1;
end;
end;
begin
var o := new t1;
if o is t1(var a) then
begin
i := 2;
assert(o = a);
end;
assert(i = 2);
end.

View file

@ -0,0 +1,45 @@
type
Person = class
name: string;
age: integer;
constructor(name: string; age: integer);
begin
self.name := name;
self.age := age;
end;
procedure Deconstruct(var name: string; var age: integer);
begin
name := self.name;
age := self.age;
end;
end;
begin
var p := new Person('John', 25);
var s := '';
var i := 0;
if p is Person(var name, var age) then
begin
s := name;
i := age;
end;
assert(s = 'John');
assert(i = 25);
s := '';
i := 0;
match p with
Person(name, age):
begin
s := name;
i := age;
end;
end;
assert(s = 'John');
assert(i = 25);
end.

13
TestSuite/case7.pas Normal file
View file

@ -0,0 +1,13 @@
var i: integer;
procedure p1(s: string) :=
case s of
else Inc(i);
end;
begin
p1('abc');
p1('');
p1(nil);
assert(i = 3);
end.

21
TestSuite/generics68.pas Normal file
View file

@ -0,0 +1,21 @@
var i: integer;
type
I1 = interface
procedure p1;
end;
// Обязательно класс, не запись
t2 = class(I1)
public procedure p1;
begin
i := 1;
end;
end;
// Обязательно I1(o), (o as I1) работает без проблем
procedure p0<T>(o: T) := I1(o).p1;
begin
p0(new t2);
assert(i = 1);
end.

View file

@ -0,0 +1,7 @@
unit u_deconstruct1;
type
t1 = class
procedure Deconstruct(var a,b: byte) := exit;
end;
end.

View file

@ -0,0 +1,10 @@
uses u_deconstruct1;
begin
var i := 0;
if new t1 is t1(var a) then
begin
i := 1;
end;
assert(i = 1);
end.

View file

@ -926,7 +926,7 @@ namespace SymbolTable
((to.symbol_kind == symbol_kind.sk_overload_function) && (add.symbol_kind == symbol_kind.sk_overload_function))
||
((to.symbol_kind == symbol_kind.sk_overload_procedure) && (add.symbol_kind == symbol_kind.sk_overload_procedure))
|| to.sym_info != add.sym_info && to.sym_info is PascalABCCompiler.TreeRealization.function_node && add.sym_info is PascalABCCompiler.TreeRealization.function_node
|| to.sym_info != add.sym_info && (to.sym_info is PascalABCCompiler.TreeRealization.function_node || to.symbol_kind == symbol_kind.sk_overload_function) && add.sym_info is PascalABCCompiler.TreeRealization.function_node
/*&& (to.sym_info as PascalABCCompiler.TreeRealization.function_node).is_extension_method*/ && (add.sym_info as PascalABCCompiler.TreeRealization.function_node).is_extension_method
);
}

View file

@ -93,7 +93,8 @@ namespace PascalABCCompiler.TreeConverter
out type_node[] parameterTypes)
{
parameterTypes = new type_node[givenParameterTypes.Length];
candidate.parameters[0].name = "Self"; // SSM 23.06.20 #2268 - это если в NET где-то такое нашли
if (candidate.parameters.Count > 0)
candidate.parameters[0].name = "Self"; // SSM 23.06.20 #2268 - это если в NET где-то такое нашли
var selfParameter = candidate.is_extension_method ? candidate.parameters.FirstOrDefault(IsSelfParameter) : null;
Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method");
var candidateParameterTypes =

View file

@ -10928,7 +10928,7 @@ namespace PascalABCCompiler.TreeConverter
context.leave_code_block();
if (ifn == null)
{
ifn = new if_node(en, new statements_list(null), null, get_location(_case_node));
ifn = new if_node(new bool_const_node(false, null), new statements_list(null), null, get_location(_case_node));
main_ifn = ifn;
}
ifn.else_body = else_statement;