Which language elements can be annotated using attributes language feature of Delphi?
Asked Answered
G

1

32

Delphi 2010 introduced custom attributes which can be added to type declarations and methods. For which language elements can a custom attribute be used?

The examples which I have found so far include class declarations, fields and methods. (And AFAIK generic classes do not support custom attributes).

Some examples are shown in this article. It looks like variables (external to any class declaration) also can have attributes.

Based on this article, attributes can be used for

  • class and record fields and methods
  • method parameters
  • properties
  • non-local enumeration declarations
  • non-local variable declarations

Are there other language elements where attributes can be placed?


Update: this article indicates that custom attributes can be placed before properties: http://francois-piette.blogspot.de/2013/01/using-custom-attribute-for-data.html

It contains this code example:

type
  TConfig = class(TComponent)
  public
    [PersistAs('Config', 'Version', '1.0')]
    Version : String;
    [PersistAs('Config', 'Description', 'No description')]
    Description : String;
    FTest : Integer;
    // No attribute => not persistent
    Count : Integer;
    [PersistAs('Config', 'Test', '0')]
    property Test : Integer read FTest write FTest;
  end;

I guess that there is also a way to read attributes on method arguments like

procedure Request([FormParam] AUsername: string; [FormParam] APassword: string);
Glossography answered 25/5, 2011 at 5:39 Comment(3)
+1 Interesting question. The documentation states that attributes are for "annotating types and type members" - I suspect that means anything in a type clause, as well as whatever is declared inside a record or class (member variables, properties, functions, procedures, internal classes, etc.)Stereotype
That link about properties isn't working for me. If you remember what it said, would you mind editing the answer below to demonstrate use of attributes on properties? (I cannot find another source for that link because the citation doesn't include anything about author, topic, forum, or even date.)Hasbeen
@RobKennedy thanks for noticing! I could not find the original source, but another article and updated the questionGlossography
T
28

Interesting question! You can declare attributes on almost anything, the problem is retrieving them using RTTI. Here's a quick console demo of declaring custom attributes for:

  • Enums
  • Function type
  • Procedure type
  • Method type (of object)
  • Aliased type
  • Record type
  • Class type
  • Record type that's internal to a class
  • Record field
  • Record method
  • Class instance field
  • Class class field (class var)
  • Class method
  • Global variable
  • Global function
  • Local variable

Didn't find a way to declare a custom attribute for a property of a class. But a custom attribute can be attached to the getter or setter methods.

Code, the story continues after the code:

program Project25;

{$APPTYPE CONSOLE}

uses
  Rtti;

type
  TestAttribute = class(TCustomAttribute);

  [TestAttribute] TEnum = (first, second, third);
  [TestAttribute] TFunc = function: Integer;
  [TestAttribute] TEvent = procedure of object;
  [TestAttribute] AliasInteger = Integer;

  [TestAttribute] ARecord = record
    x:Integer;
    [TestAttribute] RecordField: Integer;
    [TestAttribute] procedure DummyProc;
  end;

  [TestAttribute] AClass = class
  strict private
    type [TestAttribute] InnerType = record y:Integer; end;
  private
    [TestAttribute]
    function GetTest: Integer;
  public
    [TestAttribute] x: Integer;
    [TestAttribute] class var z: Integer;
    // Can't find a way to declare attribute for property!
    property Test:Integer read GetTest;
    [TestAttribute] class function ClassFuncTest:Integer;
  end;

var [TestAttribute] GlobalVar: Integer;

[TestAttribute]
procedure GlobalFunction;
var [TestAttribute] LocalVar: Integer;
begin
end;

{ ARecord }

procedure ARecord.DummyProc;
begin
end;

{ AClass }

class function AClass.ClassFuncTest: Integer;
begin
end;

function AClass.GetTest: Integer;
begin
end;

begin
end.

The trouble is retrieving those custom attributes. Looking at the rtti.pas unit, custom attributes can be retrieved for:

  • Record type (TRttiRecordType)
  • Instance type (TRttiInstanceType)
  • Method type (TRttiMethodType)
  • Pointer type (TRttiPointerType) - what's that used for?
  • Procedure type (TRttiProcedureType)

There's no way of retrieving any sort of RTTI for "unit" level or local variables and procedures, hence no way of retrieving information about attributes.

Thumbsdown answered 25/5, 2011 at 6:10 Comment(3)
No support for attributes on properties is odd (and a shame - properties are one of the awesome things about Delphi classes.) Btw, +1 for an excellent answer.Stereotype
@Stereotype M: see my update, it looks like attributes on properties work fineGlossography
What about procedure and function parameters, can they have attributes?Glossography

© 2022 - 2024 — McMap. All rights reserved.