@@ -144,7 +144,7 @@ import SwiftSyntax
144
144
145
145
/// Capture, parameter and body names introduced in this scope.
146
146
@_spi ( Experimental) public var defaultIntroducedNames : [ LookupName ] {
147
- captureNames + parameterNames + introducedNamesInBody
147
+ parameterNames + captureNames + introducedNamesInBody
148
148
}
149
149
150
150
@_spi ( Experimental) public var scopeDebugName : String {
@@ -202,7 +202,7 @@ import SwiftSyntax
202
202
} else {
203
203
signatureResults = LookupResult . getResultArray (
204
204
for: self ,
205
- withNames: ( captureNames + parameterNames ) . filter { name in
205
+ withNames: ( parameterNames + captureNames ) . filter { name in
206
206
checkIdentifier ( identifier, refersTo: name, at: lookUpPosition)
207
207
}
208
208
)
@@ -574,13 +574,40 @@ import SwiftSyntax
574
574
@_spi ( Experimental) extension SwitchCaseSyntax : SequentialScopeSyntax {
575
575
/// Names introduced within `case` items.
576
576
var namesFromLabel : [ LookupName ] {
577
- label. as ( SwitchCaseLabelSyntax . self) ? . caseItems. flatMap { child in
577
+ guard let switchCaseItemList = label. as ( SwitchCaseLabelSyntax . self) ? . caseItems else { return [ ] }
578
+
579
+ let extractedNames = switchCaseItemList. flatMap { child in
578
580
if let exprPattern = child. pattern. as ( ExpressionPatternSyntax . self) {
579
581
return LookupName . getNames ( from: exprPattern. expression)
580
582
} else {
581
583
return LookupName . getNames ( from: child. pattern)
582
584
}
583
- } ?? [ ]
585
+ }
586
+
587
+ if switchCaseItemList. count <= 1 {
588
+ return extractedNames
589
+ }
590
+
591
+ var orderedKeys : [ Identifier ] = [ ]
592
+ var partitioned : [ Identifier : [ LookupName ] ] = [ : ]
593
+
594
+ for extractedName in extractedNames {
595
+ guard let identifier = extractedName. identifier else { continue }
596
+
597
+ if !partitioned. keys. contains ( identifier) {
598
+ orderedKeys. append ( identifier)
599
+ }
600
+
601
+ partitioned [ identifier, default: [ ] ] . append ( extractedName)
602
+ }
603
+
604
+ return
605
+ orderedKeys
606
+ . compactMap { key in
607
+ guard let names = partitioned [ key] else { return nil }
608
+
609
+ return . equivalentNames( names)
610
+ }
584
611
}
585
612
586
613
/// Names introduced within `case` items
@@ -607,7 +634,7 @@ import SwiftSyntax
607
634
checkIdentifier ( identifier, refersTo: name, at: lookUpPosition)
608
635
}
609
636
610
- if label. range. contains ( lookUpPosition) {
637
+ if label. range. contains ( lookUpPosition) && !isInWhereClause ( lookUpPosition : lookUpPosition ) {
611
638
return config. finishInSequentialScope ? [ ] : lookupInParent ( identifier, at: lookUpPosition, with: config)
612
639
} else if config. finishInSequentialScope {
613
640
return sequentialLookup (
@@ -629,6 +656,20 @@ import SwiftSyntax
629
656
+ lookupInParent( identifier, at: lookUpPosition, with: config)
630
657
}
631
658
}
659
+
660
+ /// Returns `true` if `lookUpPosition` is inside a `where`
661
+ /// clause associated with one of the case items of this scope.
662
+ private func isInWhereClause( lookUpPosition: AbsolutePosition ) -> Bool {
663
+ guard let switchCaseItemList = label. as ( SwitchCaseLabelSyntax . self) ? . caseItems else { return false }
664
+
665
+ for item in switchCaseItemList {
666
+ if item. whereClause? . range. contains ( lookUpPosition) ?? false {
667
+ return true
668
+ }
669
+ }
670
+
671
+ return false
672
+ }
632
673
}
633
674
634
675
@_spi ( Experimental) extension ProtocolDeclSyntax : ScopeSyntax , LookInMembersScopeSyntax {
@@ -903,7 +944,9 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
903
944
at lookUpPosition: AbsolutePosition ,
904
945
with config: LookupConfig
905
946
) -> [ LookupResult ] {
906
- if bindings. first? . accessorBlock? . range. contains ( lookUpPosition) ?? false {
947
+ if ( bindings. first? . accessorBlock? . range. contains ( lookUpPosition) ?? false )
948
+ || shouldIntroduceSelfIfLazy ( lookUpPosition: lookUpPosition)
949
+ {
907
950
return defaultLookupImplementation (
908
951
in: ( isMember ? [ . implicit( . self ( self ) ) ] : LookupName . getNames ( from: self ) ) ,
909
952
identifier,
@@ -929,6 +972,16 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
929
972
930
973
return resultsToInterleave + lookupInParent( identifier, at: lookUpPosition, with: config)
931
974
}
975
+
976
+ /// Returns `true`, if `lookUpPosition` is in initializer of
977
+ /// this variable declaration and the declaration is lazy.
978
+ private func shouldIntroduceSelfIfLazy( lookUpPosition: AbsolutePosition ) -> Bool {
979
+ guard bindings. first? . initializer? . range. contains ( lookUpPosition) ?? false else { return false }
980
+
981
+ return modifiers. contains {
982
+ $0. name. tokenKind == . keyword( . lazy)
983
+ }
984
+ }
932
985
}
933
986
934
987
@_spi ( Experimental) extension DeinitializerDeclSyntax : ScopeSyntax {
0 commit comments