1010//
1111//===----------------------------------------------------------------------===//
1212
13+ import SwiftIfConfig
1314import SwiftSyntax
1415
1516@_spi ( Experimental) extension SyntaxProtocol {
@@ -391,7 +392,11 @@ import SwiftSyntax
391392}
392393@_spi ( Experimental) extension ExtensionDeclSyntax : LookInMembersScopeSyntax {
393394 @_spi ( Experimental) public var lookupMembersPosition : AbsolutePosition {
394- extendedType. position
395+ if let memberType = extendedType. as ( MemberTypeSyntax . self) {
396+ return memberType. name. positionAfterSkippingLeadingTrivia
397+ }
398+
399+ return extendedType. positionAfterSkippingLeadingTrivia
395400 }
396401
397402 @_spi ( Experimental) public var defaultIntroducedNames : [ LookupName ] {
@@ -420,8 +425,8 @@ import SwiftSyntax
420425 + defaultLookupImplementation( identifier, at: lookUpPosition, with: config, propagateToParent: false )
421426 + [ . lookInMembers( self ) ]
422427 + lookupInParent( identifier, at: lookUpPosition, with: config)
423- } else if !extendedType. range. contains ( lookUpPosition) && genericWhereClause != nil {
424- if inRightTypeOrSameTypeRequirement ( lookUpPosition) {
428+ } else if !extendedType. range. contains ( lookUpPosition) , let genericWhereClause {
429+ if genericWhereClause . range . contains ( lookUpPosition) {
425430 return [ . lookInGenericParametersOfExtendedType( self ) ] + [ . lookInMembers( self ) ]
426431 + defaultLookupImplementation( identifier, at: lookUpPosition, with: config)
427432 }
@@ -433,23 +438,6 @@ import SwiftSyntax
433438 return [ . lookInGenericParametersOfExtendedType( self ) ]
434439 + lookupInParent( identifier, at: lookUpPosition, with: config)
435440 }
436-
437- /// Returns `true` if `checkedPosition` is a right type of a
438- /// conformance requirement or inside a same type requirement.
439- private func inRightTypeOrSameTypeRequirement(
440- _ checkedPosition: AbsolutePosition
441- ) -> Bool {
442- genericWhereClause? . requirements. contains { elem in
443- switch Syntax ( elem. requirement) . as ( SyntaxEnum . self) {
444- case . conformanceRequirement( let conformanceRequirement) :
445- return conformanceRequirement. rightType. range. contains ( checkedPosition)
446- case . sameTypeRequirement( let sameTypeRequirement) :
447- return sameTypeRequirement. range. contains ( checkedPosition)
448- default :
449- return false
450- }
451- } ?? false
452- }
453441}
454442
455443@_spi ( Experimental) extension AccessorDeclSyntax : ScopeSyntax {
@@ -491,7 +479,7 @@ import SwiftSyntax
491479
492480 let implicitSelf : [ LookupName ] = [ . implicit( . self ( self ) ) ]
493481 . filter { name in
494- checkIdentifier ( identifier, refersTo: name, at: lookUpPosition)
482+ checkIdentifier ( identifier, refersTo: name, at: lookUpPosition) && !attributes . range . contains ( lookUpPosition )
495483 }
496484
497485 return defaultLookupImplementation (
@@ -512,13 +500,19 @@ import SwiftSyntax
512500@_spi ( Experimental) extension CatchClauseSyntax : ScopeSyntax {
513501 /// Implicit `error` when there are no catch items.
514502 @_spi ( Experimental) public var defaultIntroducedNames : [ LookupName ] {
503+ var containsExpressionSyntax = false
504+
515505 let extractedNames = catchItems. flatMap { item in
516506 guard let pattern = item. pattern else { return [ LookupName] ( ) }
517507
508+ if !containsExpressionSyntax && pattern. is ( ExpressionPatternSyntax . self) {
509+ containsExpressionSyntax = true
510+ }
511+
518512 return LookupName . getNames ( from: pattern)
519513 }
520514
521- return extractedNames. isEmpty ? [ . implicit( . error( self ) ) ] : extractedNames
515+ return extractedNames. isEmpty && !containsExpressionSyntax ? [ . implicit( . error( self ) ) ] : extractedNames
522516 }
523517
524518 @_spi ( Experimental) public var scopeDebugName : String {
@@ -594,14 +588,27 @@ import SwiftSyntax
594588 checkIdentifier ( identifier, refersTo: name, at: lookUpPosition)
595589 }
596590
597- return sequentialLookup (
598- in: statements,
599- identifier,
600- at: lookUpPosition,
601- with: config,
602- propagateToParent: false
603- ) + LookupResult. getResultArray ( for: self , withNames: filteredNamesFromLabel)
604- + ( config. finishInSequentialScope ? [ ] : lookupInParent ( identifier, at: lookUpPosition, with: config) )
591+ if label. range. contains ( lookUpPosition) {
592+ return config. finishInSequentialScope ? [ ] : lookupInParent ( identifier, at: lookUpPosition, with: config)
593+ } else if config. finishInSequentialScope {
594+ return sequentialLookup (
595+ in: statements,
596+ identifier,
597+ at: lookUpPosition,
598+ with: config,
599+ propagateToParent: false
600+ )
601+ } else {
602+ return sequentialLookup (
603+ in: statements,
604+ identifier,
605+ at: lookUpPosition,
606+ with: config,
607+ propagateToParent: false
608+ )
609+ + LookupResult. getResultArray ( for: self , withNames: filteredNamesFromLabel)
610+ + lookupInParent( identifier, at: lookUpPosition, with: config)
611+ }
605612 }
606613}
607614
@@ -697,6 +704,18 @@ import SwiftSyntax
697704 }
698705}
699706
707+ @_spi ( Experimental) extension MacroDeclSyntax : WithGenericParametersScopeSyntax {
708+ public var defaultIntroducedNames : [ LookupName ] {
709+ signature. parameterClause. parameters. flatMap { parameter in
710+ LookupName . getNames ( from: parameter)
711+ }
712+ }
713+
714+ @_spi ( Experimental) public var scopeDebugName : String {
715+ " MacroDeclScope "
716+ }
717+ }
718+
700719@_spi ( Experimental)
701720extension SubscriptDeclSyntax : WithGenericParametersScopeSyntax , CanInterleaveResultsLaterScopeSyntax {
702721 /// Parameters introduced by this subscript and possibly `self` keyword.
@@ -758,7 +777,7 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
758777 ) -> [ LookupResult ] {
759778 var thisScopeResults : [ LookupResult ] = [ ]
760779
761- if !parameterClause . range. contains ( lookUpPosition) && !returnClause . range . contains ( lookUpPosition ) {
780+ if accessorBlock ? . range. contains ( lookUpPosition) ?? false {
762781 thisScopeResults = defaultLookupImplementation (
763782 identifier,
764783 at: position,
@@ -866,8 +885,6 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
866885 with config: LookupConfig
867886 ) -> [ LookupResult ] {
868887 if bindings. first? . accessorBlock? . range. contains ( lookUpPosition) ?? false {
869- let isMember = parentScope? . is ( MemberBlockSyntax . self) ?? false
870-
871888 return defaultLookupImplementation (
872889 in: ( isMember ? [ . implicit( . self ( self ) ) ] : LookupName . getNames ( from: self ) ) ,
873890 identifier,
@@ -887,10 +904,99 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
887904 with config: LookupConfig ,
888905 resultsToInterleave: [ LookupResult ]
889906 ) -> [ LookupResult ] {
890- guard parentScope ? . is ( MemberBlockSyntax . self ) ?? false else {
907+ guard isMember else {
891908 return lookup ( identifier, at: lookUpPosition, with: config)
892909 }
893910
894911 return resultsToInterleave + lookupInParent( identifier, at: lookUpPosition, with: config)
895912 }
896913}
914+
915+ @_spi ( Experimental) extension DeinitializerDeclSyntax : ScopeSyntax {
916+ @_spi ( Experimental) public var defaultIntroducedNames : [ LookupName ] {
917+ [ . implicit( . self ( self ) ) ]
918+ }
919+
920+ @_spi ( Experimental) public var scopeDebugName : String {
921+ " DeinitializerScope "
922+ }
923+ }
924+
925+ @_spi ( Experimental) extension IfConfigDeclSyntax : IntroducingToSequentialParentScopeSyntax , SequentialScopeSyntax {
926+ /// Names from all clauses.
927+ var namesIntroducedToSequentialParent : [ LookupName ] {
928+ clauses. flatMap { clause in
929+ clause. elements. flatMap { element in
930+ LookupName . getNames ( from: element, accessibleAfter: element. endPosition)
931+ } ?? [ ]
932+ }
933+ }
934+
935+ /// Performs sequential lookup in the active clause.
936+ /// Active clause is determined by the `BuildConfiguration`
937+ /// inside `config`. If not specified, defaults to the `#else` clause.
938+ func lookupFromSequentialParent(
939+ _ identifier: Identifier ? ,
940+ at lookUpPosition: AbsolutePosition ,
941+ with config: LookupConfig
942+ ) -> [ LookupResult ] {
943+ let clause : IfConfigClauseSyntax ?
944+
945+ if let buildConfiguration = config. buildConfiguration {
946+ ( clause, _) = activeClause ( in: buildConfiguration)
947+ } else {
948+ clause =
949+ clauses
950+ . first { clause in
951+ clause. poundKeyword. tokenKind == . poundElse
952+ }
953+ }
954+
955+ return sequentialLookup (
956+ in: clause? . elements? . as ( CodeBlockItemListSyntax . self) ?? [ ] ,
957+ identifier,
958+ at: lookUpPosition,
959+ with: config,
960+ ignoreNamedDecl: true ,
961+ propagateToParent: false
962+ )
963+ }
964+
965+ /// Returns all `NamedDeclSyntax` nodes in the active clause specified
966+ /// by `BuildConfiguration` in `config` from bottom-most to top-most.
967+ func getNamedDecls( for config: LookupConfig ) -> [ NamedDeclSyntax ] {
968+ let clause : IfConfigClauseSyntax ?
969+
970+ if let buildConfiguration = config. buildConfiguration {
971+ ( clause, _) = activeClause ( in: buildConfiguration)
972+ } else {
973+ clause =
974+ clauses
975+ . first { clause in
976+ clause. poundKeyword. tokenKind == . poundElse
977+ }
978+ }
979+
980+ guard let clauseElements = clause? . elements? . as ( CodeBlockItemListSyntax . self) else { return [ ] }
981+
982+ var result : [ NamedDeclSyntax ] = [ ]
983+
984+ for elem in clauseElements. reversed ( ) {
985+ if let namedDecl = elem. item. asProtocol ( NamedDeclSyntax . self) {
986+ result. append ( namedDecl)
987+ } else if let ifConfigDecl = elem. item. as ( IfConfigDeclSyntax . self) {
988+ result += ifConfigDecl. getNamedDecls ( for: config)
989+ }
990+ }
991+
992+ return result
993+ }
994+
995+ @_spi ( Experimental) public var defaultIntroducedNames : [ LookupName ] {
996+ [ ]
997+ }
998+
999+ @_spi ( Experimental) public var scopeDebugName : String {
1000+ " IfConfigScope "
1001+ }
1002+ }
0 commit comments