diff --git a/CodeCompletion/CodeFormatter.cs b/CodeCompletion/CodeFormatter.cs
index b56030269..25c239675 100644
--- a/CodeCompletion/CodeFormatter.cs
+++ b/CodeCompletion/CodeFormatter.cs
@@ -1682,7 +1682,11 @@ namespace CodeFormatters
if (_program_module.program_name != null)
visit_node(_program_module.program_name);
if (_program_module.used_units != null && _program_module.used_units.source_context != null)
- visit_node(_program_module.used_units);
+ {
+ if (_program_module.program_block != null && _program_module.program_block.program_code.left_logical_bracket.text.StartsWith("##"))
+ ;
+ else visit_node(_program_module.used_units);
+ }
if (_program_module.program_block != null)
visit_node(_program_module.program_block);
//sb.Append(".");
diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs
index 1e5df7bd4..2b6e5d445 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 = "7";
public const string Build = "1";
- public const string Revision = "2784";
+ public const string Revision = "2785";
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 807571a3a..ea6127f79 100644
--- a/Configuration/Version.defs
+++ b/Configuration/Version.defs
@@ -1,4 +1,4 @@
-%COREVERSION%=1
-%REVISION%=2784
%MINOR%=7
+%REVISION%=2785
+%COREVERSION%=1
%MAJOR%=3
diff --git a/PABCNetHelp/LangGuide/Classes/attributes.html b/PABCNetHelp/LangGuide/Classes/attributes.html
index bfbe29cff..f5869d2bf 100644
--- a/PABCNetHelp/LangGuide/Classes/attributes.html
+++ b/PABCNetHelp/LangGuide/Classes/attributes.html
@@ -2,7 +2,8 @@
@@ -11,11 +12,46 @@
Атрибуты
-
Текст находится в разработке
+
В языке имеется ограниченное число стандартных атрибутов, задаваемых
+ключевыми словами - например: атрибуты уровня доступа public, private и
+protected, атрибуты static, virtual и override для методов.
+
Пользовательские атрибуты (далее просто атрибуты) - специальные языковые
+конструкции, позволяющие помечать классы, методы, подпрограммы, параметры
+некоторым именем (возможно с параметрами).
+
Например, для механизма сериализации класс помечается атрибутом
+[Serializable], а поля, которые не следует сериализовывать, атрибутом
+[NonSerialized]. При Unit-тестировании тестовый метод помечается атрибутом
+[Test] или атрибутом [TestCase]. Распознаются атрибуты методом отражения
+(рефлексии).
+
Атрибут - это обычный класс, унаследованный от System.Atribute. Например:
-
t
+
type AuthorAttribute = class(System.Attribute)
+ auto property Name: string; constructor (n: string);
+ begin name := n; end; end;
-
Е
+
Следует обратить внимание, что класс атрибута принято оканчивать на
+Attribute.
+
При пометке сущности атрибутом имя атрибута заключается в квадратные скобки. Конструктор атрибута предоставляет
+также возможность использовать атрибуты с
+параметрами. Например, можно пометить класс
+атрибутом AuthorAttribute.
+
+
[Author('Alex')] type My = class // ...
+ end;
+
+
Следует обратить внимание, что окончание Attribute можно не
+указывать.
+
Распознать, помечен ли данный класс атрибутом, можно, используя
+отражение:
+
+
begin var t := typeof(My);
+ var attrs := t.GetCustomAttributes(false);
+ foreachvar attr in attrs
+ do if attr is AuthorAttribute (var auth)
+ then Print(auth.Name);
+ end.
+
+
След
\ No newline at end of file
diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
index af75ff147..7dd66fdf6 100644
--- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
+++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
@@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
-// DateTime: 25.12.2020 21:59:53
+// DateTime: 07.01.2021 12:07:22
// UserName: ?????????
// GPLEX input file
// GPLEX frame file
diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y
index dcc937463..f2d1ecf9e 100644
--- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y
+++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y
@@ -188,20 +188,24 @@ parse_goal
{ root = $1; }
| parts
{ root = $1; }
- | tkShortProgram stmt_list
+ | tkShortProgram uses_clause stmt_list
{
- var stl = $2 as statement_list;
+ var stl = $3 as statement_list;
stl.left_logical_bracket = $1;
stl.right_logical_bracket = new token_info("");
- root = $$ = NewProgramModule(null, null, null, new block(null, stl, @$), new token_info(""), @$);
+ var ul = $2 as uses_list;
+ root = $$ = NewProgramModule(null, null, ul, new block(null, stl, @$), new token_info(""), @$);
}
- | tkShortSFProgram stmt_list
+ | tkShortSFProgram uses_clause stmt_list
{
- var stl = $2 as statement_list;
+ var stl = $3 as statement_list;
stl.left_logical_bracket = $1;
var un = new unit_or_namespace(new ident_list("SF"),null);
+ var ul = $2 as uses_list;
+ if (ul == null)
//var un1 = new unit_or_namespace(new ident_list("School"),null);
- var ul = new uses_list(un,null);
+ ul = new uses_list(un,null);
+ else ul.Insert(0,un);
//ul.Add(un1);
root = $$ = NewProgramModule(null, null, ul, new block(null, stl, @$), new token_info(""), @$);
}
diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
index d6e15b05e..d50cbdbb4 100644
--- a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
+++ b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
@@ -2,9 +2,9 @@
// GPPG version 1.3.6
// Machine: DESKTOP-G8V08V4
-// DateTime: 25.12.2020 21:59:54
+// DateTime: 07.01.2021 12:07:22
// UserName: ?????????
-// Input file
+// Input file
// options: no-lines gplex
@@ -59,7 +59,7 @@ public abstract class ScanBase : AbstractScanner
{
- // Verbatim content from ABCPascal.y
+ // Verbatim content from D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y
// пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅ GPPGParser, пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ gppg
public syntax_tree_node root; // пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ
@@ -71,13 +71,13 @@ public partial class GPPGParser: ShiftReduceParser scanner) : base(scanner) { }
- // End verbatim content from ABCPascal.y
+ // End verbatim content from D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y
#pragma warning disable 649
private static Dictionary aliasses;
#pragma warning restore 649
private static Rule[] rules = new Rule[987];
- private static State[] states = new State[1633];
+ private static State[] states = new State[1635];
private static string[] nonTerms = new string[] {
"parse_goal", "unit_key_word", "class_or_static", "assignment", "optional_array_initializer",
"attribute_declarations", "ot_visibility_specifier", "one_attribute", "attribute_variable",
@@ -168,7 +168,7 @@ public partial class GPPGParser: ShiftReduceParser parts
{ root = ValueStack[ValueStack.Depth-1].stn; }
break;
- case 5: // parse_goal -> tkShortProgram, stmt_list
+ case 5: // parse_goal -> tkShortProgram, uses_clause, stmt_list
{
var stl = ValueStack[ValueStack.Depth-1].stn as statement_list;
- stl.left_logical_bracket = ValueStack[ValueStack.Depth-2].ti;
+ stl.left_logical_bracket = ValueStack[ValueStack.Depth-3].ti;
stl.right_logical_bracket = new token_info("");
- root = CurrentSemanticValue.stn = NewProgramModule(null, null, null, new block(null, stl, CurrentLocationSpan), new token_info(""), CurrentLocationSpan);
+ var ul = ValueStack[ValueStack.Depth-2].stn as uses_list;
+ root = CurrentSemanticValue.stn = NewProgramModule(null, null, ul, new block(null, stl, CurrentLocationSpan), new token_info(""), CurrentLocationSpan);
}
break;
- case 6: // parse_goal -> tkShortSFProgram, stmt_list
+ case 6: // parse_goal -> tkShortSFProgram, uses_clause, stmt_list
{
var stl = ValueStack[ValueStack.Depth-1].stn as statement_list;
- stl.left_logical_bracket = ValueStack[ValueStack.Depth-2].ti;
+ stl.left_logical_bracket = ValueStack[ValueStack.Depth-3].ti;
var un = new unit_or_namespace(new ident_list("SF"),null);
+ var ul = ValueStack[ValueStack.Depth-2].stn as uses_list;
+ if (ul == null)
//var un1 = new unit_or_namespace(new ident_list("School"),null);
- var ul = new uses_list(un,null);
+ ul = new uses_list(un,null);
+ else ul.Insert(0,un);
//ul.Add(un1);
root = CurrentSemanticValue.stn = NewProgramModule(null, null, ul, new block(null, stl, CurrentLocationSpan), new token_info(""), CurrentLocationSpan);
}
diff --git a/Parsers/PascalABCParserNewSaushkin/PABC.ymc b/Parsers/PascalABCParserNewSaushkin/PABC.ymc
index 1961773d3..19bbff829 100644
--- a/Parsers/PascalABCParserNewSaushkin/PABC.ymc
+++ b/Parsers/PascalABCParserNewSaushkin/PABC.ymc
@@ -300,5 +300,6 @@ script=
+
diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt
index d8ecb9777..a226de8f9 100644
--- a/Release/pabcversion.txt
+++ b/Release/pabcversion.txt
@@ -1 +1 @@
-3.7.1.2784
+3.7.1.2785
diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh
index a47b64893..35dc8c8a0 100644
--- a/ReleaseGenerators/PascalABCNET_version.nsh
+++ b/ReleaseGenerators/PascalABCNET_version.nsh
@@ -1 +1 @@
-!define VERSION '3.7.1.2784'
+!define VERSION '3.7.1.2785'
diff --git a/SyntaxTree/tree/NodesBuilder.cs b/SyntaxTree/tree/NodesBuilder.cs
index 0560d7e0b..416ec4d6f 100644
--- a/SyntaxTree/tree/NodesBuilder.cs
+++ b/SyntaxTree/tree/NodesBuilder.cs
@@ -190,9 +190,11 @@ namespace PascalABCCompiler.SyntaxTree
var ts = m as procedure_definition;
if (!HasConstructor)
{
- if (ts != null && ts.proc_header is constructor)
+ if (ts != null && ts.proc_header is constructor
+ && (ts.proc_header.parameters?.params_list.SelectMany(tp => tp.idents.idents).Count() ?? 0) == names.Count
+ )
{
- HasConstructor = true;
+ HasConstructor = true; // на самом деле это означает, что есть конструктор с точно таким же количеством параметров
}
}
diff --git a/TestSuite/CompilationSamples/graph3d.pas b/TestSuite/CompilationSamples/graph3d.pas
index 676c990f8..84be6d6a8 100644
--- a/TestSuite/CompilationSamples/graph3d.pas
+++ b/TestSuite/CompilationSamples/graph3d.pas
@@ -379,7 +379,7 @@ type
procedure AddToObject3DList;
procedure DeleteFromObject3DList;
-
+ protected
procedure CreateBase0(m: Visual3D; x, y, z: real);
begin
model := m;
@@ -395,7 +395,7 @@ type
hvp.Children.Add(model);
AddToObject3DList;
end;
-
+ private
procedure SetX(xx: real) := Invoke(()->begin transltransform.OffsetX += xx - Self.X; end);
function GetX: real := InvokeReal(()->transfgroup.Value.OffsetX);
procedure SetY(yy: real) := Invoke(()->begin transltransform.OffsetY += yy - Self.Y; end);
diff --git a/bin/Lib/Graph3D.pas b/bin/Lib/Graph3D.pas
index 676c990f8..84be6d6a8 100644
--- a/bin/Lib/Graph3D.pas
+++ b/bin/Lib/Graph3D.pas
@@ -379,7 +379,7 @@ type
procedure AddToObject3DList;
procedure DeleteFromObject3DList;
-
+ protected
procedure CreateBase0(m: Visual3D; x, y, z: real);
begin
model := m;
@@ -395,7 +395,7 @@ type
hvp.Children.Add(model);
AddToObject3DList;
end;
-
+ private
procedure SetX(xx: real) := Invoke(()->begin transltransform.OffsetX += xx - Self.X; end);
function GetX: real := InvokeReal(()->transfgroup.Value.OffsetX);
procedure SetY(yy: real) := Invoke(()->begin transltransform.OffsetY += yy - Self.Y; end);
diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas
index 9ced3bea4..a53568731 100644
--- a/bin/Lib/PABCSystem.pas
+++ b/bin/Lib/PABCSystem.pas
@@ -11815,6 +11815,12 @@ begin
until not NextCombHelper(ind,m,n);
end;
+/// Возвращает все сочетания по m элементов
+function Combinations(Self: sequence of T; m: integer): sequence of array of T; extensionmethod;
+begin
+ Result := Self.ToArray.Combinations(m);
+end;
+
// Возвращает все сочетания по 2 элемента в виде кортежей
{function Combinations2(Self: array of T): sequence of (T,T); extensionmethod;
begin
@@ -11858,12 +11864,23 @@ begin
until not NextPermutation(ind);
end;
+/// Возвращает все перестановки множества элементов, заданного последовательностью
+function Permutations(Self: sequence of T): sequence of array of T; extensionmethod;
+begin
+ Result := Self.ToArray.Permutations
+end;
+
/// Возвращает все частичные перестановки из n элементов по m
function Permutations(Self: array of T; m: integer): sequence of array of T; extensionmethod;
begin
Result := Self.Combinations(m).SelectMany(c->c.Permutations);
end;
+/// Возвращает все частичные перестановки из n элементов по m
+function Permutations(Self: sequence of T; m: integer): sequence of array of T; extensionmethod;
+begin
+ Result := Self.ToArray.Permutations(m);
+end;
/// Возвращает n-тую декартову степень множества элементов, заданного массивом
function Cartesian(Self: array of T; n: integer): sequence of array of T; extensionmethod;
@@ -11895,6 +11912,11 @@ begin
end;
end;
+/// Возвращает n-тую декартову степень множества элементов, заданного массивом
+function Cartesian(Self: sequence of T; n: integer): sequence of array of T; extensionmethod;
+begin
+ Result := Self.ToArray.Cartesian(n);
+end;
// Внутренние функции для одномерных массивов
diff --git a/bin/PascalABCNET.chm b/bin/PascalABCNET.chm
index 12698fe4a..aab3d049a 100644
Binary files a/bin/PascalABCNET.chm and b/bin/PascalABCNET.chm differ