Global actors support in DocC

I am currently developing a closed-source SDK as part of a team, and we are using DocC.
However, I have noticed that DocC is not picking up when something is marked with @MainActor.
This leads to very confusing situations, e.g. the consumer adopts a protocol marked with @MainActor, and the whole class implicitly becomes one.
I did some investigation, and it looks like it is not being emmited into Symbol Graph files. Same thing applies to any custom global actors. Am I correct in my understanding that this issue can't be fixed on DocC side, since this is a limitation of the compiler?
Looks like the compiler picks up other attributes listed here (I did not check the whole list :))
Thanks.

Right, this is something that would need to be resolved in the Swift compiler. I'm wondering if this is somehow related to [SR-15407] DocC (wrongly) renders actors as classes · Issue #212 · apple/swift-docc · GitHub. Maybe @QuietMisdreavus has ideas?

Global actors are represented as "custom attributes" in the Swift AST, attached to any declaration that is on a global actor. See the CustomAttr class, which is also used for other custom attributes like property wrappers.

Doug

3 Likes

It does look related to that issue, though not directly. That issue is more about making sure that actors show up with the actor keyword in their declarations, instead of the class they currently render.

This is excellent information, thanks! It looks like the symbol graph currently discard these custom attributes, so to render @MainActor we'd need to allow them in.

2 Likes

This will be a separate issue. The Swift AST represents actors as classes ClassDecl, and one separate checks whether it's an actor via isActor().

Doug

1 Like

thanks for your reply. would you say this is an improvement required on the compiler side? to emit the custom attributes into the symbol graph. or is this a bug?

I don't know enough about the symbol graph to tell you, sorry.

Doug

This does require a change to the compiler-side implementation of the symbol graph; currently it discards custom attributes, including the way @MainActor appears internally. It will need to be updated to save them and properly emit @MainActor (and possibly other property wrappers) on those declarations.

2 Likes

Thanks! Would you say this is an improvement and I should create a ticket here? Can this be considered a StarterBug? I'd really like to contribute with this one.

Yes! Feel free to file an issue under the "Swift-DocC" component, even though this is more in the "SymbolGraphGen" area of the compiler. (The symbol graph is primarily consumed by Swift-DocC, and the end effect will be seen there.)

I'm not 100% sure on the best way to implement it, but the place to start is the declaration fragment printer options. Removing the DAK_Custom attribute from the ExcludeAttrs listing will cause custom attributes to start appearing in declarations. However, this won't just get @MainActor; this also includes property wrappers, as Doug mentioned. I'm not sure how attributes get rendered in the declaration fragments AST printer, but tracing through that (i like to bounce between DeclarationFragmentsPrinter.cpp and the superclass in lib/AST/ASTPrinter.cpp to figure things out) should get you most of the way there.

I'm honestly not sure about whether we want to emit every custom attribute - that creates more of a design discussion than i'm willing to comment on by myself. That's why i'm suggesting walking through the printer and seeing if it's possible to filter out custom attributes other than @MainActor.

I hope this helps!

1 Like

Big thanks for your response and explanation! I have created a ticket for this, I'll try to set up the toolchain on my laptop this weekend to do some digging.

1 Like