IDE: implemented using Ancestor component when saving inherited root component, codetools: added flag to search in ancestors for dangling events

git-svn-id: trunk@10046 -
This commit is contained in:
mattias 2006-10-07 20:49:56 +00:00
parent b6f164d0aa
commit c038401b5b
6 changed files with 286 additions and 61 deletions

View File

@ -540,7 +540,8 @@ type
VarType: shortstring; ErrorOnClassNotFound: boolean): boolean; VarType: shortstring; ErrorOnClassNotFound: boolean): boolean;
function FindDanglingComponentEvents(Code: TCodeBuffer; function FindDanglingComponentEvents(Code: TCodeBuffer;
const AClassName: string; const AClassName: string;
RootComponent: TComponent; ExceptionOnClassNotFound: boolean; RootComponent: TComponent; ExceptionOnClassNotFound,
SearchInAncestors: boolean;
out ListOfPInstancePropInfo: TFPList): boolean; out ListOfPInstancePropInfo: TFPList): boolean;
// functions for events in the object inspector // functions for events in the object inspector
@ -3571,7 +3572,8 @@ end;
function TCodeToolManager.FindDanglingComponentEvents(Code: TCodeBuffer; function TCodeToolManager.FindDanglingComponentEvents(Code: TCodeBuffer;
const AClassName: string; RootComponent: TComponent; const AClassName: string; RootComponent: TComponent;
ExceptionOnClassNotFound: boolean; out ListOfPInstancePropInfo: TFPList ExceptionOnClassNotFound, SearchInAncestors: boolean;
out ListOfPInstancePropInfo: TFPList
): boolean; ): boolean;
begin begin
Result:=false; Result:=false;
@ -3582,7 +3584,8 @@ begin
if not InitCurCodeTool(Code) then exit; if not InitCurCodeTool(Code) then exit;
try try
Result:=FCurCodeTool.FindDanglingComponentEvents(AClassName,RootComponent, Result:=FCurCodeTool.FindDanglingComponentEvents(AClassName,RootComponent,
ExceptionOnClassNotFound,ListOfPInstancePropInfo); ExceptionOnClassNotFound,SearchInAncestors,
ListOfPInstancePropInfo);
except except
on e: Exception do Result:=HandleException(e); on e: Exception do Result:=HandleException(e);
end; end;

View File

