How to check for class Attributes from Delphi

Issue #191 resolved
Jon-Lennart Aasenden created an issue

I am working on an IDE that uses DWScript and its JavaScript codegen as it’s core compiler.
One of the many challenges is that of packages, which I feel we solved quite elegantly using ordinary Zip-Files.

However, to avoid having a registration-file of sorts, which describe a visual component, it’s class, unit and so on – I suddenly remembered that DWScript supports class attributes (based on TCustomAttribute).

What is not so clear is how to extract or enumerate the attributes attached to a TClassSymbol. I have ofcourse tried to look at IDWSProgram.Attributes.GetAttributesFor() but with little luck.

From what I can see of the code (and I am of course open to being wrong) is that attributes is stored via RTTI (?). I also located the TdwsSymbolAttributes class, but there is practically zero documentation on this. RTTI would perhaps make sense since that is also the approach used by Delphi itself. However, RTTI within a DWScript that is not designed to execute - but be wholeheartedly converted to JS, is a bit tricky.

Could I trouble you for an example of how to fetch a list of assigned attributes to a TClassSymbol? Or perhaps more user-friendly, to expose a function like GetTypeAttributes() which simplify the process?

This is quite urgent for the QTX project since I really want to avoid registration files. With Attributes I can just generate a “uses file1, file2..” mini program, compile to get the AST, then traverse the TClassSymbols for each unit, check for my custom “[RegisterWidget]” attribute – and that would be enough to register the visual controls.

Hope you have time to show us how to get at the attributes, or implement a simple helper method 🙂

Thank you for you awesome work as always Eric!

/Jon

Comments (5)

  1. Jon-Lennart Aasenden reporter

    Took a bit of searching, but found an entry via:

    IDWSProgram.ProgramObject.Attributes.AttributesFor(ThisClass);
    

    This returns an array for the attributes a class has attached. I can then traverse to the attribute class via:

    lItems[x].AttributeConstructor.Typ.Name
    

    where lItems[] is the array returned by AttributesFor()

    Not the most intuitive place, but it works :)

  2. Eric Grange repo owner

    For the RTTI part, there is an exemple in the test case FunctionsRTTI \ class_attribs.pas, which should also work with the JS codegen.

    The support is rather low-level right now as you found out, it is just a big minimalist array with all the attributes for everything, and it could use some support functions and utilities. The idea was to get the big array compiled, but have all the RTTI support functions written script-side, so they could be used across target platforms, without imposing the penalty of a rich RTTI for projects that don’t need it, but can make do with basic stuff.

  3. Jon-Lennart Aasenden reporter

    Indeed, works well now. From the Delphi side of things it could perhaps be made a bit more intuitive, like exposing a ClassAttributes reference inside TClassSymbol – but once I found where you put them, it was smooth sailing.

    As always, thank you for your work, awesome stuff!

  4. Log in to comment