@@ -45,6 +45,107 @@ extension Parser {
45
45
}
46
46
}
47
47
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 `consumeModuleSelectorTokens()`.
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 `::`. `consumeModuleSelectorTokens()` will create a
57
+ // 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 ('_', operators, certain keywords).
63
+ return self . at ( . identifier, . wildcard, . binaryOperator)
64
+ || self . at ( . keyword( . self ) , . keyword( . Self) , . keyword( . super) ) || self . at ( . keyword( . Any) )
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 consumeModuleSelectorTokens( ) -> (
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) = consumeModuleSelectorTokens ( ) 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
+
48
149
extension Parser {
49
150
struct DeclNameOptions : OptionSet {
50
151
var rawValue : UInt8
@@ -68,6 +169,12 @@ extension Parser {
68
169
}
69
170
70
171
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
+
71
178
// Consume the base name.
72
179
let base : RawTokenSyntax
73
180
if let identOrSelf = self . consume ( if: . identifier, . keyword( . self ) , . keyword( . Self) )
@@ -80,7 +187,7 @@ extension Parser {
80
187
let special = self . consume ( if: . keyword( . `deinit`) , . keyword( . `subscript`) )
81
188
{
82
189
base = special
83
- } else if flags . contains ( . keywords ) && self . currentToken. isLexerClassifiedKeyword {
190
+ } else if allowKeywords && self . currentToken. isLexerClassifiedKeyword {
84
191
base = self . consumeAnyToken ( remapping: . identifier)
85
192
} else {
86
193
base = missingToken ( . identifier)
@@ -89,7 +196,7 @@ extension Parser {
89
196
// Parse an argument list, if the flags allow it and it's present.
90
197
let args = self . parseArgLabelList ( flags)
91
198
return RawDeclReferenceExprSyntax (
92
- moduleSelector: nil ,
199
+ moduleSelector: moduleSelector ,
93
200
baseName: base,
94
201
argumentNames: args,
95
202
arena: self . arena
@@ -212,12 +319,8 @@ extension Parser {
212
319
var keepGoing = self . consume ( if: . period)
213
320
var loopProgress = LoopProgressCondition ( )
214
321
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 ( )
221
324
let generics : RawGenericArgumentClauseSyntax ?
222
325
if self . at ( prefix: " < " ) {
223
326
generics = self . parseGenericArguments ( )
@@ -228,8 +331,7 @@ extension Parser {
228
331
RawMemberTypeSyntax (
229
332
baseType: result,
230
333
period: keepGoing!,
231
- moduleSelector: nil ,
232
- unexpectedBeforeName,
334
+ moduleSelector: memberModuleSelector,
233
335
name: name,
234
336
genericArgumentClause: generics,
235
337
arena: self . arena
0 commit comments