@ -185,10 +185,11 @@ type
SourceChangeCache: TSourceChangeCache): boolean; SourceChangeCache: TSourceChangeCache): boolean;
function GatherPublishedClassElements(const TheClassName: string; function GatherPublishedClassElements(const TheClassName: string;
ExceptionOnClassNotFound, WithVariables, WithMethods, ExceptionOnClassNotFound, WithVariables, WithMethods,
WithProperties: boolean; WithProperties, WithAncestors: boolean;
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean; out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
function FindDanglingComponentEvents(const TheClassName: string; function FindDanglingComponentEvents(const TheClassName: string;
RootComponent: TComponent; ExceptionOnClassNotFound: boolean; RootComponent: TComponent; ExceptionOnClassNotFound,
SearchInAncestors: boolean;
out ListOfPInstancePropInfo: TFPList): boolean; out ListOfPInstancePropInfo: TFPList): boolean;
// blocks (e.g. begin..end) // blocks (e.g. begin..end)
@ -4026,15 +4027,71 @@ end;
function TStandardCodeTool.GatherPublishedClassElements( function TStandardCodeTool.GatherPublishedClassElements(
const TheClassName: string; const TheClassName: string;
ExceptionOnClassNotFound, WithVariables, WithMethods, WithProperties: boolean; ExceptionOnClassNotFound, WithVariables, WithMethods, WithProperties,
WithAncestors: boolean;
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean; out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
function Add(AFindContext: PFindContext): boolean;
var
ClassNode: TCodeTreeNode;
CurTool: TFindDeclarationTool;
SectionNode: TCodeTreeNode;
ANode: TCodeTreeNode;
CurProcName: String;
NewNodeExt: TCodeTreeNodeExtension;
CurPropName: String;
CurVarName: String;
begin
Result:=false;
ClassNode:=AFindContext^.Node;
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) then exit;
CurTool:=AFindContext^.Tool;
CurTool.BuildSubTreeForClass(ClassNode);
SectionNode:=ClassNode.FirstChild;
while (SectionNode<>nil) do begin
if SectionNode.Desc=ctnClassPublished then begin
ANode:=SectionNode.FirstChild;
while ANode<>nil do begin
if (ANode.Desc=ctnProcedure) and WithMethods then begin
CurProcName:=CurTool.ExtractProcName(ANode,[]);
//debugln('TStandardCodeTool.GatherPublishedClassElements CurProcName="',CurProcName,'"');
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurProcName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end
else if (ANode.Desc=ctnVarDefinition) and WithVariables then begin
CurVarName:=CurTool.ExtractDefinitionName(ANode);
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurVarName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end
else if (ANode.Desc=ctnProperty) and WithProperties then begin
CurPropName:=CurTool.ExtractPropName(ANode,false);
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurPropName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end;
ANode:=ANode.NextBrother;
end;
end;
SectionNode:=SectionNode.NextBrother;
end;
Result:=true;
end;
var var
ClassNode, SectionNode: TCodeTreeNode; ClassNode: TCodeTreeNode;
ANode: TCodeTreeNode; AncestorList: TFPList;// of PFindContext
CurProcName: String; i: Integer;
NewNodeExt: TCodeTreeNodeExtension;
CurVarName: String;
CurPropName: String;
begin begin
Result:=false; Result:=false;
TreeOfCodeTreeNodeExtension:=nil; TreeOfCodeTreeNodeExtension:=nil;
@ -4044,52 +4101,26 @@ begin
ClassNode:=FindClassNodeInInterface(TheClassName,true,false, ClassNode:=FindClassNodeInInterface(TheClassName,true,false,
ExceptionOnClassNotFound); ExceptionOnClassNotFound);
if ClassNode=nil then exit; if ClassNode=nil then exit;
TreeOfCodeTreeNodeExtension:=TAVLTree.Create(@CompareCodeTreeNodeExt); AncestorList:=nil;
BuildSubTreeForClass(ClassNode); try
SectionNode:=ClassNode.FirstChild; if WithAncestors then begin
while (SectionNode<>nil) do begin if not FindClassAndAncestors(ClassNode,AncestorList) then exit;
if SectionNode.Desc=ctnClassPublished then begin end else begin
ANode:=SectionNode.FirstChild; AddFindContext(AncestorList,CreateFindContext(Self,ClassNode));
while ANode<>nil do begin
if (ANode.Desc=ctnProcedure) and WithMethods then begin
CurProcName:=ExtractProcName(ANode,[]);
//debugln('TStandardCodeTool.GatherPublishedClassElements CurProcName="',CurProcName,'"');
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurProcName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end
else if (ANode.Desc=ctnVarDefinition) and WithVariables then begin
CurVarName:=ExtractDefinitionName(ANode);
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurVarName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end
else if (ANode.Desc=ctnProperty) and WithProperties then begin
CurPropName:=ExtractPropName(ANode,false);
NewNodeExt:=NodeExtMemManager.NewNode;
with NewNodeExt do begin
Node:=ANode;
Txt:=CurPropName;
end;
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
end;
ANode:=ANode.NextBrother;
end;
end; end;
SectionNode:=SectionNode.NextBrother; TreeOfCodeTreeNodeExtension:=TAVLTree.Create(@CompareCodeTreeNodeExt);
for i:=0 to AncestorList.Count-1 do begin
if not Add(PFindContext(AncestorList[i])) then exit;
end;
finally
FreeListOfPFindContext(AncestorList);
end; end;
Result:=true; Result:=true;
end; end;
function TStandardCodeTool.FindDanglingComponentEvents( function TStandardCodeTool.FindDanglingComponentEvents(
const TheClassName: string; RootComponent: TComponent; const TheClassName: string; RootComponent: TComponent;
ExceptionOnClassNotFound: boolean; ExceptionOnClassNotFound, SearchInAncestors: boolean;
out ListOfPInstancePropInfo: TFPList): boolean; out ListOfPInstancePropInfo: TFPList): boolean;
var var
PublishedMethods: TAVLTree; PublishedMethods: TAVLTree;
@ -4165,7 +4196,8 @@ begin
// search all available published methods // search all available published methods
//debugln('TStandardCodeTool.FindDanglingComponentEvents A ',MainFilename,' ',DbgSName(RootComponent)); //debugln('TStandardCodeTool.FindDanglingComponentEvents A ',MainFilename,' ',DbgSName(RootComponent));
Result:=GatherPublishedClassElements(TheClassName,ExceptionOnClassNotFound, Result:=GatherPublishedClassElements(TheClassName,ExceptionOnClassNotFound,
false,true,false,PublishedMethods); false,true,false,SearchInAncestors,
PublishedMethods);
if not Result then exit; if not Result then exit;
// go through all components // go through all components
CheckMethodsInComponent(RootComponent); CheckMethodsInComponent(RootComponent);

View File

@ -246,7 +246,7 @@ begin
// find all dangling events // find all dangling events
//debugln('RemoveDanglingEvents A ',PascalBuffer.Filename,' ',DbgSName(RootComponent)); //debugln('RemoveDanglingEvents A ',PascalBuffer.Filename,' ',DbgSName(RootComponent));
if not CodeToolBoss.FindDanglingComponentEvents(PascalBuffer, if not CodeToolBoss.FindDanglingComponentEvents(PascalBuffer,
RootComponent.ClassName,RootComponent,false,ListOfPInstancePropInfo) RootComponent.ClassName,RootComponent,false,true,ListOfPInstancePropInfo)
then begin then begin
//debugln('RemoveDanglingEvents Errors in code'); //debugln('RemoveDanglingEvents Errors in code');
if OkOnCodeErrors then if OkOnCodeErrors then

View File

@ -881,7 +881,7 @@ Begin
DebugLn(['WARNING: TCustomFormEditor.DeleteComponent freeing orphaned component ',DbgSName(AComponent)]); DebugLn(['WARNING: TCustomFormEditor.DeleteComponent freeing orphaned component ',DbgSName(AComponent)]);
TryFreeComponent(AComponent); TryFreeComponent(AComponent);
end; end;
// if not free, then free the handle to hide it // if not free, then hide it
if (not FreeComponent) and (AComponent is TWinControl) then begin if (not FreeComponent) and (AComponent is TWinControl) then begin
AWinControl:=TWinControl(AComponent); AWinControl:=TWinControl(AComponent);
if AWinControl.HandleAllocated and (AWinControl.Parent=nil) then begin if AWinControl.HandleAllocated and (AWinControl.Parent=nil) then begin

View File

@ -554,9 +554,9 @@ type
// methods for 'save unit' // methods for 'save unit'
function DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo; function DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
var ResourceCode: TCodeBuffer): TModalResult; var ResourceCode: TCodeBuffer): TModalResult;
function DoSaveFileResources(AnUnitInfo: TUnitInfo; function DoSaveUnitComponent(AnUnitInfo: TUnitInfo;
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult; ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
function DoSaveFileResourceToBinStream(AnUnitInfo: TUnitInfo; function DoSaveUnitComponentToBinStream(AnUnitInfo: TUnitInfo;
var BinCompStream: TExtMemoryStream): TModalResult; var BinCompStream: TExtMemoryStream): TModalResult;
function DoRemoveDanglingEvents(AnUnitInfo: TUnitInfo; function DoRemoveDanglingEvents(AnUnitInfo: TUnitInfo;
OkOnCodeErrors: boolean): TModalResult; OkOnCodeErrors: boolean): TModalResult;
@ -592,6 +592,7 @@ type
Flags: TCloseFlags): TModalResult; Flags: TCloseFlags): TModalResult;
function UnitComponentIsUsed(AnUnitInfo: TUnitInfo; function UnitComponentIsUsed(AnUnitInfo: TUnitInfo;
CheckHasDesigner: boolean): boolean; CheckHasDesigner: boolean): boolean;
function GetAncestorUnit(AnUnitInfo: TUnitInfo): TUnitInfo;
// methods for creating a project // methods for creating a project
function CreateProjectObject(ProjectDesc, function CreateProjectObject(ProjectDesc,
@ -4027,7 +4028,7 @@ begin
end; end;
{$ENDIF} {$ENDIF}
function TMainIDE.DoSaveFileResources(AnUnitInfo: TUnitInfo; function TMainIDE.DoSaveUnitComponent(AnUnitInfo: TUnitInfo;
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult; ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
var var
ComponentSavingOk: boolean; ComponentSavingOk: boolean;
@ -4038,6 +4039,8 @@ var
CompResourceCode, LFMFilename, TestFilename, ResTestFilename: string; CompResourceCode, LFMFilename, TestFilename, ResTestFilename: string;
UnitSaveFilename: String; UnitSaveFilename: String;
ADesigner: TDesigner; ADesigner: TDesigner;
AncestorUnit: TUnitInfo;
AncestorInstance: TComponent;
{$IFDEF TRANSLATESTRING}Grubber:TLRTGrubber;{$ENDIF} {$IFDEF TRANSLATESTRING}Grubber:TLRTGrubber;{$ENDIF}
begin begin
Result:=mrCancel; Result:=mrCancel;
@ -4086,7 +4089,13 @@ begin
Grubber:=TLRTGrubber.Create; Grubber:=TLRTGrubber.Create;
Writer.OnWriteStringProperty:=@Grubber.Grub; Writer.OnWriteStringProperty:=@Grubber.Grub;
{$ENDIF} {$ENDIF}
Writer.WriteDescendent(AnUnitInfo.Component,nil); AncestorUnit:=GetAncestorUnit(AnUnitInfo);
if AncestorUnit<>nil then
AncestorInstance:=AncestorUnit.Component
else
AncestorInstance:=nil;
DebugLn(['TMainIDE.DoSaveUnitComponent AncestorInstance=',dbgsName(AncestorInstance)]);
Writer.WriteDescendent(AnUnitInfo.Component,AncestorInstance);
if DestroyDriver then Writer.Driver.Free; if DestroyDriver then Writer.Driver.Free;
FreeAndNil(Writer); FreeAndNil(Writer);
AnUnitInfo.ComponentLastBinStreamSize:=BinCompStream.Size; AnUnitInfo.ComponentLastBinStreamSize:=BinCompStream.Size;
@ -4294,7 +4303,7 @@ begin
{$ENDIF} {$ENDIF}
end; end;
function TMainIDE.DoSaveFileResourceToBinStream(AnUnitInfo: TUnitInfo; function TMainIDE.DoSaveUnitComponentToBinStream(AnUnitInfo: TUnitInfo;
var BinCompStream: TExtMemoryStream): TModalResult; var BinCompStream: TExtMemoryStream): TModalResult;
var var
Writer: TWriter; Writer: TWriter;
@ -4868,7 +4877,7 @@ begin
OpenFlags,AncestorType,AncestorUnitInfo); OpenFlags,AncestorType,AncestorUnitInfo);
if Result=mrAbort then exit; if Result=mrAbort then exit;
if Result=mrOk then begin if Result=mrOk then begin
Result:=DoSaveFileResourceToBinStream(AncestorUnitInfo, Result:=DoSaveUnitComponentToBinStream(AncestorUnitInfo,
AncestorBinStream); AncestorBinStream);
if Result<>mrOk then exit; if Result<>mrOk then exit;
AncestorBinStream.Position:=0; AncestorBinStream.Position:=0;
@ -4923,6 +4932,8 @@ begin
NewComponent:=FormEditor1.CreateRawComponentFromStream(BinStream, NewComponent:=FormEditor1.CreateRawComponentFromStream(BinStream,
AncestorType,AncestorBinStream,copy(NewUnitName,1,255),true); AncestorType,AncestorBinStream,copy(NewUnitName,1,255),true);
AnUnitInfo.Component:=NewComponent; AnUnitInfo.Component:=NewComponent;
if (AncestorUnitInfo<>nil) then
AnUnitInfo.AddRequiresComponentDependency(AncestorUnitInfo);
if NewComponent=nil then begin if NewComponent=nil then begin
// error streaming component -> examine lfm file // error streaming component -> examine lfm file
DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"'); DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"');
@ -5266,6 +5277,14 @@ begin
exit(true); exit(true);
end; end;
function TMainIDE.GetAncestorUnit(AnUnitInfo: TUnitInfo): TUnitInfo;
begin
if (AnUnitInfo=nil) or (AnUnitInfo.Component=nil) then
Result:=nil
else
Result:=AnUnitInfo.FindAncestorUnit;
end;
function TMainIDE.CreateProjectObject(ProjectDesc, function TMainIDE.CreateProjectObject(ProjectDesc,
FallbackProjectDesc: TProjectDescriptor): TProject; FallbackProjectDesc: TProjectDescriptor): TProject;
begin begin
@ -6019,7 +6038,7 @@ begin
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TMainIDE.DoSaveEditorFile B');{$ENDIF} {$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TMainIDE.DoSaveEditorFile B');{$ENDIF}
// save resource file and lfm file // save resource file and lfm file
if (ResourceCode<>nil) or (ActiveUnitInfo.Component<>nil) then begin if (ResourceCode<>nil) or (ActiveUnitInfo.Component<>nil) then begin
Result:=DoSaveFileResources(ActiveUnitInfo,ResourceCode,LFMCode,Flags); Result:=DoSaveUnitComponent(ActiveUnitInfo,ResourceCode,LFMCode,Flags);
if Result in [mrIgnore, mrOk] then if Result in [mrIgnore, mrOk] then
Result:=mrCancel Result:=mrCancel
else else

View File

@ -80,6 +80,37 @@ type
uilAutoRevertLocked uilAutoRevertLocked
); );
TUnitCompDependencyList = (
ucdlRequires,
ucdlUsedBy
);
{ TUnitComponentDependency }
TUnitComponentDependency = class
private
FRequiresUnit: TUnitInfo;
FUsedByUnit: TUnitInfo;
procedure SetRequiresUnit(const AValue: TUnitInfo);
procedure SetUsedByUnit(const AValue: TUnitInfo);
public
NextDependency, PrevDependency:
array[TUnitCompDependencyList] of TUnitComponentDependency;
constructor Create;
destructor Destroy; override;
procedure Clear;
function NextUsedByDependency: TUnitComponentDependency;
function PrevUsedByDependency: TUnitComponentDependency;
function NextRequiresDependency: TUnitComponentDependency;
function PrevRequiresDependency: TUnitComponentDependency;
procedure AddToList(var FirstDependency: TUnitComponentDependency;
ListType: TUnitCompDependencyList);
procedure RemoveFromList(var FirstDependency: TUnitComponentDependency;
ListType: TUnitCompDependencyList);
property RequiresUnit: TUnitInfo read FRequiresUnit write SetRequiresUnit;
property UsedByUnit: TUnitInfo read FUsedByUnit write SetUsedByUnit;
end;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
{ TUnitInfo } { TUnitInfo }
@ -105,6 +136,8 @@ type
fEditorIndex: integer; fEditorIndex: integer;
fFileName: string; fFileName: string;
fFileReadOnly: Boolean; fFileReadOnly: Boolean;
FFirstRequiredComponent: TUnitComponentDependency;
FFirstUsedByComponent: TUnitComponentDependency;
fHasResources: boolean; // source has resource file fHasResources: boolean; // source has resource file
FIgnoreFileDateOnDiskValid: boolean; FIgnoreFileDateOnDiskValid: boolean;
FIgnoreFileDateOnDisk: longint; FIgnoreFileDateOnDisk: longint;
@ -175,6 +208,7 @@ type
function WriteUnitSourceToFile(const AFileName: string): TModalResult; function WriteUnitSourceToFile(const AFileName: string): TModalResult;
procedure Clear; procedure Clear;
procedure ClearModifieds; procedure ClearModifieds;
procedure ClearComponentDependencies;
procedure CreateStartCode(Descriptor: TProjectFileDescriptor; procedure CreateStartCode(Descriptor: TProjectFileDescriptor;
const NewUnitName: string); const NewUnitName: string);
procedure DecreaseAutoRevertLock; procedure DecreaseAutoRevertLock;
@ -193,6 +227,11 @@ type
procedure SetSourceText(const SourceText: string); override; procedure SetSourceText(const SourceText: string); override;
function GetSourceText: string; override; function GetSourceText: string; override;
// component dependencies
procedure AddRequiresComponentDependency(RequiredUnit: TUnitInfo);
procedure RemoveRequiresComponentDependency(RequiredUnit: TUnitInfo);
function FindAncestorUnit: TUnitInfo;
public public
{ Properties } { Properties }
// Unit lists // Unit lists
@ -225,6 +264,10 @@ type
read fCustomHighlighter write fCustomHighlighter; read fCustomHighlighter write fCustomHighlighter;
property EditorIndex: integer read fEditorIndex write SetEditorIndex; property EditorIndex: integer read fEditorIndex write SetEditorIndex;
property FileReadOnly: Boolean read fFileReadOnly write SetFileReadOnly; property FileReadOnly: Boolean read fFileReadOnly write SetFileReadOnly;
property FirstRequiredComponent: TUnitComponentDependency
read FFirstRequiredComponent;
property FirstUsedByComponent: TUnitComponentDependency
read FFirstUsedByComponent;
property HasResources: boolean read GetHasResources write fHasResources; property HasResources: boolean read GetHasResources write fHasResources;
property Loaded: Boolean read fLoaded write SetLoaded; property Loaded: Boolean read fLoaded write SetLoaded;
property LoadingComponent: boolean read FLoadingComponent write FLoadingComponent; property LoadingComponent: boolean read FLoadingComponent write FLoadingComponent;
@ -755,6 +798,7 @@ end;
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
destructor TUnitInfo.Destroy; destructor TUnitInfo.Destroy;
begin begin
Component:=nil;
Source:=nil; Source:=nil;
FreeAndNil(FBookmarks); FreeAndNil(FBookmarks);
Project:=nil; Project:=nil;
@ -919,6 +963,7 @@ begin
fUserReadOnly := false; fUserReadOnly := false;
if fSource<>nil then fSource.Clear; if fSource<>nil then fSource.Clear;
Loaded := false; Loaded := false;
ClearComponentDependencies;
end; end;
procedure TUnitInfo.ClearModifieds; procedure TUnitInfo.ClearModifieds;
@ -927,6 +972,12 @@ begin
SessionModified:=false; SessionModified:=false;
end; end;
procedure TUnitInfo.ClearComponentDependencies;
begin
while FFirstRequiredComponent<>nil do FFirstRequiredComponent.Free;
while FFirstUsedByComponent<>nil do FFirstUsedByComponent.Free;
end;
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
TUnitInfo SaveToXMLConfig TUnitInfo SaveToXMLConfig
@ -1229,6 +1280,38 @@ begin
Result:=Source.Source; Result:=Source.Source;
end; end;
procedure TUnitInfo.AddRequiresComponentDependency(RequiredUnit: TUnitInfo);
var
ADependency: TUnitComponentDependency;
begin
if RequiredUnit=nil then RaiseGDBException('inconsistency');
ADependency:=TUnitComponentDependency.Create;
ADependency.RequiresUnit:=RequiredUnit;
ADependency.UsedByUnit:=Self;
end;
procedure TUnitInfo.RemoveRequiresComponentDependency(RequiredUnit: TUnitInfo);
begin
RequiredUnit.Free;
end;
function TUnitInfo.FindAncestorUnit: TUnitInfo;
var
Dependency: TUnitComponentDependency;
begin
if Component<>nil then begin
Dependency:=FirstRequiredComponent;
while Dependency<>nil do begin
Result:=Dependency.RequiresUnit;
if (Result.Component<>nil)
and (Component.ClassParent=Result.Component.ClassType) then
exit;
Dependency:=Dependency.NextRequiresDependency;
end;
end;
Result:=nil;
end;
function TUnitInfo.ReadOnly: boolean; function TUnitInfo.ReadOnly: boolean;
begin begin
Result:=UserReadOnly or FileReadOnly; Result:=UserReadOnly or FileReadOnly;
@ -1367,6 +1450,7 @@ begin
if fComponent=AValue then exit; if fComponent=AValue then exit;
fComponent:=AValue; fComponent:=AValue;
UpdateList(uilWithComponent,fComponent<>nil); UpdateList(uilWithComponent,fComponent<>nil);
if fComponent=nil then ClearComponentDependencies;
end; end;
procedure TUnitInfo.SetIsPartOfProject(const AValue: boolean); procedure TUnitInfo.SetIsPartOfProject(const AValue: boolean);
@ -4504,5 +4588,92 @@ begin
[ofProjectLoading,ofRegularFile]); [ofProjectLoading,ofRegularFile]);
end; end;
{ TUnitComponentDependency }
procedure TUnitComponentDependency.SetRequiresUnit(const AValue: TUnitInfo);
begin
if FRequiresUnit=AValue then exit;
if FRequiresUnit<>nil then
RemoveFromList(FRequiresUnit.FFirstUsedByComponent,ucdlUsedBy);
FRequiresUnit:=AValue;
if FRequiresUnit<>nil then
AddToList(FRequiresUnit.FFirstUsedByComponent,ucdlUsedBy);
end;
procedure TUnitComponentDependency.SetUsedByUnit(const AValue: TUnitInfo);
begin
if FUsedByUnit=AValue then exit;
if FUsedByUnit<>nil then
RemoveFromList(FUsedByUnit.FFirstRequiredComponent,ucdlRequires);
FUsedByUnit:=AValue;
if FUsedByUnit<>nil then
AddToList(FUsedByUnit.FFirstRequiredComponent,ucdlRequires);
end;
constructor TUnitComponentDependency.Create;
begin
Clear;
end;
destructor TUnitComponentDependency.Destroy;
begin
RequiresUnit:=nil;
UsedByUnit:=nil;
inherited Destroy;
end;
procedure TUnitComponentDependency.Clear;
begin
end;
function TUnitComponentDependency.NextUsedByDependency
: TUnitComponentDependency;
begin
Result:=NextDependency[ucdlUsedBy];
end;
function TUnitComponentDependency.PrevUsedByDependency
: TUnitComponentDependency;
begin
Result:=PrevDependency[ucdlUsedBy];
end;
function TUnitComponentDependency.NextRequiresDependency
: TUnitComponentDependency;
begin
Result:=NextDependency[ucdlRequires];
end;
function TUnitComponentDependency.PrevRequiresDependency
: TUnitComponentDependency;
begin
Result:=PrevDependency[ucdlRequires];
end;
procedure TUnitComponentDependency.AddToList(
var FirstDependency: TUnitComponentDependency;
ListType: TUnitCompDependencyList);
begin
NextDependency[ListType]:=FirstDependency;
FirstDependency:=Self;
PrevDependency[ListType]:=nil;
if NextDependency[ListType]<>nil then
NextDependency[ListType].PrevDependency[ListType]:=Self;
end;
procedure TUnitComponentDependency.RemoveFromList(
var FirstDependency: TUnitComponentDependency;
ListType: TUnitCompDependencyList);
begin
if FirstDependency=Self then FirstDependency:=NextDependency[ListType];
if NextDependency[ListType]<>nil then
NextDependency[ListType].PrevDependency[ListType]:=PrevDependency[ListType];
if PrevDependency[ListType]<>nil then
PrevDependency[ListType].NextDependency[ListType]:=NextDependency[ListType];
NextDependency[ListType]:=nil;
PrevDependency[ListType]:=nil;
end;
end. end.