From 196824299021b19383df7fed2df3231562b1194e Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Thu, 7 Feb 2019 09:37:46 +0300 Subject: [PATCH] fix #1707 --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- TestSuite/InterfNoCycle.pas | 13 +++ .../TreeConversion/syntax_tree_visitor.cs | 4 + bin/Lib/PABCSystem.pas | 82 +++++++++++++++---- 6 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 TestSuite/InterfNoCycle.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 7d794fcaa..0edb47d21 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "4"; public const string Build = "2"; - public const string Revision = "1972"; + public const string Revision = "1974"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 643254443..e8252b9b3 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=4 -%REVISION%=1972 +%REVISION%=1974 %COREVERSION%=2 %MAJOR%=3 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 6eefe4da7..8ac37154b 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.4.2.1972' +!define VERSION '3.4.2.1974' diff --git a/TestSuite/InterfNoCycle.pas b/TestSuite/InterfNoCycle.pas new file mode 100644 index 000000000..66dc8a15b --- /dev/null +++ b/TestSuite/InterfNoCycle.pas @@ -0,0 +1,13 @@ +type + I6 = interface end; + I0 = interface end; + + I1 = interface(I0) end; + I2 = interface(I1,I6,I6) end; + + t1 = class(I0, I2) end; + t2 = class(I1, I2) end; + t3 = class(I0, I1) end; +begin + Assert(1=1) +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 9110b41f9..3a461b4b8 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -12095,6 +12095,10 @@ namespace PascalABCCompiler.TreeConverter private void check_cycle_interface_inheritance(common_type_node cnode, type_node base_of_cnode, List interfaces) { + // Для интерфейсов всё это излишне. Поскольку нельзя использовать предописанные интерфейсы в списке наследования, то + // циклически интерфейс может наследовать только от себя. Поэтому достаточно проверять нерекурсивно свой список ImplementingInterfaces и если там есть этот интерфейс, то ошибка + if (!cnode.IsInterface) + return; interfaces.Add(cnode); common_type_node bt = base_of_cnode as common_type_node; if (bt != null && bt.original_generic != null) diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index b8db1adf7..6f4437e45 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -9201,7 +9201,7 @@ begin end; /// Возвращает индекс первого минимального элемента начиная с позиции index -function IndexMin(Self: IList; index: integer := 0): integer; extensionmethod; where T: IComparable; +function IndexMin(Self: List; index: integer := 0): integer; extensionmethod; where T: IComparable; begin var min := Self[index]; Result := index; @@ -9214,7 +9214,7 @@ begin end; /// Возвращает индекс первого максимального элемента начиная с позиции index -function IndexMax(self: IList; index: integer := 0): integer; extensionmethod; where T: System.IComparable; +function IndexMax(Self: List; index: integer := 0): integer; extensionmethod; where T: System.IComparable; begin var max := Self[index]; Result := index; @@ -9226,12 +9226,12 @@ begin end; end; -/// Возвращает индекс последнего минимального элемента -function LastIndexMin(Self: IList): integer; extensionmethod; where T: System.IComparable; +/// Возвращает индекс первого минимального элемента начиная с позиции index +function IndexMin(Self: array of T; index: integer := 0): integer; extensionmethod; where T: IComparable; begin - var min := Self[Self.Count - 1]; - Result := Self.Count - 1; - for var i := Self.Count - 2 downto 0 do + var min := Self[index]; + Result := index; + for var i := index + 1 to Self.Count - 1 do if Self[i].CompareTo(min) < 0 then begin Result := i; @@ -9239,8 +9239,21 @@ begin end; end; +/// Возвращает индекс первого максимального элемента начиная с позиции index +function IndexMax(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable; +begin + var max := Self[index]; + Result := index; + for var i := index + 1 to Self.Count - 1 do + if Self[i].CompareTo(max) > 0 then + begin + Result := i; + max := Self[i]; + end; +end; + /// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] -function LastIndexMin(Self: IList; index: integer): integer; extensionmethod; where T: System.IComparable; +function LastIndexMin(Self: List; index: integer): integer; extensionmethod; where T: System.IComparable; begin var min := Self[index]; Result := index; @@ -9252,21 +9265,33 @@ begin end; end; -/// Возвращает индекс последнего максимального элемента -function LastIndexMax(Self: IList): integer; extensionmethod; where T: System.IComparable; +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] +function LastIndexMin(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable; begin - var max := Self[Self.Count - 1]; - Result := Self.Count - 1; - for var i := Self.Count - 2 downto 0 do - if Self[i].CompareTo(max) > 0 then + var min := Self[index]; + Result := index; + for var i := index - 1 downto 0 do + if Self[i].CompareTo(min) < 0 then begin Result := i; - max := Self[i]; + min := Self[i]; end; end; +/// Возвращает индекс последнего минимального элемента +function LastIndexMin(Self: List): integer; extensionmethod; where T: System.IComparable; +begin + Result := Self.LastIndexMin(Self.Count - 1); +end; + +/// Возвращает индекс последнего минимального элемента +function LastIndexMin(Self: array of T): integer; extensionmethod; where T: System.IComparable; +begin + Result := Self.LastIndexMin(Self.Count - 1); +end; + /// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] -function LastIndexMax(Self: IList; index: integer): integer; extensionmethod; where T: System.IComparable; +function LastIndexMax(Self: List; index: integer): integer; extensionmethod; where T: System.IComparable; begin var max := Self[index]; Result := index; @@ -9278,6 +9303,31 @@ begin end; end; +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] +function LastIndexMax(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable; +begin + var max := Self[index]; + Result := index; + for var i := index - 1 downto 0 do + if Self[i].CompareTo(max) > 0 then + begin + Result := i; + max := Self[i]; + end; +end; + +/// Возвращает индекс последнего максимального элемента +function LastIndexMax(Self: List): integer; extensionmethod; where T: System.IComparable; +begin + Result := Self.LastIndexMax(Self.Count - 1); +end; + +/// Возвращает индекс последнего максимального элемента +function LastIndexMax(Self: array of T): integer; extensionmethod; where T: System.IComparable; +begin + Result := Self.LastIndexMax(Self.Count - 1); +end; + /// Заменяет в массиве или списке все вхождения одного значения на другое procedure Replace(Self: IList; oldValue, newValue: T); extensionmethod; begin