This commit is contained in:
Бондарев Иван 2017-05-25 10:37:16 +02:00
parent 0196b08946
commit 819c41c2f3
12 changed files with 141 additions and 2 deletions

9
TestSuite/generics12.pas Normal file
View file

@ -0,0 +1,9 @@
function DQNToNullable<T>(v: T): T; where T: record;
begin
var res := new System.Nullable<T>(v);
Result := res.Value;
end;
begin
assert(DQNToNullable(2) = 2);
end.

View file

@ -0,0 +1,31 @@
unit u_explicitinterface;
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 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.

View file

@ -0,0 +1,18 @@
unit u_interface1;
type IInt1 = interface
function Test: integer;
end;
TClass = class(IInt1)
public function Test: integer;
begin
Result := 3;
end;
end;
var obj : IInt1;
begin
obj := new TClass;
assert(obj.Test=3);
end.

View file

@ -0,0 +1,30 @@
unit u_interface2;
type TClass<T> = class(IEnumerable<T>)
public function GetEnumerator: IEnumerator<T>;
begin
end;
public function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator;
begin
end;
end;
procedure Test;
begin
var i := 1;
var seq1 := i.Iterate(x->x+1);
var lst := new List<integer>;
foreach var j in seq1 do
begin
lst += j;
if j > 10 then
break;
end;
assert(lst[5] = 6);
end;
begin
Test;
end.

View file

@ -0,0 +1,15 @@
unit u_interface3;
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.

View file

@ -0,0 +1,31 @@
unit u_interface4;
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.

View file

@ -0,0 +1 @@
uses u_explicitinterface; begin end.

View file

@ -0,0 +1 @@
uses u_interface1; begin end.

View file

@ -0,0 +1 @@
uses u_interface2; begin end.

View file

@ -0,0 +1 @@
uses u_interface3; begin end.

View file

@ -0,0 +1 @@
uses u_interface4; begin end.

View file

@ -148,14 +148,14 @@ namespace PascalABCCompiler.TreeRealization
{ {
return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName); return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName);
} }
if (gpe.is_value && !tn.is_value) if (gpe.is_value && !tn.is_value && !tn.is_generic_parameter)
{ {
return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_VALUE_TYPE", tn.PrintableName); return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_VALUE_TYPE", tn.PrintableName);
} }
if (gpe.base_class != null && gpe.base_class != SystemLibrary.SystemLibrary.object_type) if (gpe.base_class != null && gpe.base_class != SystemLibrary.SystemLibrary.object_type)
{ {
type_node base_type = generic_convertions.determine_type(gpe.base_class, tparams, method_param_types); type_node base_type = generic_convertions.determine_type(gpe.base_class, tparams, method_param_types);
if (base_type != tn && !type_table.is_derived(base_type, tn)) if (base_type != tn && !type_table.is_derived(base_type, tn) && !tn.is_generic_parameter)
{ {
return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_DERIVED_FROM_{1}", tn.PrintableName, base_type.name); return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_DERIVED_FROM_{1}", tn.PrintableName, base_type.name);
} }