diff --git a/.gitattributes b/.gitattributes index 286868663b..a6836001c1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -580,6 +580,7 @@ components/codetools/ide/codystrconsts.pas svneol=native#text/pascal components/codetools/ide/codyutils.pas svneol=native#text/pascal components/codetools/ide/declarevardlg.lfm svneol=native#text/plain components/codetools/ide/declarevardlg.pas svneol=native#text/pascal +components/codetools/ide/identifierdictionary.pas svneol=native#text/plain components/codetools/ide/languages/codystrconsts.it.po svneol=native#text/plain components/codetools/ide/languages/codystrconsts.po svneol=native#text/plain components/codetools/ide/languages/codystrconsts.pt_BR.po svneol=native#text/plain diff --git a/components/codetools/ide/cody.lpk b/components/codetools/ide/cody.lpk index a2ff3509b5..2d6aab4088 100644 --- a/components/codetools/ide/cody.lpk +++ b/components/codetools/ide/cody.lpk @@ -4,7 +4,7 @@ - + @@ -19,7 +19,7 @@ - + @@ -65,6 +65,10 @@ + + + + diff --git a/components/codetools/ide/cody.pas b/components/codetools/ide/cody.pas index a14973f05a..273daa0e93 100644 --- a/components/codetools/ide/cody.pas +++ b/components/codetools/ide/cody.pas @@ -9,7 +9,8 @@ interface uses PPUListDlg, CodyStrConsts, AddAssignMethodDlg, CodyCtrls, CodyFrm, CodyRegistration, DeclareVarDlg, CodyUtils, CodyNodeInfoDlg, - CodyCopyDeclaration, AddWithBlockDlg, LazarusPackageIntf; + CodyCopyDeclaration, AddWithBlockDlg, IdentifierDictionary, + LazarusPackageIntf; implementation diff --git a/components/codetools/ide/identifierdictionary.pas b/components/codetools/ide/identifierdictionary.pas new file mode 100644 index 0000000000..1354f226a6 --- /dev/null +++ b/components/codetools/ide/identifierdictionary.pas @@ -0,0 +1,275 @@ +{ + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************** + + Author: Mattias Gaertner + + Abstract: + Quick lookup database for identifiers in units. +} +unit IdentifierDictionary; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, AVL_Tree, BasicCodeTools, FileProcs; + +type + TUDIdentifier = class; + TUDUnit = class; + TUnitDictionary = class; + + { TUDItem } + + TUDItem = class + public + Name: string; + end; + + { TUDFileItem } + + TUDFileItem = class(TUDItem) + public + Filename: string; + constructor Create(const aName, aFilename: string); + end; + + { TUDUnitGroup } + + TUDUnitGroup = class(TUDFileItem) + public + Dictionary: TUnitDictionary; + Units: TAVLTree; // tree of TIDUnit sorted with CompareIDItems + constructor Create(const aName, aFilename: string); + destructor Destroy; override; + function AddUnit(NewUnit: TUDUnit): TUDUnit; overload; + function AddUnit(const aName, aFilename: string): TUDUnit; overload; + end; + + { TUDUnit } + + TUDUnit = class(TUDFileItem) + public + FileAge: longint; + FirstIdentifier: TUDIdentifier; + UnitGroups: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems + constructor Create(const aName, aFilename: string); + destructor Destroy; override; + function AddIdentifier(aName: PChar): TUDIdentifier; + end; + + { TUDIdentifier } + + TUDIdentifier = class(TUDItem) + public + DUnit: TUDUnit; + NextInUnit: TUDIdentifier; + constructor Create(const aName: string); overload; + constructor Create(aName: PChar); overload; + end; + + { TUnitDictionary } + + TUnitDictionary = class + private + FIdentifiers: TAVLTree; // tree of TUDIdentifier sorted with CompareIDItems + FUnitsByName: TAVLTree; // tree of TUDUnit sorted with CompareIDItems + FUnitsByFilename: TAVLTree; // tree of TUDUnit sorted with CompareIDFileItems + FUnitGroupsByName: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems + FUnitGroupsByFilename: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDFileItems + public + constructor Create; + destructor Destroy; override; + procedure Clear; + function AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup; overload; + function AddUnitGroup(const aName, aFilename: string): TUDUnitGroup; overload; + end; + +function CompareNameWithIDItem(NamePChar, Item: Pointer): integer; +function CompareIDItems(Item1, Item2: Pointer): integer; +function CompareFileNameWithIDFileItem(NameAnsiString, Item: Pointer): integer; +function CompareIDFileItems(Item1, Item2: Pointer): integer; + +procedure IDCheckUnitNameAndFilename(const aName, aFilename: string); + +implementation + +function CompareNameWithIDItem(NamePChar, Item: Pointer): integer; +var + i: TUDItem absolute Item; +begin + Result:=CompareDottedIdentifiers(PChar(NamePChar),PChar(Pointer(i.Name))); +end; + +function CompareIDItems(Item1, Item2: Pointer): integer; +var + i1: TUDItem absolute Item1; + i2: TUDItem absolute Item2; +begin + Result:=CompareDottedIdentifiers(PChar(Pointer(i1.Name)),PChar(Pointer(i2.Name))); +end; + +function CompareFileNameWithIDFileItem(NameAnsiString, Item: Pointer): integer; +var + i: TUDFileItem absolute Item; +begin + Result:=CompareFilenames(AnsiString(NameAnsiString),i.Filename); +end; + +function CompareIDFileItems(Item1, Item2: Pointer): integer; +var + i1: TUDFileItem absolute Item1; + i2: TUDFileItem absolute Item2; +begin + Result:=CompareFilenames(i1.Filename,i2.Filename); +end; + +procedure IDCheckUnitNameAndFilename(const aName, aFilename: string); + + procedure InvalidName; + begin + raise Exception.Create('invalid UnitName="'+aName+'" Filename="'+aFilename+'"'); + end; + +var + ShortName: String; +begin + ShortName:=ExtractFileNameOnly(aFilename); + if CompareDottedIdentifiers(PChar(Pointer(aName)),PChar(Pointer(ShortName)))<>0 + then + InvalidName; +end; + +{ TUDIdentifier } + +constructor TUDIdentifier.Create(const aName: string); +begin + Name:=aName; +end; + +constructor TUDIdentifier.Create(aName: PChar); +begin + Name:=GetIdentifier(aName); +end; + +constructor TUDUnit.Create(const aName, aFilename: string); +begin + IDCheckUnitNameAndFilename(aName,aFilename); + inherited Create(aName,aFilename); + UnitGroups:=TAVLTree.Create(@CompareIDItems); +end; + +destructor TUDUnit.Destroy; +begin + // the groups are freed by the TUnitDictionary + FreeAndNil(UnitGroups); + inherited Destroy; +end; + +function TUDUnit.AddIdentifier(aName: PChar): TUDIdentifier; +begin + Result:=TUDIdentifier.Create(aName); +end; + +{ TUDUnitGroup } + +constructor TUDUnitGroup.Create(const aName, aFilename: string); +begin + IDCheckUnitNameAndFilename(aName,aFilename); + inherited Create(aName,aFilename); + Units:=TAVLTree.Create(@CompareIDItems); +end; + +destructor TUDUnitGroup.Destroy; +begin + // the units are freed by the TIdentifierDictionary + FreeAndNil(Units); + inherited Destroy; +end; + +function TUDUnitGroup.AddUnit(NewUnit: TUDUnit): TUDUnit; +begin + Result:=NewUnit; + Units.Add(Result); +end; + +function TUDUnitGroup.AddUnit(const aName, aFilename: string): TUDUnit; +begin + Result:=AddUnit(TUDUnit.Create(aName,aFilename)); +end; + +{ TUDFileItem } + +constructor TUDFileItem.Create(const aName, aFilename: string); +begin + Name:=aName; + Filename:=aFilename; +end; + +{ TUnitDictionary } + +constructor TUnitDictionary.Create; +begin + FIdentifiers:=TAVLTree.Create(@CompareIDItems); + FUnitsByName:=TAVLTree.Create(@CompareIDItems); + FUnitsByFilename:=TAVLTree.Create(@CompareIDFileItems); + FUnitGroupsByName:=TAVLTree.Create(@CompareIDItems); + FUnitGroupsByFilename:=TAVLTree.Create(@CompareIDFileItems); +end; + +destructor TUnitDictionary.Destroy; +begin + Clear; + FreeAndNil(FIdentifiers); + FreeAndNil(FUnitsByName); + FreeAndNil(FUnitsByFilename); + FreeAndNil(FUnitGroupsByName); + FreeAndNil(FUnitGroupsByFilename); + inherited Destroy; +end; + +procedure TUnitDictionary.Clear; +begin + FUnitGroupsByFilename.Clear; + FUnitGroupsByName.FreeAndClear; + FUnitsByFilename.Clear; + FUnitsByName.FreeAndClear; + FIdentifiers.FreeAndClear; +end; + +function TUnitDictionary.AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup; +begin + if Group.Dictionary<>nil then + raise Exception.Create('TIdentifierDictionary.AddUnitGroup Group.Dictionary<>nil'); + Result:=Group; + Result.Dictionary:=Self; + FUnitGroupsByName.Add(Result); + FUnitGroupsByFilename.Add(Result); +end; + +function TUnitDictionary.AddUnitGroup(const aName, aFilename: string + ): TUDUnitGroup; +begin + Result:=AddUnitGroup(TUDUnitGroup.Create(aName,aFilename)); +end; + +end. +