* fixed assigning "id" to a protocol instance and using protocol instances

to call methods + test

git-svn-id: trunk@15453 -
This commit is contained in:
Jonas Maebe 2010-06-19 16:19:13 +00:00
parent a2af005101
commit 790c7954b7
4 changed files with 97 additions and 3 deletions

1
.gitattributes vendored
View File

@ -9273,6 +9273,7 @@ tests/test/tobjc2.pp svneol=native#text/plain
tests/test/tobjc20.pp svneol=native#text/plain
tests/test/tobjc21.pp svneol=native#text/plain
tests/test/tobjc22.pp svneol=native#text/plain
tests/test/tobjc22a.pp svneol=native#text/plain
tests/test/tobjc23.pp svneol=native#text/plain
tests/test/tobjc24.pp svneol=native#text/plain
tests/test/tobjc25.pp svneol=native#text/plain

View File

@ -1268,7 +1268,7 @@ implementation
eq:=te_convert_l1;
end
{ All Objective-C classes are compatible with ID }
else if is_objcclass(def_to) and
else if is_objc_class_or_protocol(def_to) and
(def_from=objc_idtype) then
begin
doconv:=tc_equal;

View File

@ -1981,6 +1981,7 @@ implementation
var
hashedid : THashedIDString;
orgclass : tobjectdef;
i : longint;
begin
orgclass:=classh;
{ The contextclassh is used for visibility. The classh must be equal to
@ -1991,7 +1992,9 @@ implementation
internalerror(200811161);
result:=false;
hashedid.id:=s;
while assigned(classh) do
{ an Objective-C protocol can inherit from multiple other protocols
-> uses ImplementedInterfaces instead }
if is_objcprotocol(classh) then
begin
srsymtable:=classh.symtable;
srsym:=tsym(srsymtable.FindWithHash(hashedid));
@ -2002,7 +2005,30 @@ implementation
result:=true;
exit;
end;
classh:=classh.childof;
for i:=0 to classh.ImplementedInterfaces.count-1 do
begin
if searchsym_in_class(TImplementedInterface(classh.ImplementedInterfaces[i]).intfdef,contextclassh,s,srsym,srsymtable) then
begin
result:=true;
exit;
end;
end;
end
else
begin
while assigned(classh) do
begin
srsymtable:=classh.symtable;
srsym:=tsym(srsymtable.FindWithHash(hashedid));
if assigned(srsym) and
is_visible_for_object(srsym,contextclassh) then
begin
addsymref(srsym);
result:=true;
exit;
end;
classh:=classh.childof;
end;
end;
if is_objcclass(orgclass) then
result:=search_class_helper(orgclass,s,srsym,srsymtable)

67
tests/test/tobjc22a.pp Normal file
View File

@ -0,0 +1,67 @@
{ %target=darwin }
{ %cpu=powerpc,powerpc64,i386,x86_64,arm }
{ Written by Jonas Maebe in 2009, released into the public domain }
program protocoltest;
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
type
MyProtocolA = objcprotocol
function newMethod: longint; message 'n';
end;
MyProtocolB = objcprotocol(MyProtocolA)
class function newClassMethod: longint; message 'newClassMethod';
end;
{ TMyObject }
TMyObjectA = objcclass(NSObject, MyProtocolA)
function newMethod: longint;
end;
TMyObjectB = objcclass(NSObject,MyProtocolB)
function newMethod: longint;
class function newClassMethod: longint;
end;
{ TMyObjectA }
function TMyObjectA.newMethod: longint;
begin
result:=1;
end;
{ TMyObjectB }
function TMyObjectB.newMethod: longint;
begin
result:=3;
end;
class function TMyObjectB.newClassMethod: longint;
begin
result:=4;
end;
var
a : MyProtocolA;
b : MyProtocolB;
begin
a:=TMyObjectA.alloc.init;
b:=TMyObjectB.alloc.init;
if a.newMethod<>1 then
halt(1);
if b.newMethod<>3 then
halt(3);
if b.newclassmethod<>4 then
halt(4);
id(a).release;
id(b).release;
end.