Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-05

Differences between 'tsym' and 'tdef'

11 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Joost van der Sluis

Hi all,

I'm trying to implement extended RTTI property attributes as supported by recent Delphi versions. Extending the parser to allow the property attributes syntax was easy.

Now I want to add the extended-attribute information to Tpropertysym, but have to decide how to do that. It is possible to add more then one such property attribute to one property, so it needs some kind of table.

Now I'm wondering if I should make this new field of Tpropertysym a TDef or a TSym(table). I know that Tsym can store itself to a ppu while a TDef does not. But There was something else, too. But I don't remember exactly.

So two questions: how should I extend the Tpropertysym for the extended attributes, and what is the dfference/use of Tdef and Tsym.

I once figured this out for another compiler-patch but I forgot it.

Joost

Reply by email

Paul Ishenin
to Joost van der Sluis
Joost van der Sluis wrote
Now I'm wondering if I should make this new field of Tpropertysym a TDef or a TSym(table). I know that Tsym can store itself to a ppu while a TDef does not. But There was something else, too. But I don't remember exactly.

TSym is about symbol and TDef is about definition. Each symbol is just an identifier which compiler founds during parse which may have > 1 definitions (overloaded functions for example). A definition does not have a name (generally) but instead have information how to work with it. It may refer to no are stored in a TSymTable and ppu (look at TStoredDef).

A property does not have a definition of itself - only a symbol and list of fields/procedures for read,write,stored.

So two questions: how should I extend the Tpropertysym for the extended attributes, and what is the dfference/use of Tdef and Tsym.

Does any symbol in delphi may have this information? If property has this information and you created a descendant property - will it have the same attributes as an ancestor property?

For now if only property may have this information then choose TPropertySym for storing it.

Best regards,
Paul Ishenin

Reply by email

Joost van der Sluis
to Paul Ishenin
Paul Ishenin wrote 16 lines
18.05.12 5:32, Joost van der Sluis wrote: > Now I'm wondering if I should make this new field of Tpropertysym a TDef > or a TSym(table). I know that Tsym can store itself to a ppu while a > TDef does not. But There was something else, too. But I don't remember > exactly. TSym is about symbol and TDef is about definition. Each symbol is just an identifier which compiler founds during parse which may have > 1 definitions (overloaded functions for example). A definition does not have a name (generally) but instead have information how to work with it. It may refer to no are stored in a TSymTable and ppu (look at TStoredDef). A property does not have a definition of itself - only a symbol and list of fields/procedures for read,write,stored.

Thanks.

Show quoted text 6 lines
> So two questions: how should I extend the Tpropertysym for the extended > attributes, and what is the dfference/use of Tdef and Tsym. Does any symbol in delphi may have this information? If property has this information and you created a descendant property - will it have the same attributes as an ancestor property?

This information can be bound to a properties but also whole classes at least. (I'll have to test for methods and public fields) So no, not only properties may have this information.

And, to answer your second question, properties in a descendant class do *not* inherited the properties of the ancestor. I found that pretty strange, but that's how it is implemented in Delphi.

For now if only property may have this information then choose TPropertySym for storing it.

So in this case create a special symbol and symtable for it?

Joost.

Reply by email

Sven Barth
to Joost van der Sluis: I'm trying to implement extended RTTI property attributes as supported by recent Delphi…
"Joost van der Sluis" wrote 6 lines
Hi all, I'm trying to implement extended RTTI property attributes as supported by recent Delphi versions. Extending the parser to allow the property attributes syntax was easy.

Nice :D

It might be good to write tests that can be added to $fpcdir/tests/test, which helped me a lot with class helpers. :)

Now I'm wondering if I should make this new field of Tpropertysym a TDef or a TSym(table). I know that Tsym can store itself to a ppu while a TDef does not. But There was something else, too. But I don't remember exactly.

As attributes can be added to more than just properties it might be better to add this more up in the hierarchy (e.g. tdef, like the generic stuff)

I once figured this out for another compiler-patch but I forgot it.

Do you work in a branch? If not it might be better to change this as attributes are a bigger change and this way they can be merged/integrated more easily than with a patch.

Regards,
Sven

Reply by email

Paul Ishenin
to Joost van der Sluis: Thanks. This information can be bound to a properties but also whole classes at least.…
Joost van der Sluis wrote
This information can be bound to a properties but also whole classes at least. (I'll have to test for methods and public fields) So no, not only properties may have this information.

If methods may have this information then it is not possible to put it to tsym because paticular method is a tprocdef and several tprocdefs may have 1 tprocsym (overloaded methods). Therefore I would put this info to tstoreddef. But what to do with a property? Create a special def for it?

And, to answer your second question, properties in a descendant class do *not* inherited the properties of the ancestor. I found that pretty strange, but that's how it is implemented in Delphi.

There may be 3 cases. Does it work in any:

case 1: property descendant

TAncestor = class
   [attributes]
   property SomeProp: TSomeType read GetSomeProp;
end;
TDescendant = class(TAncestor)
   property SomeProp write SetSomeProp; // <- this is property descendant
end;

case 2: new property hides old

TDescendant = class(TAncestor)
   property SomeProp: TSomeType read GetSomeProp; // <- this property
hides old SomeProp
end;

case 3: new class uses property as is

TDescendant = class(TAncestor)
end;
So in this case create a special symbol and symtable for it?

Looking at
http://docwiki.embarcadero.com/RADStudio/en/Annotating_Types_and_Type_Members I see that attribute is a class + a list of arguments for that class contructor. As this is a class - compiler already creates a symbol and a definition for it and all it members. So you need to store a link to this class (or to class contructor) + a list of arguments to pass there. So it is not a special symbol, just a reference to it. If you need an example of how to store/restore reference to a class then look at how it is done with tobjectdef.childof or tobjectdef.extendeddef.

Best regards,
Paul Ishenin

Reply by email

Joost van der Sluis
to Paul Ishenin
Paul Ishenin wrote 27 lines
18.05.2012 14:23, Joost van der Sluis wrote: > This information can be bound to a properties but also whole classes at > least. (I'll have to test for methods and public fields) So no, not only > properties may have this information. If methods may have this information then it is not possible to put it to tsym because paticular method is a tprocdef and several tprocdefs may have 1 tprocsym (overloaded methods). Therefore I would put this info to tstoreddef. But what to do with a property? Create a special def for it? > And, to answer your second question, properties in a descendant class do > *not* inherited the properties of the ancestor. I found that pretty > strange, but that's how it is implemented in Delphi. There may be 3 cases. Does it work in any: case 1: property descendant TAncestor = class [attributes] property SomeProp: TSomeType read GetSomeProp; end; TDescendant = class(TAncestor) property SomeProp write SetSomeProp; // <- this is property descendant end;

This one should not have any attributes.

Show quoted text 6 lines
case 2: new property hides old TDescendant = class(TAncestor) property SomeProp: TSomeType read GetSomeProp; // <- this property hides old SomeProp end;

Also not.

case 3: new class uses property as is TDescendant = class(TAncestor) end;

Also not. (I know, it is strange behavior. But there are more strange things, as there is no type-checking in attributes. It seems like they just hacked this together rather quickly...)

Show quoted text 11 lines
> So in this case create a special symbol and symtable for it? Looking at http://docwiki.embarcadero.com/RADStudio/en/Annotating_Types_and_Type_Members I see that attribute is a class + a list of arguments for that class contructor. As this is a class - compiler already creates a symbol and a definition for it and all it members. So you need to store a link to this class (or to class contructor) + a list of arguments to pass there. So it is not a special symbol, just a reference to it. If you need an example of how to store/restore reference to a class then look at how it is done with tobjectdef.childof or tobjectdef.extendeddef.

Indeed. And I do have the symbol of the corresponding type and a list of parameters already. I thought I needed a symbol/definition to store the references. Else I would have to store those references in the TPropertySym, but also in the symbol of the class. That doesn't look good to me?

Joost.

Reply by email

Paul Ishenin
to Joost van der Sluis
Joost van der Sluis wrote 5 lines
Indeed. And I do have the symbol of the corresponding type and a list of parameters already. I thought I needed a symbol/definition to store the references. Else I would have to store those references in the TPropertySym, but also in the symbol of the class. That doesn't look good to me?

I think you need to store this information both in TStoredDef - for classes, records, enumerations, arays, ordinals, functions. At the same time you need to store it in tpropertysym, tfieldvarsym (maybe TStoredSym) since they are not definitions.

Best regards,
Paul Ishenin

Reply by email

Sven Barth
"Joost van der Sluis" wrote
Also not. (I know, it is strange behavior. But there are more strange things, as there is no type-checking in attributes. It seems like they just hacked this together rather quickly...)

You mean typechecking regarding the constructor arguments? Would it be possible to add this?

Another note: does Delphi allow/support attributes in interfaces? If so you need to check that GUIDs are handled correctly (AFAIK they can also be string constants instead of "naked strings")

Regards,
Sven

Reply by email

Joost van der Sluis
to Sven Barth
Sven Barth wrote 10 lines
Am 18.05.2012 09:49 schrieb "Joost van der Sluis" : > Also not. (I know, it is strange behavior. But there are more strange > things, as there is no type-checking in attributes. It seems like they > just hacked this together rather quickly...) > You mean typechecking regarding the constructor arguments? Would it be possible to add this?

I think I can. But in Delphi you can also give a non-exsisting attribute, ie:

  TMyClass=class
  private
    FName: string;
  published
    [TThisTypeIsNowhereDefined('You','Can','Enter','Anything','here'1)]
    property Name: string read FName;
  end;

This will compile in Delphi, but it won't work. This is especially annoying if you forgot to add the unit in which
TThisTypeIsNowhereDefined is defined. In that case it will also compile, but it will not work. And you will seek for that error for long. I know. ;)

Another note: does Delphi allow/support attributes in interfaces? If so you need to check that GUIDs are handled correctly (AFAIK they can also be string constants instead of "naked strings")

I started my implementation by copying the part where interface GUID's are parsed, so I already took care of that. (But it's simple: interfaces do not support attributes)

Joost

Reply by email

Alexander Klenin
to Joost van der Sluis
Joost van der Sluis wrote 16 lines
I think I can. But in Delphi you can also give a non-exsisting attribute, ie:  TMyClass=class  private    FName: string;  published    [TThisTypeIsNowhereDefined('You','Can','Enter','Anything','here'1)]    property Name: string read FName;  end; This will compile in Delphi, but it won't work. This is especially annoying if you forgot to add the unit in which TThisTypeIsNowhereDefined is defined. In that case it will also compile, but it will not work. And you will seek for that error for long. I know. ;)

That's just evil. I hope FPC will check attributes at compile-time, at least in objfpc mode?

Alexander S. Klenin

Reply by email