mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 21:06:11 +02:00
* tests with Delphi showed that an attribute class must explicitely declare a parameterless constructor if it should be used, cause TCustomAttribute.Create is private
Note: this also means that TCustomAttribute itself can not be used as an attribute * adjusted existing tests + added test git-svn-id: trunk@42471 -
This commit is contained in:
parent
c282f21b1b
commit
e97a2cb03e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13220,6 +13220,7 @@ tests/test/tcustomattr19.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr2.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr20.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr21.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr22.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr3.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr4.pp svneol=native#text/pascal
|
||||
tests/test/tcustomattr5.pp svneol=native#text/pascal
|
||||
|
@ -1143,6 +1143,17 @@
|
||||
result:=longint(E_NOINTERFACE);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TCustomAttribute
|
||||
****************************************************************************}
|
||||
|
||||
|
||||
constructor TCustomAttribute.Create;
|
||||
begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Exception Support
|
||||
****************************************************************************}
|
||||
|
@ -428,8 +428,16 @@
|
||||
{$endif FPC_USE_PSABIEH}
|
||||
end;
|
||||
|
||||
{$PUSH}
|
||||
{ disable the warning that the constructor should be public }
|
||||
{$WARN 3018 OFF}
|
||||
TCustomAttribute = class(TObject)
|
||||
private
|
||||
{ if the user wants to use a parameterless constructor they need to
|
||||
explicitely declare it in their type }
|
||||
constructor Create;
|
||||
end;
|
||||
{$POP}
|
||||
|
||||
Const
|
||||
ExceptProc : TExceptProc = Nil;
|
||||
|
@ -9,6 +9,7 @@ uses
|
||||
type
|
||||
{ TMyAttr }
|
||||
TMyAttrAttribute = class(TCustomAttribute)
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
type
|
||||
@ -17,6 +18,11 @@ type
|
||||
TMyObject = class(TObject)
|
||||
end;
|
||||
|
||||
constructor TMyAttrAttribute.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
at: PAttributeTable;
|
||||
AClassAttribute: TCustomAttribute;
|
||||
|
@ -8,11 +8,11 @@ uses
|
||||
|
||||
type
|
||||
TTest = class(TCustomAttribute)
|
||||
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
TTestAttribute = class(TCustomAttribute)
|
||||
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
{ the attribute with the Attribute suffix is preferred }
|
||||
@ -21,9 +21,20 @@ type
|
||||
|
||||
end;
|
||||
|
||||
constructor TTestAttribute.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
constructor TTest.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
at: PAttributeTable;
|
||||
attr: TCustomAttribute;
|
||||
|
||||
begin
|
||||
at := GetAttributeTable(TypeInfo(TTestObj));
|
||||
if not Assigned(at) then
|
||||
|
@ -6,8 +6,17 @@ program tcustomattr17;
|
||||
{$modeswitch prefixedattributes}
|
||||
|
||||
type
|
||||
[TCustomAttribute]
|
||||
TTest = class(TCustomAttribute)
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
[TTest]
|
||||
Int = Integer;
|
||||
|
||||
constructor TTest.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
||||
|
@ -7,53 +7,63 @@ uses
|
||||
TypInfo;
|
||||
|
||||
type
|
||||
[TCustomAttribute]
|
||||
TAttr = class(TCustomAttribute)
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
[TAttr]
|
||||
TTestRec = record
|
||||
|
||||
end;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TEnum = (
|
||||
eOne
|
||||
);
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TSet = set of TEnum;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TPtr = ^LongInt;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TLongInt = type LongInt;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TMyMethod = procedure of object;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TMyProc = procedure;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TMyStaticArray = array[0..3] of Integer;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TMyDynArray = array of Integer;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
IMyIntf = interface
|
||||
|
||||
end;
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TString8 = String[8];
|
||||
|
||||
[TCustomAttribute]
|
||||
[TAttr]
|
||||
TStringCP = type AnsiString(1234);
|
||||
|
||||
constructor TAttr.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
typeinfos: array of PTypeInfo;
|
||||
i: SizeInt;
|
||||
at: PAttributeTable;
|
||||
attr: TCustomAttribute;
|
||||
|
||||
begin
|
||||
typeinfos := [
|
||||
TypeInfo(TTestRec),
|
||||
@ -79,7 +89,7 @@ begin
|
||||
attr := GetAttribute(at, 0);
|
||||
if not Assigned(attr) then
|
||||
Halt(i * 10 + 2);
|
||||
if attr.ClassType <> TCustomAttribute then
|
||||
if attr.ClassType <> TAttr then
|
||||
Halt(i * 20 + 3);
|
||||
end;
|
||||
|
||||
|
24
tests/test/tcustomattr22.pp
Normal file
24
tests/test/tcustomattr22.pp
Normal file
@ -0,0 +1,24 @@
|
||||
{ %FAIL }
|
||||
|
||||
program tcustomattr22;
|
||||
|
||||
{$mode objfpc}
|
||||
{$modeswitch prefixedattributes}
|
||||
|
||||
type
|
||||
TTestAttribute = class(TCustomAttribute)
|
||||
constructor Create(aArg: LongInt);
|
||||
end;
|
||||
|
||||
[TTestAttribute(42), TTestAttribute]
|
||||
TMyTest = class
|
||||
|
||||
end;
|
||||
|
||||
constructor TTestAttribute.Create(aArg: LongInt);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
@ -1,3 +1,5 @@
|
||||
{ %FAIL }
|
||||
|
||||
program tcustomattr9;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
@ -8,7 +10,7 @@ uses
|
||||
|
||||
type
|
||||
{ tmyt }
|
||||
// TCustomAttribute without constructor
|
||||
// TCustomAttribute's constructor is private!
|
||||
tmyt = class(TCustomAttribute);
|
||||
|
||||
type
|
||||
@ -16,20 +18,6 @@ type
|
||||
TMyObject = class(TObject)
|
||||
end;
|
||||
|
||||
var
|
||||
at: PAttributeTable;
|
||||
AClassAttribute: TCustomAttribute;
|
||||
|
||||
begin
|
||||
at := GetAttributeTable(TMyObject.ClassInfo);
|
||||
if not Assigned(at) then
|
||||
halt(1);
|
||||
if at^.AttributeCount<>1 then
|
||||
halt(2);
|
||||
|
||||
AClassAttribute := GetAttribute(at,0);
|
||||
if AClassAttribute = nil then
|
||||
halt(3);
|
||||
writeln('ok');
|
||||
end.
|
||||
|
||||
|
@ -6,6 +6,7 @@ interface
|
||||
|
||||
type
|
||||
TTestAttribute = class(TCustomAttribute)
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
TTest2Attribute = class(TCustomAttribute)
|
||||
@ -14,6 +15,11 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
constructor TTestAttribute.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
constructor TTest2Attribute.Create(const aStr: String);
|
||||
begin
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user