www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get unknown symbol (struct, method, class) tagged with User Defined

reply Doug <overprose gmail.com> writes:
I've seen a lot of examples of how to get a list of User Defined 
Attributes from a known symbol but I haven't seen any for how to 
get a list of symbols when only the UDA is known.

The use case is the same as seen in Rust with Serde[1]. Library 
users annotate a struct to mark it for serialization. In Java and 
Spring, you can mark a method with  Secured to add authorization 
to an endpoint[2]. In both of these cases, you have no idea which 
symbol the UDA will be applied to.

So far I've only seen a way to get unknown UDAs from known 
symbols but not how to get unknown symbols from UDAs. Is there 
any documentation for how to get a list of symbols annotated with 
a specific UDA?


1: Serde: https://github.com/serde-rs/json
2: Spring: 
https://www.baeldung.com/spring-security-method-security
May 11 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 May 2020 at 02:51:39 UTC, Doug wrote:
 So far I've only seen a way to get unknown UDAs from known 
 symbols but not how to get unknown symbols from UDAs. Is there 
 any documentation for how to get a list of symbols annotated 
 with a specific UDA?
see std.traits.getSymbolsByUDA http://dpldocs.info/experimental-docs/std.traits.getSymbolsByUDA.html there's some caveats, like it only searches one particular parent symbol for its children (that's because the way this works is you reflect through children checking each symbol child's uda list to see if it is present) but it basically works for many things at least contained per-module. you can pass each module you care about in though to generate a more full list
May 11 2020
parent reply Doug <overprose gmail.com> writes:
On Tuesday, 12 May 2020 at 02:53:53 UTC, Adam D. Ruppe wrote:
 see std.traits.getSymbolsByUDA
Thanks for the link. I did see that one. But that function searches within known symbols. My use case if for a library that's used outside of my application. In that case, I wouldn't know which symbol a library applies an annotation to. This is why I asked for how to get a list of unknown symbols from a known UDA. To use a REST frame work as an example, I would supply a GET annotation and a user would apply that annotation to a handler method. I wouldn't know the method or module in advanced so I wouldn't know which symbol to pass to "getSymbolsByUDA" of any of it's sibling functions. I'm curious to see what I'd be able to do if this is possible.
May 11 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/11/20 11:30 PM, Doug wrote:
 On Tuesday, 12 May 2020 at 02:53:53 UTC, Adam D. Ruppe wrote:
 see std.traits.getSymbolsByUDA
Thanks for the link. I did see that one. But that function searches within known symbols. My use case if for a library that's used outside of my application. In that case, I wouldn't know which symbol a library applies an annotation to. This is why I asked for how to get a list of unknown symbols from a known UDA. To use a REST frame work as an example, I would supply a GET annotation and a user would apply that annotation to a handler method. I wouldn't know the method or module in advanced so I wouldn't know which symbol to pass to "getSymbolsByUDA" of any of it's sibling functions. I'm curious to see what I'd be able to do if this is possible.
So the idea is that you know the parent symbol. In the case of serialization/deserialization, you give an instance of a type to serialize or deserialize. Then the library can search the symbols inside that type to see if any has the UDA you are looking for. In the Rust example, there is a line of code: let p: Person = serde_json::from_str(data)?; I'm assuming that this conversion is detected and figured out (i.e. this is how serde "finds" the type desired). For D, it would look something like: auto p = serde_json.from_str!Person(data); If you want a list of ALL symbols that have the UDA in the application, that would require some form of runtime reflection (like Java). D has very limited support for runtime reflection. In D, you would use some form of registration to tell the system about your symbols. -Steve
May 11 2020
next sibling parent Doug <overprose gmail.com> writes:
On Tuesday, 12 May 2020 at 04:02:18 UTC, Steven Schveighoffer 
wrote:

 In the case of serialization/deserialization, you give an 
 instance of a type to serialize or deserialize. Then the 
 library can search the symbols inside that type to see if any 
 has the UDA you are looking for.

 In the Rust example, there is a line of code:

 let p: Person = serde_json::from_str(data)?;

 I'm assuming that this conversion is detected and figured out 
 (i.e. this is how serde "finds" the type desired). For D, it 
 would look something like:

 auto p = serde_json.from_str!Person(data);

 If you want a list of ALL symbols that have the UDA in the 
 application, that would require some form of runtime reflection 
 (like Java). D has very limited support for runtime reflection. 
 In D, you would use some form of registration to tell the 
 system about your symbols.

 -Steve
Thanks for the feedback. I've got a better idea of what is and isn't possible now. I'll see about looking at one or two D JSON libraries to see how they approach things. It should help shed some more light on the subject.
May 12 2020
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2020-05-12 06:02, Steven Schveighoffer wrote:

 If you want a list of ALL symbols that have the UDA in the application, 
 that would require some form of runtime reflection (like Java). D has 
 very limited support for runtime reflection. In D, you would use some 
 form of registration to tell the system about your symbols.
I think it's possible to implement the `RTInfo` template in `object.d`. But that requires a custom druntime. `RTInfo` is a template that is instantiated once for each type in the program. -- /Jacob Carlborg
May 13 2020