@@ -176,7 +176,7 @@ import SwiftSyntax
176176 /// All names introduced by the closure signature.
177177 /// Could be closure captures or (shorthand) parameters.
178178 ///
179- /// Example:
179+ /// ### Example
180180 /// ```swift
181181 /// let x = { [weak self, a] b, _ in
182182 /// // <--
@@ -222,7 +222,7 @@ import SwiftSyntax
222222
223223 /// Finds parent scope, omitting ancestor `if` statements if part of their `else if` clause.
224224 ///
225- /// Example:
225+ /// ### Example
226226 /// ```swift
227227 /// func foo() {
228228 /// if let a = x {
@@ -262,7 +262,7 @@ import SwiftSyntax
262262 /// Lookup triggered from inside of `else`
263263 /// clause is immediately forwarded to parent scope.
264264 ///
265- /// Example:
265+ /// ### Example
266266 /// ```swift
267267 /// if let a = x {
268268 /// // <-- a is visible here
@@ -290,6 +290,24 @@ import SwiftSyntax
290290 LookupName . getNames ( from: member. decl)
291291 }
292292 }
293+
294+ /// Creates a result from associated type declarations
295+ /// made by it's members.
296+ func lookupAssociatedTypeDeclarations(
297+ _ identifier: Identifier ? ,
298+ at lookUpPosition: AbsolutePosition ,
299+ with config: LookupConfig
300+ ) -> [ LookupResult ] {
301+ let filteredNames = members. flatMap { member in
302+ guard member. decl. kind == . associatedTypeDecl else { return [ LookupName] ( ) }
303+
304+ return LookupName . getNames ( from: member. decl)
305+ } . filter { name in
306+ checkIdentifier ( identifier, refersTo: name, at: lookUpPosition)
307+ }
308+
309+ return filteredNames. isEmpty ? [ ] : [ . fromScope( self , withNames: filteredNames) ]
310+ }
293311}
294312
295313@_spi ( Experimental) extension GuardStmtSyntax : IntroducingToSequentialParentScopeSyntax {
@@ -308,7 +326,7 @@ import SwiftSyntax
308326 /// Lookup triggered from within of the `else` body
309327 /// returns no names.
310328 ///
311- /// Example:
329+ /// ### Example
312330 /// ```swift
313331 /// guard let a = x else {
314332 /// return // a is not visible here
@@ -330,10 +348,10 @@ import SwiftSyntax
330348 }
331349}
332350
333- @_spi ( Experimental) extension ActorDeclSyntax : TypeScopeSyntax { }
334- @_spi ( Experimental) extension ClassDeclSyntax : TypeScopeSyntax { }
335- @_spi ( Experimental) extension StructDeclSyntax : TypeScopeSyntax { }
336- @_spi ( Experimental) extension EnumDeclSyntax : TypeScopeSyntax { }
351+ @_spi ( Experimental) extension ActorDeclSyntax : TypeScopeSyntax , WithGenericParametersScopeSyntax { }
352+ @_spi ( Experimental) extension ClassDeclSyntax : TypeScopeSyntax , WithGenericParametersScopeSyntax { }
353+ @_spi ( Experimental) extension StructDeclSyntax : TypeScopeSyntax , WithGenericParametersScopeSyntax { }
354+ @_spi ( Experimental) extension EnumDeclSyntax : TypeScopeSyntax , WithGenericParametersScopeSyntax { }
337355@_spi ( Experimental) extension ExtensionDeclSyntax : TypeScopeSyntax { }
338356
339357@_spi ( Experimental) extension AccessorDeclSyntax : ScopeSyntax {
@@ -356,7 +374,95 @@ import SwiftSyntax
356374
357375@_spi ( Experimental) extension CatchClauseSyntax : ScopeSyntax {
358376 /// Implicit `error` when there are no catch items.
359- public var introducedNames : [ LookupName ] {
377+ @ _spi ( Experimental ) public var introducedNames : [ LookupName ] {
360378 return catchItems. isEmpty ? [ . implicit( . error( self ) ) ] : [ ]
361379 }
362380}
381+
382+ @_spi ( Experimental) extension SwitchCaseSyntax : ScopeSyntax {
383+ /// Names introduced within `case` items.
384+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
385+ label. as ( SwitchCaseLabelSyntax . self) ? . caseItems. flatMap { child in
386+ LookupName . getNames ( from: child. pattern)
387+ } ?? [ ]
388+ }
389+ }
390+
391+ @_spi ( Experimental) extension ProtocolDeclSyntax : ScopeSyntax {
392+ /// Protocol declarations don't introduce names by themselves.
393+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
394+ [ ]
395+ }
396+
397+ /// For the lookup initiated from inside primary
398+ /// associated type clause, this function also finds
399+ /// all associated type declarations made inside the
400+ /// protocol member block.
401+ ///
402+ /// ### Example
403+ /// ```swift
404+ /// class A {}
405+ ///
406+ /// protocol Foo<A/*<-- lookup here>*/> {
407+ /// associatedtype A
408+ /// class A {}
409+ /// }
410+ /// ```
411+ /// For the lookup started at the primary associated type `A`,
412+ /// the function returns exactly two results. First associated with the member
413+ /// block that consists of the `associatedtype A` declaration and
414+ /// the latter one from the file scope and `class A` exactly in this order.
415+ public func lookup(
416+ _ identifier: Identifier ? ,
417+ at lookUpPosition: AbsolutePosition ,
418+ with config: LookupConfig
419+ ) -> [ LookupResult ] {
420+ var results : [ LookupResult ] = [ ]
421+
422+ if let primaryAssociatedTypeClause,
423+ primaryAssociatedTypeClause. range. contains ( lookUpPosition)
424+ {
425+ results = memberBlock. lookupAssociatedTypeDeclarations (
426+ identifier,
427+ at: lookUpPosition,
428+ with: config
429+ )
430+ }
431+
432+ return results + defaultLookupImplementation( identifier, at: lookUpPosition, with: config)
433+ }
434+ }
435+
436+ @_spi ( Experimental) extension GenericParameterClauseSyntax : GenericParameterScopeSyntax {
437+ /// Generic parameter names introduced by this clause.
438+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
439+ parameters. children ( viewMode: . fixedUp) . flatMap { child in
440+ LookupName . getNames ( from: child, accessibleAfter: child. endPosition)
441+ }
442+ }
443+ }
444+
445+ @_spi ( Experimental) extension FunctionDeclSyntax : WithGenericParametersScopeSyntax {
446+ /// Function parameters introduced by this function's signature.
447+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
448+ signature. parameterClause. parameters. flatMap { parameter in
449+ LookupName . getNames ( from: parameter)
450+ }
451+ }
452+ }
453+
454+ @_spi ( Experimental) extension SubscriptDeclSyntax : WithGenericParametersScopeSyntax {
455+ /// Parameters introduced by this subscript.
456+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
457+ parameterClause. parameters. flatMap { parameter in
458+ LookupName . getNames ( from: parameter)
459+ }
460+ }
461+ }
462+
463+ @_spi ( Experimental) extension TypeAliasDeclSyntax : WithGenericParametersScopeSyntax {
464+ /// Type alias doesn't introduce any names to it's children.
465+ @_spi ( Experimental) public var introducedNames : [ LookupName ] {
466+ [ ]
467+ }
468+ }
0 commit comments