From 819c41c2f32237e36d63609db7d41fd7ec7495df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Thu, 25 May 2017 10:37:16 +0200 Subject: [PATCH] bug fix #406 --- TestSuite/generics12.pas | 9 ++++++ TestSuite/units/u_explicitinterface.pas | 31 +++++++++++++++++++ TestSuite/units/u_interface1.pas | 18 +++++++++++ TestSuite/units/u_interface2.pas | 30 ++++++++++++++++++ TestSuite/units/u_interface3.pas | 15 +++++++++ TestSuite/units/u_interface4.pas | 31 +++++++++++++++++++ TestSuite/usesunits/use_explicitinterface.pas | 1 + TestSuite/usesunits/use_interface1.pas | 1 + TestSuite/usesunits/use_interface2.pas | 1 + TestSuite/usesunits/use_interface3.pas | 1 + TestSuite/usesunits/use_interface4.pas | 1 + TreeConverter/TreeRealization/generics.cs | 4 +-- 12 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 TestSuite/generics12.pas create mode 100644 TestSuite/units/u_explicitinterface.pas create mode 100644 TestSuite/units/u_interface1.pas create mode 100644 TestSuite/units/u_interface2.pas create mode 100644 TestSuite/units/u_interface3.pas create mode 100644 TestSuite/units/u_interface4.pas create mode 100644 TestSuite/usesunits/use_explicitinterface.pas create mode 100644 TestSuite/usesunits/use_interface1.pas create mode 100644 TestSuite/usesunits/use_interface2.pas create mode 100644 TestSuite/usesunits/use_interface3.pas create mode 100644 TestSuite/usesunits/use_interface4.pas diff --git a/TestSuite/generics12.pas b/TestSuite/generics12.pas new file mode 100644 index 000000000..6310b3d72 --- /dev/null +++ b/TestSuite/generics12.pas @@ -0,0 +1,9 @@ +function DQNToNullable(v: T): T; where T: record; +begin + var res := new System.Nullable(v); + Result := res.Value; +end; + +begin + assert(DQNToNullable(2) = 2); +end. \ No newline at end of file diff --git a/TestSuite/units/u_explicitinterface.pas b/TestSuite/units/u_explicitinterface.pas new file mode 100644 index 000000000..5ed4e5dc8 --- /dev/null +++ b/TestSuite/units/u_explicitinterface.pas @@ -0,0 +1,31 @@ +unit u_explicitinterface; +type + IEnr = System.Collections.IEnumerator; + IEnb = System.Collections.IEnumerable; + + var a : integer; + type My = class(IEnumerable) + public + function IEnb.GetEnumerator(): IEnr; + begin + a := 1; + end; + function GetEnumerator(): IEnumerator; + begin + a := 2; + end; + + end; + +begin +var ien: IEnb := new My; +ien.GetEnumerator; +assert(a=1); +var ien2: IEnumerable := new My; +ien2.GetEnumerator; +assert(a=2); +a := 0; +var mc := new My; +mc.GetEnumerator(); +assert(a=2); +end. \ No newline at end of file diff --git a/TestSuite/units/u_interface1.pas b/TestSuite/units/u_interface1.pas new file mode 100644 index 000000000..8e5703e6c --- /dev/null +++ b/TestSuite/units/u_interface1.pas @@ -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. \ No newline at end of file diff --git a/TestSuite/units/u_interface2.pas b/TestSuite/units/u_interface2.pas new file mode 100644 index 000000000..d527a9424 --- /dev/null +++ b/TestSuite/units/u_interface2.pas @@ -0,0 +1,30 @@ +unit u_interface2; +type TClass = class(IEnumerable) +public function GetEnumerator: IEnumerator; +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; + foreach var j in seq1 do + begin + lst += j; + if j > 10 then + break; + end; + assert(lst[5] = 6); +end; + +begin + Test; +end. \ No newline at end of file diff --git a/TestSuite/units/u_interface3.pas b/TestSuite/units/u_interface3.pas new file mode 100644 index 000000000..e7263d53f --- /dev/null +++ b/TestSuite/units/u_interface3.pas @@ -0,0 +1,15 @@ +unit u_interface3; +type TClass = class(IEnumerable) +public function System.Collections.Generic.IEnumerable.GetEnumerator: IEnumerator; +begin + +end; + +public function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator; +begin + +end; +end; +begin + +end. \ No newline at end of file diff --git a/TestSuite/units/u_interface4.pas b/TestSuite/units/u_interface4.pas new file mode 100644 index 000000000..03e0f649f --- /dev/null +++ b/TestSuite/units/u_interface4.pas @@ -0,0 +1,31 @@ +unit u_interface4; +type + IEnr = System.Collections.IEnumerator; + IEnb = System.Collections.IEnumerable; + + var a : integer; + type My = class(IEnumerable) + public + function IEnb.GetEnumerator(): IEnr; + begin + a := 1; + end; + function System.Collections.Generic.IEnumerable.GetEnumerator(): IEnumerator; + begin + a := 2; + end; + + end; + +begin +var ien: IEnb := new My; +ien.GetEnumerator; +assert(a=1); +var ien2: IEnumerable := new My; +ien2.GetEnumerator; +assert(a=2); +a := 0; +var mc := new My; +mc.GetEnumerator(); +assert(a=2); +end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_explicitinterface.pas b/TestSuite/usesunits/use_explicitinterface.pas new file mode 100644 index 000000000..aea99ce24 --- /dev/null +++ b/TestSuite/usesunits/use_explicitinterface.pas @@ -0,0 +1 @@ +uses u_explicitinterface; begin end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_interface1.pas b/TestSuite/usesunits/use_interface1.pas new file mode 100644 index 000000000..129023650 --- /dev/null +++ b/TestSuite/usesunits/use_interface1.pas @@ -0,0 +1 @@ +uses u_interface1; begin end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_interface2.pas b/TestSuite/usesunits/use_interface2.pas new file mode 100644 index 000000000..51dfb5d64 --- /dev/null +++ b/TestSuite/usesunits/use_interface2.pas @@ -0,0 +1 @@ +uses u_interface2; begin end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_interface3.pas b/TestSuite/usesunits/use_interface3.pas new file mode 100644 index 000000000..92f96ad4b --- /dev/null +++ b/TestSuite/usesunits/use_interface3.pas @@ -0,0 +1 @@ +uses u_interface3; begin end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_interface4.pas b/TestSuite/usesunits/use_interface4.pas new file mode 100644 index 000000000..138cbae28 --- /dev/null +++ b/TestSuite/usesunits/use_interface4.pas @@ -0,0 +1 @@ +uses u_interface4; begin end. \ No newline at end of file diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 110563428..5b08066d2 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -148,14 +148,14 @@ namespace PascalABCCompiler.TreeRealization { 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); } 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); - 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); }