Skip to content

[SwiftLexicalLookup] Preliminary Qualified-Lookup API#3346

Open
filip-sakel wants to merge 11 commits into
swiftlang:mainfrom
filip-sakel:qualified-lookup
Open

[SwiftLexicalLookup] Preliminary Qualified-Lookup API#3346
filip-sakel wants to merge 11 commits into
swiftlang:mainfrom
filip-sakel:qualified-lookup

Conversation

@filip-sakel

@filip-sakel filip-sakel commented May 28, 2026

Copy link
Copy Markdown

The initial code following this discussion to implement qualified name lookup for GSoC 2026.


This PR adds support for looking up the members of a group declaration —nominal type, protocol, or extension— through the DeclGroupSyntax.findDirectMembers method. It can optionally filter by a DeclNameRef name or MemberKind kind. Further, providing a ConfiguredRegions instance, resolves #if declarations. The method returns an array of ValueDeclSyntax, a new currency type.

Value declarations are analogous to the compiler’s ValueDecl: they are syntax nodes with a name that can evaluate to a value. They provide useful properties, such as declName: DeclName which we try to match our DeclNameRef against, along with isStatic and isTypeDecl which help filter for MemberKind. You’ll note that not all value declarations are actual declarations. The two exceptions are identifier patterns (expected to appear in a variable declaration) and enum elements (inside enum case declarations). Regardless, we assume nothing about the syntax tree. We provide detailed enough errors for users to understand the causes for failure and potentially diagnose user errors in the syntax tree.

Design Rationale

You’ll notice that DeclName and DeclNameRef are more explicit than their compiler equivalents. As I explained in my last forum post, my rationale was that being forced to consider all cases ultimately reduces logic bugs. Of course, I’m open to revising this API.

MemberKind is implemented in terms of mutually exclusive flags. For instance, there’s no built-in includeStatic flag. It is instead a composition of includeNonTypeStatic and includeTypes. This design streamlines filtering and modifying member kind. (For instance, when performing lookup on a metatype, we can easily and correctly restrict the member kind to look at only static declarations through the .onlyStatic method)

As for testing, I added extensive tests for value declarations since they form the backbone of result filtering. Also, I added an assertion API that helps us test findDirectMembes results more concisely and intuitively.

Open Questions / Future Work

  1. I haven’t yet found a nice way to represent variadic parameters / parameter packs; I’m not sure if trailing closures will give us any trouble either.
  2. It’s unclear to me how we should handle property wrappers since they’re still not formal macros.
  3. We need to surface the dynamic member/callable results. The same way callAsFunction gets a special declaration name, perhaps we could do the same for: dynamicallyCall(withArguments:), dynamicallyCall(withKeywordArguments:), and subscript(dynamicMember:).
  4. We need to handle @abi and @_implements

@filip-sakel filip-sakel marked this pull request as ready for review June 8, 2026 00:36
Comment thread Sources/SwiftLexicalLookup/QualifiedLookup/DeclName.swift Outdated
Comment thread Sources/SwiftLexicalLookup/QualifiedLookup/DeclName.swift Outdated
///
/// We use ``DeclName`` because it strips away low-level information, such as a
/// node's trivia, leaving us with a `Hashable` name that we can use in lookup.
@_spi(_QualifiedLookup) public indirect enum DeclName: Hashable, CustomDebugStringConvertible {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here probably, this is more of a compiler naming, we should consider DeclarationName.

@xedin xedin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM! I think some of the naming choices should be made more swift-syntax canonical instead of trying to match what the compiler is doing.

@filip-sakel

Copy link
Copy Markdown
Author

I noticed swift-syntax itself is slightly inconsistent with Decl vs Declaration. Namely, we have all the [...]DeclSyntax types and the DeclGroupSyntax protocol, but we also have DeclarationMacro. I think either one works.

So, IIUC, we want to change:

  1. DeclName -> Decl[aration]Name
  2. DeclNameRef -> Decl[aration]NameReference
  3. DeclNameArgs -> Decl[aration]NameArguments

Also, are there any special considerations for the breaking change in the unqualified API from lookForMembers(in: Syntax) -> lookForMembers(in: any DeclGroupSyntax)?

Comment thread Sources/SwiftLexicalLookup/QualifiedLookup/DeclGroupLookup.swift Outdated
@xedin

xedin commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Maybe we make Arguments an inner type of DeclarationNameReference?

@filip-sakel

Copy link
Copy Markdown
Author

Maybe we make Arguments an inner type of DeclarationNameReference?

The problem is that both DeclarationName and DeclarationNameReference use the Arguments type, so it might be confusing to nest it under DeclarationNameReference. We could also just have type aliases for both, but DeclarationNameArguments might evolve into an actual struct for better debug descriptions and to make the API more extensible.

For now, I think any of these options works; let me know what you prefer.

@filip-sakel

Copy link
Copy Markdown
Author

@swift-ci please test

2 similar comments
@filip-sakel

Copy link
Copy Markdown
Author

@swift-ci please test

@xedin

xedin commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@swift-ci please test

@filip-sakel

Copy link
Copy Markdown
Author

@swift-ci please test

@xedin

xedin commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@swift-ci please test

@xedin

xedin commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@swift-ci please test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants