Believe it or not, the diagram below is a simplified version 😅. Here's the main idea: you give TypeQualifier some type syntax (no semantic information), and it resolves it to extended nominal types: nominal declarations and all their accessible extensions.
First, we convert the given type syntax to an array of references we can more easily look up; e.g., (Collection & MyProto).Element becomes Collection.Element and MyProto.Element. Then, we split each type reference up into the base type and its member type; in our example, the base is Collection with member type Element. Like all type syntax, Collection depends on its declaration context, so we perform unqualified type lookup to find the referenced type declaration. For now, let’s assume unqualified lookup returns a nominal declaration. If the declaration is nested within an extension, its qualified name depends on the extended type, so we have to recursively resolve that before continuing. For instance, if we don’t resolve the extended type `