mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 14:19:19 +02:00
232 lines
6.9 KiB
ObjectPascal
232 lines
6.9 KiB
ObjectPascal
{
|
|
*****************************************************************************
|
|
This file is part of the LazEdit package from the Lazarus IDE.
|
|
|
|
This content of this file is licensensed: Modified LGPL-2
|
|
Or at the users choice: Modified LGPL-3
|
|
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
|
|
for details about the license.
|
|
|
|
Alternatively, the contents of this file may be used under the terms of the
|
|
Mozilla Public License Version 1.1 http://www.mozilla.org/MPL/
|
|
|
|
A copy used under either License can have the other Licenses removed from this
|
|
header. A note should be added that the original file is available with the
|
|
above choice of License.
|
|
*****************************************************************************
|
|
}
|
|
unit LazEditHighlighterUtils;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, fgl, LazClasses, Generics.Collections, Generics.Defaults;
|
|
|
|
type
|
|
|
|
{ TLazHighlighterRange }
|
|
|
|
TLazHighlighterRange = class
|
|
protected
|
|
function DoCompare(Range: TLazHighlighterRange; ASize: integer): integer; inline;
|
|
function Compare(Range: TLazHighlighterRange): integer; virtual;
|
|
public
|
|
constructor Create(Template: TLazHighlighterRange); virtual;
|
|
procedure Assign(Src: TLazHighlighterRange); virtual; abstract;
|
|
end;
|
|
TLazHighlighterRangeClass = class of TLazHighlighterRange;
|
|
|
|
{ TLazHighlighterRanges }
|
|
|
|
TLazHighlighterRanges = class(TRefCountedObject)
|
|
constructor Create; virtual;
|
|
destructor Destroy; override;
|
|
function GetEqual(ARange: TLazHighlighterRange): TLazHighlighterRange; virtual; abstract;
|
|
|
|
procedure Allocate; deprecated 'use AddReference // will be removed in 5.99';
|
|
procedure Release; deprecated 'use ReleaseReference // will be removed in 5.99';
|
|
end;
|
|
TLazHighlighterRangesClass = class of TLazHighlighterRanges;
|
|
|
|
{ TLazHighlighterRangeForDictionary }
|
|
|
|
TLazHighlighterRangeForDictionary = class(TLazHighlighterRange)
|
|
function GetHashCode(AnInitVal: UInt32 = 0): UInt32; reintroduce; virtual;
|
|
function GetHashCodeWithoutClass(AnInitVal: UInt32 = 0): UInt32;
|
|
end;
|
|
|
|
{ TLazHighlighterRangesDictionary }
|
|
|
|
TLazHighlighterRangesDictionary = class(TLazHighlighterRanges)
|
|
private type
|
|
TLazHLrRangeDictionary = specialize TDictionary<TLazHighlighterRangeForDictionary, TLazHighlighterRangeForDictionary>;
|
|
private
|
|
FRangeDict: TLazHLrRangeDictionary;
|
|
protected
|
|
procedure FreeItems;
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
function GetEqual(ARange: TLazHighlighterRange): TLazHighlighterRange; override;
|
|
end;
|
|
|
|
function GetHighlighterRangesForHighlighter(
|
|
AnHighlighterClass: TClass {TSynCustomHighlighterClass};
|
|
ANewClass: TLazHighlighterRangesClass
|
|
): TLazHighlighterRanges;
|
|
|
|
implementation
|
|
|
|
type
|
|
TLazHighlighterRangesList = specialize TFPGMap<Pointer, TLazHighlighterRanges>;
|
|
|
|
ILazHighlighterRangeEqualityComparer = specialize IEqualityComparer<TLazHighlighterRangeForDictionary>;
|
|
|
|
{ TLazHighlighterRangeEqualityComparer }
|
|
|
|
TLazHighlighterRangeEqualityComparer = class(TInterfacedObject, ILazHighlighterRangeEqualityComparer)
|
|
public
|
|
function Equals(const ALeft, ARight: TLazHighlighterRangeForDictionary): Boolean; reintroduce;
|
|
function GetHashCode(const AValue: TLazHighlighterRangeForDictionary): UInt32; reintroduce;
|
|
end;
|
|
|
|
var
|
|
LazHighlighterRangesList: TLazHighlighterRangesList;
|
|
|
|
function GetHighlighterRangesForHighlighter(AnHighlighterClass: TClass;
|
|
ANewClass: TLazHighlighterRangesClass): TLazHighlighterRanges;
|
|
begin
|
|
if LazHighlighterRangesList = nil then
|
|
LazHighlighterRangesList := TLazHighlighterRangesList.Create;
|
|
|
|
if not LazHighlighterRangesList.TryGetData(Pointer(AnHighlighterClass), Result) then begin
|
|
Result := ANewClass.Create;
|
|
LazHighlighterRangesList.Add(Pointer(AnHighlighterClass), Result);
|
|
end;
|
|
end;
|
|
|
|
{ TLazHighlighterRangeEqualityComparer }
|
|
|
|
function TLazHighlighterRangeEqualityComparer.Equals(const ALeft,
|
|
ARight: TLazHighlighterRangeForDictionary): Boolean;
|
|
begin
|
|
Result := ALeft.Compare(ARight) = 0;
|
|
end;
|
|
|
|
function TLazHighlighterRangeEqualityComparer.GetHashCode(
|
|
const AValue: TLazHighlighterRangeForDictionary): UInt32;
|
|
begin
|
|
Result := AValue.GetHashCode;
|
|
end;
|
|
|
|
{ TLazHighlighterRange }
|
|
|
|
function TLazHighlighterRange.DoCompare(Range: TLazHighlighterRange; ASize: integer): integer;
|
|
begin
|
|
Result := InstanceSize - Range.InstanceSize;
|
|
if Result = 0 then
|
|
Result := CompareByte(Pointer(Self)^, Pointer(Range)^, ASize);
|
|
end;
|
|
|
|
function TLazHighlighterRange.Compare(Range: TLazHighlighterRange): integer;
|
|
begin
|
|
Result := DoCompare(Range, InstanceSize);
|
|
end;
|
|
|
|
constructor TLazHighlighterRange.Create(Template: TLazHighlighterRange);
|
|
begin
|
|
if (Template<>nil) and (ClassType<>Template.ClassType) then
|
|
raise Exception.Create('wrong tmpl class');
|
|
if Template<>nil then
|
|
Assign(Template);
|
|
end;
|
|
|
|
{ TLazHighlighterRanges }
|
|
|
|
constructor TLazHighlighterRanges.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
destructor TLazHighlighterRanges.Destroy;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if LazHighlighterRangesList <> nil then begin
|
|
i := LazHighlighterRangesList.IndexOfData(Self);
|
|
assert(i>=0, 'TLazHighlighterRangesDictionary.Destroy: i>=0');
|
|
LazHighlighterRangesList.Delete(i);
|
|
if LazHighlighterRangesList.Count = 0 then
|
|
FreeAndNil(LazHighlighterRangesList);
|
|
end;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TLazHighlighterRanges.Allocate;
|
|
begin
|
|
AddReference;
|
|
end;
|
|
|
|
procedure TLazHighlighterRanges.Release;
|
|
begin
|
|
ReleaseReference;
|
|
end;
|
|
|
|
{ TLazHighlighterRangeForDictionary }
|
|
|
|
function TLazHighlighterRangeForDictionary.GetHashCode(AnInitVal: UInt32): UInt32;
|
|
begin
|
|
Result := TDefaultHashFactory.GetHashCode(Pointer(Self), InstanceSize, AnInitVal);
|
|
end;
|
|
|
|
function TLazHighlighterRangeForDictionary.GetHashCodeWithoutClass(AnInitVal: UInt32): UInt32;
|
|
begin
|
|
Result := TDefaultHashFactory.GetHashCode(Pointer(Self) + SizeOf(Pointer), InstanceSize - SizeOf(Pointer), AnInitVal);
|
|
end;
|
|
|
|
{ TLazHighlighterRangesDictionary }
|
|
|
|
procedure TLazHighlighterRangesDictionary.FreeItems;
|
|
var
|
|
i: TLazHighlighterRangeForDictionary;
|
|
begin
|
|
for i in FRangeDict.Values do i.Free;
|
|
FRangeDict.Clear;
|
|
end;
|
|
|
|
constructor TLazHighlighterRangesDictionary.Create;
|
|
begin
|
|
FRangeDict := TLazHLrRangeDictionary.Create(TLazHighlighterRangeEqualityComparer.Create);
|
|
inherited Create;
|
|
end;
|
|
|
|
destructor TLazHighlighterRangesDictionary.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FreeItems;
|
|
FRangeDict.Free;
|
|
end;
|
|
|
|
function TLazHighlighterRangesDictionary.GetEqual(ARange: TLazHighlighterRange
|
|
): TLazHighlighterRange;
|
|
var
|
|
DictRange: TLazHighlighterRangeForDictionary absolute ARange;
|
|
DictResult: TLazHighlighterRangeForDictionary absolute Result;
|
|
begin
|
|
Result := nil;
|
|
if ARange=nil then
|
|
exit;
|
|
|
|
if not FRangeDict.TryGetValue(DictRange, DictResult) then begin
|
|
Result := TLazHighlighterRangeClass(DictRange.ClassType).Create(DictRange);
|
|
FRangeDict.Add(DictResult, DictResult);
|
|
end;
|
|
end;
|
|
|
|
finalization
|
|
LazHighlighterRangesList.Free;
|
|
end.
|
|
|