@@ -26,6 +26,20 @@ protocol TokenSpecSet: CaseIterable {
26
26
init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures )
27
27
}
28
28
29
+ protocol MisspelledTokenSpecSet : TokenSpecSet {
30
+ associatedtype CorrectSpecSet : TokenSpecSet
31
+
32
+ typealias FuzzyMatchSpecSet = EitherTokenSpecSet < Self , CorrectSpecSet >
33
+
34
+ var correctSpecSet : CorrectSpecSet { get }
35
+ }
36
+
37
+ extension MisspelledTokenSpecSet {
38
+ var spec : TokenSpec {
39
+ TokenSpec ( . identifier, recoveryPrecedence: correctSpecSet. spec. recoveryPrecedence)
40
+ }
41
+ }
42
+
29
43
/// A way to combine two token spec sets into an aggregate token spec set.
30
44
enum EitherTokenSpecSet < LHS: TokenSpecSet , RHS: TokenSpecSet > : TokenSpecSet {
31
45
case lhs( LHS )
@@ -58,6 +72,17 @@ enum EitherTokenSpecSet<LHS: TokenSpecSet, RHS: TokenSpecSet>: TokenSpecSet {
58
72
}
59
73
}
60
74
75
+ extension EitherTokenSpecSet where LHS: MisspelledTokenSpecSet , RHS == LHS . CorrectSpecSet {
76
+ var correctSpecSet : RHS {
77
+ switch self {
78
+ case . lhs( let misspelled) :
79
+ return misspelled. correctSpecSet
80
+ case . rhs( let correct) :
81
+ return correct
82
+ }
83
+ }
84
+ }
85
+
61
86
// MARK: - Subsets
62
87
63
88
enum AccessorModifier : TokenSpecSet {
@@ -89,6 +114,42 @@ enum AccessorModifier: TokenSpecSet {
89
114
}
90
115
}
91
116
117
+ enum MisspelledAccessorModifier : MisspelledTokenSpecSet {
118
+ case consuming
119
+ case borrowing
120
+ case nonmutating
121
+
122
+ var correctSpecSet : AccessorModifier {
123
+ switch self {
124
+ case . consuming: return . consuming
125
+ case . borrowing: return . borrowing
126
+ case . nonmutating: return . nonmutating
127
+ }
128
+ }
129
+
130
+ init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
131
+ let text = lexeme. tokenText
132
+ switch text. count {
133
+ case 6 :
134
+ switch text {
135
+ case " borrow " : self = . borrowing
136
+ default : return nil
137
+ }
138
+ case 7 :
139
+ switch text {
140
+ case " consume " : self = . consuming
141
+ default : return nil
142
+ }
143
+ case 11 :
144
+ switch text {
145
+ case " nonMutating " : self = . nonmutating
146
+ default : return nil
147
+ }
148
+ default : return nil
149
+ }
150
+ }
151
+ }
152
+
92
153
enum CanBeStatementStart : TokenSpecSet {
93
154
case `break`
94
155
case `continue`
@@ -151,6 +212,35 @@ enum CanBeStatementStart: TokenSpecSet {
151
212
}
152
213
}
153
214
215
+ enum MisspelledCanBeStatementStart : MisspelledTokenSpecSet {
216
+ case `guard`
217
+ case `switch`
218
+
219
+ var correctSpecSet : CanBeStatementStart {
220
+ switch self {
221
+ case . guard: return . guard
222
+ case . switch: return . switch
223
+ }
224
+ }
225
+
226
+ init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
227
+ let text = lexeme. tokenText
228
+ switch text. count {
229
+ case 5 :
230
+ switch text {
231
+ case " gaurd " : self = . guard
232
+ default : return nil
233
+ }
234
+ case 6 :
235
+ switch text {
236
+ case " siwtch " : self = . switch
237
+ default : return nil
238
+ }
239
+ default : return nil
240
+ }
241
+ }
242
+ }
243
+
154
244
enum CompilationCondition : TokenSpecSet {
155
245
case swift
156
246
case compiler
@@ -266,7 +356,6 @@ enum ContextualDeclKeyword: TokenSpecSet {
266
356
}
267
357
}
268
358
}
269
-
270
359
/// A `DeclarationKeyword` that is not a `ValueBindingPatternSyntax.BindingSpecifierOptions`.
271
360
///
272
361
/// `ValueBindingPatternSyntax.BindingSpecifierOptions` are injected into
@@ -339,6 +428,80 @@ enum PureDeclarationKeyword: TokenSpecSet {
339
428
}
340
429
}
341
430
431
+ enum MisspelledPureDeclarationKeyword : MisspelledTokenSpecSet {
432
+ case `associatedtype`
433
+ case `class`
434
+ case `deinit`
435
+ case `func`
436
+ case `init`
437
+ case `precedencegroup`
438
+ case `protocol`
439
+ case `typealias`
440
+
441
+ var correctSpecSet : PureDeclarationKeyword {
442
+ switch self {
443
+ case . associatedtype: return . associatedtype
444
+ case . class: return . class
445
+ case . deinit: return . deinit
446
+ case . func: return . func
447
+ case . `init`: return . `init`
448
+ case . precedencegroup: return . precedencegroup
449
+ case . protocol: return . protocol
450
+ case . typealias: return . typealias
451
+ }
452
+ }
453
+
454
+ init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
455
+ let text = lexeme. tokenText
456
+ switch text. count {
457
+ case 3 :
458
+ switch text {
459
+ case " def " : self = . func
460
+ case " fun " : self = . func
461
+ default : return nil
462
+ }
463
+ case 6 :
464
+ switch text {
465
+ case " deInit " : self = . deinit
466
+ case " object " : self = . class
467
+ default : return nil
468
+ }
469
+ case 8 :
470
+ switch text {
471
+ case " function " : self = . func
472
+ default : return nil
473
+ }
474
+ case 9 :
475
+ switch text {
476
+ case " interface " : self = . protocol
477
+ case " typeAlias " : self = . typealias
478
+ default : return nil
479
+ }
480
+ case 11 :
481
+ switch text {
482
+ case " constructor " : self = . `init`
483
+ default : return nil
484
+ }
485
+ case 13 :
486
+ switch text {
487
+ case " associatetype " , " associateType " : self = . associatedtype
488
+ default : return nil
489
+ }
490
+ case 14 :
491
+ switch text {
492
+ case " associatedType " : self = . associatedtype
493
+ default : return nil
494
+ }
495
+ case 15 :
496
+ switch text {
497
+ case " precedenceGroup " : self = . precedencegroup
498
+ default : return nil
499
+ }
500
+ default : return nil
501
+ }
502
+ }
503
+ }
504
+
342
505
typealias DeclarationKeyword = EitherTokenSpecSet <
343
506
PureDeclarationKeyword ,
344
507
ValueBindingPatternSyntax . BindingSpecifierOptions
0 commit comments