MG: get compatible published methods now works

git-svn-id: trunk@1434 -
This commit is contained in:
lazarus 2002-02-09 22:24:51 +00:00
parent f8f190fabb
commit 2a0d19493f
4 changed files with 134 additions and 69 deletions

View File

@ -50,6 +50,8 @@ type
TEventsCodeTool = class(TMethodJumpingCodeTool) TEventsCodeTool = class(TMethodJumpingCodeTool)
private private
GetCompatibleMethodsProc: TGetStringProc; GetCompatibleMethodsProc: TGetStringProc;
SearchedExprList: TExprTypeList;
SearchedCompatibilityList: TTypeCompatibilityList;
protected protected
function InsertNewMethodToClass(ClassSectionNode: TCodeTreeNode; function InsertNewMethodToClass(ClassSectionNode: TCodeTreeNode;
const AMethodName,NewMethod: string; const AMethodName,NewMethod: string;
@ -57,10 +59,10 @@ type
function CollectPublishedMethods(Params: TFindDeclarationParams; function CollectPublishedMethods(Params: TFindDeclarationParams;
FoundContext: TFindContext): TIdentifierFoundResult; FoundContext: TFindContext): TIdentifierFoundResult;
public public
procedure GetCompatiblePublishedMethods(const UpperClassName: string; function GetCompatiblePublishedMethods(const UpperClassName: string;
TypeData: PTypeData; Proc: TGetStringProc); TypeData: PTypeData; Proc: TGetStringProc): boolean;
procedure GetCompatiblePublishedMethods(ClassNode: TCodeTreeNode; function GetCompatiblePublishedMethods(ClassNode: TCodeTreeNode;
TypeData: PTypeData; Proc: TGetStringProc); TypeData: PTypeData; Proc: TGetStringProc): boolean;
function PublishedMethodExists(const UpperClassName, function PublishedMethodExists(const UpperClassName,
UpperMethodName: string; TypeData: PTypeData): boolean; UpperMethodName: string; TypeData: PTypeData): boolean;
function PublishedMethodExists(ClassNode: TCodeTreeNode; function PublishedMethodExists(ClassNode: TCodeTreeNode;
@ -177,47 +179,81 @@ begin
Result:=Result+';'; Result:=Result+';';
end; end;
procedure TEventsCodeTool.GetCompatiblePublishedMethods( function TEventsCodeTool.GetCompatiblePublishedMethods(
const UpperClassName: string; TypeData: PTypeData; Proc: TGetStringProc); const UpperClassName: string; TypeData: PTypeData;
Proc: TGetStringProc): boolean;
var ClassNode: TCodeTreeNode; var ClassNode: TCodeTreeNode;
begin begin
BuildTree(true); Result:=false;
if not InterfaceSectionFound then exit; ActivateGlobalWriteLock;
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false); try
GetCompatiblePublishedMethods(ClassNode,TypeData,Proc); {$IFDEF CTDEBUG}
writeln('[TEventsCodeTool.GetCompatiblePublishedMethods] A UpperClassName=',UpperClassName);
{$ENDIF}
BuildTree(true);
if not InterfaceSectionFound then exit;
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
{$IFDEF CTDEBUG}
writeln('[TEventsCodeTool.GetCompatiblePublishedMethods] B ',ClassNode<>nil);
{$ENDIF}
Result:=GetCompatiblePublishedMethods(ClassNode,TypeData,Proc);
finally
DeactivateGlobalWriteLock;
end;
end; end;
procedure TEventsCodeTool.GetCompatiblePublishedMethods( function TEventsCodeTool.GetCompatiblePublishedMethods(
ClassNode: TCodeTreeNode; TypeData: PTypeData; Proc: TGetStringProc); ClassNode: TCodeTreeNode; TypeData: PTypeData; Proc: TGetStringProc): boolean;
var //SearchedProc: string; var //SearchedProc: string;
//SectionNode, ANode: TCodeTreeNode; //SectionNode, ANode: TCodeTreeNode;
//CurProcHead, CurProcName: string; //CurProcHead, CurProcName: string;
Params: TFindDeclarationParams; Params: TFindDeclarationParams;
ExprList: TExprTypeList; CompListSize: integer;
begin begin
Result:=false;
{$IFDEF CTDEBUG}
writeln('[TEventsCodeTool.GetCompatiblePublishedMethods] C ',ClassNode<>nil);
{$ENDIF}
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (TypeData=nil) if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (TypeData=nil)
or (Proc=nil) then exit; or (Proc=nil) then exit;
BuildSubTreeForClass(ClassNode); ActivateGlobalWriteLock;
try
BuildSubTreeForClass(ClassNode);
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
writeln('[TEventsCodeTool.GetCompatiblePublishedMethods]'); writeln('[TEventsCodeTool.GetCompatiblePublishedMethods]');
{$ENDIF} {$ENDIF}
// 1. convert the TypeData to an expression type list // 1. convert the TypeData to an expression type list
Params:=TFindDeclarationParams.Create; Params:=TFindDeclarationParams.Create;
try
Params.ContextNode:=ClassNode.Parent;
ExprList:=CreateExprListFromMethodTypeData(TypeData,Params);
try try
// 2. search all compatible published procs Params.ContextNode:=ClassNode.Parent;
GetCompatibleMethodsProc:=Proc; SearchedExprList:=CreateExprListFromMethodTypeData(TypeData,Params);
Params.ContextNode:=ClassNode; // create compatibility list
Params.Flags:=[fdfCollect,fdfSearchInAncestors,fdfClassPublished]; CompListSize:=SizeOf(TTypeCompatibility)*SearchedExprList.Count;
Params.SetIdentifier(Self,nil,@CollectPublishedMethods); if CompListSize>0 then begin
FindIdentifierInContext(Params); GetMem(SearchedCompatibilityList,CompListSize);
end else begin
SearchedCompatibilityList:=nil;
end;
try
// 2. search all compatible published procs
GetCompatibleMethodsProc:=Proc;
Params.ContextNode:=ClassNode;
Params.Flags:=[fdfCollect,fdfSearchInAncestors,fdfClassPublished];
Params.SetIdentifier(Self,nil,@CollectPublishedMethods);
FindIdentifierInContext(Params);
finally
SearchedExprList.Free;
SearchedExprList:=nil;
if SearchedCompatibilityList<>nil then
FreeMem(SearchedCompatibilityList);
SearchedCompatibilityList:=nil;
end;
finally finally
ExprList.Free; Params.Free;
end; end;
Result:=true;
finally finally
Params.Free; DeactivateGlobalWriteLock;
end; end;
{ {
SearchedProc:=MethodTypeDataToStr(TypeData,[phpInUpperCase]); SearchedProc:=MethodTypeDataToStr(TypeData,[phpInUpperCase]);
@ -781,12 +817,34 @@ end;
function TEventsCodeTool.CollectPublishedMethods( function TEventsCodeTool.CollectPublishedMethods(
Params: TFindDeclarationParams; FoundContext: TFindContext Params: TFindDeclarationParams; FoundContext: TFindContext
): TIdentifierFoundResult; ): TIdentifierFoundResult;
var
ParamCompatibility: TTypeCompatibility;
FirstParameterNode: TCodeTreeNode;
begin begin
if (FoundContext.Node.Desc=ctnProcedure) then begin
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
writeln('[TEventsCodeTool.CollectPublishedMethods] ', writeln('[TEventsCodeTool.CollectPublishedMethods] ',
' Node=',FoundContext.Node.DescAsString, ' Node=',FoundContext.Node.DescAsString,
' "',copy(FoundContext.Tool.Src,FoundContext.Node.StartPos,20),'"',
' Tool=',FoundContext.Tool.MainFilename); ' Tool=',FoundContext.Tool.MainFilename);
{$ENDIF} {$ENDIF}
FirstParameterNode:=FoundContext.Tool.GetFirstParameterNode(
FoundContext.Node);
ParamCompatibility:=FoundContext.Tool.IsParamListCompatible(
FirstParameterNode,
SearchedExprList,false,
Params,SearchedCompatibilityList);
if ParamCompatibility=tcExact then begin
{$IFDEF CTDEBUG}
writeln('ParamCompatibility=',TypeCompatibilityNames[ParamCompatibility]);
{$ENDIF}
// ToDo: ppu, ppw, dcu
GetCompatibleMethodsProc(
FoundContext.Tool.ExtractProcName(FoundContext.Node,false));
end;
end;
Result:=ifrProceedSearch; Result:=ifrProceedSearch;
end; end;

View File

@ -268,20 +268,6 @@ type
Params: TFindDeclarationParams): boolean; Params: TFindDeclarationParams): boolean;
function FindIdentifierInUsedUnit(const AnUnitName: string; function FindIdentifierInUsedUnit(const AnUnitName: string;
Params: TFindDeclarationParams): boolean; Params: TFindDeclarationParams): boolean;
// expressions, operands, variables
function FindEndOfVariable(StartPos: integer): integer;
function FindExpressionTypeOfVariable(StartPos: integer;
Params: TFindDeclarationParams; var EndPos: integer): TExpressionType;
function ConvertNodeToExpressionType(Node: TCodeTreeNode;
Params: TFindDeclarationParams): TExpressionType;
function ReadOperandTypeAtCursor(
Params: TFindDeclarationParams): TExpressionType;
function CalculateBinaryOperator(LeftOperand, RightOperand: TExpressionType;
BinaryOperator: TAtomPosition;
Params: TFindDeclarationParams): TExpressionType;
function GetParameterNode(Node: TCodeTreeNode): TCodeTreeNode;
function GetFirstParameterNode(Node: TCodeTreeNode): TCodeTreeNode;
function PredefinedIdentToTypeDesc(Identifier: PChar): TExpressionTypeDesc;
protected protected
procedure DoDeleteNodes; override; procedure DoDeleteNodes; override;
procedure ClearNodeCaches(Force: boolean); procedure ClearNodeCaches(Force: boolean);
@ -333,6 +319,20 @@ type
Params: TFindDeclarationParams): TTypeCompatibility; Params: TFindDeclarationParams): TTypeCompatibility;
function IsCompatible(Node: TCodeTreeNode; ExpressionType: TExpressionType; function IsCompatible(Node: TCodeTreeNode; ExpressionType: TExpressionType;
Params: TFindDeclarationParams): TTypeCompatibility; Params: TFindDeclarationParams): TTypeCompatibility;
// expressions, operands, variables
function FindEndOfVariable(StartPos: integer): integer;
function FindExpressionTypeOfVariable(StartPos: integer;
Params: TFindDeclarationParams; var EndPos: integer): TExpressionType;
function ConvertNodeToExpressionType(Node: TCodeTreeNode;
Params: TFindDeclarationParams): TExpressionType;
function ReadOperandTypeAtCursor(
Params: TFindDeclarationParams): TExpressionType;
function CalculateBinaryOperator(LeftOperand, RightOperand: TExpressionType;
BinaryOperator: TAtomPosition;
Params: TFindDeclarationParams): TExpressionType;
function GetParameterNode(Node: TCodeTreeNode): TCodeTreeNode;
function GetFirstParameterNode(Node: TCodeTreeNode): TCodeTreeNode;
function PredefinedIdentToTypeDesc(Identifier: PChar): TExpressionTypeDesc;
public public
destructor Destroy; override; destructor Destroy; override;
function FindDeclaration(CursorPos: TCodeXYPosition; function FindDeclaration(CursorPos: TCodeXYPosition;
@ -1080,14 +1080,14 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] no prior node accessible
{$IFDEF ShowTriedContexts} {$IFDEF ShowTriedContexts}
//writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching prior node of ',ContextNode.DescAsString); //writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching prior node of ',ContextNode.DescAsString);
{$ENDIF} {$ENDIF}
if (ContextNode.Desc=ctnClass) if (ContextNode.Desc=ctnClass) then begin
and (fdfSearchInAncestors in Params.Flags) then if (fdfSearchInAncestors in Params.Flags) then begin
begin
// ToDo: check for circles in ancestors // ToDo: check for circles in ancestors
Result:=FindIdentifierInAncestors(ContextNode,Params); Result:=FindIdentifierInAncestors(ContextNode,Params);
if Result then exit; if Result then exit;
end;
end; end;
if ((not (fdfSearchForward in Params.Flags)) if ((not (fdfSearchForward in Params.Flags))
@ -1115,7 +1115,10 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in PriorBrothe
else else
break; break;
end; end;
end else if ContextNode.Parent<>nil then begin end else if (ContextNode.Parent<>nil)
and ((fdfSearchInParentNodes in Params.Flags)
or (ContextNode.HasAsParent(StartContextNode))) then
begin
// search next in parent // search next in parent
ContextNode:=ContextNode.Parent; ContextNode:=ContextNode.Parent;
{$IFDEF ShowTriedContexts} {$IFDEF ShowTriedContexts}
@ -1697,7 +1700,12 @@ writeln('[TFindDeclarationTool.FindBaseTypeOfNode] LOOP Result=',Result.Node.Des
{$ENDIF} {$ENDIF}
if (Result.Node.Desc in AllIdentifierDefinitions) then begin if (Result.Node.Desc in AllIdentifierDefinitions) then begin
// instead of variable/const/type definition, return the type // instead of variable/const/type definition, return the type
Result.Node:=FindTypeNodeOfDefinition(Result.Node); DummyNode:=FindTypeNodeOfDefinition(Result.Node);
if (DummyNode<>nil) or (Result.Node.Parent.Desc<>ctnParameterList) then
Result.Node:=DummyNode
else
// in parameter lists are definitions without type allowed
exit;
end else end else
if (Result.Node.Desc=ctnClass) if (Result.Node.Desc=ctnClass)
and ((Result.Node.SubDesc and ctnsForwardDeclaration)>0) then and ((Result.Node.SubDesc and ctnsForwardDeclaration)>0) then
@ -1835,11 +1843,11 @@ writeln('[TFindDeclarationTool.FindBaseTypeOfNode] Class is forward');
break; break;
end; end;
if (Result.Node=nil) and (fdfExceptionOnNotFound in Params.Flags) then begin if (Result.Node=nil) and (fdfExceptionOnNotFound in Params.Flags) then begin
if Result.Tool<>nil then begin if (Result.Tool<>nil) and (Params.Identifier<>nil) then begin
// ToDo ppu, ppw, dcu // ToDo ppu, ppw, dcu
if not Params.IdentifierTool.IsPCharInSrc(Params.Identifier) then if (not Params.IdentifierTool.IsPCharInSrc(Params.Identifier)) then
Params.IdentifierTool.RaiseException( Params.IdentifierTool.RaiseException(
'[TFindDeclarationTool.FindBaseTypeOfNode]' '[TFindDeclarationTool.FindBaseTypeOfNode]'
+' internal error: not IsPCharInSrc(Params.Identifier) ' +' internal error: not IsPCharInSrc(Params.Identifier) '
@ -2906,6 +2914,8 @@ writeln('[TFindDeclarationTool.ConvertNodeToExpressionType] B',
// predefined identifiers // predefined identifiers
if UpAtomIs('NIL') then if UpAtomIs('NIL') then
Result.Desc:=xtNil Result.Desc:=xtNil
else if UpAtomIs('POINTER') then
Result.Desc:=xtPointer
else if UpAtomIs('TRUE') or UpAtomIs('FALSE') then else if UpAtomIs('TRUE') or UpAtomIs('FALSE') then
Result.Desc:=xtConstBoolean Result.Desc:=xtConstBoolean
else if UpAtomIs('STRING') then else if UpAtomIs('STRING') then

View File

@ -2798,8 +2798,6 @@ begin
ProcNode:=ProcNode.Parent; ProcNode:=ProcNode.Parent;
if ProcNode=nil then exit; if ProcNode=nil then exit;
ProcHeadNode:=ProcNode.FirstChild; ProcHeadNode:=ProcNode.FirstChild;
while (ProcHeadNode<>nil) and (ProcHeadNode.Desc<>ctnProcedureHead) do
ProcHeadNode:=ProcHeadNode.NextBrother;
if (ProcHeadNode=nil) or (ProcHeadNode.StartPos<1) then exit; if (ProcHeadNode=nil) or (ProcHeadNode.StartPos<1) then exit;
MoveCursorToNodeStart(ProcHeadNode); MoveCursorToNodeStart(ProcHeadNode);
repeat repeat

View File

@ -898,23 +898,17 @@ procedure TMainIDE.OnPropHookGetMethods(TypeData:PTypeData;
Proc:TGetStringProc); Proc:TGetStringProc);
var ActiveSrcEdit: TSourceEditor; var ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo; ActiveUnitInfo: TUnitInfo;
NewSource: TCodeBuffer;
NewX, NewY, NewTopLine: integer;
begin begin
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit; if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
{$IFDEF IDE_DEBUG} {$IFDEF IDE_DEBUG}
writeln(''); writeln('');
writeln('[TMainIDE.OnPropHookGetMethods] ************'); writeln('[TMainIDE.OnPropHookGetMethods] ************');
{$ENDIF} {$ENDIF}
if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source, if not CodeToolBoss.GetCompatibleMethods(ActiveUnitInfo.Source,
ActiveSrcEdit.EditorComponent.CaretX, ActiveUnitInfo.Form.ClassName,TypeData,Proc) then
ActiveSrcEdit.EditorComponent.CaretY,
NewSource,NewX,NewY,NewTopLine) then
begin begin
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
NewSource, NewX, NewY, NewTopLine, true);
end else
DoJumpToCodeToolBossError; DoJumpToCodeToolBossError;
end;
end; end;
Procedure TMainIDE.ToolButtonClick(Sender : TObject); Procedure TMainIDE.ToolButtonClick(Sender : TObject);
@ -5817,13 +5811,15 @@ procedure TMainIDE.DoSwitchToFormSrc(var ActiveSourceEditor: TSourceEditor;
var ActiveUnitInfo: TUnitInfo); var ActiveUnitInfo: TUnitInfo);
var i: integer; var i: integer;
begin begin
i:=Project.IndexOfUnitWithForm(PropertyEditorHook1.LookupRoot,false); if PropertyEditorHook1.LookupRoot<>nil then begin
if (i>=0) then begin i:=Project.IndexOfUnitWithForm(PropertyEditorHook1.LookupRoot,false);
i:=Project.Units[i].EditorIndex;
if (i>=0) then begin if (i>=0) then begin
SourceNoteBook.NoteBook.PageIndex:=i; i:=Project.Units[i].EditorIndex;
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo); if (i>=0) then begin
exit; SourceNoteBook.NoteBook.PageIndex:=i;
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo);
exit;
end;
end; end;
end; end;
ActiveSourceEditor:=nil; ActiveSourceEditor:=nil;
@ -5844,6 +5840,9 @@ end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.220 2002/02/09 22:24:50 lazarus
MG: get compatible published methods now works
Revision 1.219 2002/02/09 21:09:19 lazarus Revision 1.219 2002/02/09 21:09:19 lazarus
MG: fixed sourcenotebook closing and form-unit switching MG: fixed sourcenotebook closing and form-unit switching