@@ -45,6 +45,107 @@ extension Parser {
4545 }
4646}
4747
48+ extension TokenConsumer {
49+ /// Do the subsequent tokens have the form of a module selector? Encompasses some invalid syntax which nonetheless
50+ /// can be handled by `consumeModuleSelectorTokensIfPresent()`.
51+ ///
52+ /// - Postcondition: If `true`, either the current token or the next token is `.colonColon`.
53+ mutating func isAtModuleSelector( ) -> Bool {
54+ // If this is a module selector, the next token should be `::`.
55+ guard self . peek ( isAt: . colonColon) else {
56+ // ...however, we will also allow the *current* token to be `::`. `consumeModuleSelectorTokensIfPresent()` will
57+ // create a missing identifier.
58+ return self . at ( . colonColon)
59+ }
60+
61+ // Technically the current token *should* be an identifier, but we also want to diagnose other tokens that might be
62+ // used by accident or given special meanings later ('_', certain keywords).
63+ return self . at ( . identifier, . wildcard, . keyword( . Any) )
64+ || self . at ( . keyword( . self ) , . keyword( . Self) , . keyword( . super) )
65+ }
66+
67+ mutating func unlessPeekModuleSelector< T> ( _ operation: ( inout Self ) -> T ? ) -> T ? {
68+ var lookahead = self . lookahead ( )
69+ lookahead. skipSingle ( )
70+ if lookahead. isAtModuleSelector ( ) {
71+ return nil
72+ }
73+ return operation ( & self )
74+ }
75+
76+ /// If the subsequent tokens have the form of a module selector, valid or otherwise, consume and return them;
77+ /// otherwise consume nothing and return `nil`. Additionally consumes invalid chained module selectors.
78+ ///
79+ /// Returns a tuple comprised of:
80+ ///
81+ /// - `moduleNameOrUnexpected`: The module name if present; in a valid module selector, this will be a present
82+ /// identifier, but either of those can be untrue in invalid code.
83+ /// - `colonColonToken`: The `::` indicating this module selector. Always `.colonColon`, always present.
84+ /// - `extra`: Tokens for additional trailing module selectors. There is no situation in which two module selectors
85+ /// can be validly chained.
86+ mutating func consumeModuleSelectorTokensIfPresent( ) -> (
87+ moduleNameOrUnexpected: Token , colonColonToken: Token , extra: [ Token ]
88+ ) ? {
89+ guard self . isAtModuleSelector ( ) else {
90+ return nil
91+ }
92+
93+ let moduleName : Token
94+ let colonColonToken : Token
95+
96+ // Did we forget the module name?
97+ if let earlyColonColon = self . consume ( if: . colonColon) {
98+ moduleName = self . missingToken ( . identifier)
99+ colonColonToken = earlyColonColon
100+ } else {
101+ // Consume whatever comes before the `::`, plus the `::` itself. (Whether or not the "name" is an identifier is
102+ // checked elsewhere.)
103+ moduleName = self . consumeAnyToken ( )
104+ colonColonToken = self . eat ( . colonColon)
105+ }
106+
107+ var extra : [ Token ] = [ ]
108+ while self . isAtModuleSelector ( ) {
109+ if !self . at ( . colonColon) {
110+ extra. append ( self . consumeAnyToken ( ) )
111+ }
112+ extra. append ( self . eat ( . colonColon) )
113+ }
114+ return ( moduleName, colonColonToken, extra)
115+ }
116+ }
117+
118+ extension Parser {
119+ /// Parses one or more module selectors, if present.
120+ mutating func parseModuleSelectorIfPresent( ) -> RawModuleSelectorSyntax ? {
121+ guard let ( moduleNameOrUnexpected, colonColon, extra) = consumeModuleSelectorTokensIfPresent ( ) else {
122+ return nil
123+ }
124+
125+ let leadingUnexpected : [ RawSyntax ]
126+ let moduleName : RawTokenSyntax
127+ let trailingUnexpected : [ RawSyntax ]
128+
129+ if moduleNameOrUnexpected. tokenKind == . identifier {
130+ leadingUnexpected = [ ]
131+ moduleName = moduleNameOrUnexpected
132+ } else {
133+ leadingUnexpected = [ RawSyntax ( moduleNameOrUnexpected) ]
134+ moduleName = RawTokenSyntax ( missing: . identifier, arena: arena)
135+ }
136+
137+ trailingUnexpected = extra. map { RawSyntax ( $0) }
138+
139+ return RawModuleSelectorSyntax (
140+ RawUnexpectedNodesSyntax ( leadingUnexpected, arena: arena) ,
141+ moduleName: moduleName,
142+ colonColon: colonColon,
143+ RawUnexpectedNodesSyntax ( trailingUnexpected, arena: arena) ,
144+ arena: arena
145+ )
146+ }
147+ }
148+
48149extension Parser {
49150 struct DeclNameOptions : OptionSet {
50151 var rawValue : UInt8
@@ -68,6 +169,12 @@ extension Parser {
68169 }
69170
70171 mutating func parseDeclReferenceExpr( _ flags: DeclNameOptions = [ ] ) -> RawDeclReferenceExprSyntax {
172+ // Consume a module selector if present.
173+ let moduleSelector = self . parseModuleSelectorIfPresent ( )
174+
175+ // If a module selector is found, we parse the name after it according to SE-0071 rules.
176+ let allowKeywords = flags. contains ( . keywords) || moduleSelector != nil
177+
71178 // Consume the base name.
72179 let base : RawTokenSyntax
73180 if let identOrSelf = self . consume ( if: . identifier, . keyword( . self ) , . keyword( . Self) )
@@ -80,7 +187,7 @@ extension Parser {
80187 let special = self . consume ( if: . keyword( . `deinit`) , . keyword( . `subscript`) )
81188 {
82189 base = special
83- } else if flags . contains ( . keywords ) && self . currentToken. isLexerClassifiedKeyword {
190+ } else if allowKeywords && self . currentToken. isLexerClassifiedKeyword {
84191 base = self . consumeAnyToken ( remapping: . identifier)
85192 } else {
86193 base = missingToken ( . identifier)
@@ -89,7 +196,7 @@ extension Parser {
89196 // Parse an argument list, if the flags allow it and it's present.
90197 let args = self . parseArgLabelList ( flags)
91198 return RawDeclReferenceExprSyntax (
92- moduleSelector: nil ,
199+ moduleSelector: moduleSelector ,
93200 baseName: base,
94201 argumentNames: args,
95202 arena: self . arena
@@ -212,12 +319,8 @@ extension Parser {
212319 var keepGoing = self . consume ( if: . period)
213320 var loopProgress = LoopProgressCondition ( )
214321 while keepGoing != nil && self . hasProgressed ( & loopProgress) {
215- let ( unexpectedBeforeName, name) = self . expect (
216- . identifier,
217- . keyword( . self ) ,
218- TokenSpec ( . Self, remapping: . identifier) ,
219- default: . identifier
220- )
322+ let memberModuleSelector = self . parseModuleSelectorIfPresent ( )
323+ let name = self . parseMemberTypeName ( )
221324 let generics : RawGenericArgumentClauseSyntax ?
222325 if self . at ( prefix: " < " ) {
223326 generics = self . parseGenericArguments ( )
@@ -228,8 +331,7 @@ extension Parser {
228331 RawMemberTypeSyntax (
229332 baseType: result,
230333 period: keepGoing!,
231- moduleSelector: nil ,
232- unexpectedBeforeName,
334+ moduleSelector: memberModuleSelector,
233335 name: name,
234336 genericArgumentClause: generics,
235337 arena: self . arena
0 commit comments