fpc/tests/tbs/tb0546.pp
joost 07bf44517c * Merged XPCom branch into trunk, added support for constref and changed
the IInterface implementation to be XPCom-compatible
--- Merging r15997 through r16179 into '.':
U    rtl/inc/variants.pp
U    rtl/inc/objpash.inc
U    rtl/inc/objpas.inc
U    rtl/objpas/classes/persist.inc
U    rtl/objpas/classes/compon.inc
U    rtl/objpas/classes/classesh.inc
A    tests/test/tconstref1.pp
A    tests/test/tconstref2.pp
A    tests/test/tconstref3.pp
U    tests/test/tinterface4.pp
A    tests/test/tconstref4.pp
U    tests/webtbs/tw10897.pp
U    tests/webtbs/tw4086.pp
U    tests/webtbs/tw15363.pp
U    tests/webtbs/tw2177.pp
U    tests/webtbs/tw16592.pp
U    tests/tbs/tb0546.pp
U    compiler/sparc/cpupara.pas
U    compiler/i386/cpupara.pas
U    compiler/pdecsub.pas
U    compiler/symdef.pas
U    compiler/powerpc/cpupara.pas
U    compiler/avr/cpupara.pas
U    compiler/browcol.pas
U    compiler/defcmp.pas
U    compiler/powerpc64/cpupara.pas
U    compiler/ncgrtti.pas
U    compiler/x86_64/cpupara.pas
U    compiler/opttail.pas
U    compiler/htypechk.pas
U    compiler/tokens.pas
U    compiler/objcutil.pas
U    compiler/ncal.pas
U    compiler/symtable.pas
U    compiler/symsym.pas
U    compiler/m68k/cpupara.pas
U    compiler/regvars.pas
U    compiler/arm/cpupara.pas
U    compiler/symconst.pas
U    compiler/mips/cpupara.pas
U    compiler/paramgr.pas
U    compiler/psub.pas
U    compiler/pdecvar.pas
U    compiler/dbgstabs.pas
U    compiler/options.pas
U    packages/fcl-fpcunit/src/testutils.pp

git-svn-id: trunk@16180 -
2010-10-17 20:58:22 +00:00

259 lines
5.0 KiB
ObjectPascal

