mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 15:28:00 +02:00
* fix intf map resolving with for inherited intfs
git-svn-id: trunk@3055 -
This commit is contained in:
parent
2ee71781a7
commit
b2121dae20
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -6767,6 +6767,7 @@ tests/webtbs/tw4893c.pp svneol=native#text/plain
|
||||
tests/webtbs/tw4898.pp -text
|
||||
tests/webtbs/tw4902.pp -text
|
||||
tests/webtbs/tw4922.pp svneol=native#text/plain
|
||||
tests/webtbs/tw4950.pp svneol=native#text/plain
|
||||
tests/webtbs/ub1873.pp svneol=native#text/plain
|
||||
tests/webtbs/ub1883.pp svneol=native#text/plain
|
||||
tests/webtbs/uw0555.pp svneol=native#text/plain
|
||||
|
@ -1115,10 +1115,12 @@ implementation
|
||||
var
|
||||
def: tdef;
|
||||
hs,
|
||||
prefix,
|
||||
mappedname: string;
|
||||
nextexist: pointer;
|
||||
implprocdef: tprocdef;
|
||||
begin
|
||||
prefix:=_class.implementedinterfaces.interfaces(intfindex).symtable.name^+'.';
|
||||
def:=tdef(intf.symtable.defindex.first);
|
||||
while assigned(def) do
|
||||
begin
|
||||
@ -1127,7 +1129,7 @@ implementation
|
||||
implprocdef:=nil;
|
||||
nextexist:=nil;
|
||||
repeat
|
||||
hs:=intf.symtable.name^+'.'+tprocdef(def).procsym.name;
|
||||
hs:=prefix+tprocdef(def).procsym.name;
|
||||
mappedname:=_class.implementedinterfaces.getmappings(intfindex,hs,nextexist);
|
||||
if mappedname<>'' then
|
||||
implprocdef:=gintfgetcprocdef(tprocdef(def),mappedname);
|
||||
|
@ -682,7 +682,8 @@ implementation
|
||||
{ Create unique name <interface>.<method> }
|
||||
hs:=sp+'.'+pattern;
|
||||
consume(_EQUAL);
|
||||
if (token=_ID) then
|
||||
if (i<>-1) and
|
||||
(token=_ID) then
|
||||
aclass.implementedinterfaces.addmappings(i,hs,pattern);
|
||||
consume(_ID);
|
||||
result:=true;
|
||||
|
143
tests/webtbs/tw4950.pp
Normal file
143
tests/webtbs/tw4950.pp
Normal file
@ -0,0 +1,143 @@
|
||||
// This code is provided bt Leandro Conde [leandor@gmail.com]
|
||||
// to demonstrate a problem with function redirection in interfaces
|
||||
// in the FPC compiler version 2.0.2
|
||||
//
|
||||
// In the real implementation is used to provide a set of data type
|
||||
// conversion functions: From<Type> and To<Type>.
|
||||
// In that scenario, the IBase contains functions specific por <Type>,
|
||||
// and the Derived are the <From> and <To> parts.
|
||||
|
||||
{$mode delphi}
|
||||
|
||||
program FunctionRedirectionProblem;
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
var
|
||||
cnt : longint;
|
||||
|
||||
type
|
||||
// It really doesn't matters what this interface contains,
|
||||
// is just represet some functionality set that is provided
|
||||
// with two complementary sets of implementations.
|
||||
IBase = interface
|
||||
['{6CEA50E0-1844-405F-9B6F-2E9D50BE6EFC}']
|
||||
function Base1(const Arg1: string; const Arg2: Double): Boolean;
|
||||
function Base2(const Arg1: TDateTime; const Arg2: Single): Boolean;
|
||||
function Base3(const Arg1: WideString; const Arg2: Integer): Boolean;
|
||||
end;
|
||||
|
||||
// Derived 1 to provide an IBase with a specific funtionality when used from IDerived1
|
||||
IDerived1 = interface (IBase)
|
||||
['{3DC49E1B-9A52-499E-8BCD-E1BA160329C9}']
|
||||
function Derived1Specific(Arg1: Integer): Integer;
|
||||
end;
|
||||
|
||||
// Derived 2 to provide an IBase with a complementary funtionality when used from IDerived2
|
||||
IDerived2 = interface (IBase)
|
||||
['{E44DF3BC-75C8-4284-928B-DE3162347C21}']
|
||||
function Derived2Specific(Arg1: Integer): Integer;
|
||||
end;
|
||||
|
||||
// Just for runtime testing purposes
|
||||
ITestCase = interface
|
||||
['{C608134F-2F9A-44A4-8932-F169EF40E177}']
|
||||
function Derived1: IDerived1;
|
||||
function Derived2: IDerived2;
|
||||
end;
|
||||
|
||||
type
|
||||
// Implementing all the above stuff
|
||||
TTestCase = class(TInterfacedObject, IDerived1, IDerived2, ITestCase )
|
||||
protected
|
||||
// methods from IBase in IDerived1 redirected to one function set:
|
||||
function IDerived1.Base1 = Derived1_Base1;
|
||||
function IDerived1.Base2 = Derived1_Base2;
|
||||
function IDerived1.Base3 = Derived1_Base3;
|
||||
// this is the function set for IBase in IDerived1
|
||||
function Derived1_Base1(const Arg1: string; const Arg2: Double): Boolean;
|
||||
function Derived1_Base2(const Arg1: TDateTime; const Arg2: Single): Boolean;
|
||||
function Derived1_Base3(const Arg1: WideString; const Arg2: Integer): Boolean;
|
||||
// specifics from IDerived1
|
||||
function Derived1Specific(Arg1: Integer): Integer;
|
||||
protected
|
||||
// methods from IBase in IDerived2 redirected to the other function set:
|
||||
function IDerived2.Base1 = Derived2_Base1;
|
||||
function IDerived2.Base2 = Derived2_Base2;
|
||||
function IDerived2.Base3 = Derived2_Base3;
|
||||
// this is the function set for IBase in IDerived2
|
||||
function Derived2_Base1(const Arg1: string; const Arg2: Double): Boolean;
|
||||
function Derived2_Base2(const Arg1: TDateTime; const Arg2: Single): Boolean;
|
||||
function Derived2_Base3(const Arg1: WideString; const Arg2: Integer): Boolean;
|
||||
// specifics from IDerived2
|
||||
function Derived2Specific(Arg1: Integer): Integer;
|
||||
protected // this is not essential, just for testing in runtime ITestCase
|
||||
function Derived1: IDerived1;
|
||||
function Derived2: IDerived2;
|
||||
end;
|
||||
|
||||
{ TTestCase }
|
||||
|
||||
function TTestCase.Derived1_Base1(const Arg1: string; const Arg2: Double): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
writeln('1:',arg1,arg2);
|
||||
inc(cnt);
|
||||
end;
|
||||
|
||||
function TTestCase.Derived1_Base2(const Arg1: TDateTime; const Arg2: Single): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived1_Base3(const Arg1: WideString; const Arg2: Integer): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived1Specific(Arg1: Integer): Integer;
|
||||
begin
|
||||
Result := Arg1;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived2_Base1(const Arg1: string; const Arg2: Double): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
writeln('2:',arg1,arg2);
|
||||
inc(cnt);
|
||||
end;
|
||||
|
||||
function TTestCase.Derived2_Base2(const Arg1: TDateTime; const Arg2: Single): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived2_Base3(const Arg1: WideString; const Arg2: Integer): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived2Specific(Arg1: Integer): Integer;
|
||||
begin
|
||||
Result := Arg1;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived1: IDerived1;
|
||||
begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
function TTestCase.Derived2: IDerived2;
|
||||
begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
var
|
||||
TestCase: ITestCase;
|
||||
begin
|
||||
TestCase := TTestCase.Create;
|
||||
|
||||
TestCase.Derived1.Base1('called from derived1', 3.14159);
|
||||
TestCase.Derived2.Base1('called from derived2', 2.7178);
|
||||
if cnt<>2 then
|
||||
halt(1);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user