* let search_class_helper() only return class helper methods; it could

also return regular objcclass methods before, because these are also
    registered under class helper procsyms for future id.anymethod support
  * give an error when calling an inherited method from an objccategory
    method, if that is not declared in the parent of the extended class
    (since calling inherited in an objccategory method is the same as
     calling inherited in a method of the extended class; if a method is
     replaced, calling inherited will *not* call the original method
     from the original class)

git-svn-id: trunk@14213 -
This commit is contained in:
Jonas Maebe 2009-11-18 21:49:57 +00:00
parent 4104d9f481
commit b495fbb991
6 changed files with 143 additions and 1 deletions

3
.gitattributes vendored
View File

@ -8970,6 +8970,9 @@ tests/test/tobjc26a.pp svneol=native#text/plain
tests/test/tobjc27a.pp svneol=native#text/plain
tests/test/tobjc27b.pp svneol=native#text/plain
tests/test/tobjc28.pp svneol=native#text/plain
tests/test/tobjc29.pp svneol=native#text/plain
tests/test/tobjc29a.pp svneol=native#text/plain
tests/test/tobjc29b.pp svneol=native#text/plain
tests/test/tobjc3.pp svneol=native#text/plain
tests/test/tobjc4.pp svneol=native#text/plain
tests/test/tobjc4a.pp svneol=native#text/plain

View File

@ -2232,6 +2232,12 @@ implementation
assigned(current_objectdef) then
begin
hclassdef:=current_objectdef.childof;
{ Objective-C categories *replace* methods in the class
they extend, or add methods to it. So calling an
inherited method always calls the method inherited from
the parent of the extended class }
if is_objccategory(current_objectdef) then
hclassdef:=hclassdef.childof;
{ if inherited; only then we need the method with
the same name }
if token in endtokens then

View File

@ -2033,6 +2033,7 @@ implementation
hashedid : THashedIDString;
stackitem : psymtablestackitem;
i : longint;
defowner : tobjectdef;
begin
hashedid.id:=class_helper_prefix+s;
stackitem:=symtablestack.stack;
@ -2051,8 +2052,13 @@ implementation
begin
{ does pd inherit from (or is the same as) the class
that this method's category extended?
Warning: this list contains both category and objcclass methods
(for id.randommethod), so only check category methods here
}
if pd.is_related(tobjectdef(tprocdef(tprocsym(srsym).procdeflist[i]).owner.defowner).childof) then
defowner:=tobjectdef(tprocdef(tprocsym(srsym).procdeflist[i]).owner.defowner);
if (oo_is_classhelper in defowner.objectoptions) and
pd.is_related(defowner.childof) then
begin
{ no need to keep looking. There might be other
categories that extend this, a parent or child

45
tests/test/tobjc29.pp Normal file
View File

@ -0,0 +1,45 @@
{ %target=darwin }
{ %cpu=powerpc,powerpc64,i386,x86_64,arm }
{$mode objfpc}
{$modeswitch objectivec1}
type
ta = objcclass(NSObject)
function tabaseproc(cp: longint): double; message 'tabaseproc:';
end;
ca = objccategory(ta)
function tabaseproc(cp: longint): double; reintroduce;
end;
nsobjectta = objccategory(NSObject)
function tabaseproc(cp: longint): double; message 'tabaseproc:';
end;
function ta.tabaseproc(cp: longint): double;
begin
result:=cp;
halt(1);
end;
function ca.tabaseproc(cp: longint): double;
begin
result:=inherited tabaseproc(cp+1);
end;
function nsobjectta.tabaseproc(cp: longint): double;
begin
if (cp<>4321) then
halt(1);
result:=123.625;
end;
var
a: ta;
begin
a:=ta(ta.alloc).init;
if a.tabaseproc(4320)<>123.625 then
halt(2);
a.release;
end.

35
tests/test/tobjc29a.pp Normal file
View File

@ -0,0 +1,35 @@
{ %target=darwin }
{ %cpu=powerpc,powerpc64,i386,x86_64,arm }
{ %fail }
{$mode objfpc}
{$modeswitch objectivec1}
type
ta = objcclass(NSObject)
function tabaseproc(cp: longint): double; message 'tabaseproc:';
end;
ca = objccategory(ta)
function tabaseproc(cp: longint): double; reintroduce;
end;
function ta.tabaseproc(cp: longint): double;
begin
result:=cp;
halt(1);
end;
function ca.tabaseproc(cp: longint): double;
begin
result:=inherited tabaseproc(cp+1);
end;
var
a: ta;
begin
a:=ta(ta.alloc).init;
if a.tabaseproc(4320)<>123.625 then
halt(2);
a.release;
end.

47
tests/test/tobjc29b.pp Normal file
View File

@ -0,0 +1,47 @@
{ %target=darwin }
{ %cpu=powerpc,powerpc64,i386,x86_64,arm }
{ %fail }
{$mode objfpc}
{$modeswitch objectivec1}
type
ta = objcclass(NSObject)
function tabaseproc(cp: longint): double; message 'tabaseproc:';
end;
ca = objccategory(ta)
{ should fail because of wrong message name }
function tabaseproc(cp: longint): double; message 'adifferentname:'; reintroduce;
end;
nsobjectta = objccategory(NSObject)
function tabaseproc(cp: longint): double; message 'tabaseproc:';
end;
function ta.tabaseproc(cp: longint): double;
begin
result:=cp;
halt(1);
end;
function ca.tabaseproc(cp: longint): double;
begin
result:=inherited tabaseproc(cp+1);
end;
function nsobjectta.tabaseproc(cp: longint): double;
begin
if (cp<>4321) then
halt(1);
result:=123.625;
end;
var
a: ta;
begin
a:=ta(ta.alloc).init;
if a.tabaseproc(4320)<>123.625 then
halt(2);
a.release;
end.