{ test code based on code from ttp://www.geocities.com/svi37/cyber/delphi9/iimplementation.html }
{$ifdef fpc}
{$mode delphi}
{$endif fpc}
uses
sysutils;
type
IXInterface = interface(IUnknown)
['{713252E5-4636-11D5-B572-00AA00ACFD08}']
procedure XStaticMethod;
procedure XVirtualMethod;
end;
IYInterface = interface(IUnknown)
['{713252E6-4636-11D5-B572-00AA00ACFD08}']
procedure YMethod;
end;
IZInterface = interface(IUnknown)
['{713252E4-4636-11D5-B572-00AA00ACFD08}']
end;
type
TInnerObject = class(TAggregatedObject,IXInterface,IYInterface)
public
procedure XStaticMethod;
procedure XVirtualMethod; virtual;
procedure YMethod;
end;
TSpecialObject = class(TInnerObject,IXInterface,IYInterface)
public
procedure XStaticMethod;
procedure XVirtualMethod; override;
procedure YMethod;
end;
TFoo = class({!!!! IXInterface, }IYInterface,IZInterface)
private
FInnerX: TInnerObject;
protected
function QueryInterface(constref IID: TGUID; out Obj): HResult; virtual; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
function _AddRef: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
function _Release: Integer; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
function GetX: TInnerObject; virtual;
function GetY: IYInterface;
public
constructor Create;
destructor Destroy; override;
//!!!! property InnerX: TInnerObject read GetX implements IXInterface;
property InnerY: IYInterface read GetY implements IYInterface;
end;
TBar = class(TFoo,{!!!!IXInterface,}IYInterface,IUnknown)
private
FX: TSpecialObject;
FY: IYInterface;
protected
function GetX: TInnerObject; override;
public
constructor Create;
destructor Destroy; override;
property Y: IYInterface read FY implements IYInterface;
//!!!! property X: TSpecialObject read FX implements IXInterface;
end;
{ TFoo }
constructor TFoo.Create;
var
i: IZInterface;
begin
inherited;
i := self;
FInnerX := TInnerObject.Create(i); //interface inh. to IUnknown
end;
destructor TFoo.Destroy;
begin
WriteLn('TFoo.Destroy');
FInnerX.Free;
inherited;
end;
{ TFoo.IUnknown }
function TFoo._AddRef: Integer;
begin
result := -1;
end;
function TFoo._Release: Integer;
begin
result := -1;
end;
function TFoo.QueryInterface(constref IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;function TFoo.GetX: TInnerObject;
begin
result := FInnerX;
end;
{ TFoo.IUnknown }
function TFoo.GetY: IYInterface;
begin
result := FInnerX;
end;
{ TBar }
constructor TBar.Create;
begin
inherited;
FX := TSpecialObject.Create(Self); //explicit IUnknown
FY := FX;
end;
destructor TBar.Destroy;
begin
WriteLn('TBar.Destroy');
FY := nil;
FX.Free;
inherited;
end;
function TBar.GetX: TInnerObject;
begin
result := FX;
end;
{ TInnerObject }
procedure TInnerObject.XStaticMethod;
begin
WriteLn(Format(
'Calls TInnerObject.XStaticMethod on a %s',[ClassName]));
end;
procedure TInnerObject.XVirtualMethod;
begin
WriteLn(Format(
'Calls TInnerObject.XVirtualMethod on a %s',[ClassName]));
end;
procedure TInnerObject.YMethod;
begin
WriteLn(Format(
'Calls TInnerObject.YMethod on a %s',[ClassName]));
end;
{ TSpecialObject }
procedure TSpecialObject.XStaticMethod;
begin
WriteLn(Format(
'Calls TSpecialObject.XStaticMethod on a %s',[ClassName]));
end;
procedure TSpecialObject.XVirtualMethod;
begin
// inherited;
WriteLn(Format(
'Calls TSpecialObject.XVirtualMethod on a %s',[ClassName]));
end;
procedure TSpecialObject.YMethod;
begin
WriteLn(Format(
'Calls TSpecialObject.YMethod on a %s',[ClassName]));
end;
procedure TestFoo(AFoo: TFoo);
var
o: TFoo;
x: IXInterface;
y: IYInterface;
z: IZInterface;
begin
o := AFoo;
//!!!! x := o;
//!!!! x.XStaticMethod; // if AFoo is TBar TFoo.XStatic hides TBar.XStatic
//!!!! x.XVirtualMethod;
y := o;
y.YMethod;
//!!!! z := x as IZInterface;
z := y as IZInterface;
z := o;
//!!!! x := z as IXInterface;
end;
procedure TestBar(ABar: TBar);
var
o: TBar;
x: IXInterface;
y: IYInterface;
z: IZInterface;
begin
o := ABar;
//!!!! x := o;
//!!!! x.XStaticMethod;
//!!!! x.XVirtualMethod;
y := o;
y.YMethod;
//!!!! z := x as IZInterface;
z := y as IZInterface;
z := o;
//!!!! x := z as IXInterface;
end;
procedure Test;
var
AFoo: TFoo;
ABar: TBar;
begin
AFoo := TFoo.Create;
ABar := TBar.Create;
WriteLn('***TestFoo(AFoo)*****************');
TestFoo(AFoo);
WriteLn('***TestFoo(ABar)*****************');
TestFoo(ABar);
WriteLn('***TestBar(ABar)*****************');
TestBar(ABar);
AFoo.Free;
ABar.Free;
end;
begin
WriteLn('IntGetter.TInnerObject.InstanceSize: ',TInnerObject.InstanceSize);
WriteLn('IntGetter.TSpecialObject.InstanceSize: ',TSpecialObject.InstanceSize);
WriteLn('IntGetter.TFoo.InstanceSize: ',TFoo.InstanceSize);
WriteLn('IntGetter.TBar.InstanceSize: ',TBar.InstanceSize);
Test;
end.