Is it safe to inject custom symbols into a SymbolGraph and then pass it to DocC?

I am trying to shift an existing documentation tool to work atop DocC to at first delegate as much as possible to DocC, and then (if they are welcome) sink any remaining features into DocC itself, so my own tool can evaporate.

The first difference I encountered is that the generated symbol graphs do not contain operators or precedence groups. SymbolGraph.Symbol.Kind, and similar types appear on the surface to be initializable with arbitrary custom or unknown values. Can I use those to insert descriptions of operators and precedence groups? Is the rest of DocC designed to handle such things gracefully, or do errors or crashes await me if DocC expects all input to come verbatim from the compiler?

Hi Jeremy, the symbol graphs not including operators would definitely be a bug. I don't seem to be able to reproduce this, but if you could file a bug with a code example and the resulting symbol graph, that would be super helpful: Sign in to GitHub · GitHub

Right now, if the symbol graph contains symbol kinds that DocC doesn't recognise, these symbols will be dropped IIRC. However SymbolKit does recognise operators already: swift-docc-symbolkit/KindIdentifier.swift at 076d5ca9b1501a260d2330504939e5fce49f2c25 · apple/swift-docc-symbolkit · GitHub.

Separate to this, @theMomax has been working on making the tooling integration more flexible: https://github.com/apple/swift-docc-symbolkit/pull/39

1 Like

i think Jeremy is talking about operator lexemes…? the docs for godot-swift have an example of one of them here: https://kelvin13.github.io/godot-swift/infix%20operator%20>|</

they are distinct from the functions that use the lexemes as function names (example: https://kelvin13.github.io/godot-swift/1->|<(lhs:rhs:)/)

swift-biome used to support this use-case, which is why the godot-swift docs have lexeme pages. but it was dropped from the 0.2.0 rewrite because i didn’t think anyone wanted to write documentation for the lexemes themselves. after reading this thread, i was clearly mistaken :)

Yeah, the things declared in source with operator are missing; func declarations are not dropped.

More important than any written documentation is the ability to look up precedence and associativity (by way of tracing the relationship through to a precedence group).

that’s a good point.

swift-biome 0.1 used to scan source code (instead of relying on SymbolGraphGen), so it was able to vacuum up the precedence and associativity declarations. however i’m not aware of any SymbolGraphGen capability that can do this.

i wonder it we could workaround this by using documentation extensions. maybe:

// times-operator.md 

@lexeme(infix operator >< : MultiplicationPrecedence)

`><` represents a outer- or matrix-product operation. 

we could parse the block directive argument using swift-syntax, which is already part of both the Biome and DocC stacks.

That's an interesting idea. I think ideally though the compiler would emit these into the symbol graph, and also permit attached in-source doc comments. If necessary perhaps higher level tools like DocC/Biome could handle them specially, e.g. if they have no attached doc comment or extension file, omit them completely.

2 Likes

that might be tricky since the lexemes themselves don’t have access control modifiers, their visibility depends on whether any public API uses the lexemes.

i don’t know enough about SymbolGraphGen to know if that’s a blocker though

Their visibility is implicitly and invariably public. A client can declare its own operators in an imported precedence group, and can declare its own functions for an imported operator.

That's correct.

Right now, without changes to DocC, the best thing you can do, @SDGGiesbrecht, is to just mark your custom symbols as a symbol kind that DocC knows and understands, and which is semantically close to what you need. In your case, that would probably be operator.

It is, however, not difficult to introduce a new symbol kind to DocC. If you look at the change set on this PR and search for ".extendedModule", you'll see the few places where you'd need to add your new symbol kind (except for the files in Sources/SwiftDocC/Infrastructure/Symbol Graph/, those are irrelevant in your case). In fact, I think it wouldn't be too difficult to enable loading custom symbol kinds from a configuration file once apple/swift-docc-symbolkit#39 is merged (if we want to do that).

1 Like

Long term I think this sort of flexibility would be awesome. We'll always have a need to add custom support for symbols and languages to really make them shine, but it would be amazing if—without changes to DocC itself—a bit of configuration could enable basic support for a new symbol type or even an entirely new programming language (assuming you've somehow generated a symbol graph for it).

2 Likes

Do you have a recommendation on whether to start at the compiler and work upward toward the renderer, or to start at the renderer and work downward toward the compiler? (When it comes to something like precedence groups which are more a matter of being missing than being custom.)

I can definitely take a look at this once I'm done with my current DocC project.

I started form the compiler, continued with SymbolKit, and then adapted DocC. This approach worked quite well for me. Also, if you do it this way round, I might already be done with some of the extensibility part when you start working on the higher levels, which might help you there.

1 Like