Access resolved type information

Hello,

I am trying to do some static analysis on my code and I am looking for a way to find the inferred type.

For example if you have a SwiftUI View (but I plan to apply it to other library)

struct MyView: View {
     var body: some View {
         Text("test")
     }
}

I would like to be able to request the information "what is the associatedtype Body of MyView ?"

I have look at swift-symbolgraph-extract but the information doesn't seem to be present.

Is it available somewhere ? Can you give me some pointers ?

Thanks

This is a complicated question. Ultimately in the C++ AST, a normal conformance is created to describe the conformance of MyView to View. There is also an associated type declaration for the Body associated type of View. A normal conformance stores a type for each of the protocol's associated type declarations. In this case, the type is a typealias named Body declared in MyView, but this typealias is synthesized. It's underlying type is the opaque return type of 'var body'. An opaque return type just describes its requirements (some View). It also has an underlying type, which is Text. Text is a non-generic nominal type so it just points to its struct declaration in the SwiftUI module.

I don't think there's any ready-made tool outside of the frontend itself, that can abstractly express the above at the level of detail I described it, but various "projections" that describe a subset of this information can be devised. My description is itself an oversimplification (a type witness in a conformance might be some structural type like a function type or tuple, in reality opaque archetypes have a more complex representation that also stores a substitution map, etc.)

You can take a look at lib/ConstExtract/ConstExtract.cpp for an example of a tool that dumps conformance information from the C++ AST in a JSON format.

2 Likes

Hello Slava,

Thanks a lot for this detailed answer.

Indeed what I am looking for is the underlying type. Note that I am not really looking for opaque type but all inferred type (ie which doesn't appear in the source code).

I have had a look at the output of the swiftc -debug-constraints command and it seems (but maybe it's due to the fact that my test code is too simple) that the compiler has the info at some point which make sense as it has to check the conformance of the type for typechecking the whole code.

So my understanding reading your answer is that this information is not surfaced anywhere outside of the compiler.

I was surprised that this info doesn't seem available to the LSP server to provide code completion and information. Or I just didn't find it when I looked at the data provided by SourceKit.

In what form do you expect this type? A structural representation? A mangled name? A human-readable description? Types are tree structures in Swift, so for example Text is the simplest case but they can have arbitrarily-complex structure, like Array<(Int, Optional<Int.Type>) -> ()>, etc.

The SourceKit server is implemented on top of the frontend internally, but it doesn't expose the information you're looking for.

The real solution to all these problems is to one day re-implement the compiler in Swift, and have a nice, clean standalone "SwiftTypeSystem" library fall out from this, that models the entire type systems and generics in a reasonable and correct manner. But that doesn't exist right now.

Yeah I do expect very complex types.
For my current use case both mangled name or human-readable description are good to go.
AFAIK mangled name can be demangled if necessary. And I suppose I could parse Array<(Int, Optional<Int.Type>) -> ()> to have a more structured necessary representation if necessary.

OK so I didn't missed it.

I will try to find another way then :slight_smile:

Thank you again for taking the time to answer my questions.