* when searching for a procsym in an Objective-C category for an objcclass,

try to find the procsym in the category of the objcclass that is closest
    related to the original objcclass (e.g.
     NSMutableDictionary.dictionaryWithContentsOfFile() -> prefer the
     dictionaryWithContentsOfFile() from NSMutableDictionaryCreation to the
     one from NSDictionaryCreation (part of mantis #35994)

git-svn-id: trunk@42815 -
This commit is contained in:
Jonas Maebe 2019-08-25 15:23:48 +00:00
parent d29f44e1c7
commit bc7b90185f

View File

@ -4293,25 +4293,30 @@ implementation
function search_objc_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean; function search_objc_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
var var
searchst : tsymtable;
searchsym : tsym;
hashedid : THashedIDString; hashedid : THashedIDString;
stackitem : psymtablestackitem; stackitem : psymtablestackitem;
i : longint; i : longint;
founddefowner,
defowner : tobjectdef; defowner : tobjectdef;
begin begin
hashedid.id:=class_helper_prefix+s; hashedid.id:=class_helper_prefix+s;
stackitem:=symtablestack.stack; stackitem:=symtablestack.stack;
result:=false;
founddefowner:=nil;
while assigned(stackitem) do while assigned(stackitem) do
begin begin
srsymtable:=stackitem^.symtable; searchst:=stackitem^.symtable;
srsym:=tsym(srsymtable.FindWithHash(hashedid)); searchsym:=tsym(searchst.FindWithHash(hashedid));
if assigned(srsym) then if assigned(searchsym) then
begin begin
if not(srsymtable.symtabletype in [globalsymtable,staticsymtable]) or if not(searchst.symtabletype in [globalsymtable,staticsymtable]) or
not(srsym.owner.symtabletype in [globalsymtable,staticsymtable]) or not(searchsym.owner.symtabletype in [globalsymtable,staticsymtable]) or
(srsym.typ<>procsym) then (searchsym.typ<>procsym) then
internalerror(2009111505); internalerror(2009111505);
{ check whether this procsym includes a helper for this particular class } { check whether this procsym includes a helper for this particular class }
for i:=0 to tprocsym(srsym).procdeflist.count-1 do for i:=0 to tprocsym(searchsym).procdeflist.count-1 do
begin begin
{ does pd inherit from (or is the same as) the class { does pd inherit from (or is the same as) the class
that this method's category extended? that this method's category extended?
@ -4319,7 +4324,7 @@ implementation
Warning: this list contains both category and objcclass methods Warning: this list contains both category and objcclass methods
(for id.randommethod), so only check category methods here (for id.randommethod), so only check category methods here
} }
defowner:=tobjectdef(tprocdef(tprocsym(srsym).procdeflist[i]).owner.defowner); defowner:=tobjectdef(tprocdef(tprocsym(searchsym).procdeflist[i]).owner.defowner);
if is_objccategory(defowner) and if is_objccategory(defowner) and
def_is_related(pd,defowner.childof) then def_is_related(pd,defowner.childof) then
begin begin
@ -4327,28 +4332,39 @@ implementation
in the static symtable, because then it can't be in the static symtable, because then it can't be
inlined from outside this unit } inlined from outside this unit }
if assigned(current_procinfo) and if assigned(current_procinfo) and
(srsym.owner.symtabletype=staticsymtable) then (searchsym.owner.symtabletype=staticsymtable) then
include(current_procinfo.flags,pi_uses_static_symtable); include(current_procinfo.flags,pi_uses_static_symtable);
{ no need to keep looking. There might be other { Stop looking if this is a category that extends the specified
categories that extend this, a parent or child class itself. There might be other categories that extend this,
class with a method with the same name (either but that doesn't matter. If it extens a parent, keep looking
overriding this one, or overridden by this one), in case we find the symbol in a category that extends this class
but that doesn't matter as far as the basic (or a closer parent).
procsym is concerned.
} }
srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym; if not result or
srsymtable:=srsym.owner; def_is_related(defowner.childof,founddefowner) then
addsymref(srsym); begin
result:=true; founddefowner:=defowner.childof;
exit; srsym:=tprocdef(tprocsym(searchsym).procdeflist[i]).procsym;
srsymtable:=srsym.owner;
result:=true;
if pd=founddefowner then
begin
addsymref(srsym);
exit;
end;
end;
end; end;
end; end;
end; end;
stackitem:=stackitem^.next; stackitem:=stackitem^.next;
end; end;
if result then
begin
addsymref(srsym);
exit;
end;
srsym:=nil; srsym:=nil;
srsymtable:=nil; srsymtable:=nil;
result:=false;
end; end;