DE: TMainIDE.OnPropHookCreateMethod: fixed creating JITMethod

git-svn-id: branches/fixes_1_8@55257 -
This commit is contained in:
mattias 2017-06-05 23:30:50 +00:00
parent 45b5fa41a0
commit 5e80f07825
2 changed files with 52 additions and 10 deletions

View File

@ -4797,7 +4797,7 @@ begin
PropertyHook.CompatibleMethodExists(NewValue, GetInstProp,
NewMethodIsCompatible, NewMethodIsPublished, NewIdentIsMethod);
{$IFDEF VerboseMethodPropEdit}
debugln(['TMethodPropertyEditor.SetValue NewValue="',NewValue,'" IsCompatible=',NewMethodIsCompatible,' IsPublished=',NewMethodIsPublished,' IsMethpd=',NewIdentIsMethod]);
debugln(['TMethodPropertyEditor.SetValue NewValue="',NewValue,'" IsCompatible=',NewMethodIsCompatible,' IsPublished=',NewMethodIsPublished,' IsMethod=',NewIdentIsMethod]);
{$ENDIF}
if NewMethodExists then
begin

View File

@ -67,7 +67,7 @@ uses
// CodeTools
FileProcs, FindDeclarationTool, LinkScanner, BasicCodeTools, CodeToolsStructs,
CodeToolManager, CodeCache, DefineTemplates, KeywordFuncLists, CodeTree,
StdCodeTools, CodeCreationDlg,
StdCodeTools, EventCodeTool, CodeCreationDlg,
// LazUtils
// use lazutf8, lazfileutils and lazfilecache after FileProcs and FileUtil
FileUtil, LazFileUtils, LazFileCache, LazUTF8, LazUTF8Classes, UTF8Process,
@ -12611,7 +12611,9 @@ var
OldChange: Boolean;
InheritedMethodPath, MethodClassName, ShortMethodName: String;
UseRTTIForMethods, AddOverride: Boolean;
MethodComponent: TComponent;
MethodComponent, AncestorComponent: TComponent;
Tool: TEventsCodeTool;
Ctx: TFindContext;
begin
Result.Code:=nil;
Result.Data:=nil;
@ -12619,7 +12621,7 @@ begin
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[ctfSwitchToFormSource])
then exit;
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(' ');
debugln('');
debugln('[TMainIDE.OnPropHookCreateMethod] ************ ',AMethodName);
DebugLn([' Persistent=',dbgsName(APersistent),' Unit=',GetClassUnitName(APersistent.ClassType),' Path=',APropertyPath]);
{$ENDIF}
@ -12638,25 +12640,22 @@ begin
raise Exception.Create('Invalid classname "'+AMethodName+'"');
end;
AddOverride:=true;
InheritedMethodPath:=GetInheritedMethodPath;
end else begin
MethodClassName:='';
ShortMethodName:=AMethodName;
AddOverride:=false;
InheritedMethodPath:='';
end;
InheritedMethodPath:=GetInheritedMethodPath;
OldChange:=OpenEditorsOnCodeToolChange;
OpenEditorsOnCodeToolChange:=true;
UseRTTIForMethods:=FormEditor1.ComponentUsesRTTIForMethods(ActiveUnitInfo.Component);
try
// create published method in active unit
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['TMainIDE.OnPropHookCreateMethod CreatePublishedMethod ',ActiveUnitInfo.Source.Filename,' LookupRoot=',ActiveUnitInfo.Component.ClassName,' ShortMethodName="',ShortMethodName,'" PropertyUnit=',GetClassUnitName(APersistent.ClassType),' APropertyPath="',APropertyPath,'" CallInherited=',InheritedMethodPath]);
debugln(['TMainIDE.OnPropHookCreateMethod CreatePublishedMethod ',ActiveUnitInfo.Source.Filename,' LookupRoot=',ActiveUnitInfo.Component.ClassName,' ShortMethodName="',ShortMethodName,'" PropertyUnit=',GetClassUnitName(APersistent.ClassType),' APropertyPath="',APropertyPath,'" CallInherited=',InheritedMethodPath,' AddOverride=',AddOverride]);
{$ENDIF}
if not AddOverride then begin
// ToDo: check if there is already an ancestor method
// The JITMethod must be created for that class
end;
r:=CodeToolBoss.CreatePublishedMethod(ActiveUnitInfo.Source,
ActiveUnitInfo.Component.ClassName,ShortMethodName,
ATypeInfo,UseRTTIForMethods,GetClassUnitName(APersistent.ClassType),
@ -12666,6 +12665,49 @@ begin
{$ENDIF}
ApplyCodeToolChanges;
if r then begin
if not AddOverride then begin
// Check which source class (active component or ancestor) has this method
// The JITMethod must be created for that class
// search method declaration
Ctx:=CleanFindContext;
try
Tool:=CodeToolBoss.FindCodeToolForSource(ActiveUnitInfo.Source) as TEventsCodeTool;
Tool.FindClassOfInstance(ActiveUnitInfo.Component,Ctx,true);
Ctx:=Ctx.Tool.FindClassMember(Ctx.Node,ShortMethodName,true);
except
on E: Exception do begin
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['[TMainIDE.OnPropHookCreateMethod] syntax error: searched for ',ActiveUnitInfo.Component.ClassName+'.'+ShortMethodName,' Error="',E.Message,'"']);
{$ENDIF}
CodeToolBoss.HandleException(E);
end;
end;
if (Ctx.Node=nil) or (Ctx.Node.Desc<>ctnProcedure) then begin
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['[TMainIDE.OnPropHookCreateMethod] damn, I lost the method: ',ActiveUnitInfo.Component.ClassName+'.'+ShortMethodName,' Ctx=',FindContextToString(Ctx)]);
{$ENDIF}
DoJumpToCodeToolBossError;
raise Exception.Create('source method not found: '+ActiveUnitInfo.Component.ClassName+'.'+ShortMethodName);
end;
// get method class
while not (Ctx.Node.Desc in AllClassObjects) do
Ctx.Node:=Ctx.Node.Parent;
MethodClassName:=Ctx.Tool.ExtractClassName(Ctx.Node,false,false);
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['[TMainIDE.OnPropHookCreateMethod] found method source in class MethodClassName, searching JITcomponent ...']);
{$ENDIF}
// find nearest JIT component
while CompareText(MethodComponent.ClassName,MethodClassName)<>0 do begin
if not MethodComponent.ClassParent.InheritsFrom(TComponent) then break;
AncestorComponent:=FormEditor1.FindJITComponentByClass(TComponentClass(MethodComponent.ClassParent));
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['[TMainIDE.OnPropHookCreateMethod] MethodComponent.ClassParent=',MethodComponent.ClassParent.ClassName,' JITcomponent=',DbgSName(AncestorComponent)]);
{$ENDIF}
if AncestorComponent=nil then break;
MethodComponent:=AncestorComponent;
end;
end;
Result:=FormEditor1.CreateNewJITMethod(MethodComponent,ShortMethodName);
{$IFDEF VerboseOnPropHookCreateMethod}
debugln(['TMainIDE.PropHookCreateMethod JITClass=',TJITMethod(Result.Data).TheClass.ClassName]);