@@ -45,6 +45,151 @@ extension Parser {
45
45
}
46
46
}
47
47
48
+ private enum StructuralTokens : TokenSpecSet {
49
+ case comma
50
+ case colon
51
+ case leftParen
52
+ case leftBrace
53
+ case leftSquare
54
+ case leftAngle
55
+ case rightParen
56
+ case rightBrace
57
+ case rightSquare
58
+ case rightAngle
59
+
60
+ init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
61
+ switch lexeme. rawTokenKind {
62
+ case . comma: self = . comma
63
+ case . colon: self = . colon
64
+ case . leftParen: self = . leftParen
65
+ case . leftBrace: self = . leftBrace
66
+ case . leftSquare: self = . leftSquare
67
+ case . leftAngle: self = . leftAngle
68
+ case . rightParen: self = . rightParen
69
+ case . rightBrace: self = . rightBrace
70
+ case . rightSquare: self = . rightSquare
71
+ case . rightAngle: self = . rightAngle
72
+ default : return nil
73
+ }
74
+ }
75
+
76
+ var spec : TokenSpec {
77
+ switch self {
78
+ case . comma: return . comma
79
+ case . colon: return . colon
80
+ case . leftParen: return . leftParen
81
+ case . leftBrace: return . leftBrace
82
+ case . leftSquare: return . leftSquare
83
+ case . leftAngle: return . leftAngle
84
+ case . rightParen: return . rightParen
85
+ case . rightBrace: return . rightBrace
86
+ case . rightSquare: return . rightSquare
87
+ case . rightAngle: return . rightAngle
88
+ }
89
+ }
90
+ }
91
+
92
+ extension TokenConsumer {
93
+ /// Do the subsequent tokens have the form of a module selector? Encompasses some invalid syntax which nonetheless
94
+ /// can be handled by `consumeModuleSelectorTokens()`.
95
+ ///
96
+ /// - Postcondition: If `true`, either the current token or the next token is `.colonColon`.
97
+ mutating func isAtModuleSelector( ) -> Bool {
98
+ // If this is a module selector, the next token should be `::`.
99
+ guard self . peek ( isAt: . colonColon) else {
100
+ // ...however, we will also allow the *current* token to be `::`. `consumeModuleSelectorTokens()` will create a
101
+ // missing identifier.
102
+ return self . at ( . colonColon)
103
+ }
104
+
105
+ // Technically the current token *should* be an identifier, but we also want to diagnose other tokens that might be
106
+ // used by accident (particularly keywords and `_`). However, we don't want to consume tokens which would make the
107
+ // surrounding structure mis-parse.
108
+ return self . at ( anyIn: StructuralTokens . self) == nil
109
+ }
110
+
111
+ mutating func unlessPeekModuleSelector< T> ( _ operation: ( inout Self ) -> T ? ) -> T ? {
112
+ var lookahead = self . lookahead ( )
113
+ lookahead. skipSingle ( )
114
+ if lookahead. isAtModuleSelector ( ) {
115
+ return nil
116
+ }
117
+ return operation ( & self )
118
+ }
119
+
120
+ /// If the subsequent tokens have the form of a module selector, valid or otherwise, consume and return them;
121
+ /// otherwise consume nothing and return `nil`. Additionally consumes invalid chained module selectors.
122
+ ///
123
+ /// Returns a tuple comprised of:
124
+ ///
125
+ /// - `moduleNameOrUnexpected`: The module name if present; in a valid module selector, this will be a present
126
+ /// identifier, but either of those can be untrue in invalid code.
127
+ /// - `colonColonToken`: The `::` indicating this module selector. Always `.colonColon`, always present.
128
+ /// - `extra`: Tokens for additional trailing module selectors. There is no situation in which two module selectors
129
+ /// can be validly chained.
130
+ mutating func consumeModuleSelectorTokens( ) -> (
131
+ moduleNameOrUnexpected: Token , colonColonToken: Token , extra: [ Token ]
132
+ ) ? {
133
+ guard self . isAtModuleSelector ( ) else {
134
+ return nil
135
+ }
136
+
137
+ let moduleName : Token
138
+ let colonColonToken : Token
139
+
140
+ // Did we forget the module name?
141
+ if let earlyColonColon = self . consume ( if: . colonColon) {
142
+ moduleName = self . missingToken ( . identifier)
143
+ colonColonToken = earlyColonColon
144
+ } else {
145
+ // Consume whatever comes before the `::`, plus the `::` itself. (Whether or not the "name" is an identifier is
146
+ // checked elsewhere.)
147
+ moduleName = self . consumeAnyToken ( )
148
+ colonColonToken = self . eat ( . colonColon)
149
+ }
150
+
151
+ var extra : [ Token ] = [ ]
152
+ while self . isAtModuleSelector ( ) {
153
+ if !self . at ( . colonColon) {
154
+ extra. append ( self . consumeAnyToken ( ) )
155
+ }
156
+ extra. append ( self . eat ( . colonColon) )
157
+ }
158
+ return ( moduleName, colonColonToken, extra)
159
+ }
160
+ }
161
+
162
+ extension Parser {
163
+ /// Parses one or more module selectors, if present.
164
+ mutating func parseModuleSelector( ) -> RawModuleSelectorSyntax ? {
165
+ guard let ( moduleNameOrUnexpected, colonColon, extra) = consumeModuleSelectorTokens ( ) else {
166
+ return nil
167
+ }
168
+
169
+ let leadingUnexpected : [ RawSyntax ]
170
+ let moduleName : RawTokenSyntax
171
+ let trailingUnexpected : [ RawSyntax ]
172
+
173
+ if moduleNameOrUnexpected. tokenKind == . identifier {
174
+ leadingUnexpected = [ ]
175
+ moduleName = moduleNameOrUnexpected
176
+ } else {
177
+ leadingUnexpected = [ RawSyntax ( moduleNameOrUnexpected) ]
178
+ moduleName = RawTokenSyntax . init ( missing: . identifier, arena: arena)
179
+ }
180
+
181
+ trailingUnexpected = extra. map { RawSyntax ( $0) }
182
+
183
+ return RawModuleSelectorSyntax (
184
+ RawUnexpectedNodesSyntax ( leadingUnexpected, arena: arena) ,
185
+ moduleName: moduleName,
186
+ colonColon: colonColon,
187
+ RawUnexpectedNodesSyntax ( trailingUnexpected, arena: arena) ,
188
+ arena: arena
189
+ )
190
+ }
191
+ }
192
+
48
193
extension Parser {
49
194
struct DeclNameOptions : OptionSet {
50
195
var rawValue : UInt8
@@ -68,6 +213,9 @@ extension Parser {
68
213
}
69
214
70
215
mutating func parseDeclReferenceExpr( _ flags: DeclNameOptions = [ ] ) -> RawDeclReferenceExprSyntax {
216
+ // Consume a module selector if present.
217
+ let moduleSelector = self . parseModuleSelector ( )
218
+
71
219
// Consume the base name.
72
220
let base : RawTokenSyntax
73
221
if let identOrSelf = self . consume ( if: . identifier, . keyword( . self ) , . keyword( . Self) )
@@ -89,7 +237,7 @@ extension Parser {
89
237
// Parse an argument list, if the flags allow it and it's present.
90
238
let args = self . parseArgLabelList ( flags)
91
239
return RawDeclReferenceExprSyntax (
92
- moduleSelector: nil ,
240
+ moduleSelector: moduleSelector ,
93
241
baseName: base,
94
242
argumentNames: args,
95
243
arena: self . arena
@@ -212,6 +360,7 @@ extension Parser {
212
360
var keepGoing = self . consume ( if: . period)
213
361
var loopProgress = LoopProgressCondition ( )
214
362
while keepGoing != nil && self . hasProgressed ( & loopProgress) {
363
+ let memberModuleSelector = self . parseModuleSelector ( )
215
364
let ( unexpectedBeforeName, name) = self . expect (
216
365
. identifier,
217
366
. keyword( . self ) ,
@@ -228,7 +377,7 @@ extension Parser {
228
377
RawMemberTypeSyntax (
229
378
baseType: result,
230
379
period: keepGoing!,
231
- moduleSelector: nil ,
380
+ moduleSelector: memberModuleSelector ,
232
381
unexpectedBeforeName,
233
382
name: name,
234
383
genericArgumentClause: generics,
0 commit comments