17
17
#include " TypeChecker.h"
18
18
#include " swift/AST/ASTContext.h"
19
19
#include " swift/AST/ASTVisitor.h"
20
+ #include " swift/AST/ASTWalker.h"
20
21
#include " swift/AST/DiagnosticsFrontend.h"
21
22
#include " swift/AST/Expr.h"
22
23
#include " swift/AST/NameLookup.h"
30
31
using namespace swift ;
31
32
32
33
namespace {
34
+
35
+ // / Find available closure discriminators.
36
+ // /
37
+ // / The parser typically takes care of assigning unique discriminators to
38
+ // / closures, but the parser is unavailable to this transform.
39
+ class DiscriminatorFinder : public ASTWalker {
40
+ unsigned NextDiscriminator = 0 ;
41
+
42
+ public:
43
+ Expr *walkToExprPost (Expr *E) override {
44
+ auto *ACE = dyn_cast<AbstractClosureExpr>(E);
45
+ if (!ACE)
46
+ return E;
47
+
48
+ unsigned Discriminator = ACE->getDiscriminator ();
49
+ assert (Discriminator != AbstractClosureExpr::InvalidDiscriminator &&
50
+ " Existing closures should have valid discriminators" );
51
+ if (Discriminator >= NextDiscriminator)
52
+ NextDiscriminator = Discriminator + 1 ;
53
+ return E;
54
+ }
55
+
56
+ // Get the next available closure discriminator.
57
+ unsigned getNextDiscriminator () {
58
+ if (NextDiscriminator == AbstractClosureExpr::InvalidDiscriminator)
59
+ llvm::report_fatal_error (" Out of valid closure discriminators" );
60
+ return NextDiscriminator++;
61
+ }
62
+ };
63
+
33
64
struct REPLContext {
34
65
ASTContext &Context;
35
66
SourceFile &SF;
@@ -182,14 +213,14 @@ struct PatternBindingPrintLHS : public ASTVisitor<PatternBindingPrintLHS> {
182
213
183
214
namespace {
184
215
class REPLChecker : public REPLContext {
185
- TopLevelContext &TLC ;
216
+ DiscriminatorFinder &DF ;
186
217
187
218
// / The index of the next response metavariable to bind to a REPL result.
188
219
unsigned NextResponseVariableIndex = 0 ;
189
220
190
221
public:
191
- REPLChecker (SourceFile &SF, TopLevelContext &TLC )
192
- : REPLContext(SF), TLC(TLC ) {}
222
+ REPLChecker (SourceFile &SF, DiscriminatorFinder &DF )
223
+ : REPLContext(SF), DF(DF ) {}
193
224
194
225
void processREPLTopLevelExpr (Expr *E);
195
226
void processREPLTopLevelPatternBinding (PatternBindingDecl *PBD);
@@ -222,7 +253,7 @@ void REPLChecker::generatePrintOfExpression(StringRef NameStr, Expr *E) {
222
253
Arg->setSpecifier (ParamSpecifier::Default);
223
254
auto params = ParameterList::createWithoutLoc (Arg);
224
255
225
- unsigned discriminator = TLC. claimNextClosureDiscriminator ();
256
+ unsigned discriminator = DF. getNextDiscriminator ();
226
257
227
258
ClosureExpr *CE =
228
259
new (Context) ClosureExpr (params, SourceLoc (), SourceLoc (), SourceLoc (),
@@ -429,13 +460,18 @@ Identifier REPLChecker::getNextResponseVariableName(DeclContext *DC) {
429
460
// / processREPLTopLevel - This is called after we've parsed and typechecked some
430
461
// / new decls at the top level. We inject code to print out expressions and
431
462
// / pattern bindings the are evaluated.
432
- void TypeChecker::processREPLTopLevel (SourceFile &SF, TopLevelContext &TLC,
433
- unsigned FirstDecl) {
463
+ void TypeChecker::processREPLTopLevel (SourceFile &SF, unsigned FirstDecl) {
464
+ // Walk over all decls in the file to find the next available closure
465
+ // discriminator.
466
+ DiscriminatorFinder DF;
467
+ for (Decl *D : SF.Decls )
468
+ D->walk (DF);
469
+
434
470
// Move new declarations out.
435
471
std::vector<Decl *> NewDecls (SF.Decls .begin ()+FirstDecl, SF.Decls .end ());
436
472
SF.Decls .resize (FirstDecl);
437
473
438
- REPLChecker RC (SF, TLC );
474
+ REPLChecker RC (SF, DF );
439
475
440
476
// Loop over each of the new decls, processing them, adding them back to
441
477
// the Decls list.
@@ -455,7 +491,7 @@ void TypeChecker::processREPLTopLevel(SourceFile &SF, TopLevelContext &TLC,
455
491
if (auto *PBD = dyn_cast<PatternBindingDecl>(D))
456
492
RC.processREPLTopLevelPatternBinding (PBD);
457
493
458
- contextualizeTopLevelCode (TLC, TLCD);
494
+ TypeChecker:: contextualizeTopLevelCode (TLCD);
459
495
}
460
496
461
497
SF.clearLookupCache ();
0 commit comments