Skip to content

Commit ba525b3

Browse files
committed
[NFC] Refactor DeclarationKeyword
It actually ought to be the union of three token kind subsets; turn it into a custom type so we can do that.
1 parent cd53600 commit ba525b3

File tree

2 files changed

+113
-90
lines changed

2 files changed

+113
-90
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ extension TokenConsumer {
110110
declStartKeyword = subparser.at(anyIn: DeclarationKeyword.self)?.0
111111
}
112112
switch declStartKeyword {
113-
case .lhs(.actor):
113+
case .group(.actor):
114114
// actor Foo {}
115115
if subparser.peek().rawTokenKind == .identifier {
116116
return true
@@ -123,16 +123,16 @@ extension TokenConsumer {
123123
lookahead.consumeAnyToken()
124124
} while lookahead.atStartOfDeclaration(isAtTopLevel: isAtTopLevel, allowInitDecl: allowInitDecl)
125125
return lookahead.at(.identifier)
126-
case .lhs(.case):
126+
case .simple(.case):
127127
// When 'case' appears inside a function, it's probably a switch
128128
// case, not an enum case declaration.
129129
return false
130-
case .lhs(.`init`):
130+
case .simple(.`init`):
131131
return allowInitDecl
132-
case .lhs(.macro):
132+
case .simple(.macro):
133133
// macro Foo ...
134134
return subparser.peek().rawTokenKind == .identifier
135-
case .lhs(.pound):
135+
case .simple(.pound):
136136
// Force parsing '#<identifier>' after attributes as a macro expansion decl.
137137
if hasAttribute || hasModifier {
138138
return true
@@ -215,7 +215,7 @@ extension Parser {
215215
} else if atFunctionDeclarationWithoutFuncKeyword() {
216216
// We aren't at a declaration keyword and it looks like we are at a function
217217
// declaration. Parse a function declaration.
218-
recoveryResult = (.lhs(.func), .missing(.keyword(.func)))
218+
recoveryResult = (.simple(.func), .missing(.keyword(.func)))
219219
} else {
220220
// In all other cases, use standard token recovery to find the declaration
221221
// to parse.
@@ -226,53 +226,53 @@ extension Parser {
226226
}
227227

228228
switch recoveryResult {
229-
case (.lhs(.import), let handle)?:
229+
case (.simple(.import), let handle)?:
230230
return RawDeclSyntax(self.parseImportDeclaration(attrs, handle))
231-
case (.lhs(.class), let handle)?:
231+
case (.group(.class), let handle)?:
232232
return RawDeclSyntax(
233233
self.parseNominalTypeDeclaration(for: RawClassDeclSyntax.self, attrs: attrs, introucerHandle: handle)
234234
)
235-
case (.lhs(.enum), let handle)?:
235+
case (.group(.enum), let handle)?:
236236
return RawDeclSyntax(
237237
self.parseNominalTypeDeclaration(for: RawEnumDeclSyntax.self, attrs: attrs, introucerHandle: handle)
238238
)
239-
case (.lhs(.case), let handle)?:
239+
case (.simple(.case), let handle)?:
240240
return RawDeclSyntax(self.parseEnumCaseDeclaration(attrs, handle))
241-
case (.lhs(.struct), let handle)?:
241+
case (.group(.struct), let handle)?:
242242
return RawDeclSyntax(
243243
self.parseNominalTypeDeclaration(for: RawStructDeclSyntax.self, attrs: attrs, introucerHandle: handle)
244244
)
245-
case (.lhs(.protocol), let handle)?:
245+
case (.group(.protocol), let handle)?:
246246
return RawDeclSyntax(
247247
self.parseNominalTypeDeclaration(for: RawProtocolDeclSyntax.self, attrs: attrs, introucerHandle: handle)
248248
)
249-
case (.lhs(.associatedtype), let handle)?:
249+
case (.simple(.associatedtype), let handle)?:
250250
return RawDeclSyntax(self.parseAssociatedTypeDeclaration(attrs, handle))
251-
case (.lhs(.typealias), let handle)?:
251+
case (.simple(.typealias), let handle)?:
252252
return RawDeclSyntax(self.parseTypealiasDeclaration(attrs, handle))
253-
case (.lhs(.extension), let handle)?:
253+
case (.group(.extension), let handle)?:
254254
return RawDeclSyntax(self.parseExtensionDeclaration(attrs, handle))
255-
case (.lhs(.func), let handle)?:
255+
case (.simple(.func), let handle)?:
256256
return RawDeclSyntax(self.parseFuncDeclaration(attrs, handle))
257-
case (.lhs(.subscript), let handle)?:
257+
case (.simple(.subscript), let handle)?:
258258
return RawDeclSyntax(self.parseSubscriptDeclaration(attrs, handle))
259-
case (.lhs(.`init`), let handle)?:
259+
case (.simple(.`init`), let handle)?:
260260
return RawDeclSyntax(self.parseInitializerDeclaration(attrs, handle))
261-
case (.lhs(.deinit), let handle)?:
261+
case (.simple(.deinit), let handle)?:
262262
return RawDeclSyntax(self.parseDeinitializerDeclaration(attrs, handle))
263-
case (.lhs(.operator), let handle)?:
263+
case (.simple(.operator), let handle)?:
264264
return RawDeclSyntax(self.parseOperatorDeclaration(attrs, handle))
265-
case (.lhs(.precedencegroup), let handle)?:
265+
case (.simple(.precedencegroup), let handle)?:
266266
return RawDeclSyntax(self.parsePrecedenceGroupDeclaration(attrs, handle))
267-
case (.lhs(.actor), let handle)?:
267+
case (.group(.actor), let handle)?:
268268
return RawDeclSyntax(
269269
self.parseNominalTypeDeclaration(for: RawActorDeclSyntax.self, attrs: attrs, introucerHandle: handle)
270270
)
271-
case (.lhs(.macro), let handle)?:
271+
case (.simple(.macro), let handle)?:
272272
return RawDeclSyntax(self.parseMacroDeclaration(attrs: attrs, introducerHandle: handle))
273-
case (.lhs(.pound), let handle)?:
273+
case (.simple(.pound), let handle)?:
274274
return RawDeclSyntax(self.parseMacroExpansionDeclaration(attrs, handle))
275-
case (.rhs, let handle)?:
275+
case (.binding, let handle)?:
276276
return RawDeclSyntax(self.parseBindingDeclaration(attrs, handle, inMemberDeclList: inMemberDeclList))
277277
case nil:
278278
break

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 88 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -267,82 +267,105 @@ enum ContextualDeclKeyword: TokenSpecSet {
267267
}
268268
}
269269

270-
/// A `DeclarationKeyword` that is not a `ValueBindingPatternSyntax.BindingSpecifierOptions`.
271-
///
272-
/// `ValueBindingPatternSyntax.BindingSpecifierOptions` are injected into
273-
/// `DeclarationKeyword` via an `EitherTokenSpecSet`.
274-
enum PureDeclarationKeyword: TokenSpecSet {
275-
case actor
276-
case `associatedtype`
277-
case `case`
278-
case `class`
279-
case `deinit`
280-
case `enum`
281-
case `extension`
282-
case `func`
283-
case `import`
284-
case `init`
285-
case macro
286-
case `operator`
287-
case `precedencegroup`
288-
case `protocol`
289-
case `struct`
290-
case `subscript`
291-
case `typealias`
292-
case pound
270+
/// Union of the following token kind subsets:
271+
/// - `ValueBindingPatternSyntax.BindingSpecifierOptions`
272+
/// - `DeclGroupHeaderSyntax.IntroducerOptions`
273+
/// - `DeclarationKeyword.Simple` (containing other declaration keywords)
274+
enum DeclarationKeyword: TokenSpecSet {
275+
/// A keyword introducing a binding declaration (a declaration which binds patterns to values).
276+
case binding(Binding)
277+
278+
/// A keyword introducing a declaration group (a declaration with a member block).
279+
case group(Group)
280+
281+
/// A keyword introducing a simple declaration (a declaration which is neither a group nor a binding).
282+
case simple(Simple)
293283

294284
init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) {
295-
switch PrepareForKeywordMatch(lexeme) {
296-
case TokenSpec(.actor): self = .actor
297-
case TokenSpec(.macro): self = .macro
298-
case TokenSpec(.associatedtype): self = .associatedtype
299-
case TokenSpec(.case): self = .case
300-
case TokenSpec(.class): self = .class
301-
case TokenSpec(.deinit): self = .deinit
302-
case TokenSpec(.enum): self = .enum
303-
case TokenSpec(.extension): self = .extension
304-
case TokenSpec(.func): self = .func
305-
case TokenSpec(.import): self = .import
306-
case TokenSpec(.`init`): self = .`init`
307-
case TokenSpec(.operator): self = .operator
308-
case TokenSpec(.precedencegroup): self = .precedencegroup
309-
case TokenSpec(.protocol): self = .protocol
310-
case TokenSpec(.struct): self = .struct
311-
case TokenSpec(.subscript): self = .subscript
312-
case TokenSpec(.typealias): self = .typealias
313-
case TokenSpec(.pound): self = .pound
314-
default: return nil
285+
if let simple = Simple(lexeme: lexeme, experimentalFeatures: experimentalFeatures) {
286+
self = .simple(simple)
287+
}
288+
else if let group = DeclGroupHeaderSyntax.IntroducerOptions(lexeme: lexeme, experimentalFeatures: experimentalFeatures) {
289+
self = .group(group)
290+
}
291+
else if let binding = ValueBindingPatternSyntax.BindingSpecifierOptions(lexeme: lexeme, experimentalFeatures: experimentalFeatures) {
292+
self = .binding(binding)
293+
}
294+
else {
295+
return nil
315296
}
316297
}
317298

318299
var spec: TokenSpec {
319300
switch self {
320-
case .actor: return TokenSpec(.actor, recoveryPrecedence: .declKeyword)
321-
case .associatedtype: return .keyword(.associatedtype)
322-
case .case: return TokenSpec(.case, recoveryPrecedence: .declKeyword)
323-
case .class: return .keyword(.class)
324-
case .deinit: return .keyword(.deinit)
325-
case .enum: return .keyword(.enum)
326-
case .extension: return .keyword(.extension)
327-
case .func: return .keyword(.func)
328-
case .import: return .keyword(.import)
329-
case .`init`: return .keyword(.`init`)
330-
case .macro: return TokenSpec(.macro, recoveryPrecedence: .declKeyword)
331-
case .operator: return .keyword(.operator)
332-
case .precedencegroup: return .keyword(.precedencegroup)
333-
case .protocol: return .keyword(.protocol)
334-
case .struct: return .keyword(.struct)
335-
case .subscript: return .keyword(.subscript)
336-
case .typealias: return .keyword(.typealias)
337-
case .pound: return TokenSpec(.pound, recoveryPrecedence: .openingPoundIf)
301+
case .simple(let simple): return simple.spec
302+
case .group(let group): return group.spec
303+
case .binding(let binding): return binding.spec
304+
}
305+
}
306+
307+
static let allCases: [DeclarationKeyword] = Binding.allCases.map { .binding($0) } + Group.allCases.map { .group($0) } + Simple.allCases.map { .simple($0) }
308+
}
309+
310+
extension DeclarationKeyword {
311+
/// Type for a keyword introducing a binding declaration (a declaration which binds patterns to values).
312+
typealias Binding = ValueBindingPatternSyntax.BindingSpecifierOptions
313+
314+
/// Type for a keyword introducing a declaration group (a declaration with a member block).
315+
typealias Group = DeclGroupHeaderSyntax.IntroducerOptions
316+
317+
/// Type for a keyword introducing a simple declaration (a declaration which is neither a group nor a binding).
318+
enum Simple: TokenSpecSet {
319+
case `associatedtype`
320+
case `case`
321+
case `deinit`
322+
case `func`
323+
case `import`
324+
case `init`
325+
case macro
326+
case `operator`
327+
case `precedencegroup`
328+
case `subscript`
329+
case `typealias`
330+
case pound
331+
332+
init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) {
333+
switch PrepareForKeywordMatch(lexeme) {
334+
case TokenSpec(.macro): self = .macro
335+
case TokenSpec(.associatedtype): self = .associatedtype
336+
case TokenSpec(.case): self = .case
337+
case TokenSpec(.deinit): self = .deinit
338+
case TokenSpec(.func): self = .func
339+
case TokenSpec(.import): self = .import
340+
case TokenSpec(.`init`): self = .`init`
341+
case TokenSpec(.operator): self = .operator
342+
case TokenSpec(.precedencegroup): self = .precedencegroup
343+
case TokenSpec(.subscript): self = .subscript
344+
case TokenSpec(.typealias): self = .typealias
345+
case TokenSpec(.pound): self = .pound
346+
default: return nil
347+
}
348+
}
349+
350+
var spec: TokenSpec {
351+
switch self {
352+
case .associatedtype: return .keyword(.associatedtype)
353+
case .case: return TokenSpec(.case, recoveryPrecedence: .declKeyword)
354+
case .deinit: return .keyword(.deinit)
355+
case .func: return .keyword(.func)
356+
case .import: return .keyword(.import)
357+
case .`init`: return .keyword(.`init`)
358+
case .macro: return TokenSpec(.macro, recoveryPrecedence: .declKeyword)
359+
case .operator: return .keyword(.operator)
360+
case .precedencegroup: return .keyword(.precedencegroup)
361+
case .subscript: return .keyword(.subscript)
362+
case .typealias: return .keyword(.typealias)
363+
case .pound: return TokenSpec(.pound, recoveryPrecedence: .openingPoundIf)
364+
}
338365
}
339366
}
340367
}
341368

342-
typealias DeclarationKeyword = EitherTokenSpecSet<
343-
PureDeclarationKeyword,
344-
ValueBindingPatternSyntax.BindingSpecifierOptions
345-
>
346369

347370
enum DeclarationModifier: TokenSpecSet {
348371
case __consuming

0 commit comments

Comments
 (0)