mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-06 02:59:30 +01:00
cody: dictionary: parse unit
git-svn-id: trunk@33492 -
This commit is contained in:
parent
a4621e4039
commit
7c6f076695
@ -79,7 +79,7 @@ type
|
|||||||
procedure ConsistencyCheck;
|
procedure ConsistencyCheck;
|
||||||
property Tool: TPascalParserTool read FTool;
|
property Tool: TPascalParserTool read FTool;
|
||||||
property Complete: boolean read FComplete write SetComplete;
|
property Complete: boolean read FComplete write SetComplete;
|
||||||
property Items: TAVLTree read FItems;
|
property Items: TAVLTree read FItems; // Tree of PInterfaceIdentCacheEntry
|
||||||
function CalcMemSize: PtrUInt;
|
function CalcMemSize: PtrUInt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,8 @@ unit unitdictionary;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, AVL_Tree, BasicCodeTools, FileProcs;
|
Classes, SysUtils, AVL_Tree, BasicCodeTools, FileProcs,
|
||||||
|
FindDeclarationCache, CodeToolManager;
|
||||||
|
|
||||||
type
|
type
|
||||||
TUDIdentifier = class;
|
TUDIdentifier = class;
|
||||||
@ -62,6 +63,7 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function AddUnit(NewUnit: TUDUnit): TUDUnit; overload;
|
function AddUnit(NewUnit: TUDUnit): TUDUnit; overload;
|
||||||
function AddUnit(const aName, aFilename: string): TUDUnit; overload;
|
function AddUnit(const aName, aFilename: string): TUDUnit; overload;
|
||||||
|
procedure RemoveUnit(TheUnit: TUDUnit);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TUDUnit }
|
{ TUDUnit }
|
||||||
@ -69,11 +71,14 @@ type
|
|||||||
TUDUnit = class(TUDFileItem)
|
TUDUnit = class(TUDFileItem)
|
||||||
public
|
public
|
||||||
FileAge: longint;
|
FileAge: longint;
|
||||||
FirstIdentifier: TUDIdentifier;
|
FirstIdentifier, LastIdentifier: TUDIdentifier;
|
||||||
UnitGroups: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems
|
UnitGroups: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems
|
||||||
constructor Create(const aName, aFilename: string);
|
constructor Create(const aName, aFilename: string);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function AddIdentifier(aName: PChar): TUDIdentifier;
|
function AddIdentifier(Item: TUDIdentifier): TUDIdentifier;
|
||||||
|
procedure ClearIdentifiers;
|
||||||
|
function IsInGroup(Group: TUDUnitGroup): boolean;
|
||||||
|
function GetDictionary: TUnitDictionary;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TUDIdentifier }
|
{ TUDIdentifier }
|
||||||
@ -90,17 +95,22 @@ type
|
|||||||
|
|
||||||
TUnitDictionary = class
|
TUnitDictionary = class
|
||||||
private
|
private
|
||||||
|
FDefaultGroup: TUDUnitGroup;
|
||||||
FIdentifiers: TAVLTree; // tree of TUDIdentifier sorted with CompareIDItems
|
FIdentifiers: TAVLTree; // tree of TUDIdentifier sorted with CompareIDItems
|
||||||
FUnitsByName: TAVLTree; // tree of TUDUnit sorted with CompareIDItems
|
FUnitsByName: TAVLTree; // tree of TUDUnit sorted with CompareIDItems
|
||||||
FUnitsByFilename: TAVLTree; // tree of TUDUnit sorted with CompareIDFileItems
|
FUnitsByFilename: TAVLTree; // tree of TUDUnit sorted with CompareIDFileItems
|
||||||
FUnitGroupsByName: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems
|
FUnitGroupsByName: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDItems
|
||||||
FUnitGroupsByFilename: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDFileItems
|
FUnitGroupsByFilename: TAVLTree; // tree of TUDUnitGroup sorted with CompareIDFileItems
|
||||||
|
procedure RemoveIdentifier(Item: TUDIdentifier);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Clear;
|
procedure Clear(CreateDefaults: boolean = true);
|
||||||
function AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup; overload;
|
function AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup; overload;
|
||||||
function AddUnitGroup(const aName, aFilename: string): TUDUnitGroup; overload;
|
function AddUnitGroup(const aName, aFilename: string): TUDUnitGroup; overload;
|
||||||
|
property DefaultGroup: TUDUnitGroup read FDefaultGroup;
|
||||||
|
procedure ParseUnit(Tool: TCodeTool; Group: TUDUnitGroup = nil);
|
||||||
|
function FindUnitWithFilename(const aFilename: string): TUDUnit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CompareNameWithIDItem(NamePChar, Item: Pointer): integer;
|
function CompareNameWithIDItem(NamePChar, Item: Pointer): integer;
|
||||||
@ -184,9 +194,42 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TUDUnit.AddIdentifier(aName: PChar): TUDIdentifier;
|
function TUDUnit.AddIdentifier(Item: TUDIdentifier): TUDIdentifier;
|
||||||
begin
|
begin
|
||||||
Result:=TUDIdentifier.Create(aName);
|
Result:=Item;
|
||||||
|
Result.DUnit:=Self;
|
||||||
|
if LastIdentifier<>nil then
|
||||||
|
LastIdentifier.NextInUnit:=Result
|
||||||
|
else
|
||||||
|
FirstIdentifier:=Result;
|
||||||
|
Result.NextInUnit:=nil;
|
||||||
|
LastIdentifier:=Result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUDUnit.ClearIdentifiers;
|
||||||
|
var
|
||||||
|
Item: TUDIdentifier;
|
||||||
|
Dictionary: TUnitDictionary;
|
||||||
|
begin
|
||||||
|
Dictionary:=GetDictionary;
|
||||||
|
while FirstIdentifier<>nil do begin
|
||||||
|
Item:=FirstIdentifier;
|
||||||
|
FirstIdentifier:=Item.NextInUnit;
|
||||||
|
Item.NextInUnit:=nil;
|
||||||
|
Dictionary.RemoveIdentifier(Item);
|
||||||
|
Item.Free;
|
||||||
|
end;
|
||||||
|
LastIdentifier:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUDUnit.IsInGroup(Group: TUDUnitGroup): boolean;
|
||||||
|
begin
|
||||||
|
Result:=UnitGroups.FindPointer(Group)<>nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUDUnit.GetDictionary: TUnitDictionary;
|
||||||
|
begin
|
||||||
|
Result:=TUDUnitGroup(UnitGroups.Root.Data).Dictionary;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TUDUnitGroup }
|
{ TUDUnitGroup }
|
||||||
@ -208,7 +251,9 @@ end;
|
|||||||
function TUDUnitGroup.AddUnit(NewUnit: TUDUnit): TUDUnit;
|
function TUDUnitGroup.AddUnit(NewUnit: TUDUnit): TUDUnit;
|
||||||
begin
|
begin
|
||||||
Result:=NewUnit;
|
Result:=NewUnit;
|
||||||
|
if Units.FindPointer(NewUnit)<>nil then exit;
|
||||||
Units.Add(Result);
|
Units.Add(Result);
|
||||||
|
Result.UnitGroups.Add(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TUDUnitGroup.AddUnit(const aName, aFilename: string): TUDUnit;
|
function TUDUnitGroup.AddUnit(const aName, aFilename: string): TUDUnit;
|
||||||
@ -216,6 +261,12 @@ begin
|
|||||||
Result:=AddUnit(TUDUnit.Create(aName,aFilename));
|
Result:=AddUnit(TUDUnit.Create(aName,aFilename));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TUDUnitGroup.RemoveUnit(TheUnit: TUDUnit);
|
||||||
|
begin
|
||||||
|
Units.RemovePointer(TheUnit);
|
||||||
|
TheUnit.UnitGroups.RemovePointer(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TUDFileItem }
|
{ TUDFileItem }
|
||||||
|
|
||||||
constructor TUDFileItem.Create(const aName, aFilename: string);
|
constructor TUDFileItem.Create(const aName, aFilename: string);
|
||||||
@ -226,6 +277,11 @@ end;
|
|||||||
|
|
||||||
{ TUnitDictionary }
|
{ TUnitDictionary }
|
||||||
|
|
||||||
|
procedure TUnitDictionary.RemoveIdentifier(Item: TUDIdentifier);
|
||||||
|
begin
|
||||||
|
FIdentifiers.RemovePointer(Item);
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TUnitDictionary.Create;
|
constructor TUnitDictionary.Create;
|
||||||
begin
|
begin
|
||||||
FIdentifiers:=TAVLTree.Create(@CompareIDItems);
|
FIdentifiers:=TAVLTree.Create(@CompareIDItems);
|
||||||
@ -233,11 +289,12 @@ begin
|
|||||||
FUnitsByFilename:=TAVLTree.Create(@CompareIDFileItems);
|
FUnitsByFilename:=TAVLTree.Create(@CompareIDFileItems);
|
||||||
FUnitGroupsByName:=TAVLTree.Create(@CompareIDItems);
|
FUnitGroupsByName:=TAVLTree.Create(@CompareIDItems);
|
||||||
FUnitGroupsByFilename:=TAVLTree.Create(@CompareIDFileItems);
|
FUnitGroupsByFilename:=TAVLTree.Create(@CompareIDFileItems);
|
||||||
|
FDefaultGroup:=AddUnitGroup('','');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TUnitDictionary.Destroy;
|
destructor TUnitDictionary.Destroy;
|
||||||
begin
|
begin
|
||||||
Clear;
|
Clear(false);
|
||||||
FreeAndNil(FIdentifiers);
|
FreeAndNil(FIdentifiers);
|
||||||
FreeAndNil(FUnitsByName);
|
FreeAndNil(FUnitsByName);
|
||||||
FreeAndNil(FUnitsByFilename);
|
FreeAndNil(FUnitsByFilename);
|
||||||
@ -246,13 +303,16 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TUnitDictionary.Clear;
|
procedure TUnitDictionary.Clear(CreateDefaults: boolean);
|
||||||
begin
|
begin
|
||||||
|
FDefaultGroup:=nil;
|
||||||
FUnitGroupsByFilename.Clear;
|
FUnitGroupsByFilename.Clear;
|
||||||
FUnitGroupsByName.FreeAndClear;
|
FUnitGroupsByName.FreeAndClear;
|
||||||
FUnitsByFilename.Clear;
|
FUnitsByFilename.Clear;
|
||||||
FUnitsByName.FreeAndClear;
|
FUnitsByName.FreeAndClear;
|
||||||
FIdentifiers.FreeAndClear;
|
FIdentifiers.FreeAndClear;
|
||||||
|
if CreateDefaults then
|
||||||
|
FDefaultGroup:=AddUnitGroup('','');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TUnitDictionary.AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup;
|
function TUnitDictionary.AddUnitGroup(Group: TUDUnitGroup): TUDUnitGroup;
|
||||||
@ -271,5 +331,102 @@ begin
|
|||||||
Result:=AddUnitGroup(TUDUnitGroup.Create(aName,aFilename));
|
Result:=AddUnitGroup(TUDUnitGroup.Create(aName,aFilename));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TUnitDictionary.ParseUnit(Tool: TCodeTool; Group: TUDUnitGroup);
|
||||||
|
var
|
||||||
|
SrcTree: TAVLTree;
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
Item: PInterfaceIdentCacheEntry;
|
||||||
|
UnitFilename: String;
|
||||||
|
CurUnit: TUDUnit;
|
||||||
|
NiceName: String;
|
||||||
|
SrcName: String;
|
||||||
|
IdentifierItem: TUDIdentifier;
|
||||||
|
Changed: Boolean;
|
||||||
|
begin
|
||||||
|
if Tool=nil then exit;
|
||||||
|
if Group=nil then
|
||||||
|
Group:=DefaultGroup;
|
||||||
|
// parse unit
|
||||||
|
Tool.BuildInterfaceIdentifierCache(true);
|
||||||
|
|
||||||
|
// get unit name from source
|
||||||
|
UnitFilename:=Tool.MainFilename;
|
||||||
|
NiceName:=ExtractFileNameOnly(UnitFilename);
|
||||||
|
if (LowerCase(NiceName)=NiceName)
|
||||||
|
or (UpperCase(NiceName)=NiceName) then begin
|
||||||
|
SrcName:=Tool.GetSourceName(false);
|
||||||
|
if CompareDottedIdentifiers(PChar(SrcName),PChar(NiceName))=0 then
|
||||||
|
NiceName:=SrcName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// find/create unit
|
||||||
|
CurUnit:=FindUnitWithFilename(UnitFilename);
|
||||||
|
if CurUnit<>nil then begin
|
||||||
|
// old unit
|
||||||
|
if (Group<>DefaultGroup) then begin
|
||||||
|
if CurUnit.IsInGroup(DefaultGroup) then begin
|
||||||
|
// move from no group to some group
|
||||||
|
DefaultGroup.RemoveUnit(CurUnit);
|
||||||
|
end;
|
||||||
|
Group.AddUnit(CurUnit);
|
||||||
|
end;
|
||||||
|
// update name
|
||||||
|
if CurUnit.Name<>NiceName then
|
||||||
|
CurUnit.Name:=NiceName;
|
||||||
|
end else begin
|
||||||
|
// new unit
|
||||||
|
CurUnit:=Group.AddUnit(NiceName,UnitFilename);
|
||||||
|
FUnitsByName.Add(CurUnit);
|
||||||
|
FUnitsByFilename.Add(CurUnit);
|
||||||
|
end;
|
||||||
|
|
||||||
|
SrcTree:=Tool.InterfaceIdentifierCache.Items;
|
||||||
|
// check if something changed
|
||||||
|
AVLNode:=SrcTree.FindLowest;
|
||||||
|
Changed:=false;
|
||||||
|
IdentifierItem:=CurUnit.FirstIdentifier;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
Item:=PInterfaceIdentCacheEntry(AVLNode.Data);
|
||||||
|
if (Item^.Node<>nil) and (Item^.Identifier<>nil) then begin
|
||||||
|
if (IdentifierItem=nil)
|
||||||
|
or (CompareIdentifiers(Item^.Identifier,PChar(Pointer(IdentifierItem.Name)))<>0)
|
||||||
|
then begin
|
||||||
|
Changed:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
IdentifierItem:=IdentifierItem.NextInUnit;
|
||||||
|
end;
|
||||||
|
AVLNode:=SrcTree.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
if IdentifierItem<>nil then
|
||||||
|
Changed:=true; // the old list had more identifiers
|
||||||
|
if Changed then begin
|
||||||
|
// list of identifiers has changed => rebuild
|
||||||
|
CurUnit.ClearIdentifiers;
|
||||||
|
AVLNode:=SrcTree.FindLowest;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
Item:=PInterfaceIdentCacheEntry(AVLNode.Data);
|
||||||
|
if (Item^.Node<>nil) and (Item^.Identifier<>nil) then begin
|
||||||
|
IdentifierItem:=TUDIdentifier.Create(Item^.Identifier);
|
||||||
|
CurUnit.AddIdentifier(IdentifierItem);
|
||||||
|
FIdentifiers.Add(IdentifierItem);
|
||||||
|
end;
|
||||||
|
AVLNode:=SrcTree.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitDictionary.FindUnitWithFilename(const aFilename: string
|
||||||
|
): TUDUnit;
|
||||||
|
var
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
AVLNode:=FUnitsByFilename.FindKey(Pointer(aFilename),@CompareFileNameWithIDFileItem);
|
||||||
|
if AVLNode<>nil then
|
||||||
|
Result:=TUDUnit(AVLNode.Data)
|
||||||
|
else
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user