diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index c332a69c4..cca569e36 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 = "1941"; + public const string Revision = "1950"; 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 b43f1975c..ebb509575 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=2 -%REVISION%=1941 %MINOR%=4 +%REVISION%=1950 +%COREVERSION%=2 %MAJOR%=3 diff --git a/NETGenerator/Helpers.cs b/NETGenerator/Helpers.cs index 0afedc2bc..230b52d63 100644 --- a/NETGenerator/Helpers.cs +++ b/NETGenerator/Helpers.cs @@ -194,6 +194,7 @@ namespace PascalABCCompiler.NETGenerator { public class GenericFldInfo : FldInfo { private Type _field_type; + public FieldInfo prev_fi; // передаю чтобы на третьем этапе в NegGenerator.cs (примерно 1586) можно было сконструировать правильный тип. Костыль для #1632 public override Type field_type { @@ -203,10 +204,11 @@ namespace PascalABCCompiler.NETGenerator { } } - public GenericFldInfo(FieldInfo fi, Type field_type) + public GenericFldInfo(FieldInfo fi, Type field_type, FieldInfo prev_fi) : base(fi) { _field_type = field_type; + this.prev_fi = prev_fi; } } @@ -698,14 +700,14 @@ namespace PascalABCCompiler.NETGenerator { return fi; } - public FldInfo AddGenericField(ICommonClassFieldNode f, FieldInfo fb, Type field_type) + public FldInfo AddGenericField(ICommonClassFieldNode f, FieldInfo fb, Type field_type, FieldInfo prev_fi) { - FldInfo fi = new GenericFldInfo(fb, field_type); + FldInfo fi = new GenericFldInfo(fb, field_type, prev_fi); // prev_fi - чтобы сконструировать на последнем этапе fi #if DEBUG /*if (f.name == "XYZW") { var y = f.GetHashCode(); - }*/ + } */ #endif defs[f] = fi; return fi; @@ -719,15 +721,15 @@ namespace PascalABCCompiler.NETGenerator { /*if (f.name == "XYZW") { var y = f.GetHashCode(); - }*/ - /*if (r == null && f.name == "XYZW") + } + if (r == null && f.name == "XYZW") { foreach (var k in defs.Keys) { if ((k is ICommonClassFieldNode) && (k as ICommonClassFieldNode).name == "XYZW") return (FldInfo)defs[k]; } - }*/ + } */ #endif return r; } @@ -919,7 +921,8 @@ namespace PascalABCCompiler.NETGenerator { { if (type.type_special_kind == type_special_kind.text_file) ti.is_text_file = true; - if (!ti.is_set && !ti.is_typed_file && !ti.is_text_file) return ti; + if (!ti.is_set && !ti.is_typed_file && !ti.is_text_file) + return ti; if (ti.clone_meth == null && !ti.is_typed_file && !ti.is_text_file) { if (type is ICommonTypeNode) diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index aa767d63d..4dad6d42e 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -1498,7 +1498,7 @@ namespace PascalABCCompiler.NETGenerator Type ftype = GetTypeOfGenericInstanceField(t, icfn.compiled_field); FieldInfo fi = TypeBuilder.GetField(t, icfn.compiled_field); - helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype); + helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype, null); continue; } } @@ -1562,14 +1562,44 @@ namespace PascalABCCompiler.NETGenerator { FieldInfo finfo = fldinfo.fi; Type ftype = GetTypeOfGenericInstanceField(t, finfo); - FieldInfo fi = TypeBuilder.GetField(t, finfo); - helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype); + FieldInfo fi = TypeBuilder.GetField(t, finfo); // возвращает fi: FieldOnTypeBuilderInstantiation + helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype, finfo); // передаю также старое finfo чтобы на следующей итерации вызовом TypeBuilder.GetField(t, finfo) сконструировать правильное fi } else { - FieldInfo finfo = fldinfo.fi; - FieldInfo fi = finfo; - helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type); + /* Вот этот код не выполняется ни в одном тесте и в примере + type + Base = class + XYZW: T; + end; + + Derived = class(Base) + end; + + begin + var a := new Derived; + a.XYZW := 2; + end. + срабатывает неправильно !!! + + Исправил, введя доп. поле в GenericFldInfo, которое хранит FieldBuilder и позволяет конструировать fi на следующей итерации + */ + + FieldInfo finfo = (fldinfo as GenericFldInfo).prev_fi; + FieldInfo fi = TypeBuilder.GetField(t, finfo); + helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type, finfo); + //FieldInfo finfo = fldinfo.fi; + //FieldInfo fi = finfo; + //helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type, finfo); + //#if DEBUG + + /*{ + var f = File.AppendText("d:\\aa.txt"); + f.WriteLine(DateTime.Now); + f.WriteLine($"{value.used_members[dn] as ICommonClassFieldNode} {fi} {(fldinfo as GenericFldInfo).field_type}"); + f.Close(); + }*/ + //#endif } continue; } diff --git a/NETGenerator/NETGenerator.csproj b/NETGenerator/NETGenerator.csproj index 3b8ae7a86..2a9f6282e 100644 --- a/NETGenerator/NETGenerator.csproj +++ b/NETGenerator/NETGenerator.csproj @@ -64,6 +64,7 @@ Full prompt AllRules.ruleset + DEBUG ..\bin\ diff --git a/PABCNetHelp/DocGenForStandardUnits/!GenDocGraphWPF.exe b/PABCNetHelp/DocGenForStandardUnits/!GenDocGraphWPF.exe new file mode 100644 index 000000000..1cc27eb56 Binary files /dev/null and b/PABCNetHelp/DocGenForStandardUnits/!GenDocGraphWPF.exe differ diff --git a/PABCNetHelp/LangGuide/Classes/anontypes.html b/PABCNetHelp/LangGuide/Classes/anontypes.html index c307d0b00..a26a8cd9c 100644 --- a/PABCNetHelp/LangGuide/Classes/anontypes.html +++ b/PABCNetHelp/LangGuide/Classes/anontypes.html @@ -32,7 +32,7 @@ , . . :

var d := new DateTime(2015,5,15);
- var p := new class(d.Day, d.Month, d.Year);
Println(p.Day, + var p := new class(d.Day, d.Month, d.Year);
Println(p.Day, p.Month, p.Year);
Println(p);
diff --git a/PABCNetHelp/LangGuide/Classes/autoclasses.html b/PABCNetHelp/LangGuide/Classes/autoclasses.html index 8c7e9144f..48a9ee4be 100644 --- a/PABCNetHelp/LangGuide/Classes/autoclasses.html +++ b/PABCNetHelp/LangGuide/Classes/autoclasses.html @@ -27,7 +27,7 @@
type Person = auto class
  name: string;
  age: integer;
end;
var p := new Person('',20); // -
writeln(p); // +
Writeln(p); // ToString

writeln , .

diff --git a/PABCNetHelp/LangGuide/Classes/classconstr.html b/PABCNetHelp/LangGuide/Classes/classconstr.html index 979deed21..21a8cd7c3 100644 --- a/PABCNetHelp/LangGuide/Classes/classconstr.html +++ b/PABCNetHelp/LangGuide/Classes/classconstr.html @@ -45,7 +45,7 @@ property Coun: integer read cnt;

begin
  var p: Person := new Person('
',20);
  var p1: Person := new Person('
',18);
-  writeln(Person.Count); //
+  Writeln(Person.Count); // Count
end.

, diff --git a/PABCNetHelp/LangGuide/Classes/extensionmethods.html b/PABCNetHelp/LangGuide/Classes/extensionmethods.html index 8454834c2..68c25c24f 100644 --- a/PABCNetHelp/LangGuide/Classes/extensionmethods.html +++ b/PABCNetHelp/LangGuide/Classes/extensionmethods.html @@ -39,9 +39,9 @@ HashSet<T> Self do
    action(x);
end;

:

-
function operator+=<T>(a: List<T>; x: T): +
procedure operator+=<T>(a: List<T>; x: T): List<T>; extensionmethod;
begin
  - a.Add(x);
  Result := a;
end;
+ a.Add(x);
end;

Self.

:

    diff --git a/PABCNetHelp/LangGuide/Classes/index_classes.html b/PABCNetHelp/LangGuide/Classes/index_classes.html index 14041552e..e98990723 100644 --- a/PABCNetHelp/LangGuide/Classes/index_classes.html +++ b/PABCNetHelp/LangGuide/Classes/index_classes.html @@ -3,6 +3,7 @@ + Классы и объекты: обзор @@ -57,7 +58,7 @@ Print;
        property Name: string read fName;
        property Age: integer read fAge;
      end
    ;

    procedure
    Person.Print;
    begin
      - writelnFormat('Имя: {0} Возраст: {1}', Name, Age);
    end;

    + Writeln($'Имя: {Name} Возраст: {Age}');
    end;

    После слова class в скобках может быть указано имя класса-предка (см. @@ -90,10 +91,10 @@

    Print(p.Name,p.Age);
    p.Print;

    Вывод переменной типа класс

    -

    По умолчанию процедура write для переменной типа класс выводит +

    По умолчанию процедура Write для переменной типа класс выводит содержимое её публичных полей и свойств в круглых скобках через запятую:

    -

    write(p); // Иванов 20

    +

    Write(p); // Иванов 20

    Чтобы изменить это поведение, в классе следует переопределить виртуальный метод @@ -109,13 +110,12 @@ string; override;
        begin
          Result := - string.Format('Имя: {0}  Возраст: {1}', - Name, Age);
    + $'Имя: {Name} Возраст: {Age}';
        end;
      end;
      ...
    var p: Person := new Person('Иванов',20);
    - writeln(p); // Имя: Иванов  Возраст: 20

    + Writeln(p); // Имя: Иванов  Возраст: 20

    Присваивание и передача в качестве параметров подпрограмм

    Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый diff --git a/PABCNetHelp/LangGuide/Classes/inherited.html b/PABCNetHelp/LangGuide/Classes/inherited.html index 19a034564..cccb841cf 100644 --- a/PABCNetHelp/LangGuide/Classes/inherited.html +++ b/PABCNetHelp/LangGuide/Classes/inherited.html @@ -28,7 +28,7 @@     end;
        procedure Print;
        begin
    -      writeln(': ',name,'  : ',age);
    +      Writeln(': ',name,'  : ',age);
        end;
      end;
     
      Student = class(Person)
    @@ -45,7 +45,7 @@ integer);
        procedure Print;
        begin
          inherited Print;
    -      writeln(': ',course,'  : ',group);
    +      Writeln(': ',course,'  : ',group);
        end;
      end;

    Print Student diff --git a/PABCNetHelp/LangGuide/Classes/operoverloading.html b/PABCNetHelp/LangGuide/Classes/operoverloading.html index 2af9d951d..5ec5785a3 100644 --- a/PABCNetHelp/LangGuide/Classes/operoverloading.html +++ b/PABCNetHelp/LangGuide/Classes/operoverloading.html @@ -22,15 +22,15 @@ operator . +=, -=, *=, /= - () -, + -, .

    :

    type
      Complex = record
        re,im: real;
        - class function operator+(a,b: Complex): Complex;
        + static function operator+(a,b: Complex): Complex;
        begin
          Result.re := a.re + b.re;
          Result.im := a.im + b.im;
        end;
        - class function operator=(a,b: Complex): boolean;
        begin
          Result := (a.re = b.re) + static function operator=(a,b: Complex): boolean;
        begin
          Result := (a.re = b.re) and (a.im = b.im);
        end;
      end;

    :

    @@ -55,8 +55,6 @@ , - . -. -
  • . - : .
  • , operator implicit @@ -68,19 +66,18 @@

    type
      Complex = record
        ...
        - class function operator implicit(d: real): Complex;
        + static function operator implicit(d: real): Complex;
        begin
          Result.re := d;
          Result.im := 0;
        end;
        - class function operator explicit(c: Complex): string;
        + static function operator explicit(c: Complex): string;
        begin
          Result := Format('({0},{1})',c.re,c.im);
        end;
        - class procedure operator+=(var c: Complex; + static procedure operator+=(var c: Complex; value: Complex);
        begin
          c.re += value.re;
          c.im += value.im;
        end;
        - - class function operator+(c,c1: Complex): + static function operator+(c,c1: Complex): Complex;
        begin     
          Result.re := c.re + c1.re;
          @@ -88,12 +85,12 @@ value: Complex);
        begin
        &
        end;
      end;

    -

    - +

    - class. , :

    -

    function string.operator+(str: string; n: - integer): string;
    begin
      result := str + +

    function operator+(str: string; n: + integer): string; extensionmethod;
    begin
      result := str + n.ToString;
    end;

    diff --git a/PABCNetHelp/PABCUnits/GraphWPF/Files/GraphWPF events.html b/PABCNetHelp/PABCUnits/GraphWPF/Files/GraphWPF events.html index 31142e07b..3b46b0b3d 100644 --- a/PABCNetHelp/PABCUnits/GraphWPF/Files/GraphWPF events.html +++ b/PABCNetHelp/PABCUnits/GraphWPF/Files/GraphWPF events.html @@ -1,20 +1,26 @@ - + + + + + + +

    GraphWPF

    - - - - - - - +
    /// . (x,y) - , mousebutton = 1, , 2, ; -
            
    /// . (x,y) - , mousebutton = 1, , 2, ; -
            ouseDown: procedure(x, y: real; mousebutton: integer);
    /// . (x,y) - , mousebutton = 0, , 1, , 2, ; -
            ouseUp: procedure(x, y: real; mousebutton: integer);
    /// ; -
            ouseMove: procedure(x, y: real; mousebutton: integer);
    /// ; -
            eyDown: procedure(k: Key);
    /// ; -
            eyUp: procedure(k: Key);
    /// ; -
            eyPress: procedure(ch: char);
    + + + + + +
    OnMouseDown: procedure(x, y: real; mousebutton: integer); +
             . (x,y) - , mousebutton = 1, , 2,
    OnMouseUp: procedure(x, y: real; mousebutton: integer); +
             . (x,y) - , mousebutton = 1, , 2,
    OnMouseMove: procedure(x, y: real; mousebutton: integer); +
             . (x,y) - , mousebutton = 0, , 1, , 2,
    OnKeyDown: procedure(k: Key); +
            
    OnKeyUp: procedure(k: Key); +
            
    OnKeyPress: procedure(ch: char); +
            
    OnResize: procedure; +
            
    \ No newline at end of file diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 35c8ab0cf..7a5db8609 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.4.2.1941' +!define VERSION '3.4.2.1950' diff --git a/TestSuite/CompilationSamples/BlockFileOfT.pas b/TestSuite/CompilationSamples/BlockFileOfT.pas index fa7dc444a..2d4636cc1 100644 --- a/TestSuite/CompilationSamples/BlockFileOfT.pas +++ b/TestSuite/CompilationSamples/BlockFileOfT.pas @@ -10,9 +10,9 @@ // https://github.com/SunSerega/PascalABC.Net-BlockFileOfT/blob/master/LICENSE.md (************************************************************************************) -///Модуль содержащий тип BlockFileOf -///Этот тип - альтернатива стандартному file of T -///Основное преимущество - скорость работы +///Модуль, содержащий тип BlockFileOf +///Тип-альтернатива стандартному file of T +///Главное преимущество - скорость работы unit BlockFileOfT; interface @@ -24,42 +24,36 @@ type ///-- BlockFileBase = abstract class - protected fi:FileInfo; - protected _offset:int64; - protected str:FileStream; - protected bw:BinaryWriter; - protected br:BinaryReader; + protected fi: FileInfo; + protected _offset: int64; + protected str: FileStream; + protected bw: BinaryWriter; + protected br: BinaryReader; protected linked := new List; - protected procedure Link(f:BlockFileBase); + protected procedure Link(f: BlockFileBase); protected procedure UnLink; - private class function MessageBox(wnd: System.IntPtr; message, caption: string; flags: cardinal):integer; - external 'User32.dll'; + private static function MessageBox(wnd: System.IntPtr; message, caption: string; flags: cardinal): integer; external 'User32.dll'; end; - ///Тип, записывающий данные в файл по принципу схожему с "file of " - ///Но в отличии от "file of " - данный тип сохраняет всю запись одним блоком, - ///так, как она записа в памяти. - ///Это даёт значительное преимущество по скорости, но ограничевает, - ///типы, которые могут быть использованы в виде полей + ///Тип, записывающий данные в файл по схожему с "file of " принципу + ///Но, в отличии от типизированных файлов, данный тип сохраняет всю запись одним блоком так, как она записа в памяти. + ///Это даёт значительное преимущество по скорости, но ограничивает типы, которые могут быть использованы в качестве полей типа /// - ///Ожидается, что в видет шаблонного параметра будет передана запись, - ///не содержащая динамичных полей. - ///Иначе целостность данных будет терятся - ///Это значит, что поля записи T и всех вложенных записей - НЕ могут быть: - /// -Указатели - /// -Ссылочных типов (то есть классами) - /// -Особых типов, которые .Net считает "опасными". Как char или System.DateTime - ///Но эти ограничения можно обойти, про это в справке - BlockFileOf=class(BlockFileBase) + ///Это значит, что поля записи T и всех вложенных записей не могут быть: + /// - Указателями + /// - Ссылочными типами (классами / динамическими массивами) + /// - Особоопасными в .NET типами. Например, char и System.DateTime + ///Однако, эти ограничения можно обойти, об этом в справке + BlockFileOf = class(BlockFileBase) - private class sz: integer; + private static sz: integer; - private class procedure TestForRefT(tt: System.Type); + private static procedure TestForRefT(tt: System.Type); begin if tt.IsClass then begin @@ -82,7 +76,7 @@ type TestForRefT(fi.FieldType); end; - private class constructor := + private static constructor := try TestForRefT(typeof(T)); @@ -116,193 +110,227 @@ type end; end; - private function GetName:string; - private function GetFullName:string; + private function GetName: string; + private function GetFullName: string; - private function GetExists:boolean; + private function GetExists: boolean; - private function GetFileSize:int64 := (GetByteFileSize - _offset) div sz; - private procedure SetFileSize(size:int64) := SetByteFileSize(_offset + size*sz); + private function GetFileSize: int64 := (GetByteFileSize - _offset) div sz; + private procedure SetFileSize(size: int64) := SetByteFileSize(_offset + size*sz); - private function GetByteFileSize:int64; - private procedure SetByteFileSize(size:int64); + private function GetByteFileSize: int64; + private procedure SetByteFileSize(size: int64); - private function GetPos:int64 := (GetPosByte-_offset) div sz; - private procedure SetPos(pos:int64) := SetPosByte(_offset + pos*sz); - private function GetPosByte:int64; - private procedure SetPosByte(pos:int64); + private function GetPos: int64 := (GetPosByte-_offset) div sz; + private procedure SetPos(pos: int64) := SetPosByte(_offset + pos*sz); + private function GetPosByte: int64; + private procedure SetPosByte(pos: int64); - private function InternalReadLazy(c:integer; start_pos:int64):sequence of T; + private function InternalReadLazy(c: integer; start_pos: int64):sequence of T; ///Инициализирует переменную файла, не привязывая её к файлу на диске public constructor := exit; - ///Инициализирует переменную файла, привязывая её к файлу fname - public constructor(fname:string) := + + ///Инициализирует переменную файла, привязывая её к файлу с именем fname + public constructor(fname: string) := Assign(fname); - ///Инициализирует переменную файла, привязывая её к файлу fname - ///А так же устанавливая значение смещени от начала в байтах на offset - public constructor(fname:string; offset:int64) := + + ///Инициализирует переменную файла, привязывая её к файлу с именем fname + ///Устанавливает значение смещения от начала в байтах на offset + public constructor(fname: string; offset: int64) := Assign(fname, offset); + ///- constructor BlockFileOf<>(f:BlockFileOf<>); - ///Инициализирует новую переменную, создавая связку данной переменной - ///После вызова этого конструктора - переданная и созданная переменная будут - ///использовать общий файловый поток, но записывать разные типы данных (у них может быть разный T) - ///Это значит, что переменная которую передали в конструктор должно уже иметь открытый файловый поток + ///Инициализирует новую переменную, создавая связку с заданной переменной + ///После вызова этого конструктора переданная и созданная переменные будут использовать общий файловый поток, но записывать разные типы данных (у них может быть разный T) + ///Это значит, что переменная, которую передали в конструктор, уже должна иметь открытый файловый поток ///Метод Close разрывает эту связь. public constructor(f: BlockFileBase) := Link(f); + ///Возвращает или задаёт размер блока из одного элемента в байтах + ///Задавать это свойство не рекомендуется + public property TSize: integer read integer(sz) write sz := value; - ///Размер блока из одного элемента типа T, в байтах - ///Хоть это свойство и можно перезаписывать, но это не рекомендуется - ///Если перезаписать на число, большее чем было - в файл будет сохранять лишние нули - ///А если на меньшее - получите неопределённое поведение (скорее всего вылет, но далеко не сразу) - public property TSize:integer read integer(sz) write sz := value; + ///Возвращает или задаёт смещение от начала файла до начала элементов в байтах + public property Offset: int64 read _offset write _offset; - ///Смещение от начала файла до начала элементов (в байтах) - public property Offset:int64 read _offset write _offset; - ///Количество сохранённых в файл элементов типа T - ///Чтоб установить длину файла - надо открыть файл. Но прочитать длину можно не открывая - public property Size:int64 read GetFileSize write SetFileSize; - ///Полный размер файла, в байтах - ///Чтоб установить длину файла - надо открыть файл. Но прочитать длину можно не открывая - public property ByteSize:int64 read GetByteFileSize write SetByteFileSize; - ///Имя файла (только имя самого файла, без имени папки) - public property Name:string read GetName; - ///Полное имя файла (вместе с именами всех под-папок, вплодь до корня диска) - public property FullName:string read GetFullName; - ///Существует ли файл - public property Exists:boolean read GetExists; + ///Возвращает или задаёт количество сохранённых в файл элементов + ///Задавать можно только после открытия файла + public property Size: int64 read GetFileSize write SetFileSize; - ///Номер текущего элемета типа T в файле (нумеруя с 0) - public property Pos:int64 read GetPos write SetPos; - ///Номер текущего байта от начала файла (нумеруя с 0) - public property PosByte:int64 read GetPosByte write SetPosByte; - ///Привязана ли переменная к файлу - public property Assigned:boolean read fi <> nil; - ///Открыт ли файл - public property Opened:boolean read str <> nil; - ///Достигнут ли конец файла - public property EOF:boolean read ByteSize-PosByte < sz; - ///Основной поток открытого файла (или nil если файл не открыт) - ///Внимание! Любое действие которое изменит этот поток - приведёт к неожиданным последствиям, используйте его только если знаете что делаете - public property BaseStream:FileStream read str; - ///Переменная, которая записывает данные в основной поток (или nil если файл не открыт) - ///Внимание! Любое действие которое изменит основной поток файла - приведёт к неожиданным последствиям, используйте его только если знаете что делаете - public property BinWriter:BinaryWriter read bw; - ///Переменная, которая читает данные из основного потока (или nil если файл не открыт) - ///Внимание! Любое действие которое изменит основной поток файла - приведёт к неожиданным последствиям, используйте его только если знаете что делаете - public property BinReader:BinaryReader read br; - ///Переменная, показывающая данные о файле (или nil, если переменная не привязана к файлу) - public property FileInfo:System.IO.FileInfo read fi; + ///Возвращает или задаёт размер файла в байтах + ///Задавать можно только после открытия файла + public property ByteSize: int64 read GetByteFileSize write SetByteFileSize; + ///Возвращает неполное имя файла + public property Name: string read GetName; + ///Возвращает полное имя файла + public property FullName: string read GetFullName; - ///Привязывает данную переменную к файлу {fname} - ///Привязывать можно и к не существующим файлам, при откритии определёнными способами (как Rewrite) новый файл будет создан - public procedure Assign(fname:string); - ///Привязывает данную переменную к файлу {fname} - ///А так же устанавливая значение смещени от начала в байтах на offset - ///Привязывать можно и к не существующим файлам, при откритии определёнными способами (как Rewrite) новый файл будет создан - public procedure Assign(fname:string; offset:int64); - ///Убирает свять переменной и файла, если связь есть + ///Определяет, существует ли файл + public property Exists: boolean read GetExists; + + ///Возвращает номер текущего элемета в файле (нумеруя с 0) + public property Pos: int64 read GetPos write SetPos; + + ///Возвращает номер текущего байта от начала файла (нумеруя с 0) + public property PosByte: int64 read GetPosByte write SetPosByte; + + ///Определяет, привязана ли переменная к файлу + public property Assigned: boolean read fi <> nil; + + ///Определяет, открыт ли файл + public property Opened: boolean read str <> nil; + + ///Определяет, достигнут ли конец файла + public property EOF: boolean read ByteSize-PosByte < sz; + + ///Возвращает поток текущего файла (или nil если файл не открыт) + ///Внимание! Любое действие, связанное с изменением данного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете + public property BaseStream: FileStream read str; + + ///Возвращает BinaryWriter текущего файла (или nil если файл не открыт) + ///Внимание! Любое действие, связанное с изменением основного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете + public property BinWriter: BinaryWriter read bw; + + ///Возвращает BinaryReader текущего файла (или nil если файл не открыт) + ///Внимание! Любое действие, связанное с изменением основного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете + public property BinReader: BinaryReader read br; + + ///Возвращает FileInfo текущего файла (или nil, если переменная не привязана к файлу) + public property FileInfo: System.IO.FileInfo read fi; + + ///Привязывает текущий экземпляр BlockFileOf к файлу с именем fname + ///Привязывать можно и к несуществующим файлам, при открытии на запись будет создан новый файл + public procedure Assign(fname: string); + + ///Привязывает данную переменную к файлу с именем fname + ///Устанавливает смещение от начала файла до начала элементов в байтах на offset + ///Привязывать можно и к несуществующим файлам, при открытии чем то вроде Rewrite будет создан новый файл + public procedure Assign(fname: string; offset: int64); + + ///Удаляет связь переменной с файлом, если связь есть public procedure UnAssign; - ///Открывает файл, способом описанным в переменной mode - ///Чтоб получить переменную этого типа - пишите System.IO.FileMode.<способ_открытия_файла> - public procedure Open(mode:FileMode); + + ///Открывает файл способом mode + public procedure Open(mode: FileMode); + ///Удаляет связаный файл, если он существует public procedure Delete; + ///Переименовывает файл - ///Если указать другое расположение - файл будет перемещён - public procedure Rename(NewName:string); + ///При указании иного расположения файл будет перемещён + public procedure Rename(NewName: string); - ///Создает (или обнуляет) привязаный файл + ///Создает файл public procedure Rewrite; - ///Привязывает данную переменную к файлу {fname} и создает (или обнуляет) этот файл - public procedure Rewrite(fname:string); - ///Привязывает данную переменную к файлу {fname} и создает (или обнуляет) этот файл - ///А так же устанавливая значение смещени от начала в байтах на offset - public procedure Rewrite(fname:string; offset:int64); - ///Открывает файл (ожидается, что он уже существует) и устанавливает позицию на начало файла + ///Привязывает данную переменную к файлу с именем fname и создает (или обнуляет) его + public procedure Rewrite(fname: string); + + ///Привязывает данную переменную к файлу с именем fname и создает (или обнуляет) его + ///Устанавливает смещение от начала файла до начала элементов в байтах на offset + public procedure Rewrite(fname: string; offset: int64); + + ///Открывает файл на чтение public procedure Reset; - ///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию на начало файла - public procedure Reset(fname:string); - ///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию на начало файла - ///А так же устанавливая значение смещени от начала в байтах на offset - public procedure Reset(fname:string; offset:int64); - ///Открывает файл (ожидается, что он уже существует) и устанавливает позицию в конце файла + ///Привязывает данную переменную к файлу с именем fname и открывает его на чтение + public procedure Reset(fname: string); + + ///Привязывает данную переменную к файлу с именем fname и открывает его на чтение + ///Устанавливает смещение от начала файла до начала элементов в байтах на offset + public procedure Reset(fname: string; offset: int64); + + ///Открывает файл и устанавливает позицию на конец файла public procedure Append; - ///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию в конце файла - public procedure Append(fname:string); - ///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию в конце файла - ///А так же устанавливая значение смещени от начала в байтах на offset - public procedure Append(fname:string; offset:int64); - ///Переставляет позицию в файле на элемент #pos (нумеруя с 0) - public procedure Seek(pos:int64) := self.Pos := pos; - ///Переставляет файловый курсор на байт #pos (нумеруя с 0) от начала файла - public procedure SeekByte(pos:int64) := self.PosByte := pos; + ///Привязывает данную переменную к файлу с именем fname и открывает его, устанавливая позицию на конец файла + public procedure Append(fname: string); + + ///Привязывает данную переменную к файлу с именем fname и открывает его, устанавливая позицию на конец файла + ///Устанавливает смещение от начала файла до начала элементов в байтах на offset + public procedure Append(fname: string; offset: int64); + + ///Ставит позицию в файле на элемент pos (нумеруя с 0) + public procedure Seek(pos: int64) := self.Pos := pos; + + ///Ставит файловый курсор на байт pos (нумеруя с 0) от начала файла + public procedure SeekByte(pos: int64) := self.PosByte := pos; ///Записывает все изменения в файл и отчищает внутренние буферы - ///До вызова Flush или Close - все изменения и кеш хранятся в оперативной памяти - ///Поэтому, если вы записываете/читаете много (сотни мегабайт) - лучше вызывать Flush время от времени + ///До вызова Flush или Close все изменения и кеш хранятся в оперативной памяти + ///Поэтому, если вы проводите операции с большими объёмами памяти, лучше вызывать Flush время от времени public procedure Flush; + ///Сохраняет и закрывает файл, если он открыт public procedure Close; - ///Записывает один элемент одним блоком в файл - ///И переставляет файловый курсор на 1 элемет вперёд + ///Переставляет файловый курсор на 1 элемет вперёд public procedure Write(o: T); + ///Записывает массив элементов одним блоком в файл - ///И переставляет файловый курсор на o.Length элеметов вперёд - public procedure Write(params o:array of T); + ///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданном массиве + public procedure Write(params o: array of T); + ///Записывает последовательность элементов, у которой можно узнать длину, одним блоком в файл - ///И переставляет файловый курсор на o.Count элеметов вперёд - public procedure Write(o:ICollection); - ///Записывает последовательность элементов, у которой нельзя узнать длину, по 1 элементу типа T в файл - ///И переставляет файловый курсор на o.Count элеметов вперёд - public procedure Write(o:sequence of T); - ///Записывает count элементов массива, начиная с элемента #from, одним блоком в файл - ///И переставляет файловый курсор на сount элеметов вперёд - public procedure Write(o:array of T; from,count:integer); - ///Записывает count элементов последовательности, у которой можно узнать длину, начиная с элемента #from, одним блоком в файл - ///И переставляет файловый курсор на сount элеметов вперёд - public procedure Write(o:ICollection; from,count:integer); - ///Записывает count элементов последовательности, у которой нельзя узнать длину, начиная с элемента #from, одним блоком в файл - ///И после каждого элемента переставляет файловый курсор на 1 элемет вперёд - public procedure Write(o:sequence of T; from,count:integer); + ///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданной коллекции + public procedure Write(o: ICollection); + + ///Записывает последовательность элементов, у которой нельзя узнать длину, по 1 элементу в файл + ///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданной последовательности + public procedure Write(o: sequence of T); + + ///Записывает count элементов массива, начиная с элемента from, одним блоком в файл + ///Переставляет файловый курсор на сount элеметов вперёд + public procedure Write(o: array of T; from, count: integer); + + ///Записывает count элементов последовательности, у которой можно узнать длину, начиная с элемента from, одним блоком в файл + ///Переставляет файловый курсор на сount элеметов вперёд + public procedure Write(o: ICollection; from, count: integer); + + ///Записывает count элементов последовательности, у которой нельзя узнать длину, начиная с элемента from, одним блоком в файл + ///После каждого элемента переставляет файловый курсор на 1 элемет вперёд + public procedure Write(o: sequence of T; from, count: integer); ///Читает один элемент из файла одним блоком - ///И переставляет файловый курсор на 1 элемет вперёд - public function Read:T; - ///Читает массив из count одним блоком + ///Переставляет файловый курсор на 1 элемет вперёд + public function Read: T; + + ///Читает массив из count элементов из файла одним блоком + ///Переставляет файловый курсор на count элеметов вперёд + public function Read(count: integer): array of T; + + ///Читает массив из count элементов одним блоком, начиная с элемента start_elm ///И переставляет файловый курсор на count элеметов вперёд - public function Read(count:integer):array of T; - ///Читает массив из count элементов одним блоком, начиная с элемента #start_elm - ///И переставляет файловый курсор на count элеметов вперёд - public function Read(start_elm, count:integer):array of T; + public function Read(start_elm, count: integer): array of T; + ///Возвращает ленивую последовательность из count элементов - ///После завершения чтения - курсор окажется на эдлементе #(start_elm+count) - ///Каждый раз читать будет начиная с элемента, на котором сейчас стоит файловый курсор - public function ReadLazy(count:integer):sequence of T := InternalReadLazy(count, PosByte); - ///Возвращает ленивую последовательность из count элементов, начиная с элемента #start_elm - ///После прочтения i элементов последовательности - позиция в файле будет передвигаться на элемент #(start_elm+i) - ///Каждый раз читать будет начиная с элемента #start_elm - public function ReadLazy(start_elm, count:integer):sequence of T := InternalReadLazy(count, _offset + start_elm*sz); + ///После завершения чтения курсор окажется на последнем элементе возвращаемой последовательности + ///Каждый раз чтение будет происходить, начиная с элемента, на котором в данный момент стоит файловый курсор + public function ReadLazy(count: integer): sequence of T := InternalReadLazy(count, PosByte); + + ///Возвращает ленивую последовательность из count элементов, начиная с элемента start_elm + ///После завершения чтения курсор окажется на последнем элементе возвращаемой последовательности + ///Каждый раз чтение будет происходить, начиная с элемента start_elm + public function ReadLazy(start_elm, count: integer): sequence of T := InternalReadLazy(count, _offset + start_elm*sz); + ///Возвращает ленивую последовательность из блоков-массивов с элементами типа T - ///Каждый блок хранит столько элементов - чтоб не превышать объём в 4096 байт (4КБ) - ///После прочтения каждого блока - файловый корсор будет переставлен на его конец - public function ToSeqBlocks:sequence of array of T := ToSeqBlocks(4096); + ///Каждый блок хранит такое количество байт, которое не превышает 4 КБ + ///После прочтения каждого блока файловый корсор будет переставлен на его конец + public function ToSeqBlocks: sequence of array of T := ToSeqBlocks(4096); + ///Возвращает ленивую последовательность из блоков-массивов с элементами типа T - ///Каждый блок хранит столько элементов - чтоб не превышать объём в последовательность байт - ///После прочтения каждого блока - файловый корсор будет переставлен на его конец - public function ToSeqBlocks(blocks_size:integer):sequence of array of T; - ///Возвращает ленивую последовательность из всех элементов хранящихся в файле - ///После прочтения i элементов последовательности - позиция в файле будет передвигаться на элемент #i - public function ToSeq:sequence of T; + ///Каждый блок хранит такое количество байт, которое не превышает blocks_size + ///После чтения каждого блока файловый корсор будет переставлен на его конец + public function ToSeqBlocks(blocks_size: integer): sequence of array of T; + + ///Возвращает ленивую последовательность из всех элементов, хранящихся в файле + ///После прохода по элементам последовательности позиция в файле будет передвигаться на последний использованный элемент + public function ToSeq: sequence of T; protected procedure Finalize; override; begin @@ -316,19 +344,19 @@ type type FileNotAssignedException = class(Exception) constructor := - inherited Create($'Данная переменная не была привязана к файлу{10}Используйте метод Assign'); + inherited Create($'Данная переменная не привязана к файлу{10}Используйте метод Assign'); end; FileNotOpenedException = class(Exception) constructor(fname:string) := - inherited Create($'Файл {fname} ещё не открыт, откройте его с помощью Open, Reset, Append или Rewrite'); + inherited Create($'Файл {fname} не открыт, откройте его с помощью Open, Reset, Append или Rewrite'); end; FileNotClosedException = class(Exception) constructor(fname:string) := - inherited Create($'Файл {fname} ещё открыт, закройте его методом Close перед тем как продолжать'); + inherited Create($'Файл {fname} открыт, закройте его методом Close перед тем как продолжать'); end; CannotReadAfterEOF = class(Exception) constructor := - inherited Create($'Нельзя читать за пределами файла. Можно только записывать'); + inherited Create($'Нельзя читать за пределами файла'); end; {$endregion Exception's} @@ -337,7 +365,7 @@ implementation {$region Linking} -procedure BlockFileBase.Link(f:BlockFileBase); +procedure BlockFileBase.Link(f: BlockFileBase); begin if f.str = nil then raise new FileNotOpenedException($'{f.fi.FullName}, чью переменную передали в конструктор BlockFileOf,'); @@ -369,14 +397,14 @@ end; {$region property implementation} -function BlockFileOf.GetName:string; +function BlockFileOf.GetName: string; begin if fi = nil then raise new FileNotAssignedException; fi.Refresh; Result := fi.Name; end; -function BlockFileOf.GetFullName:string; +function BlockFileOf.GetFullName: string; begin if fi = nil then raise new FileNotAssignedException; //fi.Refresh;//А тут не надо @@ -385,7 +413,7 @@ end; -function BlockFileOf.GetByteFileSize:int64; +function BlockFileOf.GetByteFileSize: int64; begin if fi = nil then raise new FileNotAssignedException; if str <> nil then @@ -397,7 +425,7 @@ begin Result := fi.Length; end; -procedure BlockFileOf.SetByteFileSize(size:int64); +procedure BlockFileOf.SetByteFileSize(size: int64); begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -406,14 +434,14 @@ end; -function BlockFileOf.GetPosByte:int64; +function BlockFileOf.GetPosByte: int64; begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); Result := str.Position; end; -procedure BlockFileOf.SetPosByte(pos:int64); +procedure BlockFileOf.SetPosByte(pos: int64); begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -426,13 +454,13 @@ end; {$region Basic} -procedure BlockFileOf.Assign(fname:string); +procedure BlockFileOf.Assign(fname: string); begin if str <> nil then raise new FileNotClosedException(fi.FullName); fi := new System.IO.FileInfo(fname); end; -procedure BlockFileOf.Assign(fname:string; offset:int64); +procedure BlockFileOf.Assign(fname: string; offset: int64); begin Assign(fname); _offset := offset; @@ -444,7 +472,7 @@ begin fi := nil; end; -procedure BlockFileOf.Open(mode:FileMode); +procedure BlockFileOf.Open(mode: FileMode); begin if fi = nil then raise new FileNotAssignedException; if str <> nil then raise new FileNotClosedException(fi.FullName); @@ -459,14 +487,14 @@ begin fi.Delete; end; -function BlockFileOf.GetExists:boolean; +function BlockFileOf.GetExists: boolean; begin if fi = nil then raise new FileNotAssignedException; fi.Refresh; Result := fi.Exists; end; -procedure BlockFileOf.Rename(NewName:string); +procedure BlockFileOf.Rename(NewName: string); begin if fi = nil then raise new FileNotAssignedException; if str <> nil then raise new FileNotClosedException(fi.FullName); @@ -480,13 +508,13 @@ end; procedure BlockFileOf.Rewrite := Open(FileMode.Create); -procedure BlockFileOf.Rewrite(fname:string); +procedure BlockFileOf.Rewrite(fname: string); begin Assign(fname); Rewrite; end; -procedure BlockFileOf.Rewrite(fname:string; offset:int64); +procedure BlockFileOf.Rewrite(fname: string; offset: int64); begin Assign(fname, offset); Rewrite; @@ -499,13 +527,13 @@ end; procedure BlockFileOf.Reset := Open(FileMode.Open); -procedure BlockFileOf.Reset(fname:string); +procedure BlockFileOf.Reset(fname: string); begin Assign(fname); Reset; end; -procedure BlockFileOf.Reset(fname:string; offset:int64); +procedure BlockFileOf.Reset(fname: string; offset: int64); begin Assign(fname, offset); Reset; @@ -515,16 +543,19 @@ end; {$region Append} -procedure BlockFileOf.Append := -Open(FileMode.Append); +procedure BlockFileOf.Append; +begin + Open(FileMode.Open); + str.Position := str.Length; +end; -procedure BlockFileOf.Append(fname:string); +procedure BlockFileOf.Append(fname: string); begin Assign(fname); Append; end; -procedure BlockFileOf.Append(fname:string; offset:int64); +procedure BlockFileOf.Append(fname: string; offset: int64); begin Assign(fname, offset); Append; @@ -575,7 +606,7 @@ begin bw.Write(a); end; -procedure BlockFileOf.Write(params o:array of T); +procedure BlockFileOf.Write(params o: array of T); begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -594,7 +625,7 @@ begin bw.Write(a); end; -procedure BlockFileOf.Write(o:ICollection); +procedure BlockFileOf.Write(o: ICollection); type TArr = array of T; begin if o is TArr(var a) then @@ -622,13 +653,13 @@ begin bw.Write(a); end; -procedure BlockFileOf.Write(o:sequence of T) := +procedure BlockFileOf.Write(o: sequence of T) := if o is ICollection(var c) then Write(c) else foreach var el in o do Write(el); -procedure BlockFileOf.Write(o:array of T; from,count:integer); +procedure BlockFileOf.Write(o: array of T; from, count: integer); begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -647,7 +678,7 @@ begin bw.Write(a); end; -procedure BlockFileOf.Write(o:ICollection; from,count:integer); +procedure BlockFileOf.Write(o: ICollection; from, count: integer); type TArr = array of T; begin if o is TArr(var a) then @@ -678,7 +709,7 @@ begin bw.Write(a); end; -procedure BlockFileOf.Write(o:sequence of T; from,count:integer) := +procedure BlockFileOf.Write(o: sequence of T; from, count: integer) := if o is ICollection(var c) then Write(c,from,count) else Write(o.Skip(from).Take(count)); @@ -687,7 +718,7 @@ if o is ICollection(var c) then {$region Read} -function BlockFileOf.Read:T; +function BlockFileOf.Read: T; begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -703,7 +734,7 @@ begin gc_hnd.Free; end; -function BlockFileOf.Read(count:integer):array of T; +function BlockFileOf.Read(count: integer): array of T; begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -723,13 +754,13 @@ begin gc_hnd2.Free; end; -function BlockFileOf.Read(start_elm, count:integer):array of T; +function BlockFileOf.Read(start_elm, count:integer): array of T; begin Pos := start_elm; Result := Read(count); end; -function BlockFileOf.InternalReadLazy(c:integer; start_pos:int64):sequence of T; +function BlockFileOf.InternalReadLazy(c: integer; start_pos: int64): sequence of T; begin if fi = nil then raise new FileNotAssignedException; if str = nil then raise new FileNotOpenedException(fi.FullName); @@ -742,7 +773,7 @@ begin end; end; -function BlockFileOf.ToSeqBlocks(blocks_size:integer):sequence of array of T; +function BlockFileOf.ToSeqBlocks(blocks_size: integer): sequence of array of T; begin var c := blocks_size div sz; var i := 0; @@ -767,7 +798,7 @@ begin end; end; -function BlockFileOf.ToSeq:sequence of T; +function BlockFileOf.ToSeq: sequence of T; begin var i := 0; while not EOF do diff --git a/TestSuite/CompilationSamples/GraphWPF.pas b/TestSuite/CompilationSamples/GraphWPF.pas index 678919d5f..5c05c22aa 100644 --- a/TestSuite/CompilationSamples/GraphWPF.pas +++ b/TestSuite/CompilationSamples/GraphWPF.pas @@ -448,21 +448,20 @@ var GraphWindow: GraphWindowType; // ----------------------------------------------------- //>> События модуля GraphWPF # GraphWPF events // ----------------------------------------------------- -var - /// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши - OnMouseDown: procedure(x, y: real; mousebutton: integer); - /// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши - OnMouseUp: procedure(x, y: real; mousebutton: integer); - /// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши - OnMouseMove: procedure(x, y: real; mousebutton: integer); - /// Событие нажатия клавиши - OnKeyDown: procedure(k: Key); - /// Событие отжатия клавиши - OnKeyUp: procedure(k: Key); - /// Событие нажатия символьной клавиши - OnKeyPress: procedure(ch: char); - /// Событие изменения размера графического окна - OnResize: procedure; +/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши +var OnMouseDown: procedure(x, y: real; mousebutton: integer); +/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши +var OnMouseUp: procedure(x, y: real; mousebutton: integer); +/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши +var OnMouseMove: procedure(x, y: real; mousebutton: integer); +/// Событие нажатия клавиши +var OnKeyDown: procedure(k: Key); +/// Событие отжатия клавиши +var OnKeyUp: procedure(k: Key); +/// Событие нажатия символьной клавиши +var OnKeyPress: procedure(ch: char); +/// Событие изменения размера графического окна +var OnResize: procedure; //{{{--doc: Конец секции 3 }}} diff --git a/TestSuite/DerivedGenericField_1632BugFix.pas b/TestSuite/DerivedGenericField_1632BugFix.pas new file mode 100644 index 000000000..00e731574 --- /dev/null +++ b/TestSuite/DerivedGenericField_1632BugFix.pas @@ -0,0 +1,19 @@ +type + Base = class + XYZW: T; + procedure p(d: T); + begin + XYZW := d; + end; + end; + + Derived = class(Base) + //XYZW: T1; + end; + +begin + var a := new Derived; + a.p(2); + a.XYZW := 2; + Assert(a.XYZW=2); +end. \ No newline at end of file diff --git a/bin/Lib/GraphWPF.pas b/bin/Lib/GraphWPF.pas index 678919d5f..5c05c22aa 100644 --- a/bin/Lib/GraphWPF.pas +++ b/bin/Lib/GraphWPF.pas @@ -448,21 +448,20 @@ var GraphWindow: GraphWindowType; // ----------------------------------------------------- //>> События модуля GraphWPF # GraphWPF events // ----------------------------------------------------- -var - /// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши - OnMouseDown: procedure(x, y: real; mousebutton: integer); - /// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши - OnMouseUp: procedure(x, y: real; mousebutton: integer); - /// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши - OnMouseMove: procedure(x, y: real; mousebutton: integer); - /// Событие нажатия клавиши - OnKeyDown: procedure(k: Key); - /// Событие отжатия клавиши - OnKeyUp: procedure(k: Key); - /// Событие нажатия символьной клавиши - OnKeyPress: procedure(ch: char); - /// Событие изменения размера графического окна - OnResize: procedure; +/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши +var OnMouseDown: procedure(x, y: real; mousebutton: integer); +/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши +var OnMouseUp: procedure(x, y: real; mousebutton: integer); +/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши +var OnMouseMove: procedure(x, y: real; mousebutton: integer); +/// Событие нажатия клавиши +var OnKeyDown: procedure(k: Key); +/// Событие отжатия клавиши +var OnKeyUp: procedure(k: Key); +/// Событие нажатия символьной клавиши +var OnKeyPress: procedure(ch: char); +/// Событие изменения размера графического окна +var OnResize: procedure; //{{{--doc: Конец секции 3 }}} diff --git a/bin/PascalABCNET.chm b/bin/PascalABCNET.chm index b1372e445..44177aadb 100644 Binary files a/bin/PascalABCNET.chm and b/bin/PascalABCNET.chm differ